Skip to content

Bring Peter's club-member redesign to a staged release - #3

Merged
oliverdougherC merged 29 commits into
mainfrom
feat/peter-foreground
Sep 23, 2026
Merged

oliverdougherC merged 29 commits into
mainfrom
feat/peter-foreground

Conversation

@oliverdougherC

@oliverdougherC oliverdougherC commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Scope

This draft PR is stacked on draft PR #2 (feat/hermes-peter, base 332d366). Head c900f0e on feat/peter-foreground; P910 runs gateway code revision 2800d97 with VM runner/worker revision 08c8968. The head follows those image builds with documentation only. Local backlog keys PETER-01 through PETER-17 are mapped in the requirement-to-evidence matrix; they are not published issue numbers.

Peter has one durable foreground slot; audience-scoped conversation, club facts and project files; private officer controls; honest progress and cancellation; durable delivery; and a capability-bound announcement outbox. A dedicated P910 VM runs pinned Rust and controlled wheel/crate access without general worker egress. Requested files and sandbox work require actual worker results.

Follow-up quality fixes

  • Bare greetings get a one- or two-word casual reply. Ordinary answers use fewer words and lighter punctuation. Peter-authored Discord text contains no em dashes; verified worker stages appear as short playful lines with elapsed time.
  • The configured chat allowance increased from 3 to 20 per user and from 15 to 120 per guild per minute. The scoped conversation lease renews on each accepted follow-up for five minutes. Nah, no longer gets mistaken for another person's name, and a final-line Peter can address him.
  • Qwen3.8 Flash Next is sourced from the trusted runtime setting. Peter now accepts the user's correction instead of claiming Claude; he does not persist his runtime model as a club fact that could become stale. A natural ordinary remember that request hands off to the worker, whose broker enforces current officer permission for club memory. Bounded saved public notes reach later chat without exposing personal memory.
  • Private #testing joined #officers as a configured officer-control channel. Fresh role and private-channel checks still guard every shared club mutation.

Verification

  • Full local Python suite at deployed code: 1,115 passed, 2 optional skips, one third-party audioop deprecation warning. Python compilation and diff whitespace checks passed.
  • Hosted CI at code revision 2800d97: push and PR both passed unit and all image jobs. Final documentation-only head CI also passed: push and PR.
  • Live gateway/worker VM smoke: 31 passed, 0 failed, 0 skipped, including Rust build, pinned Hermes fixture, blocked host/internet/runner access, and authenticated broker rejection. Final package smoke: 6 passed, 0 failed. Host firewall and guest runner remain healthy.
  • Live private #testing: hey peter → yo; Yo Peter → whats good; a casual Qwen correction and an unpinged Nah, Qwen under the hood both received truthful replies. Replaying the screenshot's exact two-message exchange, including the model the powers you ... remember that, returned Qwen3.8 Flash Next under the hood without a model-name memory write. Oliver set, recalled, and undid a synthetic club fact. A separate natural remember that request created a real club-memory row via the worker; the disposable note was verified and soft-deleted with audit retained. Earlier live tests cover source-backed research, independently checked Rust attachments, project continuation after restart, queueing, cancellation, and a test-destination announcement.
  • The post-release online snapshot /mnt/NVME/docker/appdata/peterbot/backups/weekly-20260923T213656Z was verified and restored to separate staging. Protected prior config/images remain available. Weekly private housekeeping is scheduled.

Deployment and limits

P910 gateway peterbot-hermes-gateway:2800d97 and guest runner/worker :08c8968 are healthy. Authenticated diagnostics report Discord, model, runner, and queue ready, with zero queued/running work or unknown cleanup at final verification. Members can converse and request isolated research/coding in seven configured channels; officer controls in private #officers and #testing remain role-bound. The cutover and rollback runbook records the single-gateway procedure.

A separate nonofficer Discord account was unavailable for a live denial; policy and gateway integration tests cover it. An earlier research reply cited the official Rust blog domain rather than the exact article URL. The first scheduled weekly housekeeping execution has not yet occurred, although the same command and a separate restore passed manually. No release-test message was sent to public #announcements. Human review and merge remain separate from this authorized deployment.

ofhd added 29 commits September 22, 2026 19:03
Store only final requester and assistant turns under exact Discord guild, requester, channel, and audience keys. Keep explicit constraints verbatim under a fixed context budget so natural follow-ups can survive a restart without copying private threads into public replies.

Constraint: Discord access must be revalidated by the gateway before reading this store.

Confidence: medium

Scope-risk: narrow

Tested: PYTHONPATH=. .venv/bin/pytest -q tests/test_conversation_store.py (4 passed)

Not-tested: Gateway integration and live restart continuation remain pending.
Record fixed-stage timing and token counters without task text or Discord identities. Add a synthetic streamed-model probe so the served Qwen configuration can be evaluated before changing routing budgets.

Constraint: Private operational measurements must not collect prompts, reasoning, capability tokens, or member identifiers.

Confidence: medium

Scope-risk: narrow

Tested: PYTHONPATH=. .venv/bin/pytest -q tests/test_ops_metrics.py (3 passed); Python compile check for model probe.

Not-tested: Live model matrix and gateway instrumentation are pending.
Persist one source-bound officer intent, destination, nonce, and send receipt. A crash-ambiguous send stays unknown until a checked reconciliation, while known rejections get bounded retries. Refuse newer state schemas rather than opening them with older code.

Constraint: Gateway must recheck live officer role and private control location immediately before sending.

Confidence: medium

Scope-risk: narrow

Tested: PYTHONPATH=. .venv/bin/pytest -q tests/test_announcement_outbox.py tests/test_conversation_store.py tests/test_ops_metrics.py (16 passed)

Not-tested: Discord send integration and live destination receipt remain pending.
Store versioned roster, public/private facts, and bounded style dials under source-bound control intents. Public snapshots supersede stale static text and respect office effective dates; historical records remain available for audit and undo.

Constraint: Discord roles and current private-channel access, not published office titles or memory, authorize each mutation.

Confidence: medium

Scope-risk: moderate

Tested: PYTHONPATH=. .venv/bin/pytest -q tests/test_club_state.py tests/test_style_state.py tests/test_agent_memory.py tests/test_knowledge_and_recap.py (46 passed)

Not-tested: Gateway control routing, live officer edits, and next-turn model injection remain pending.
Allow a trusted fresh club snapshot and bounded style instruction to enter the fast reply system context. When a live snapshot is supplied it replaces older static knowledge, so a roster edit can take effect at the next turn.

Constraint: The gateway must obtain these inputs from authorized stores, never model or member text.

Confidence: medium

Scope-risk: narrow

Tested: PYTHONPATH=. .venv/bin/pytest -q tests/test_conversation_model.py (23 passed)

Not-tested: Gateway wiring and a live next-turn Discord response remain pending.
Separate first streamed token from first answer or tool delta and validate assembled tool-call arguments in the synthetic compatibility probe. This keeps reasoning activity from masquerading as reply latency.

Constraint: Probe output must not include reasoning text or private prompts.

Confidence: medium

Scope-risk: narrow

Tested: Python compile check; one earlier synthetic non-thinking greeting completed on served Qwen backend.

Not-tested: Updated fields have not yet been exercised on an idle backend.
Use the pinned Discord client’s rate-limited request path for the one Create Message field its high-level helper lacks. Require an already-claimed outbox row and verify the returned message belongs to the intended channel before recording a receipt.

Constraint: Discord nonce uniqueness lasts only a few minutes; the durable outbox must freeze ambiguous sends across longer gaps.

Confidence: medium

Scope-risk: narrow

Tested: PYTHONPATH=. .venv/bin/pytest -q tests/test_discord_outbox_sender.py (3 passed)

Not-tested: Live test-channel send and gateway role recheck remain pending.
Persist bounded full-snapshot manifests and verified content-addressed blobs under a trusted gateway store. Exact guild, requester, and channel scope plus explicit grants govern restore; partial results remain labelled unverified, and retention reclaims only truly unreferenced blobs.

Constraint: Disposable workers never receive host paths or authority to choose a Principal.

Confidence: medium

Scope-risk: moderate

Tested: PYTHONPATH=. .venv/bin/pytest -q tests/test_project_store.py (66 passed); local agent full suite 867 passed, 3 gateway mid-edit failures, 1 optional skip.

Not-tested: Gateway/runner wiring, staging restore, and live p910 continuation remain pending.
Add aggregate-only operator diagnostics and explicit retention gates around
existing SQLite stores. Online snapshots verify their manifests and project
blobs, and the P910 housekeeping command backs up and reports without
deleting live state. Stage restore and diagnostics were exercised against a
copy of the actual deployment data.

Constraint: P910 gateway runs as uid 10000 with state under data/hermes
Constraint: Retention must never delete active work or unknown deliveries
Confidence: high
Scope-risk: moderate
Directive: Keep retention apply explicit and backup-verified; do not auto-delete snapshots
Tested: 21 focused operator/backup tests; P910 online snapshot, verification and staging restore; housekeeping shell syntax
Not-tested: Scheduled cron execution on the final release image (cutover gate)
A foreground lease and FIFO envelope store admit one cognitive chain across
requesters while preserving queued task ownership through restart. In-process
chat turns are interrupted honestly, and worker cleanup uncertainty holds the
slot until reconciled. This also provides the shared scheduler used by the
operator diagnostic slice.

Constraint: One Discord gateway may hold the bot token and one foreground slot
Constraint: Unknown worker cleanup must not release the slot optimistically
Confidence: high
Scope-risk: moderate
Tested: 19 focused foreground concurrency/restart tests
Not-tested: Live cross-user Discord queue and gateway restart (release gate)
Provision a dedicated P910 guest with separate runner control and worker
networks, a deny-first worker firewall, and a pinned Rust toolchain. The
trusted gateway brokers exact public package releases with hash, size, DNS,
redirect, and quota checks; the disposable worker installs or builds from a
read-only image cache or a capability-scoped fetch without direct internet.
Project bytes and valid partial output can return across the boundary.

Constraint: Workers must not receive Docker control, Discord credentials, or general egress
Constraint: P910 has libvirt/KVM access without passwordless host sudo
Confidence: high
Scope-risk: broad
Directive: Keep broker alias, guest firewall, Compose overlay, and worker image contract in sync
Tested: Merged-tree suite 1066 pass/2 optional skip; restricted-worker package smoke 10/10; VM Rust/isolation smoke 30 pass/1 declared broker skip; VM reboot verification
Not-tested: Final gateway broker 401 path and member task delivery on deployed image (release gate)
Route every club request through the durable foreground owner, then answer
small talk with a bounded conversational turn or hand serious work to the
isolated Hermes worker. Persist audience-scoped turns and project files, inject
fresh club facts and bounded style, and give officers source-bound private
controls for facts, roster, style, and allowlisted announcements. Real progress,
owner cancellation, durable delivery, and on-demand dependency diagnostics
make long work and failures visible without another model call.

Constraint: Discord identity, audience, and current roles must be rechecked at action and delivery time
Constraint: An unknown Discord send or worker cleanup outcome must remain frozen for reconciliation
Confidence: high
Scope-risk: broad
Directive: Preserve the single foreground slot and source-bound control intent when extending tools or channels
Tested: Merged-tree suite 1066 pass/2 optional skip; Python compile; focused command/routing 52 pass; staged P910 old-job migration preserved four delivered receipts
Not-tested: Live Discord officer controls, announcement receipt, project restart continuation, idle p50/p95 (release gates)
A capability's package requests now serialize their quota checks and byte
accounting, so concurrent fetches cannot both spend the same remainder. A
waiting model request also rechecks current authority after acquiring the
lock. Add regressions for both races and a repeatable VM package smoke that
uses the production worker profile. Record the final image's offline wheel and
crate proof after the guest's setup-only NAT link was removed.

Constraint: Workers have one capability-scoped broker path, not general internet
Constraint: Cancellation or role loss can occur while a request waits on the model lock
Confidence: high
Scope-risk: moderate
Directive: Recheck authorization after every asynchronous lock wait before an upstream side effect
Tested: Merged-tree suite 1068 pass/2 optional skip; quota and model-wait regressions; VM Rust/isolation 30 pass/1 declared broker skip; VM offline package smoke 6 pass after NAT detach/reboot
Not-tested: Live gateway broker capability path and Discord member task (cutover gate)
Docker gave the first worker the broker's .240.2 alias, causing its broker
socket to connect to itself. Reserve that address in guest IPAM, allocate
workers from a separate range, and verify the exact /32 alias rather than a
substring of the bridge broadcast address. A narrow persistent P910 UFW rule
permits only the guest control address to the host-only broker port. Also keep
multiple versions of one offline crate in Cargo's local index and use the
numeric broker address in the example configuration.

Constraint: The worker network remains internal and the gateway is reachable only through the authenticated broker path
Constraint: The guest has no general NAT interface after setup
Rejected: Widen worker egress or expose the broker on a public interface | breaks the isolation boundary
Confidence: high
Scope-risk: moderate
Directive: Never allocate 192.168.240.2 to a worker; check real broker reachability after every network recreation
Tested: Full local suite 1070 pass/2 optional skip; Rust recipe tests 35 pass/1 optional skip; VM reboot/IPAM verification; synthetic host-only broker path 31 pass/0 skip and post-reboot worker HTTP 401
Not-tested: Actual gateway broker connection and Discord task delivery (cutover gate)
P910's UFW INPUT rule admitted a temporary host listener, but Docker publishes
the gateway port by DNAT into a container. That path reaches DOCKER-USER first,
where the host's final drop blocked the guest. Insert one idempotent, narrow
allow keyed to virbr-ctl, the guest source, and conntrack's original host-only
broker address and port. Reapply it with the existing firewall service when
Docker restarts.

Constraint: No broader tailnet, internet, or guest-to-container access may be opened
Rejected: Expose the broker on 0.0.0.0 | violates VM boundary
Confidence: high
Scope-risk: narrow
Directive: Preserve the conntrack original-destination match; DOCKER-USER sees post-DNAT container IPs
Tested: Real deployed gateway VM smoke 31 pass/0 skip including broker 401; host firewall service active with PartOf=docker.service; static Rust recipe tests 36 pass/1 optional skip
Not-tested: Full P910 host Docker daemon reboot/restart (other services must not be disrupted for this rehearsal)
Live Discord testing showed a greeting that was already running still emitted
an acknowledgment claiming another request was ahead. Send that transport
notice only while an envelope remains queued; an active turn already has a
typing indicator and should answer normally. Preserve the one-attempt behavior
for a genuinely queued request even if its acknowledgment send fails.

Constraint: A queue acknowledgment must never claim contention that does not exist
Confidence: high
Scope-risk: narrow
Tested: 20 focused foreground tests; merged-tree suite 1072 pass/2 optional skip
Not-tested: Live greeting after the corrected gateway image is redeployed
Live #testing showed a clean conversational completion saying source files
were on their way even though it never called Hermes and delivered nothing.
For explicit attachment or sandbox-execution requests, treat a clean text
answer as an unmet side effect and hand the accepted objective to the worker.
Ordinary conceptual coding questions still answer directly; malformed model
tool output still cannot authorize execution.

Constraint: Peter must never claim he created or attached a file without verified work
Rejected: Force every coding keyword into the worker before a model turn | wastes time and misroutes explanations
Confidence: high
Scope-risk: narrow
Tested: 37 focused conversation tests; merged-tree suite 1075 pass/2 optional skip
Not-tested: Live Rust source attachment after updated gateway redeploy
The VM worker saved and attached a continued project file, but its reply said
Discord attachments were unavailable. Tell the worker that the trusted
gateway attaches saved artifacts, so it names files without sending members
to sandbox paths. Persist the follow-up's status message receipt, edit that
message with real progress, and use it for the final answer instead of leaving
a stale "I'll take a look" beside a second result message.

Constraint: An unknown Discord send stays frozen; a known status receipt is edited instead of replayed
Confidence: high
Scope-risk: narrow
Tested: Live private counter.py continuation saved a second version and delivered the updated attachment; merged-tree suite 1076 pass/2 optional skip
Not-tested: Live continuation after gateway restart on the updated image
Idle production-model probes showed a 44.173s p95 coding handoff with deep thinking. An explicit request for a file or sandbox execution already has a trusted postcondition that requires real worker output. Give only that request shape a short non-thinking first attempt; preserve thinking for research and ambiguous work, and retain the existing clean-tool and postcondition gates.

Constraint: The served Qwen vLLM endpoint can spend its completion budget on reasoning before a simple tool call.

Rejected: Turn off thinking for all deep requests | earlier live routing uncertainty for research and ambiguous work.

Confidence: high

Scope-risk: narrow

Tested: 5/5 idle backend coding routes in 2.462s p95; 61 focused tests; 1076 full-suite passes with 2 optional skips.

Not-tested: Member-account live coding request; post-deploy Discord timing pending.
The live P910 cutover, member enablement, isolated worker probes, Discord deliverables, CI, backups, and model timings now have a durable release record. Keep the pre-cutover snapshot historical and document the exact single-gateway switch and rollback procedure. Include sanitized raw latency rows so the proposed targets can be checked against measured results.

Constraint: The deployed code image is revision 274c86a; this commit changes documentation only.

Confidence: high

Scope-risk: narrow

Tested: Documentation links and diff whitespace checked; 1076 Python tests and 31 VM/6 package checks passed at deployed code revision.

Not-tested: First scheduled cron execution and a live request from a separate nonofficer account.
A bare greeting now gets a one or two word reply without a model call. Ordinary chat and worker prompts favor the fewest useful words, and every Peter-authored Discord text path removes em dashes. Long-running work keeps the same truthful stage keys and elapsed time, but edits one playful status line instead of repeating formal progress prose.

Constraint: Keep real work, role checks, one foreground slot, cancellation, and attachment delivery unchanged.

Rejected: Make every answer one sentence | research and code sometimes need more detail.

Confidence: high

Scope-risk: moderate

Tested: 1087 Python tests passed, 2 optional skips; focused voice and progress tests; compileall and diff whitespace check.

Not-tested: Live Discord tone and stage display until the P910 redeploy.
The first PR CI attempt hit a fixed-sleep race in the queue acknowledgement test while the push run and PR rerun passed. Wait for the first holder and acknowledgement events instead of guessing scheduler timing. Record the deployed casual voice revision, its live greeting and status behavior, and the verified post-update snapshot.

Constraint: This commit changes test timing and documentation only; the deployed code image remains revision 62e2b9f.

Confidence: high

Scope-risk: narrow

Tested: Full voice suite 1087 passed with 2 optional skips at code revision; queue acknowledgement test passed 10 repeated runs; P910 worker smoke 31/31 and package smoke 6/6; live Discord voice and timed task delivery; snapshot verify and separate restore.

Not-tested: A separate nonofficer Discord account and the first scheduled housekeeping invocation.
A three-per-minute user limit and an overbroad name-prefix check interrupted ordinary back-and-forth. Raise the configured conversation allowance to 20 per user and 120 per guild, renew scoped follow-up leases for five-minute gaps, and recognize a final-line Peter address. Preserve the same one-foreground-slot scheduler and fresh officer-role checks, while preparing the private testing channel as another bounded control surface.

Constraint: Ordinary member writes to club memory remain denied; only a verified officer in a configured private channel may control shared facts.

Rejected: Listen to every server message | unrelated chatter should remain silent.

Confidence: high

Scope-risk: moderate

Tested: 124 focused routing/config/policy tests and compileall; production cutover pending.

Not-tested: Live Discord nonresponse and rate-limit repro until deployment.
The five-minute renewable conversation lease is deliberate, so the configuration test should assert that new default instead of the prior two-minute value. This resolves the hosted unit failure without changing runtime behavior from the previous commit.

Confidence: high

Scope-risk: narrow

Tested: 149 focused settings, awareness, guard and policy tests.

Not-tested: Live Discord behavior until the combined deployment.
The requested pilot now permits a verified officer to update and undo a synthetic club fact from private testing. The integration test also proves a member in the same channel cannot mutate it and the existing public-channel denial remains in force.

Constraint: Testing is configured as a private control channel only in the P910 protected Hermes config; runtime still checks the Discord role and channel on every action.

Confidence: high

Scope-risk: narrow

Tested: Officer control gateway suite 7 passed.

Not-tested: Live Discord control edit until final rollout.
The live model repeatedly claimed Claude despite the trusted runtime being Qwen, and clean text replies could refuse or promise a memory write without doing it. Ground model identity in the gateway's current configured model, replace contradictory self-claims with a short truthful line, and keep operator model identity out of club facts. Explicit ordinary memory-save requests hand off to the isolated worker, whose broker still enforces officer scope; saved public club notes can inform later chat without exposing personal memory. Private testing officer controls acknowledge runtime-model corrections without a stale write.

Constraint: User corrections are conversational data, not authorization; only the current Discord role and private configured channel authorize club fact mutations.

Rejected: Persist the model name as a club fact | it would become stale after a backend change.

Confidence: high

Scope-risk: moderate

Tested: 1114 full-suite passes and 2 optional skips, then 97 focused passes after identity-regex refinement; compileall and diff whitespace check.

Not-tested: Live Discord model-correction and natural memory write until the P910 cutover.
The screenshot's 'the model the powers you' typo was not matched by the identity route, so it could be sent to the worker as a memory write instead of answered from the trusted runtime model. Accept that narrow wording alongside the grammatical form and keep the same no-stale-memory response.

Confidence: high

Scope-risk: narrow

Tested: 58 focused conversation tests and diff whitespace check; previous full candidate 1114 passed with 2 optional skips.

Not-tested: Live screenshot-phrase reply until the gateway hotfix is redeployed.
The final P910 gateway now handles the exact screenshot correction, keeps casual replies, renews conversations, and accepts verified officer controls in private testing. Document the mixed gateway/VM image revisions after the narrow typo hotfix, the increased chat limits, live Discord results, synthetic-memory cleanup, successful restricted-worker probes, and the verified recovery snapshot. Point historical pilot notes to the active runbook to prevent stale deployment instructions.

Constraint: The deployed gateway code revision is 2800d97; this commit changes documentation only.

Confidence: high

Scope-risk: narrow

Tested: 1115 local Python passes with 2 optional skips; hosted code CI unit/images green; 31/31 VM isolation and 6/6 package smoke; live Discord Qwen, followup and memory controls; backup verify and staging restore.

Not-tested: A separate live nonofficer Discord identity and the first scheduled weekly housekeeping run.
Describe the current member workflow and VM-backed Hermes deployment, distinguish historical pilot evidence, and point readers to the live verification and cutover guides.

Confidence: high

Scope-risk: narrow

Tested: 1115 passed, 2 optional skips; JSON validation; Python compileall; local Markdown links; git diff --check

Not-tested: New image deployment to P910
@oliverdougherC
oliverdougherC changed the base branch from feat/hermes-peter to main September 23, 2026 23:10
@oliverdougherC
oliverdougherC marked this pull request as ready for review September 23, 2026 23:13
@oliverdougherC
oliverdougherC merged commit 2f93e9b into main Sep 23, 2026
4 checks passed
@oliverdougherC
oliverdougherC deleted the feat/peter-foreground branch September 27, 2026 00:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant