Proved now
One enrolled client closed the complete observed all-prefab ZDO window through Lumberjacks priority delivery with exact durable accounting.
The validated, hash-recorded P7 run observed 83,220 eligible server-to-client ZDO revisions in one strict single-client window. All 83,220 were durably received by Lumberjacks and closed as applied or safely superseded with durable acknowledgement; zero eligible revisions used native ZDO delivery. This 100% denominator covers that declared ZDO delivery window only, not every Valheim packet, RPC, simulation, ownership decision, Steam login, or base peer-transport function.
The validated, hash-recorded one-client result is real. Volunteer readiness and concurrent correctness have separate, visible gates.
One enrolled client closed the complete observed all-prefab ZDO window through Lumberjacks priority delivery with exact durable accounting.
Valheim still decides which world-object revisions a player should receive. The server mod redirects those eligible revisions through Lumberjacks, the Gateway stores and leases them, and the enrolled client mod applies them on Unity's main thread before acknowledging a terminal outcome.
Build the peer-specific list of world-object revisions.
Intercept eligible revisions, attach stable ordering metadata, and redirect the declared ZDO delivery path.
Durably record envelopes and make pending work available to the authenticated consumer.
Poll in the background, marshal onto Unity's main thread, invoke RPC_ZDOData, and validate the outcome.
Acknowledge only an applied or safely superseded terminal outcome and retain the accounting result.
The graph is generated from each milestone's declared dependencies. Build the single-volunteer experience without waiting for the queue redesign; keep capacity at one until recipient isolation passes.
A safe one-seat pilot with immutable packaging, preflight, proof, and rollback.
Recipient isolation, loss-safe delivery, and real two-account proof.
The proven volunteer journey and two-client correctness join before measured cohorts.
Shadow, validate, and replace Valheim relevance and the remaining network planes.
The community-facing program: honest trust, legible tuning, replay workbooks, a turnkey local lab, delegable community support, and first federation light — owner-controlled, opt-in, built in the open.
A milestone moves only when its exit statement is supported by reproducible evidence.
Turn the exact working Gateway, mod, deployment, world, and evidence into a reproducible release.
Bind the actual joining Steam account to enrollment, compatibility, and capacity.
Replace hand copying and hand-edited config with an immutable generic package plus a personal one-use bootstrap.
For the enforced one-seat window, prove each selected ZDO revision reached durable Gateway storage, the authenticated client, Unity application or safe supersession, and a durable terminal acknowledgement.
Remove the shared-window queue and producer-loss hazards while preserving the peer identity available at Valheim's per-peer sync-list boundary.
Move the automated recipient model through two simultaneous real Valheim clients before any multi-seat invitation exists.
Invite one trusted non-developer only after the host has proved the exact cold-started deployment and rollback path.
Move from the owned two-account gate to 2–4 and then 5–8 invited players only when correctness and capacity evidence permit.
Run active lab experiments against Valheim's relevance, ownership, replication, presentation, and remaining RPC judgments now; keep production promotion gated on the earlier real-player milestones and bounded evidence.
Publish what the mod captures and how to opt out, set honest alpha expectations, and make the weekly community cycle a copy-paste rhythm — so the next person who joins meets trust, not surprises.
Turn folklore weights into chains of evidence — every knob inventoried and every tuning change ledgered — and let each GM conversation also answer an open governance question.
Make tuning a replay -> adjust -> diff loop with no game required, back every knob with a tradeoff card, and end each doc chapter in something executable that proves it is still true.
Bring the whole server-side system up with docker compose on your own machine, so seeing your own kill land on your own localhost dashboard is the demo.
Shape support and contribution so a trained volunteer — not just the operator — can run them, and each hands-on onboarding session gets measurably shorter.
Make the turnkey lab the node all along — same gateway surface, same signed-config trust — so projection becomes "turn on peering", then exchange one small signed artifact between two boxes.
A public catalog of the tools a volunteer can actually run today — each with an honest status, a way to run it locally, one place to talk about it, and a named first task — so helping has an on-ramp and ownership has a ladder.
Host preflight happens before an invitation is sent. A known-red deployment never becomes volunteer troubleshooting, and joining alone is not participation completion.
May this participant start the scheduled test now?
Which delivery path is the session using?
What is the ledger doing right now?
Did the volunteer's effort produce a usable packet?
What did the sealed run prove about the declared network test?
A volunteer succeeds by completing or attempting the assigned work and returning a usable evidence packet. Finding a networking defect is valuable successful participation; it does not require the system test itself to pass.
draft-v1 · Planned for the first canary; invitations are not open until M0-M3 close.
The page states the experiment, assigned test cards, expected time, risks, captured data, support, and recovery path.
Steam enrollment, exact release, BepInEx, TLS, Gateway, server, capacity, readiness, and rollback checks are green.
The personal dashboard shows LUMBERJACKS ACTIVE, current card instructions, and fresh received/applied/acknowledged traffic.
A retained pseudonymous receipt separates participation completion from the networking verdict and includes the submitted observations.
Participation records whether the volunteer's effort counted. The system verdict separately records what the sealed networking run proved.
Did the volunteer's effort produce a usable packet?
What did the sealed run prove about the declared network test?
The required commitment is explicit; the ordinary-play extension is optional and declining it never reduces participation status.
Redeem the invite, install the exact package, pass preflight, choose a backed-up character, and reach READY TO JOIN.
Complete T02 dense arrival, T03 rapid frontier travel, and T05 quiet drain.
Return the bounded observation report so participation can close independently of the system verdict.
Offered only after the required guided route closes cleanly; declining it does not reduce participation status.
The invite assigns a small subset. Each card tells the volunteer what to do, what to notice, how long it takes, and what the instrumentation proves.
The latest owner observation corroborates the data path but does not replace or widen the historical 83,220-revision baseline. Live delivery and the formal sealed verdict remain visibly separate.
Operational note: Gateway image sha256:c361c8fc6d823d7be935e43221f69eb948355c9a35b516263316306a2805c97f was rebuilt from committed source 002b12c, pinned as m12-motionauthws-20260722-r1, and admits frozen mod m12-motion-20260722-r1. Health was good; TCP 42317 and UDP 4005 were published; the alpha seat gate remained disabled with the compatibility capacity value present exactly once.
Each eligible revision advances through an accountable route and terminal outcome. Retries do not create new unique work, and a heartbeat alone cannot close this chain.
One enrolled client · persistent all-prefab ZDO redirect · 2026-07-16 UTC
83,220 of 83,220 eligible ZDO revisions in the declared strict single-client window closed through Lumberjacks; this is not a denominator for all Valheim networking.
The claim grows one authority plane at a time. Compatibility dependencies remain visible.
| Plane | Current state | Boundary |
|---|---|---|
| Invite / Steam enrollment | Partial | Implemented, but not yet the sole live admission roster. |
| Valheim admission | Partial | Gateway responder exists; must bind actual SteamID, enrollment, release, readiness, and capacity. |
| Eligible server-to-client ZDO delivery | Proved for one client | Validated, hash-recorded strict P7 window; concurrent queue isolation is not yet proved. |
| Candidate relevance / inference | Native | Valheim still creates the peer-specific candidate list. |
| ZDO application | Lumberjacks adapter | Client poller applies and validates on Unity's main thread before ACK. |
| Player-motion transport | Observe-first Lumberjacks canary | Enrolled clients can carry measured motion over token-bound UDP with binary WebSocket fallback; native presentation remains the default until a tester opts into apply. |
| Ownership / simulation / non-ZDO RPC | Native | Later authority-plane work. |
| Steam login / base peer transport | Native by design | May remain bootstrap and compatibility unless replacement adds measured value. |
Every non-merge commit appends one note. Newest entries appear first; history remains append-only.
Impact: The public page now carries the never-expiring invite in both hero and footer, published from 6b38b3c.
Impact: The provisioning bot gains a guild-invite command with the same yes-ceremony as its content writes; it minted a never-expiring invite on the same channel and recorded it, so the fourteen-day warning countdown the offline check carried is gone for good. The old invite is left to lapse on its own - every copy already shared keeps working until then. The page now carries the permanent invite. Operator rationale stands recorded: the hosting moves within a year, so link lifetime was never the constraint.
Impact: The completion report claimed 37 guard tests by double-counting: 28 was already the combined total (19 generator + 9 verifier). The count is now stated correctly - the guards themselves were never miscounted, only the prose.
Impact: The public workbench artifact now links the MCP Mod Channel thread on its Discuss row, MC-1 completes in-thread via the derived default, and the page is published from 42c2115.
Impact: The operator's provisioning run created the MCP mod channel thread from seed 10 (plan 23bc2b88476e, exactly one create). MC-1 completes in the tool's own thread again: the forum-interim completion override is deleted, done_when says in-the-thread, and the Discuss row links the thread - the derived tool-thread default now carries it. The one-pager matches.
Impact: Two independently correct changes broke each other. The boot-determinism work made the systemd unit start with docker compose up -d --wait plus Restart=on-failure, and the schema repair added a one-shot dbschema service to the default service set. Verified locally: docker compose up -d --wait exits 1 on a one-shot that succeeded, reporting 'container ... exited (0)'. On P7 that would have failed every ExecStart and retried every 30 seconds - the exact failure --wait was added to prevent. dbschema is now behind a schema profile so it is not in the waited set, and the ordering guarantee moved into the unit as ExecStartPre docker compose run --rm dbschema, which auto-enables the profile and starts postgres through its own depends_on. The four depends_on service_completed_successfully gates are gone because compose auto-enables a dependency's profile and would pull the service back into the waited set. Trade-off recorded in both files: a bare docker compose up -d on the VM no longer applies the schema, so the unit is the authoritative starter. The local stack keeps the direct gate because nothing there uses --wait. Also reconciled the environment.example comment that still described LUMBERJACKS_ROOT as boot-critical because postgres bind-mounts init.sql through it - true of the old compose, false since the schema repair landed.
infra/gcp/p7/RUNBOOK-schema-repair.mdImpact: LUMBERJACKS_ROOT was documented as a required runtime declaration in the P7 README and environment.example long after it stopped resolving to a real path, and docker-compose.yml no longer consumes it at all. That stale required-marker is how a schema-less database survived undetected: the variable looked load-bearing, so nobody checked that the path it named still existed. Removed from both, with an explicit do-not-reintroduce note pointing at the schema runbook. The operator still has to remove the line from the box, and should read it first because it is the forensic evidence. Also recorded why bootstrap.sh.tftpl is deliberately left alone: it is metadata_startup_script, already drifted, and force-replaces the VM on apply, so it belongs to the terraform reconcile effort rather than a docs cleanup.
infra/gcp/p7/RUNBOOK-schema-repair.mdImpact: Two signals that reported the opposite of reality got closed at the mechanism and written down as durable decisions rather than as incident notes. ADR 0014 states that a service managing other services must fail loudly, must not report success before it has converged, and must retry - with the corollary that where two mechanisms can start the same thing, one is authoritative and the other is only for crash recovery. It also records what was deliberately NOT changed: the database health fan-in stays, because loosening it would trade one visible failure for four silent crash-loops. ADR 0015 states that bytes whose exact value is load-bearing get their line endings pinned by the repository rather than left to a contributor's git configuration, covering generated artifacts that are hashed and published and files that are parsed on Linux, with the corollary that a failing verification gate must be diagnosed before it is acted on. The session retrospective carries the timeline, five engineering-seat reads, and six numbered lessons, including one that grades a prior lesson as acted-on yet still recurring because it had been captured narrowly instead of as a repo-wide mechanism. Two open decisions are registered: what the cloud VM is still for now that the community surface is served elsewhere and demos need no VM, and when to spend a cold restart proving the boot fixes given that half of them need an infrastructure reconcile that has been deferred all along. The handoff's machine-state bullet is corrected and now points at the runbook and the ADR.
Impact: The P7 game database had no tables at all, so every gameplay-event INSERT failed and the /community Gameplay Feed and Quests panels could never populate. Schema reached Postgres only through docker-entrypoint-initdb.d, which runs once on an empty data directory and is skipped silently forever after - and P7's data directory is a persistent bind mount, so that window opened once per disk. The 2026-07-24 state-disk replacement consumed it, four days after the repo unification moved init.sql under Lumberjacks/ and left the compose mount path naming no file (Docker materializes a missing bind source as an empty directory, so nothing complained). init.sql is now idempotent and complete at all 13 GameDbContext tables, including natural_resources and region_profiles which existed only in an EF migration that has never been applied anywhere. A one-shot dbschema service applies it on every start and gates the four .NET services behind service_completed_successfully, so a missing schema is a loud startup failure instead of an empty public panel. Also on record: /api/v0/telemetry/regions serves a hardcoded WorldState seed and is not a database health signal.
infra/gcp/p7/RUNBOOK-schema-repair.md Lumberjacks/infra/docker/init.sqlImpact: The 2026-07-29 retro gains its third addendum, covering a live-operations session with zero commits: the P7 stack was brought up for a remote demo and taken back down, the empty-world tick numbers were framed as a floor rather than as evidence of scale, the ask to have automated clients play each other was declined against the pinned networking hold and its own removal commit, and a graceful-stop hazard the operator memory already describes verbatim was re-fired and then cleaned up (699 MB of orphaned partials removed, world verified intact by size and md5). fieldlab's register gains the two decisions that session surfaced: pruning the stale world auto-backups, declined in favour of keeping recovery copies of a 9.16M-ZDO world; and restoring the swarm harness from its removal commit, left open and gated behind lab clients only the operator can seed.
Impact: The live AM4 workbench was recorded as still serving the pre-review render, pending an operator republish. It is not: the served page is byte-exact with the committed render whose provenance stamp names a commit descended from the trust review, and a full post-publish verification of the live funnel returns PASS across 69 checks with zero failures and zero warnings. No republish is owed. The misreading came from a line-ending trap rather than a deployment problem: scripts/workbench-verify-live.mjs hashes the local HTML as a raw Buffer, and the repository carried no .gitattributes, so a Windows checkout with core.autocrlf=true produced a CRLF working copy whose digest could never match a server serving LF. The gate failed against a deployment that was byte-correct, which is the worst kind of gate failure - it invites an unnecessary republish and teaches the operator to distrust a passing check. A .gitattributes now pins generated and Linux-destined files to LF: generated HTML because its bytes are hashed and published, and shell scripts, systemd units and compose files because they are parsed on Linux where a carriage return is a syntax error. Stored blobs were already LF - git add --renormalize staged nothing - so this changes only what a checkout writes into the working tree, and it removes a class of failure that depended on one contributor's git configuration rather than on anything in the repository.
Impact: A cold stop/start of the P7 VM left six containers in Created with nothing serving while SSH answered normally. Root cause: nothing in the repo ever installed or enabled comfy-lumberjacks-p7.service - the GCE startup script set up disk, swap, docker and the ops agent and stopped, so the unit's enablement was hand-made state on the box, which is exactly the 'no hand-built state to lose' the cost runbook cited to justify stop/start as safe. Three compounding defects: a failed ConditionPathExists silently SKIPS a unit (inactive, no error, no log - the 'alive over SSH, serving nothing' signature), docker compose up -d returns at Created so Type=oneshot marked the unit active while nothing ran, and with no Restart= a single transient failure parked the stack permanently. Every service hard-depends on postgres condition service_healthy, so postgres is a single fan-in point whose failure leaves every dependent in Created. The unit now uses AssertPathExists, --wait, Restart=on-failure with an unlimited start burst, and a clean-slate down before every start; the startup script installs and enables the unit from the deployed checkout and orders the docker daemon after the state-disk mount, which was previously unguarded and could resolve bind mounts against the empty mountpoint on the root disk. Also found: COMPOSE_PROFILES=tls was missing from environment.example while the live box had it, so rebuilding the env file from the template would have produced a stack with no TLS terminator and no error, because an unselected profile is not a failure.
Impact: provision.json site_base_url is set to the live AM4 funnel, so the four link-carrying seeds and the new MCP Mod Channel seed resolve their placeholders and are ready for the operator's next provisioning run. Operator call recorded 2026-07-29: the hosting will move to a different server within a year, and a link with that lifetime is acceptable - the URL is already public on every published page, and the P7 cutover recipe replaces it when the move happens.
Impact: tests/test_guest_package.py built every case against a sealed release bundle that .gitignore deliberately keeps out of the repo, so five of the six tests failed on any clean clone for want of a machine-local build artifact. The tooling tests now build against a committed synthetic release fixture under tests/fixtures/guest-package/, which exercises the same paths because no guest-package script parses the DLL. The one question a fixture cannot answer, whether the real sealed DLL still matches the manifest shipped beside it, became its own test that runs where the bundle exists and skips with an explicit reason where it does not.
Impact: The completion report in docs/audit answers the review's nine sections: the MC-1 contradiction and its two-track resolution, the completion schema, how counts compute (11 actionable, now true), production and preview provenance with the shipped false stamp reproduced as a test, twelve offline guards, the full remote-check inventory with a passing 60-check live receipt, 37 green guard tests, and what stays unverified until the operator republishes. HANDOFF and BUILDING teach the two-phase render, the new npm scripts, and the thread-URL recipe including the MC-1 override removal.
Impact: The verifier now mirrors workbench_discord.py's token resolution (env var, env-named file, then workbench-discord.token or discord.env under the user profile), so a machine where the bot can post is a machine where the verifier can verify. First live pre-publish run against the AM4 funnel: 60 checks, 0 failed, 0 warnings - invite, all 8 member-only destinations, all 11 task destinations, 28 GitHub URLs, 4 repo-visibility checks, 8 routes.
Impact: The public page now derives its access-policy sentences, links every LICENSING.md mention, says the project operator, and is published from a3e14a2.
Impact: The access-policy sentence on every card is now computed from source.kind and code_contributions instead of living as prose in source.note - the sentence was byte-identical in three notes and nearly so in a fourth, a drift surface the schema already owned. Notes keep only tool-specific facts, and validation refuses policy vocabulary or a note contradicting the structured rights. LICENSING.md joins OWNERS.md in the named-means-linked rule (it was named six times and linked zero). The ladder's stage 4 now says the project operator, defined once in OWNERS.md with why the role has authority - the page no longer names a person a stranger was never introduced to, and the catalog refuses person names outright. Four doc rows that named public files inertly now link them.
Impact: New release-path verifier (workbench:verify-live) proves everything the page asks a visitor to click: the Discord invite resolves to the expected guild and has not expired (cross-checked against provision-state), every member-only thread URL exists in that guild via the bot token (fail-closed when the token is absent), every GitHub URL answers 200 and declared-public repos really are public, the site routes answer 200 on-origin, and post-publish the downloads stream with the claimed digest, size, and header while the served page hash equals the local render. Failures are classed per check with a JSON receipt under captures/. Publish-WorkbenchAssets now runs the pre-publish pass as Gate 4 and the full pass after the upload. Render and check stay fully offline - live state belongs to the release path only.
Impact: The public page now counts only tasks a stranger can complete today (11, all actionable - true since MC-1 routes to the forum), shows the MCP Mod Channel Discuss row as a real forum link, and names its source commit 9828ff0.
Impact: First tasks gain a completion model: by default a task completes in its tool's thread and is actionable exactly when that thread exists - a thread-less tool now fails the build instead of shipping an uncompletable task, which is how MC-1 shipped. An explicit completion object routes a task to the main forum meanwhile or marks it blocked with a reason; blocked tasks render visibly with the reason and leave the hero count, which now means actionable-now (with a separate blocked tally when nonzero). MC-1 becomes completable today: its done_when names the forum honestly and the card's Discuss row links it. Thread-creation prep landed for the operator's next provisioning run: seed 10, a provision.json entry, and the bot now resolves ACCESS-URL from source.href for not-published tools. Hardcoded task-count prose and a wrong headline tool count are build failures. Also removed a stray NUL byte in the generator that made grep treat it as binary.
Impact: The committed workbench.html now names its source commit - Published from 29e2698 - replacing the false uncommitted-working-tree claim the page carried since the 11:50 UTC render. From here every committed render either names the input commit or fails check.
Impact: The workbench freshness line becomes two honest modes: a deterministic Published-from stamp naming the last commit that touched workbench.json or the generator, and a Preview stamp for uncommitted inputs that can never publish. check now compares the artifact byte-for-byte when the inputs are clean and refuses a preview stamp in a clean tree - the exact false claim the committed page carried until today - while Publish-WorkbenchAssets gains Gate 0: clean provenance inputs plus a production stamp before any upload. The generator gains exports behind a CLI guard, and the first guard tests land: 8 node --test cases on throwaway git fixtures, including both provenance negatives (production stamp over dirty inputs, preview stamp in a clean tree).
Impact: The 2026-07-29 retro gains an addendum covering the second session: the review that found eight of twelve pending decisions were tasks in decision costumes, the lifecycle Derek adopted (registers are queues, one decision one home, the named First Stranger gate), and the six delegated calls shipped as rubber-stamped artifacts with a single circle-back trigger. Five prior lessons graded for follow-through (both applicable ones acted-on, including the max_tokens fix proven live by this retro's own offload); five new lessons recorded on classification-before-decision, durable principles, named triggers, delegation provenance, and verify-before-registering. Offload provenance stated honestly: one flash draft, minor-fixes verdict, judgment seats kept frontier.
fieldlab/retro/SESSION-RETRO-2026-07-29.mdImpact: Derek delegated the six future-facing register entries; each is now decided, documented, and live. CLA.md v1.0 (plain-language, sign-by-sentence, ledger at docs/legal/cla-signatures.md) closes PD-1's instrument slot - a DCO transfers no rights and Baseline's model needs the tree owned. SECURITY.md ships with GitHub private vulnerability reporting enabled on the repo as the primary channel plus a tagged mailbox fallback and honest solo-maintainer promises. Every public audit finding now carries a standing disposition in docs/audit/2026-07-29-findings-disposition.md. The AI-contribution bar is symmetric and disclosure-based - built by one human directing many agents, judged on verification not provenance. Reply cadence affirms batch rhythm without a calendar promise; the P7 cutover checklist gains the posted-content URL re-sync step. Every artifact records the decision mode (agent-decided under recorded delegation, operator rubber stamp) and the circle-back: the First Stranger gate's first firing - first alpha tester live or first contribution inquiry.
Impact: docs/decisions/ now exists as the canonical home for long-lived decision rationale: PD-1 records the governance-and-contributions posture with its operating principle and leaves the contributor-agreement instrument explicitly open; PD-2 names the First Stranger gate once and collects every deferred security-posture item under it as a due-list. The root register is realigned to the queue-not-archive lifecycle - resolved entries compressed to one-liners linking their durable home, two stale priority rankings reclassified to re-rank at adoption resume, the duplicate direct-join entry closed, and six newly identified true decisions registered (contributor instrument, disclosure path, audit-findings disposition, AI-contribution bar, reply cadence, cutover URL re-sync). AGENTS.md drops the expired TEMP RULE and states the lifecycle; the cost runbook points its external-cohort wording at the named gate.
Impact: The lj-workbench container was recreated with LUMBERJACKS_ROADMAP_HTML pointing at the mounted roadmap.html, so /roadmap now serves the tree's render instead of the image-baked copy that had gone stale by eight journal notes. Served hashes verified for both pages after the recreate; health, join, and the download route all answer 200. Content updates to either public page are now one file copy.
HANDOFF-2026-07-29.mdImpact: fieldlab/retro/SESSION-RETRO-2026-07-29.md records the session that landed both recoverable tools' raw material byte-exact, synced every surface, and republished the page: what shipped commit by commit, the four design corrections that mattered, the follow-through on every 2026-07-28 lesson, and five new lessons - including the root cause of the prior session's HEARTH unreliability (max_tokens starving thinking-model output) and the classifier-blocked exporter commit left explicitly for the operator.
fieldlab/retro/SESSION-RETRO-2026-07-29.mdImpact: The live Recoverable pieces thread now carries the dated update pointing volunteers at recipes/camera-gallery/ and recipes/quest-submission-bridge/ in baseline, applied from the operator-approved receipt (plan ba37ecab31d2). A fresh plan pass shows the thread matches the repo; the four tool threads remain blocked by design while site_base_url is null.
tools/workbench/discord/receipts/2026-07-29-plan.mdImpact: The Discord sync receipt shows exactly one pending change: the Recoverable pieces thread gains the dated update pointing at the re-landed raw material. The four tool threads stay blocked by design while provision.json site_base_url is null, so an apply cannot touch them. Applying remains operator-gated: apply --yes --expect-plan ba37ecab31d2.
tools/workbench/discord/receipts/2026-07-29-plan.mdImpact: All 24 landed files' HEAD blobs equal their archive source blobs at ae81c83. All five landed Python scripts compile. The bridge demo runs end to end from the landed copy: one payload consumed, review markdown carries the Thrall rank and evidence path, and the inbox walks pending to accepted to exported, drafting the /slayer submit command with two transitions journaled. The contract fixture consumes cleanly, the camera dry-run prints its cut plan against the landed timeline sample, entrypoint links pass, generated outputs stay invisible to git, and the tree is clean with exactly the four landing commits on top.
plans/recoverable-pieces-landing-workbook.mdImpact: plans/recoverable-pieces-landing-workbook.md records the reusable playbook the 2026-07-29 landings executed: three find-lanes anchored on d75ffb2/57654fd/ae81c83, the migrate-vs-document decision record, byte-exact landing mechanics with the sha proof, the doc-sync surface list, the verification suite, and a model-tier legend so deterministic tools and cheaper models carry the mechanical steps. Result ledger cites C1-C3.
plans/recoverable-pieces-landing-workbook.mdImpact: Both recoverable tool cards, the workbench catalog entries, the Discord seed, and the cold-pickup handoff now say where the pieces actually are: byte-exact unwired copies at recipes/quest-submission-bridge/ and recipes/camera-gallery/ alongside the archive links. The camera card's wrong pre-prune ref cc322ee is corrected to d75ffb2/57654fd, the catalog piece list gains the four real files it was missing, and the handoff carries a dated addendum for the posted threads and the live am4 URL. Statuses stay recoverable-not-running and QB-1/CG-1 stay the claiming tasks.
Lumberjacks/docs/workbench/workbench.jsonImpact: The pruned camera flythrough pipeline raw material - segment 1's working waypoint extractor, the segment 2-4 briefs, video_to_gallery.py, and both sample fixtures - is back in-repo at recipes/camera-gallery/, byte-identical to the public comfy archive at ae81c83 (= pre-prune 57654fd), with provenance, the MIT boundary, and the samples' privacy note recorded. CG-1 stays the claiming task; the valheim-camera-proof kit stays archive-only. Segment 3 remains the real gap.
recipes/camera-gallery/PROVENANCE.mdImpact: The pruned back half of the quest submission bridge - bridge_consumer.py, review_inbox.py, their fixtures, and the original QUEST/PROOF briefs - is back in-repo at recipes/quest-submission-bridge/, byte-identical to the public comfy archive at ae81c83 (which equals pre-prune ref 57654fd), with provenance and the MIT license boundary recorded. QB-1 stays the claiming task; nothing is wired to the live mod.
recipes/quest-submission-bridge/PROVENANCE.mdImpact: The pinned forum post, the catalog page footer, and the retained long-form announcement all now say the same true thing the short announcement says: every thread gets read, and replies come when the operator checks in - he is currently sharing time with other projects. The old roughly-twice-a-week promise is gone from every member-facing surface, synced to Discord through the bot's diff pass and to the public page by file copy, both hash-verified.
Lumberjacks/docs/workbench/discord/05-pinned-how-this-works.md; Lumberjacks/docs/workbench/workbench.jsonImpact: The announcement now says the true thing in the operator's own voice: built for fun, then because it looked promising, discoveries beyond expectation, cannot do it alone, the community paved the paths, other projects need him now, the work is left where others can look, borrow, and suggest, and he will be back to build more. Reply expectations adjusted to match - replies come when he checks in, rather than a promised twice-weekly rhythm.
Lumberjacks/docs/workbench/discord/drafts/00-announcement-SHORT-20260729.mdImpact: The long-form announcement draft is superseded by a short form per the operator: two sentences, a four-tool list, two ground rules, one call to action - keeping the load-bearing facts (the pause was a choice, statuses are honest, replies batch about twice a week, the server is not open but the tooling is, nothing is owed by anyone) and cutting everything else.
Lumberjacks/docs/workbench/discord/drafts/00-announcement-SHORT-20260729.mdImpact: The bot posted the four held tool threads to the live forum from their seed files, verbatim, against a reviewed plan hash - quest picker, ComfyStewardView, community telemetry, and the Steam join flow - with the recoverable-pieces and how-this-works posts already in place from the earlier apply. Every catalog card now links its real discussion thread, the republished public page carries all six, and the announcement draft is filled with the live address and staged for the operator to post himself: the one message the bot is hard-coded to never send. The full loop the rollout promised is now closed end to end: a stranger can reach the public catalog, download a verified kit, run it cold, and land in the right thread to say what happened.
tools/workbench/discord/provision-state.json; Lumberjacks/docs/workbench/workbench.json; Lumberjacks/docs/workbench/discord/drafts/00-announcement-READY-20260729.mdImpact: The Community Workbench is on the public internet at the AM4 tailnet funnel address: Tailscale terminates TLS at the edge and Caddy splits the front door - the community surfaces (catalog, downloads, roadmap, community pages, the join flow, the aggregates API) serve unauthenticated from an explicit allowlist, the operator boundary surface is blocked at the funnel because the gateway would see the proxy as loopback, unmatched paths get an honest 404, and the operator's existing gallery keeps its authentication at every deep path with only its bare-root index moving under a subpath. Root redirects to the storefront. The join card now points at the live HTTPS endpoint - which retires the old plaintext-credential caveat - and states plainly that the full Steam round-trip on this host is unproven and is exactly first task SJ-1. The GCP VM remains the later lean step for the game world itself, since UDP cannot ride the funnel.
HANDOFF-2026-07-29.md; Lumberjacks/docs/workbench/workbench.json; Lumberjacks/scripts/workbench.mjsImpact: Stabilization now runs on local hardware per the operator: AM4 hosts the workbench-enabled Gateway on the tailnet, and every loop the P7 deploy would have proven is verified there instead - the served catalog page is hash-identical to the repo render, both cold-start kits download hash-exact with correct integrity headers and a wire-downloaded kit runs cold with the corrected config path, the telemetry starter kit's own poller reads the live aggregates API off a simulation ticking at twenty hertz, the navigation sweep is green, and the operator boundary surface correctly refuses a non-operator vantage. The GCP deploy becomes the later lean-and-mean step; the community threads and announcement wait on the public site either way, since the local lane's addresses mean nothing off the tailnet.
HANDOFF-2026-07-29.md; tools/workbench/Publish-WorkbenchAssets.ps1; Lumberjacks/docs/workbench/workbench.jsonImpact: Closes the last blocking item before a deploy could bring a joinable world back up. The public docs that describe the server as Steam-unlisted but password-free are accurate as written and need no change. The consequence a volunteer would otherwise miss is now on the steam-join card: the invite gates the enrollment flow, not the world, so anyone who knows the address can direct-connect without it. Revisit at the first external cohort, the same gate that makes TLS and rate limiting non-optional
Impact: The invite resolves but expires 2026-08-28, so on that date the page's only entry point for a non-member dies while the href stays well-formed and allowlisted — the one failure no existing guard could see. The date is now recorded beside the invite and workbench:check warns inside 14 days and fails once past it. Server verification level is 0, so no phone or email gate blocks a volunteer
Impact: The stylesheet carried a guarantee it did not provide. Measured in Chromium 148, a collapsed disclosure body reports checkVisibility false and zero innerText with details:not([open]) > *:not(summary){display:block !important} applied — identical to without it, because the UA hides the contents through an internal slot author CSS cannot reach. The rule is gone and a print-only note states which two per-card sections do not print. Everything a decision rests on already lives outside <details> and prints
Impact: Whether a publish succeeded depended on how git checked the file out, not on the code. A here-string carries the .ps1's own line endings; on a Windows clone those are CRLF, so the remote shell reads 'set -euo pipefail\r' and aborts after the uploads have already landed in /tmp. Promote-GatewayImage.ps1 normalises and never broke; Publish-WorkbenchAssets, Publish-Modpack and Publish-CompanionBootstrap cloned the pattern without it
Impact: The tools.json key mismatch that made every /workbench/downloads/{id} answer 503 is now a test failure rather than a deploy failure. Seven tests pin the documented shape, the exact 'tools'-key regression, and the refusals for a mismatched digest or size; a committed sample pointer is deserialized into the endpoint's own record, and the publish script gained a third gate that re-parses the JSON it is about to upload and compares its key shape to that same sample. Both sides are now pinned to one file
Impact: The cold-pickup handoff and the operator checklist now state current truth: the repository is public and two prior decisions resolve themselves (the roadmap links work for everyone; the public-source claim is literally true); the audit trail is committed; the Discord forum is live on the new server with the four tool threads held until deploy; ENDtoEND.txt is verified absent from the public repo with zero git history. Two operational facts surfaced: the P7 VM has been stopped since 2026-07-25 - the site has been down four days, current burn is roughly the storage floor, and the deploy session must start the VM first - and the public repo now advertises password-free direct-join, a live operator decision (server password vs accept) queued before the VM comes back up.
HANDOFF-2026-07-29.md; DEREK-BATCH-1.md; DECISIONS-PENDING.mdImpact: Every /workbench/downloads/{id} would have returned 503 on the real deploy: the publish script emitted the artifact array under 'tools' while WorkbenchDownloadEndpoints deserializes 'downloads' and treats a null list as an invalid pointer. No test covers that shape, so the first real deploy was the detector. GCP stays stopped, preserving the VM spend for actual UAT
Impact: A first-time visitor can now actually reach the community: join then Start Here then a tool thread, with the member-only links labelled as such. The displayed freshness can no longer go stale because it is derived from git rather than typed. All four OWNERS.md promises resolve. Each of the seven tools declares its own stage-3 right, so ComfyStewardView no longer inherits a commit-access promise its all-rights-reserved licence cannot honour
Impact: Eight statements on a page whose whole premise is that its statuses match reality were falsified the moment djcdevelopment/baseline went public. All three private-until-claimed source blocks now render live links into the repo, the two always-visible stage-3 access mentions are gone, and stage 3's reward is restated as commit access
Impact: The catalog reads as a storefront rather than an encyclopedia. Nothing was deleted: a 222-string zero-loss check confirms every sentence in workbench.json still renders, and new check() guards fail the build if status_detail, requirements, or download digests are ever moved inside a disclosure
Impact: The bot credential was already covered by a wildcard, but the file that actually appeared at the repository root is now listed by its own name as well, at the root and at any depth. A pattern is easy to skim past when someone is checking whether their secret is safe; a named line answers the question directly. Verified that the credential has never been committed on any branch: the path has never existed in any tree, no file of that kind has ever existed in the repository's history, and a content search across every reference finds no commit that ever added or removed the value.
.gitignoreImpact: The handoff block that goes to the agent updating the catalog page now states verified live facts instead of the pre-provisioning prediction: two threads posted, no member replies yet, nothing exported, and the candidate journal not yet existing. It calls out that five of the seven tools will carry a null discussion link until the catalog deploys and that one tool never gets a thread at all, so nulls read as the designed state rather than as missing data, and it records that the page generator already allowlists the forum's link host, so the thread URLs will render as live links.
tools/workbench/discord/WORKBOOK.mdImpact: The forum went live on the new community server, provisioned from this repository rather than by hand. The channel carries the eight-tag taxonomy with required tags on and the post-guidelines text, the how-this-works guide is posted and pinned, and the recoverable-pieces thread is open and tagged. The four tool threads that link to the catalog page are deliberately held back until that page is deployed, so nobody arrives at a placeholder or a missing page. The live plan hash matched the receipt approved before the bot was ever invited, which means the operator approved precisely what shipped.
tools/workbench/discord/receipts/2026-07-29-plan.md; tools/workbench/discord/provision-state.jsonImpact: The credential reader only understood a bare token or one specific key name, so an env-style file whose line was named differently was read back with the key name still attached and failed as an unauthorized response with nothing to point at. It now accepts either shape - bare token, or a named line in any of the common spellings, quoted or not, with or without a byte-order mark or carriage returns - and rejects a placeholder or an id on length before it can become a mystery failure, without ever echoing the value. A new read-only identity check reports the bot, whether it can see the server, and whether the channel exists, and prints the authorization link itself when the bot has not been added yet, so the operator never has to go looking for an application id. The refusal to read a credential from inside the working tree stays, and the ignore rule was widened to cover the filename that actually appeared, because this repository commits and pushes without being asked.
tools/workbench/discord/workbench_discord.py; .gitignoreImpact: The forum setup instructions handed the operator a bash one-liner - a directory create chained to a file write with the shell-and operator - on a Windows PowerShell 5.1 box, where that separator is a parse error and neither command exists. Every runnable snippet in the workbook, the setup doc and the tool README is now PowerShell with Windows paths and one command per block. The token file gets an explicit ascii encoding, because PowerShell 5.1 writes a byte-order mark on its utf8 setting and a mark in front of a bearer token surfaces only as an unauthorized response much later; the token reader now also strips one if it finds it, so both spellings work.
tools/workbench/discord/WORKBOOK.md; Lumberjacks/docs/workbench/discord/09-discord-bot-setup.mdImpact: The forum provisioning work now has a tick-box workbook covering the one-time bot setup, the provisioning run, the second run that follows the catalog deploy, and the feedback pass - plus a paste-ready handoff block for the next agent describing where the thread URLs come from, which catalog fields they fill, which generated file must never be hand-edited, and which rules bind that agent too. Written because three separate hands are touching this in sequence and the ordering constraint between the forum posts and the catalog deploy is easy to miss.
tools/workbench/discord/WORKBOOK.mdImpact: The provisioner tracked which messages belong to a managed post only through its own state file. If that record were lost, a post whose body spans two messages would have looked one message short and the next converge run would have appended a duplicate continuation to a live community thread. The tool now rediscovers a post by reading the thread: the opening message plus the unbroken run of its own messages that follow it, stopping at the first reply from anyone else. A member reply in the thread is left untouched and a post someone wrote by hand is still recognised as unmaintainable rather than edited.
tools/workbench/discord/workbench_discord.pyImpact: The community forum is now config-as-code: the forum channel, its eight-tag taxonomy, its post-guidelines text and its six opening posts are all generated from files already in this repository, and re-running the tool converges on drift - a deleted tag returns, a hand-edited pinned post is restored to the written text - instead of duplicating anything. The tool does structure and never conversation: there is no code path that sends a sentence nobody wrote in the repo, mentions are disabled on every write, and the announcement post is on a denylist no flag can lift, so replies to the community stay the operator's own on the operator's own rhythm. It also replaces the external export step that feeds the feedback distiller. Standard library only, no resident process, batch-run on demand.
tools/workbench/discord/; Lumberjacks/docs/workbench/discord/09-discord-bot-setup.md; tools/workbench/discord/receipts/2026-07-29-plan-offline.mdImpact: Three operator calls land: pull requests are open to anyone with something to contribute, with the operator as the sole approval gate (CONTRIBUTING.md rewritten; the CLA-versus-DCO instrument stays an open item, narrowed); ladder stage 3 is renamed from Steward to Contributor because Steward is an overloaded term on the server - the license suite's community-steward safe harbor and the ComfyStewardView product name are deliberately unaffected; and the public comfy archive's community data stays as-is, with consent from everyone named, misattributions already corrected on request, and the live quest data on record as donated by active volunteer GMs. A new Discord server exists and a task is queued to provision the workbench forum from the repo's own seed files.
CONTRIBUTING.md; Lumberjacks/docs/workbench/workbench.json; DECISIONS-PENDING.mdImpact: Per the operator's call, docs/audit joins history: the 36-hour independent audit, the GCP burn-rate review, the contributor-onboarding review brief, and its annotated fresh-eyes results. The review's own recommendation argued these memos double as newcomer orientation; they are now visible to git instead of sitting untracked. The remaining audit-related decisions stay tracked on the operator checklist.
docs/audit/2026-07-24-independent-36h-audit.md; docs/audit/2026-07-25-gcp-burn-rate-review.md; docs/audit/2026-07-29-contributor-onboarding-review.mdImpact: The fresh-eyes review's agent-executable fixes are in: three stale handoff files now redirect at the canonical one and four pre-Valheim greenfield-era docs carry archive notices; five living docs' references to pruned files are annotated with honest recovery refs (fieldlab-native docs to the pre-prune commit, comfy-origin material to the public archive) and the fieldlab ADR index's dead canon line now points at the living roadmap, strategy, and lane pin; a START-HERE page tags every area live, paused, built-not-deployed, cockpit, or historical; BUILDING.md consolidates the two build environments and the commit ceremony out of agent-facing docs; a 26-term GLOSSARY disambiguates the three things called workbench; and the decisions register's own pre-lint wording is corrected. Historical records - retros, the journal, the prune audit, frozen status JSON - were deliberately left verbatim.
START-HERE.md; BUILDING.md; GLOSSARY.md; fieldlab/docs/adr/README.mdImpact: The operator's corrections override the burn memo's framing: the early overspec was deliberate limit-testing with 800-plus headless connections, and 2 vCPU with 16 GB is the declared floor, so the 8 GB downsizes are rejected and only a same-shape e2-highmem-2 family swap remains, priced after invoiced data exists. The disk growth is self-inflicted prod-cadence backups running during dev loops on an heirloom world preserved elsewhere - a new lever flips the valheim-server to the existing dev backup posture with a written re-arm rule. Today's cohort is the operator's own three accounts plus name-known friends, so duty-cycle scheduling loses its product-hours weight and the aggressive stopped-except-sessions default becomes natural. Sequencing set: billing export tonight, full shakedown at end of night, first scheduled restart watched once as the last unproven claim.
infra/gcp/p7/RUNBOOK-cost-and-cycle.md; DECISIONS-PENDING.mdImpact: Four independent levers with staged commands the operator runs himself: BigQuery billing export first (turns plus-or-minus twenty percent estimates into invoiced truth), orphaned-snapshot cleanup as list-first-then-eyeball (the dead 250 GB lineage, live state-v2 dailies explicitly untouched), VM scheduling with an honest duty-cycle ladder (about twenty-five dollars a month at eight hours nightly, more only with longer off-hours or stacking), and machine right-sizing. Both stop-start levers carry the live-alpha-server downtime warning in bold with a post-in-Discord-first instruction, and the no-terraform-apply rule heads the document with the destroy plan quoted. What makes any of this viable now is recorded plainly: the deploy lane is baked, image-pinned, and restart-predictable.
infra/gcp/p7/RUNBOOK-cost-and-cycle.md; docs/audit/2026-07-25-gcp-burn-rate-review.mdImpact: A dated temp rule (expires 2026-07-29 05:00 PT, self-deleting) tells every builder session in this repo to forgo unit tests when the contract or seam is highly likely to be integration-tested shortly by the operator himself - the operator-in-the-seat mode distinction applied for one night, per-change judgment, with irreversible or production-critical changes still tested. A root CLAUDE.md now points Claude sessions at AGENTS.md so working rules reach every agent brand. The GCP spend and cycle-time question enters the decision register with a staged runbook on the way: the deploy lane being baked and predictable is what makes revisiting the always-on VM posture viable.
AGENTS.md; CLAUDE.md; DECISIONS-PENDING.mdImpact: Derek's canonical product framing is now written down: Baseline is a toolkit for building a whole community on Valheim - identity baked in, telemetry first-class, vertical integration paths from server through transpiling, and headless/automated/MCP-driven testing - serving communities that already run mods, spreadsheets, bots and checklists so they spend less time on tracking and more on creating; forking pieces out is the highest compliment. HEARTH/Mechnet, the operator's personal AI lab, is explicitly NOT part of any Baseline deliverable, and community-facing automation must run without it. The handoff doc now carries the boundary rule; the privacy scanner's machine-path rule doubles as its guard.
docs/baseline-vision-and-boundary.md; HANDOFF-2026-07-29.mdImpact: HANDOFF-2026-07-29.md at the repo root is the canonical resume point for any agent or the operator: session state, what shipped, pending items by actor, commit ceremony and gotchas, a key-file index, and step-by-step resume recipes for the thread-URL fill, the deploy batch, zip rebuilds, and un-pinning the networking lane. The execution-status postscript on the operator's plan file points here.
HANDOFF-2026-07-29.mdImpact: Three research agents surveyed solo-maintainer practice, modding-community norms, and agent-automation patterns; 13 deduplicated ideas were scored in a weighted matrix and the top five built: a journal-to-announcement drafter that assembles never-auto-posted Discord draft skeletons from the roadmap journal, a forum tag taxonomy rendering the existing ownership ladder into Discord triage, a bug-fix-shaped first-task authoring lens backed by newcomer merge-rate evidence, an Already-answered one-pager section plus a seven-reply saved-replies starter set, and a batch feedback distiller that turns Discord thread exports into an append-only candidate-issues journal with nothing auto-filed. Both scripts are deterministic and work with the local LLM fleet down; ranks six through thirteen are staged as backlog, several deliberately parked until the first real volunteer exists.
plans/cognitive-lift-portfolio.md; tools/workbench/new_announcement_draft.py; tools/workbench/distill_feedback.py; Lumberjacks/docs/workbench/discord/07-forum-tags-setup.mdImpact: The rollout's Discord layer exists as reviewable files, not posts: an announcement that states the pause plainly and is explicitly not a verdict on anyone, one thread seed per first-wave tool with achievable first tasks, a pinned how-this-works post covering the batch-reply rhythm and graceful step-back, and one thread for the two revivable pieces where reviving is the claiming path. OWNERS.md opens the append-only ownership ledger all 7 tools report unclaimed into. Derek review gates everything: nothing posts until the announcement batch, and DEREK-BATCH-1.md carries every open decision including the StewardView license posture.
Lumberjacks/docs/workbench/discord/00-announcement.md; Lumberjacks/docs/workbench/OWNERS.md; DEREK-BATCH-1.mdImpact: Two downloadable kits now exist: a quest-picker kit with a synthetic sample guild, verified to run from a fresh folder with only Python and openpyxl, and a telemetry starter kit that polls the public aggregates-only v0 API with the standard library. Every zip passes a mandatory deny-list privacy scanner (real player handles, guild workbooks, tailnet hosts, SteamIDs, credentials, machine paths, the server IP) before it can be built, and the publish script refuses any artifact whose hash does not match what the public page claims. A real cross-tool defect found during verification is fixed: the picker told players the pruned config path while the mod reads comfy-network-sense - a silent failure for every volunteer until now. Per-tool one-pagers land alongside.
tools/workbench/Test-WorkbenchZipPrivacy.ps1; tools/workbench/New-WorkbenchZip.ps1; recipes/quest-catalogs/render_quest_picker.py; Lumberjacks/docs/workbench/tools/quest-picker.mdImpact: A 2026-07-23 journal record used the wrong licensing term for this project. The accurate term is public source under Business Source License 1.1 with the community-steward safe harbor, converting to AGPL-3.0-only at the recorded Change Date. Journal records are append-only, so the original stands with this correction beside it; a glossary entry now defines the term, and the generator refuses the inaccurate phrase in any newly written note or roadmap field.
Lumberjacks/scripts/roadmap.mjs; LICENSING.mdImpact: The Community Workbench is built: workbench.json (7 tools, 5-stage ownership ladder, honesty invariants) renders through workbench.mjs into a self-contained /workbench page served like the roadmap (mount-override, per-request reload), with a fail-closed /workbench/downloads lane that verifies SHA-256 per request. Statuses state what runs and what does not: no rate limiting on the join flow yet, StewardView license under review, recoverable pieces marked claimable. Nav links added across the community pages. Not yet deployed - the page and packages ship together in one gated deploy batch.
Lumberjacks/docs/workbench/workbench.json; Lumberjacks/scripts/workbench.mjs; Lumberjacks/src/Game.Gateway/Endpoints/WorkbenchViewEndpoints.csImpact: The guest-package installer finally has a README (its reissue TODO quoted as a known gap); the quest vertical-slice architecture doc now carries a banner mapping which layers are live, which moved into the mod, and which were pruned to the public archive; the MCP mod-channel gateway accepts COMFY_GATEWAY_PYTHON instead of a hardcoded other-repo venv path while staying localhost dev-only; and the missing gm-template example is explicitly labeled as Workbench first task QP-1 in sources.json.
tools/guest-package/README.md; docs/quest-vertical-slice-architecture.md; network/mcp/etc/start-comfy-gateway.cmd; recipes/quest-catalogs/sources.jsonImpact: The networking lane parks on a deliberate hard hold at a green machine-state: every remaining step needs live two-human Steam observation and none is scheduled; the hold, its pinned items, and a one-command resume path are recorded in fieldlab/PINNED-networking-lane-2026-07.md. Adoption milestone A7 Community Workbench opens to carry the shifted effort: a public catalog of tools a volunteer can run today with honest statuses, cold-start packages, per-tool discussion threads, and an ownership ladder. The 2026-07-23 to 07-25 stretch is closed by a session retrospective; no live network authority changes during the pause.
fieldlab/PINNED-networking-lane-2026-07.md; fieldlab/retro/SESSION-RETRO-2026-07-28.md; plans/remaining-human-tests.mdImpact: Hot Harmony patch bodies now accumulate per-call timing and emit per-interval rollups to perf-patchload.jsonl behind a new default-off Perf key perfPatchLoadRollupEnabled, with a lab runbook for an inert-versus-armed A/B comparison; volunteer telemetry is unchanged. The benchmark has not been run: lab clients client01/client02 remain unseeded and that one-time Steam login stays a pinned human step. COMMANDS.md now records that the netcode probe is console-started only after the config-surface cull.
fieldlab/docs/runbook-patchload-ab-benchmark.md; fieldlab/experiments/patchload-ab/patchload-lab.cfg; network/mod/ComfyNetworkSense/CHANGELOG.mdImpact: A written policy now governs ComfyNetworkSense Harmony patches: attribute prefix/postfix applied in Awake as the default shape, transpilers only for surgical call-site swaps that must degrade to a no-op, an inlining escalation ladder, load-bearing patch ordering recorded at the patch site, and detour cost measured rather than assumed. It codifies existing practice so hot-path changes stay deliberate; no code changed.
fieldlab/docs/harmony-patch-policy.mdImpact: Repeat deterministic replay rejected a 50 ms bracket floor, then showed a bounded 100-200 ms relative-transit policy can reduce aggregate disturbed-path stalls and large corrections versus chase while spending less delay than fixed 200 ms; no DLL or live authority changed.
fieldlab/experiments/creative-runtime/cre-e08-adaptive-presentation-replay/experiment.md; fieldlab/experiments/creative-runtime/cre-e08-adaptive-presentation-replay/runs/pure-20260725T045003Z/receipt.json; fieldlab/experiments/creative-runtime/cre-e08-adaptive-presentation-replay/runs/pure-20260725T045003Z-repeat/comparison/comparison.jsonImpact: The bounded i5 repair lane now detects a non-answering Companion bind mount, restarts Docker through a durable interactive task, preserves failure diagnostics, and restores the exact client package without starting Valheim.
tools/i5/Repair-I5DockerDesktop.ps1; tools/i5/README.mdImpact: Two-client receipts now isolate the final APPLY and OBSERVE segments, reject OBSERVE-side apply activity as contradictory, and keep competing-writer identity explicitly unresolved before any live visual claim.
fieldlab/experiments/creative-runtime/cre-e06-motion-phase-rollups/experiment.mdImpact: Deterministic replay showed that smaller fixed buffers retain synthetic burst stalls and corrections, while 200 ms removes them only by increasing current-time error; no client DLL or authority change was promoted.
fieldlab/experiments/creative-runtime/cre-e07-presentation-replay/runs/pure-20260725T040847Z/receipt.json; fieldlab/experiments/creative-runtime/cre-e07-presentation-replay/runs/pure-20260725T040847Z-repeat/comparison/comparison.jsonImpact: Wave 0 and the physical feel window now share one fail-closed bundle analyzer; synthetic fixtures prove both-client success and missing-client rejection before a live join window.
fieldlab/experiments/creative-runtime/cre-e06-motion-phase-rollups/Test-BundleAdapter.ps1; fieldlab/scripts/Summarize-TwoClientMotionPhaseBundles.ps1; tools/i5/Start-TwoClientCapture.ps1Impact: Wave 0 preflight now permits fast client-pull package pointers while still requiring both clients to match that package, its hash, and the Gateway-admitted mod identity.
tools/i5/Test-Wave0Readiness.ps1Impact: The autonomous Valheim lab can now stage a caller-selected DLL and block before launch unless the shared payload hash matches it, preventing concurrent dirty worktree builds from contaminating experiment receipts.
fieldlab/docs/runbook-headless-valheim-lab.mdImpact: The public client-pull pointer now serves the clean CRE-E06 build; OMEN and i5 installed the same verified package and DLL with rollback backups while Gateway and server remain on the admitted m30 identity.
docs/roadmap/m31-motionphase-client-package.jsonImpact: Existing client JSONL and Companion captures now separate receive, drain/coalesce, bind, render, error, freshness, and source-agnostic interframe displacement without per-frame files or broader Valheim authority.
fieldlab/experiments/creative-runtime/cre-e06-motion-phase-rollups/experiment.mdImpact: Repeat source-derived receipts show receive coalescing is already latest-per-object while render work scales with frame rate and fresh remotes; runtime phase costs and visual causality remain deliberately unclaimed.
Impact: Repeat lab receipts show latest-wins and expiry reduce deterministic presentation apply work while preserving final fresh state; placement remains an explicit client, per-recipient, or pre-fanout decision and no live authority changed.
Impact: Retained WebSocket and UDP receipts show stale rejection, gap and wrap acceptance, authenticated resume behavior, detached-token rejection, and topology-aware relay accounting without changing live gameplay authority.
Impact: Proves selected presentation work reaches WebSocket fallback and bound UDP while deferred and dropped work remains absent, without changing Valheim authority.
fieldlab/experiments/creative-runtime/cre-e02-gateway-pressure-route/runs/gateway_udp-20260724T141258Z/receipt.jsonImpact: Proves bounded selective degradation and semantic routing in pure lab runs without changing Valheim authority.
fieldlab/experiments/creative-runtime/cre-e01-runtime-envelope/runs/pure-20260724T133947Z/receipt.jsonImpact: Every public Gateway dashboard now carries a low-key Baseline, Lumberjacks, Comfy, and license-details footer, while the root README identifies Baseline as canonical and makes the legal map unambiguous.
Impact: Defines public evidence, private-person defaults, configurable delayed aggregate trends, and a narrow independent-review path for community trust.
Impact: Eligible independent operators can now keep profit without a separate agreement while serving at most 100 active members, remaining under USD 25,000 in aggregate annual community revenue, publishing the exact deployed source, and protecting player data; larger organizations use a flexible negotiated path.
LICENSE.mdImpact: Adds a local /workbench hierarchy over roadmap and goal sources, stamps Docker source identity, and preserves redacted immutable snapshots without moving Steam credentials into the local image.
Impact: Current releases permit noncommercial community deployment only with a public reproducible source offer; commercial production use now requires a separate agreement, third-party material is explicitly excluded, and each version has a dated AGPL conversion.
LICENSE.mdImpact: Coordinates readiness, concurrent capture, bounded apply-observe roles, and named motion patterns on the existing OMEN/i5 Companion lane without keyboard automation or authority promotion.
Impact: The local authority lane can refresh and preflight multiple disposable clients before any starts, clean up partial starts, and aggregate receipts for the eventual two-player shadow/strict run.
Impact: Disposable lab runs now fail before human login when payload, runtime, Valheim seed, or existing profile is missing; closed probe evidence can flow through Docker AuthorityLab normalize/replay without manual file movement.
Impact: Restores existing-profile autojoin only for profile-gated headless/rendered clients; adds verified refresh/start/stop lifecycle, bounded MCP motion commands, native JSONL normalization/replay, and explicit evidence boundaries without changing P7 authority.
Impact: Runs E02 recipient queue and E03 motion relay through real Gateway WebSocket, WAL restart, and bound UDP seams before native capture or P7 promotion.
Impact: Adds synthetic E00-E03 receipts, bounded failure evidence, linked policy decisions, and discovery status tooling before any live authority promotion.
Impact: Moves the dev P7 backup posture into explicit environment knobs so idle imported worlds do not generate unbounded hourly zip churn, while production can turn bounded backups on with retention limits.
Impact: The Wave 0 fallback path now has Suggest-Wave0DefectPacket.ps1, which reads failed live receipts, annotations, and the visual seal to recommend a defect kind and exact New-Wave0DefectPacket command before an agent retains the named defect packet.
Impact: The Wave 0 return packet now indexes the full pre-live evidence set, including roadmap freshness, auto-wait fixtures, visual-seal fixtures, named-defect fixtures, and two-machine bundle smoke, so the operator handoff matches the actual gate coverage instead of an older four-check subset.
Impact: The Wave 0 pre-live audit now fails when the living roadmap source, rendered HTML, or public /roadmap page does not name the live P7 modpack, Gateway, and Companion bootstrap releases, catching stale public status before a tester is asked to join.
Impact: The public roadmap current-focus block now matches the verified Wave 0 runtime state: P7, OMEN, and i5 are aligned on m30-rolecontrol-20260723-r1, Companion bootstrap r26 is published, and the remaining gate is the live two-client apply/observe visual proof.
Impact: The Companion bootstrap builder now rejects packages that omit PowerShell scripts referenced by the Companion Wave 0 command surface, preventing a repeat of the package gap where UI commands were present but the downloaded bundle could not run them.
Impact: The public Companion bootstrap now points at companion-bootstrap-20260723-r26; the downloaded package hash matches the manifest and includes the Wave 0/i5 operator scripts referenced by the Companion handoff commands.
Impact: The Wave 0 lane now has Wait-Wave0LiveGate.ps1, a bounded wrapper that can start before/during client joins, wait for P7 peer_count to reach the live threshold, then delegate to the existing live gate; Companion and return packets now prefer the low-touch wait command.
Impact: The i5 deploy lane now has a bounded Repair-I5DockerDesktop command that recovers Docker Desktop Linux engine readiness, recreates the Companion with both compose files, verifies the Wave 0 packet endpoint, and emits a JSON receipt instead of requiring operator KVM work.
Impact: The public credential-free Companion bootstrap now points at companion-bootstrap-20260723-r24; the downloaded package hash matches the manifest and contains the Wave 0 packet endpoint, redacted Companion status, and init-enabled Docker Compose service.
Impact: The local Companion now exposes read-only Wave 0 handoff packets as Markdown and JSON, redacts raw enrollment ids from status, and runs the Docker Companion service with init enabled to reduce zombie-container rebuild failures on remote test clients.
Impact: The public credential-free Companion bootstrap now points at companion-bootstrap-20260723-r23; the downloaded package hash matches the manifest and the packaged Companion status endpoint contains the named-defect fallback command for the two-client Wave 0 handoff.
Impact: The Companion Wave 0 panel and status endpoint now show both allowed exit paths for the remaining two-client gate: seal the visual evidence when it passes, or retain a named defect packet when visual proof is inconclusive or cannot be sealed.
Impact: The public credential-free Companion bootstrap now points at companion-bootstrap-20260723-r22; the downloaded package hash matches the manifest and the packaged Companion status endpoint contains the final visual-evidence seal command for the two-client Wave 0 handoff.
Impact: The local Companion Wave 0 panel now exposes the full operator sequence: first live gate, first visual annotation, role reversal, reversal annotation, and final visual-evidence seal, reducing the remaining two-client test to a visible checklist instead of reconstructed chat context.
Impact: The public credential-free Companion bootstrap now points at companion-bootstrap-20260723-r21, and the downloaded package hash matches the manifest, so a fresh alpha install receives the local Wave 0 live-gate panel without GitHub auth or manual file transfer.
Impact: The local Companion now shows a Wave 0 live-gate panel and serves a redacted status endpoint that tells an operator whether local setup, P7 telemetry, peer count, and recent capture evidence are ready before running the two-client apply/observe proof.
Impact: The P7 infrastructure defaults now reflect the live n2-highmem-2 cost-sized VM and disable noisy Cloud Logging ingestion while retaining on-VM docker logs and OTLP metrics/traces for alpha diagnostics.
Impact: The public roadmap current-release block now reflects the deployed m30 role-control Gateway and ComfyNetworkSense runtime identity, matching the P7/OMEN/i5 readiness receipts used by the Wave 0 return packet.
Impact: P7 now runs Gateway m30 and the matching ComfyNetworkSense server DLL; the public client-pull manifest points at the rebuilt m30 package, and both OMEN and i5 installed it through Companion without browser copy/paste.
Impact: The m30 role-control candidate has public-safe artifact evidence for the mod DLL, client-pull package, and local Gateway/service images, while explicitly marking that P7 and clients still run m29 until promotion.
Impact: The role-control live-gate work now has a distinct mod release identity and locally verified Gateway image admission target, avoiding changed DLL bytes being published under the prior m29 identity.
Impact: The live gate can set OMEN/i5 APPLY versus OBSERVE ONLY through the existing local Companion command lane, then verify the split before moving characters, reducing manual tester touch and preventing ambiguous role-reversal evidence.
Impact: Gateway motion admission now has a focused non-human test seam for distinct-recipient fan-out, same-recipient suppression, unauthorized sessions, malformed frames, duplicate or old sequence rejection, and source-ZDO binding before asking for another live two-client course.
tests/Game.Gateway.Tests/ValheimMotionRelayTests.csImpact: A post-deployment no-player smoke capture against P7 m29 verified that the public telemetry endpoints, local Companion diagnostics, and transport-capture writer are live after the heartbeat-age deployment. The rebuilt OMEN Companion emits final_local_motion.server_ping_age_ms and server_ping_age_jitter_ms; the run remains INCONCLUSIVE for movement because no peer window was present.
Impact: P7 now runs Gateway m29-heartbeatage-20260723-r1 admitting the same m29 mod release; the dedicated Valheim server runtime and cold-start ComfyNetworkSense DLL hashes are 697f318f9dda7d5273253b787549de16c89abc9f1c365970c8944d917bc08424. The public client-pull manifest now points at m29-heartbeatage-20260723-r1 with package sha256 2b3cbb54eccc1860a3e93bc01586c17878cbc5e5ffd6e7d37f0c51cbca256475, and OMEN installed that package through Companion. i5 was not changed because the optional tailnet lane reported the laptop offline.
Impact: ComfyNetworkSense now has a new immutable release identity for the heartbeat-semantics correction: m29-heartbeatage-20260723-r1. The release cut verified the net48 mod DLL carries that identity and the Gateway image lumberjacks-gateway:m29-heartbeatage-20260723-r1 admits the same mod release; a repo-local modpack builder now creates the small Companion package from the local Valheim payload while preserving personalized config.
network/mod/ComfyNetworkSense/ComfyNetworkSense.cs tools/modpack/New-AlphaModpack.ps1Impact: Client telemetry now records server_ping_age_ms and variation with explicit ZRpc heartbeat provenance; legacy rtt_ms aliases remain during alpha while HUD, scoring, Companion summaries, and the retained probe stop presenting heartbeat age as round-trip latency.
Impact: Future two-client runs can stop at the failing integration boundary instead of treating missing Gateway deltas as native motion or repeatedly asking a tester to reproduce the same lookup failure.
Impact: P7 Gateway, dedicated server, OMEN, and i5 now run the m20-playerindex-20260723-r1 release; the Companion bootstrap pointer is r20. The release adds a bounded live Player/ZNetView index fallback after direct ZDO and ZDOMan scene lookup fail, ready for the next controlled APPLY test.
Impact: The m19-zdoresolve-20260723-r1 mod/Gateway identity is now sealed and published; P7, OMEN, and i5 all point at the same verified client package while the dedicated server reports ready. The release includes the ZDO-object motion lookup fallback and client-local capture truth.
Impact: Motion packets now resolve through ZDOMan and the ZNetScene ZDO overload after direct ZDOID lookup fails, targeting the observed alpha failure where UDP motion arrived but no remote GameObject was found. Live clients remain unchanged until the paired mod release is published.
Impact: The local Companion can now deliver allow-listed movement patterns to a running client mod with JSONL receipts, while capture verdicts distinguish active motion readiness from counters that advance without an active motion lane.
Impact: Records Derek's decision to go forward with the repo automation that auto-commits Gateway work and force-pushes/rewrites main: baseline is a solo open-source working sample, so no collaborators are disrupted by a history rewrite. Checked off in DECISIONS-PENDING.md; memory updated to ACCEPTED. Decision record only.
Impact: The update page now highlights the verified runtime modpack row separately from the Gateway image release, so operators can distinguish the current downloadable package from the server image that serves the page.
image digest sha256:eafabacad2842267c09b0a74fd2b4f4a4abe89d9260befe33581045ae65a24ddImpact: The m27 Gateway serves the current runtime modpack pointer as the first release-history row and retains prior static entries below it, preventing future client-pull releases from falling out of the public table.
commit pendingImpact: The update page now derives its first historical row from the verified runtime modpack manifest and appends the prior static alpha history, so future client-pull packages cannot silently be omitted from the release table. Gateway m27 is live on P7 with the frozen admitted mod identity unchanged.
image digest sha256:4181681d014844e6476b4a96a05c029b11a93f702a546c40fc985f99bdb13f0cImpact: P7 now serves Gateway m26-releasehistory-20260723-r1, which keeps the frozen m15 admitted mod identity and corrects the public pre-signin release table to include the current m17-motionstate package followed by the four prior releases. The live update page and runtime modpack manifest agree.
image digest sha256:4e2262f3a6aa108136239be14dd87b914abe90ff976aafc385ac6e9081e86745Impact: Companion r25 records observed motion states and final WebSocket/UDP readiness in per-run evidence, treats missing or stale Valheim heartbeat telemetry as incomplete, and exposes the same evidence in the OMEN/i5 two-client comparison. This is diagnostic evidence only; distinct-recipient fan-out and opt-in presentation remain gated.
commits 8afe022 and 2fe26e9Impact: Adds fieldlab/retro/SESSION-RETRO-2026-07-23.md (the offload-orchestration adoption session: M1 plus M2-1/M2-3 plus the A1-A6 track, and the discovery that the repo automation force-pushes and rewrites main) and DECISIONS-PENDING.md (open substrate-gap and next-step decisions). Documentation only.
Impact: P7 now runs Gateway image m25-motiondash-20260723-r1, still admitting mod identity m15-hudrecover-20260723-r1. Public /community, OMEN Companion, and i5 Companion all include the motion_state/client-readiness text, while /api/v0/telemetry/valheim remains fresh with motion_state=idle and zero peers.
Impact: P7 now serves companion-bootstrap-20260723-r24 with SHA-256 9b75174e711c579c6cc1edebb9292ebb51d91ec0166ba60db1f554a5d332b253. The bootstrap carries the Companion dashboard change that displays client motion_state and WebSocket/UDP readiness beside aggregate motion counters.
Impact: Companion and the public community trace now include the Valheim heartbeat's motion_state plus WebSocket/UDP readiness beside aggregate ingress counters. A zero-frame window can now be read as idle, observing, or error instead of an ambiguous native-motion-only baseline.
Impact: Adds an adoption track and milestones A1 Trust and Rhythm (complete) through A6 Projection to the living roadmap, so community/adoption commits journal under A1-A6 instead of being mislabeled as netcode M-milestones. A1 and A2 exit evidence record the shipped M1/M2 adoption docs. Roadmap data only; no runtime behavior change.
Impact: The earlier m16 package was superseded before testing because the server deploy rebuilt the DLL at current HEAD. P7 now runs Gateway image m24-motionstate-20260723-r1, still admitting mod identity m15-hudrecover-20260723-r1, and current.json points at m17-motionstate-20260723-r1 with package SHA-256 57d073b694dd660cc3a050d0772687553ba3cdb0978a62a4baa865167e7c022a. OMEN, i5, and the server all carry the matching current-head ComfyNetworkSense DLL hash, and /api/v0/telemetry/valheim now exposes motion_state plus UDP/WebSocket motion counters.
Impact: P7 current.json now points at m16-motionstate-20260723-r1, a config-preserving alpha modpack with SHA-256 a66c190c2f9dd2845ce87ed1bfeea58e65438d987b85b4bc32c76c909a216551. The package keeps the admitted mod identity m15-hudrecover-20260723-r1, so testers can pull the HUD/heartbeat motion-state diagnostics without requiring a Gateway image restart.
Impact: The Valheim mod now reports observe-first motion state, UDP/WebSocket readiness, counters, and last error in its heartbeat, and the transport strip shows the same state in-game so two-client captures can distinguish idle, disconnected, observing, and failing motion lanes without changing native presentation.
Impact: Public Companion bootstrap r23 now carries the burst movement capture UI, adding a 30-second one-second-sample preset for sprint and stutter-step tests. OMEN and i5 were both restarted through the canonical Companion lanes and report r23 in redacted diagnostics; the public manifest verifies the r23 package hash.
Impact: The Companion readiness banner now explicitly identifies the read-only dashboard state when Valheim is not visible, tells operators that updates require the Valheim folder mount, and names the i5 Start-I5Companion.ps1 lane. This addresses the i5/OMEN no-/valheim mount failure mode discovered through redacted diagnostics; public bootstrap r22 carries the guidance.
Impact: The Companion now exposes a one-click redacted diagnostics JSON with local readiness, hashed enrollment identity, current public release pointers, live Gateway/Valheim/cutover/motion snapshots, and recent capture verdicts. OMEN and i5 were rebuilt and verified with no access-key/client-key fields; public bootstrap r21 carries the change.
Impact: The public /join/update page now shows a current downloadable mod pack box sourced from the runtime manifest before the historical release table, alongside the current Companion bootstrap. Gateway-only image m23-updatepage-20260723-r1 was cut and promoted to P7 while continuing to admit frozen mod release m15-hudrecover-20260723-r1; live telemetry and page HTML verify the deployment.
Impact: The Companion moving-parts panel now includes a compact live readout for peers, player names, Lumberjacks motion receive/relay counts, cutover mode, queue depth, and ack/apply counters, so alpha testers can see the active transport window without scanning tile prose or raw JSON. OMEN and i5 were rebuilt and verified; public bootstrap r20 carries the change.
Impact: Transport capture runs can now be downloaded as a single zip containing summary.json and samples.jsonl, and the Companion UI links that bundle from both the current capture result and recent capture history. OMEN and i5 were rebuilt and verified by downloading and inspecting bundle.zip; public bootstrap r19 carries the change.
Impact: The Companion evidence panel now exposes 15 second smoke, 60 second movement, and 180 second session capture presets with explicit progress copy, so alpha testers can collect appropriately sized transport evidence without editing JSON or relying on a single hard-coded 60 second run. OMEN and i5 were rebuilt and smoke-captured; public bootstrap r18 carries the change.
Impact: Transport capture summaries now include an explicit interpretation and next operator action for incomplete telemetry, Lumberjacks motion observed, native-only movement, and no-peer windows, so alpha testers can understand what their saved evidence proves without reading raw JSONL. OMEN and i5 were rebuilt and smoke-captured; public bootstrap r17 carries the change.
Impact: Transport capture summaries now include Companion/bootstrap, Gateway, Valheim mod, server instance, cutover mode, and manifest identity, so a downloaded evidence bundle states which running stack produced the observation. OMEN and i5 were rebuilt and smoke-captured; public bootstrap r16 carries the change.
Impact: Companion live signals and transport captures now read peer count and server state from the actual nested Valheim heartbeat shape, so a two-client test will not incorrectly summarize an active peer window as zero peers. OMEN and i5 were rebuilt, and public bootstrap r15 carries the fix.
Impact: Transport captures now summarize observed player names and first/last/delta ranges for peer, motion, pending, active-consumer, acknowledged, and applied counters, so a tester's downloaded summary states what changed during the run without requiring manual JSONL inspection. OMEN and i5 were rebuilt and smoke-captured; public bootstrap r14 carries the update.
Impact: The local Companion dashboard now includes a compact rolling signal stream derived from public deployment, Valheim, cutover, and motion telemetry, so testers can see peer, player-name, queue, acknowledgement, applied, and Lumberjacks-motion counter changes without opening the operator-gated boundary page. OMEN and i5 were rebuilt, and public bootstrap r13 carries the stream.
Impact: Companion now compares the local bootstrap release stamped by the packaged launcher with the public P7 bootstrap manifest, shows a direct download link when the local bundle is stale or unknown, and the r12 public bootstrap includes release metadata so future tester machines can prove which Companion bundle launched their dashboard.
Impact: The tracked latest-bootstrap manifest now advertises the public Gateway-hosted Companion bootstrap instead of private GitHub release assets, and the P7 bootstrap publisher rewrites that pointer after each public upload so tester links do not drift back to an authenticated channel.
Impact: P7 now serves the credential-free Companion bootstrap through Gateway runtime endpoints backed by a mounted current.json pointer, so alpha testers can download the local dashboard bootstrap without GitHub auth while rapid Valheim mod/config updates remain on the authenticated client-pull lane.
Impact: The Companion bootstrap publisher now maintains a tracked latest-bootstrap manifest with immutable GitHub release URLs and package SHA-256, giving operators and testers a stable way to discover the current Companion zip without relying on chat-pasted release links.
Impact: Companion and the PowerShell transport-truth fallback now stamp each capture summary with a verdict and final current-read, so downloaded evidence directly states whether a run saw Lumberjacks motion, native-only motion, incomplete telemetry, or no peer window.
Impact: Companion now lists recent local transport-truth captures with summary and sample download links, letting testers recover evidence after refresh without inspecting Docker volumes or running shell commands.
Impact: Companion can now capture a bounded transport-truth window from the browser, store summary and JSONL evidence in its data volume, and serve both files for download so alpha testers do not need a shell command to preserve movement/cutover evidence.
Impact: A bounded PowerShell capture now records Companion/Gateway deployment, Valheim peer, cutover, and motion counters into JSONL plus summary output so two-client movement tests can be preserved as evidence instead of screenshots.
Impact: The local Companion now translates live Gateway, Valheim, cutover, and motion counters into a single operator-facing current read so alpha testers can tell whether movement is native Valheim or Lumberjacks motion without inspecting raw JSON.
Impact: OMEN and i5 Companion dashboards now surface /live/valheim-motion UDP/WebSocket receive and relay counters before a two-client movement test, making the Valheim-native versus Lumberjacks-motion boundary visible without operator API spelunking.
Impact: New alpha testers can now download an immutable credential-free Companion bootstrap that includes the moving-parts status panel and /trace fallback behavior; the zip digest is recorded in a public-safe receipt.
Impact: OMEN and i5 Companion dashboards now summarize the live client, modpack, Gateway, Valheim, and cutover state, and the P7 promotion lane updates LUMBERJACKS_VERSION so deployment telemetry matches the running image.
Impact: The canonical data-and-trust doc and public page now describe gameplay identity as player id sent through the event actor_id field, reducing ambiguity before alpha testers opt in.
Impact: Alpha testers now have a linked public page that states what telemetry captures, what is never captured, where records live, who can see them, and how to opt out before installing the modpack.
Impact: The local Companion now exposes /trace as the obvious builder URL for the private boundary diagnostics page, while preserving /ops/boundary for direct operator use.
Impact: Gateway-only alpha updates can now promote a locally verified Docker image to P7 by archive hash and durable image pin, without copying source to the VM or rebuilding there.
Impact: The operator page now foregrounds recent normalized events and compact health signals, while open-segment tails are labeled separately from malformed records.
Impact: The private alpha release channel now carries a generic Docker launcher and matching SHA-256 manifest, separate from Gateway image promotion and rapid mod/config packages.
Impact: The immutable bootstrap publisher now treats an absent release as the expected creation path on Windows PowerShell instead of failing before upload.
Impact: The credential-free Docker bootstrap zip and its SHA-256 manifest can be released together without a Gateway image rollout; rapid mod/config releases remain on the client-pull lane.
Impact: The generic Docker launcher now supports configured Steam libraries and an explicit Valheim path; the local page distinguishes its own updater version from the checked mod release.
Impact: An already-enrolled tester can extract a loopback Companion bundle that finds Valheim, starts Docker Desktop, preserves local configuration, and opens the dashboard without copying a credential.
Impact: The i5 deploy lane now records the Docker Desktop logon launcher and loopback Companion recovery check, keeping Valheim startup and player configuration outside the task.
Impact: Install and rollback now reject requests without explicit confirmation, so the compact Docker-safe checkbox is a real write boundary rather than a visual hint.
Impact: Docker-backed local updates require an explicit game-closed confirmation before install, avoiding a false host-process signal while preserving immediate release feedback.
Impact: The first real Companion install on OMEN verified the authenticated m15 package and preserved the local config, but exposed a root README.txt beside the Valheim payload. Companion now ignores non-payload package metadata while continuing to write only validated Valheim-relative entries. The live proof updated 31 files, retained a rollback backup, and left the config hash unchanged.
Impact: The local Companion page now presents the actual alpha sequence as visible readiness checks and gated actions: find Valheim, find config, confirm profile, stop the game, check the release, then install or roll back. Raw JSON moved into collapsed diagnostics so the primary page explains what to do next.
Impact: OMEN now serves the Dockerized Companion on 127.0.0.1:8080 in place of the nginx-only dashboard. It reaches P7 through the authenticated host tunnel, preserving community, runtime manifest, and private boundary-trace views on one local origin; i5 remains pending because it is offline on the tailnet.
Impact: P7 now runs Gateway m18-companion-20260723-r1 while admitting the existing m15 mod. The current.json pointer was atomically published after Gateway start and the public manifest changed to the hash-verified package without recreating Gateway, establishing the no-restart mod/config release lane. The publisher now uses PowerShell 5.1-compatible no-BOM output and a sudo base64 remote script so remote failures cannot be reported as success.
Impact: A loopback-only ASP.NET Core Companion now preserves the :8080 dashboard while checking, hash-verifying, installing, and backing up authenticated mod packages from a Gateway runtime current.json pointer. Mod/config publication can change the mounted artifact without a Gateway image rollout or restart; first-install Steam enrollment remains browser based.
Impact: The Steam update callback now sends no-store cache headers and names the returned zip with the live Gateway release, admitted mod release, package hash prefix, and enrollment prefix so testers can tell whether the downloaded package is current. P7 runs Gateway release m17-updatefilename-20260723-r1 while continuing to admit the frozen m15-hudrecover mod.
docs/roadmap/m17-updatefilename-gateway-release.json src/Game.Gateway/Valheim/SteamEnrollmentEndpoints.cs src/Game.Gateway/Valheim/EnrollmentPages.csImpact: The pre-signin /join/update page now displays the current Gateway release plus the last four alpha releases, with UTC timestamps, mod versions, and short reasons. The route also sends no-store cache headers so operators can distinguish stale browser/proxy HTML from a stale downloaded zip.
docs/roadmap/m16-updatehistory-gateway-release.json src/Game.Gateway/Valheim/EnrollmentPages.csImpact: ComfyNetworkSense 0.5.35 / m15-hudrecover keeps the NET SHOW recovery tab visible even when an older local config disabled the transport strip, then re-enables the strip when clicked. P7 now runs the matching Gateway admission image and serves a config-preserving Steam update package for this recovery build.
docs/roadmap/m15-hudrecover-server-mod-deploy.json fieldlab/docs/runbook-transport-truth-strip.mdImpact: ComfyNetworkSense 0.5.34 / m14-hudtoggle starts the alpha transport strip collapsed with a side NET SHOW/HIDE tab so low-resolution testers can reach Valheim menu buttons. P7 now runs the matching Gateway admission image and serves a config-preserving update package through the Steam update page.
docs/roadmap/m14-hudtoggle-server-mod-deploy.json fieldlab/docs/runbook-transport-truth-strip.mdImpact: P7 now serves the latest modpack manifest and Steam-authenticated update download from m13-portal while continuing to admit the frozen m12-motion client mod.
docs/roadmap/m13-portal-gateway-release.json infra/gcp/p7/docker-compose.ymlImpact: Alpha testers can pull current mod files through the portal without operator-mediated machine copies or ordinary credential rotation; first install and admin recovery remain separate paths.
src/Game.Gateway/Valheim/SteamEnrollmentEndpoints.cs src/Game.Gateway/Valheim/ModPackBuilder.cs infra/gcp/p7/VOLUNTEER-ENDPOINT.mdImpact: Rebuilt m12-motionauthws-20260722-r1 from committed source 002b12c, verified 565 passing tests and the baked m12-motion-20260722-r1 admission identity, promoted exact image c361c8fc, and repeated the public enrolled TLS-to-UDP ingress canary successfully with zero invalid, unauthorized, or stale drops.
Impact: Moved ASP.NET WebSocket feature setup ahead of the Valheim access gate, added a regression test, cut and deployed a Gateway-only image that still admits frozen mod m12-motion-20260722-r1, and proved public TLS plus token-bound UDP ingress with zero format, authorization, or stale drops. Distinct-recipient relay remains the two-account canary gate.
Impact: A valid enrollment now takes precedence over Caddy's private socket peer, so the enrolled WebSocket retains its opaque recipient and can arm the m12 motion lane over TLS; promotion drills can also resume hash-checked preuploaded or already-loaded artifacts after Windows/IAP SCP failures.
infra/gcp/p7/PROMOTION-DRILL.mdImpact: The m12 candidate carries real observed Valheim player transforms over session-token UDP with serialized binary WebSocket fallback, an observe-first client and explicit apply switch, motion counters in the community trace, and a documented two-player canary; native Valheim remains the rollback path and FULL NETCODE remains NO.
infra/gcp/p7/VALHEIM-MOTION-CANARY.mdImpact: P7 and OMEN now carry the exact 0.5.32 artifact; the dashboard reports the native-versus-Lumberjacks boundary, the full artifact rollback drill passed, and durable image pins were verified. The i5 artifact is staged but not installed.
docs/roadmap/m11-transport-build-candidate-v3.jsonImpact: The in-game truth strip and community dashboard now distinguish native Valheim peer and receive semantics from Lumberjacks ZDO delivery, show unused WebSocket/UDP lanes, and record deliberate HTTP/MCP fault switches; the container release gate also excludes host test artifacts and preserves UTF-8 during release cuts.
Impact: The public community Valheim card now uses accepted post-restart handshake history to show sanitized character display names beside the peer count, making live alpha sessions easier to understand without exposing Steam IDs, host names, UIDs, credentials, or positions.
src/Game.Gateway/Valheim/ValheimHandshakeService.cs src/Game.Gateway/Valheim/ValheimTelemetryHeartbeatService.cs src/Game.Gateway/Community/community.html docs/dashboard/viewing-the-surfaces.mdImpact: The public community page now hides idle baseline panels and promotes deployment, Valheim, cutover, tick health, and a single live trace rail so builder alpha testers see moving system signals instead of a screen full of empty cards.
src/Game.Gateway/Community/community.html docs/dashboard/viewing-the-surfaces.mdImpact: Gateway now emits append-only ZDO poll, acknowledgement, and consumer-heartbeat boundary events alongside queued batches, and the operator boundary dashboard renders queued, polled, acknowledged, applied, per-stage duration, window, recipient, and recent-row views for builder alpha testing. The Steam-bound personal mod-pack download path remains the preferred no-paste installer flow and is documented with the dashboard surfaces. The durable alpha seat override now has an explicit named mode, LUMBERJACKS_ALPHA_SEAT_GATE=disabled, so operators do not confuse it with Valheim's native max-player count; the old numeric variable remains only for rollback compatibility.
src/Game.Gateway/BoundaryEvents/BoundaryEventDiagnostics.cs src/Game.Gateway/Valheim/ValheimZdoRedirectEndpoints.cs src/Game.Gateway/Community/boundary.html docs/dashboard/viewing-the-surfaces.md infra/gcp/p7/docker-compose.ymlImpact: P7 now serves an operator-only /ops/boundary dashboard and /ops/boundary/summary API over the trusted tunnel, summarizing append-only identity, authorization, request, and ZDO queue boundary events without exposing the surface through public forwarded clients.
src/Game.Gateway/BoundaryEvents/BoundaryEventDiagnostics.cs src/Game.Gateway/Community/boundary.html tools/omen-dashboard/nginx.confImpact: Gateway image m6-seatcapacity-20260722-r1 is live on P7 and applies VALHEIM_HANDSHAKE_SEAT_CAPACITY=0 at startup for p7-primary-v1, so two-player alpha testing no longer depends on an in-memory /handshake/config POST after every restart.
src/Game.Gateway/Valheim/ValheimHandshakeStartup.cs infra/gcp/p7/docker-compose.yml fieldlab/docs/runbook-copresence-fanout-live-test.mdImpact: P7 now runs Gateway image m1-rescue-20260722-r1, still admitting the frozen m5-recipients-20260720-r1 mod release, with the admin rescue pack endpoint live. The P7 mod-pack template was refreshed to carry the current ComfyNetworkSense.dll hash used on OMEN, then a tester-specific rescue zip was issued without exposing bootstrap or client credentials in chat.
Impact: Adds an admin-gated POST /api/v0/enrollment/pack operator path for known alpha testers whose Steam callback or stale install blocks setup. The endpoint selects an active enrollment by SteamID or enrollment ID, rotates the client credential, invalidates any pending bootstrap for that enrollment, and streams the same personalized drop-in zip as the public join flow so recovery no longer requires Discord key relay or manual config editing.
Impact: The two-client alpha finding is now represented as code rather than speculation: player-character ZDOs can bypass static-world band shaping, and an off-by-default send-cadence override reports whether the loaded Valheim assembly exposes the helper seam before any A/B test uses it. Portal caching was left as the existing local implementation instead of duplicated.
network/mod/ComfyNetworkSense/Core/Services/ZdoRedirectRunner.cs network/mod/ComfyNetworkSense/Core/Services/ZdoSendCadenceOverride.cs fieldlab/docs/runbook-alpha-player-motion-fast-lane.mdImpact: Gateway-only release m3-boundary-20260722-r1 is live on P7, admits the frozen m5-recipients-20260720-r1 mod, writes durable boundary-event JSONL segments, and captures direct-public deny versus Caddy/TLS private-plane allow for the admin enrollment route as a stop-ship before widening.
docs/build-release-runbook.md docs/roadmap/valheim-volunteer-roadmap.jsonImpact: Operators have one repeatable PowerShell entry point and a checked-in procedure for the SDK 9 build, test, release identity, and image promotion boundaries.
Impact: Host SDK version no longer determines release verification, the shipping image cannot bypass the solution test lane, and operators have one documented container path while the net48 mod build remains intentionally separate.
Impact: Alpha operators can inspect identity/auth/completion and one queue boundary without changing authorization behavior; heavier tracing, integrity manifests, and identity-model refactoring remain deferred.
Impact: The first implementation now persists only identity.resolved, authorization.decided, zdo.batch.queued, and request.completed. Request entry remains in memory; segments rotate by flush, close, and atomic rename; and the initial parser performs validation plus basic counts. Compression, sidecar manifests, hashing, trace reconstruction, schema-drift analysis, percentiles, derived databases, cross-service instrumentation, and principal-model refactoring remain deferred until real event history justifies them.
Lumberjacks/docs/roadmap/valheim-volunteer-roadmap.jsonImpact: The self-service flow is a material improvement over manual secret exchange while remaining an intentionally provisional alpha boundary. M1 now requires trusted-proxy-aware authorization and explicit operator/workload authority before access widens. M3 now names a smaller intermediate step before any unified identity platform: a schema-versioned append-only event stream for boundary decisions and one reconstructable request lifecycle, with rotated source segments and derived analyses. Protocol emulators, observer services, and formal attestation remain deferred until product contracts settle.
Lumberjacks/docs/roadmap/valheim-volunteer-roadmap.jsonImpact: Distance-band area-of-interest now runs mod-side on the ZDO redirect producer (ADR 0011): per observing peer, near (<30m) redirects every pass, mid (30-64m) is thinned to 5Hz, far (>64m) is dropped, and landmarks are delivered by granted reach. Validated live at the densest single-player build (auto-ported in via a rebuilt server-driven harness): ~85% of redirect candidates dropped, ~13% thinned, ~3% full-rate, 46,900 applied and acknowledged with zero superseded/rejected/native/pending and no duplicate storm. The measurement that justified it falsified the recovered 9,600-row pressure model (tick cost scales with player count, which the model omitted) and showed send-volume, not the AoI filter, is the tick ceiling. Load-bearing invariant: suppress, ack, and emit are three separate operations - a dropped far object is still acked to Valheim (skipping it causes a duplicate storm) but not emitted, and suppressed-not-emitted ZDOs must not touch the delivery-gate counters. Behind zdoBandShapingEnabled (default false) for instant rollback. Unvalidated: far-to-approach re-sync of a dropped static object, and multi-player density.
fieldlab/evidence/aoi-band-shaping-p7-baseline-20260721/README.md fieldlab/docs/adr/0011-aoi-lives-on-the-producer.mdImpact: The first handoff was a status page; this one is a work queue. Ten tasks, each stating what to do, why it matters and how you will know it worked, every one traceable to something found on 2026-07-21 rather than speculated. Ordered with sequencing made explicit: re-provision the local gateway off the retired repo and resolve the dev-build split-brain first because both are traps that cost time before they cost anything else; then the AoI line, which must run in order - add band-population counters, run the knee sweep, then add hysteresis and re-measure, because damping before measuring destroys the baseline and instrumenting after measuring means running the experiment twice; then the two-client isolation gate, which is the program's own stated next correctness gate and needs a human in the seat; then landmark reach as the payoff; then three tail-hygiene items. Each test section is concrete enough to execute - exact docker inspect format strings for the gateway, the specific assertion in ValheimZdoIntegrationContractTests that must change deliberately for the split-brain, the two curves plus the correlation check for the knee, and unit-testable oscillation cases for hysteresis. Retains the do-not-re-execute warning about the withdrawn config-surface recommendations, since that file still carries its original D2/D3 reasoning below the revision banner and a future session could reasonably act on it and delete the far-field proxy prototype.
HANDOFF.mdImpact: HANDOFF.md at repo root, deliberately short and linking out rather than restating. It leads with the three things that bite: the live comfy-gateway runs from the retired C:/work/comfy checkout so edits here do not reach the running 8720 surface, fieldlab/autonomous must not be deleted because it is that gateway's live definition plus a running Valheim server, and the P7 VM is still billing by decision. Then the four open register items with the gateway re-provision at the top, two ready-to-start paths, the design decisions that must be read before touching AoI, and an explicit do-not-re-execute pointing at the withdrawn config-surface recommendations. Also corrects a standing claim: I told Derek repeatedly through the session that the work was local and unpushed, which was true when said and stopped being true when the background flake-fix session pushed main - the reflog shows f945562 update by push, carrying 17 of the day's commits with it. Only the last two remain local. Nothing was damaged, but the state I had been asserting was stale and saying so is cheaper than letting him find it.
HANDOFF.mdImpact: Derek's design principle, and a correction to how I first recorded it. He said consistent fidelity - even ugly or choppy - preserves immersion so long as it is consistent. I read that as hold everything constant and drafted a decision condemning adaptive degrade for changing behaviour under load. He corrected it: adaptive design is still consistent, it is predictive falloff. That distinction is the whole decision. Adaptive degradation is a deterministic function of an observable condition, so when it gets crowded it thins out is a rule a player learns immediately and then predicts correctly - the world having physics, not a break in immersion. It also beats holding full fidelity until collapse, because the collapse is the discontinuity. So the protected property is predictability rather than sameness. The mechanism is endorsed; what is defective is the missing damping at the threshold, since AdaptiveDegrade lifts the instant a broadcast fits again with no cooldown and no hysteresis, meaning at exactly budget it can answer differently tick to tick from a cause no player can perceive. That is indistinguishable from randomness at the player's end. The spatial boundary has the identical flaw with plain <= comparisons in InterestManager, so an entity at exactly 100.0 units flips bands every tick. Hysteresis is therefore reclassified as a fidelity requirement rather than a performance optimisation. The knee measurement is refined again: spread is only a defect when uncorrelated, so p99 divergence must be recorded against the density axis rather than as a scalar, because variance that tracks load is the system telling the truth while variance with no visible cause is the immersion killer. Also sets the tuning procedure - find the knee, back off to what holds under the worst band, run that everywhere - and accepts that this will lose throughput benchmarks on purpose.
fieldlab/docs/adr/0010-consistency-is-predictability.md Lumberjacks/docs/network/aoi-knee-experiment-brief.mdImpact: Derek's framing correction: being both the trained perceiver and the builder is the ideal position for someone with extreme standards for consistent fidelity, not an odd one. The instrument was never meant to find the problem - he already knows where it is by feel - but to make what he perceives transmissible to a budget, a regression test, and a machine deciding what to drop under load. That reframes the target, and the brief had it wrong. Consistent fidelity is not a softer performance goal, it is a different one, and the knee should be defined by where p99 pulls away from p50 rather than by the first budget breach. A frame that is merely late sometimes feels worse than one uniformly slower, and by the time game.tick.overruns fires the experience has already degraded. The brief now asks for two curves from the same /tick read - variance onset as the knee that matters and failure onset as the hard ceiling - and predicts the first arrives meaningfully before the second, noting that if it does not, that is itself a finding. The supporting argument is that the telemetry schema Derek specified is already variance-oriented throughout: jitter beside rtt, p95 frame time beside average fps, correction count and magnitude, time since last authoritative update, and TickMetrics keeping p50/p99/max per phase rather than a mean. Measuring this system by averages would contradict what it was instrumented to care about.
Lumberjacks/docs/network/aoi-knee-experiment-brief.mdImpact: A companion poster to the conditional-logic audit SVG, recording the process rather than the findings. Sixteen times during the audit and its follow-through a confident claim reversed on inspection, and the poster lists each in order with who caught it: Derek three, a gemini-pro thread four, me six, a tool three. The shape is the point. Not one was careless - each was a correct inference from a boundary drawn too small, whether one repo, one file, one packed context or one thread's view. Gitignored var dir implied gone; InterestManager emits nothing implied the campaign would be blind; audit output describes files so it implied D3 was independent of D4. All locally valid, all wrong. The last three are near-misses that would have broken something running: deleting fieldlab/autonomous, which defines two containers live at the time; cutting a method from a comment that had drifted above the production redirect arming; and treating the matrix retirement as a gateway bounce when the live gateway runs from the retired repo. Each was caught by a check costing seconds - docker ps, an assertion before a delete, a git grep after one. Recorded because the audit's value was not the findings but the refusal to trust them.
fieldlab/docs/audit-2026-07-21-the-twists.svgImpact: Matrix retirement, source side: deleted matrix.py, removed the four /valheim/matrix custom HTTP routes from the gateway kernel that lazily imported it, and cleaned three providers lists including the argparse default in gateway.py. Both surviving providers still import cleanly. But the running gateway is untouched, and why is the finding: docker inspect reports the live comfy-valheim-lab-comfy-gateway-1 was launched from C:/work/comfy/fieldlab/autonomous/valheim-lab.compose.yml with COMFY_ROOT=C:/work/comfy and an image built 2026-07-15 from that repo's network/mcp. Baseline's copy of that compose is a faithful clone that has never driven anything. This is the same failure the P7 cutover fixed, for a local service - source edits in baseline do not reach the running gateway. Registered as its own decision because it is a re-provision rather than a bounce and the state root holds a live Valheim world. D3 plus D4 executed together on Derek's instruction: 15 keys, ZdoInjectionRunner, OwnershipObserveRunner, OwnershipPinRunner, and TryDriveNetcodeProbeAuto - the lab-window coupling that armed all of them from one place. Two near-misses, both caught by asserting before deleting. TryEnsurePrimaryRedirect, the PRODUCTION redirect arming, sits inside the line range a stale comment implied belonged to the probe auto-start; the comment had drifted above the wrong method, so cutting from it would have deleted the live serving path's arming. And NetcodeProbeMaxDetailRows, kept on the original reasoning, turned out to matter more than that reasoning knew - TryEnsurePrimaryRedirect reads it as the detail-row cap for the live redirect runner. The gateway-side injection surface was left in place because ValheimZdoInjectionService is referenced by ValheimHandshakeService. The mod's heartbeat no longer emits injection_applied, _rendered or _rejected; the gateway declares those nullable so they arrive unset with no contract change.
fieldlab/docs/config-surface-decisions.md fieldlab/DECISIONS-PENDING.mdImpact: Asked to clean up the outstanding recommendations, most of them did not survive contact with the code - which is the finding, not a failure. Executed: D7, where zdoRedirectEnabled still described itself as intended for private lab runs long after it began carrying production traffic, now corrected along with why it still defaults off, and where checking the neighbours showed only one key was actually rotten rather than the several assumed, since the ownership keys genuinely remain lab experiments. And D5, flipping zdoRedirectActiveSeconds and handshakeResponderActiveSeconds from 90 to 0, so the production posture is now the default and a VM configured from defaults no longer silently auto-disarms the redirect 90 seconds into a session. Withdrawn after re-reading: D2's three groups are all load-bearing - the priority probe writes the manifest the landmark design depends on, the shadow runner is entangled with the manual route walk kept when the swarm harness went, and the projection runner renders local-only Unity primitives without ZNetView or ZDO ownership, which is precisely the far-field proxy mechanism the landmark design needs and the only prior art for it in the repo. D3 is deferred with D4 because TryDriveNetcodeProbeAuto is the arming path for the ownership observe and pin runners. The orphan sweep also stopped short: matrix.py is lazily imported by three custom HTTP routes in the gateway kernel, so retiring it is kernel surgery on the running 8720 gateway plus a bounce. Most seriously, fieldlab/autonomous/valheim-lab.compose.yml was deleted as dead swarm scaffolding and then restored - docker ps shows it is the live definition of the running comfy-gateway and a Valheim server. Its client services are profile-gated and are now clearly marked in-file as unable to self-drive. ADR 0009 was corrected: it had claimed docker compose up would launch menu-idling clients, which is wrong since they sit behind a clients profile - an ADR arguing for verification against an independent source should not carry an unverified claim.
fieldlab/docs/config-surface-decisions.md fieldlab/docs/adr/0009-verify-against-an-independent-source.mdImpact: The parallel-channel resolution recorded an hour ago was one layer too high. The real answer is the dual-channel transport, which was built for exactly this. InterestManager's own header states that reliable-lane messages - structure placed, entity removed - always go to the full region, and that the class only filters datagram-lane tick broadcasts. So the reliable lane is already region-wide and already exempt from interest filtering. And ValheimPriorityDeliveryPlanner.ReliableTiers already contains structural_anchor, the lighthouse tier, alongside player_critical, portal and storage_crafting. The routing exists; nothing needed inventing. The lane split is semantic rather than merely technical: reliable carries this exists or this changed, which is rare and region-wide, while datagram carries where it is right now, which is every tick and filtered. A static landmark is therefore pure reliable-lane traffic - one message when placed and zero datagrams forever, because it does not move. Its cost is a function of how often it changes, not of how far away it is, which is why it can be visible at 1500 metres for essentially nothing and why the aggressive datagram cut costs landmarks literally nothing. The priority manifest broadcast is one mechanism riding this lane, useful for announcing a set of landmarks at once, but it is an application-level convenience on top of the transport property rather than the property itself. Both the design note and the experiment brief were corrected to lead with the lane split.
Lumberjacks/docs/network/landmark-reach-design.md Lumberjacks/docs/network/aoi-knee-experiment-brief.mdImpact: Derek proposed increasing local sampling while aggressively cutting everything past roughly 30 yards. Checked against the recovered model the targeting is right and the lever is larger than it looks. At extreme density with combat_build, self at 0m and near at 50m both peak at 2000 updates per second and 1536 kbps, mid at 200m is an order of magnitude cheaper, and far at 500m is already exactly zero - so cutting harder at distance buys nothing and the entire budget lives in the near_20hz band from 0 to 50 metres. Area scales as the square of the radius, so pulling the full-rate radius from 50m to about 30m removes roughly 71 percent of the objects in the only expensive band. One caution changes the shape: Valheim activates and renders by zone at 64 metres, which is why the mod's NearbyRadiusMeters and BuildScanRadiusMeters both default to 64 and why the code uses ZoneSystem.GetZone and IsZoneLoaded. Thirty yards is inside one zone, so dropping an object at 27 metres leaves it visible and interactable while its state goes stale - present but wrong. The refinement is to thin the rate rather than drop the object, which is what the model's own thin_datagrams_to_5hz_defer_detail already describes, applied at 200m today instead of 30m. That yields full rate to 30m, thinned to the 64m zone boundary, dropped beyond. Derek then immediately spotted the hole: if everything past the boundary is dropped, a client can never learn a landmark exists at 500 metres, because the announcement would travel the path just severed. Un-cutting range to listen for distant great works would hand back exactly the saving. The resolution is that landmarks were never on that path - the priority manifest is broadcast rather than interest-filtered, the mod already subscribes via LumberjacksPriorityManifestListener, and InterestManager never consults it. The client hears an announcement naming a tier, position and reach, then spawns the far-field proxy locally; the real build is never replicated at range. That keeps per-tick churn bounded by the interest radius and landmark discovery bounded by how many great works exist rather than how far away they are. The aggressive cut is affordable precisely because discovery is a separate, sparse, distance-free channel.
Lumberjacks/docs/network/aoi-knee-experiment-brief.md Lumberjacks/docs/network/landmark-reach-design.mdImpact: Derek's design inverts the obvious approach to long-range visibility. Rather than making area-of-interest clever enough to show more at distance - unbounded, and worst exactly when the world is busiest - long-range presence becomes a scarce property that must be granted: a reward a master builder earns and places, pieces that are invisible up close but read as structure at great distance. The cost ceiling becomes a design parameter instead of an emergent property of how much people built, and the limitation becomes something the community can see and work toward rather than something the engine hides. It is also an inverted level of detail, since the proxy exists only at range where the real build is not loaded. The scoping primitive is mark-a-thing-and-define-its-reach, and Derek's intuition that the same mechanism serves itemid or ZDOid is correct for a concrete reason: ValheimPriorityObject already carries StableKey, which is already the planner's dedup and ordering key, plus an absolute Position, and the mod already filters by prefab stable hash in three places. The manifest even has a delivery wire already - a broadcast endpoint on the gateway and a listener in the mod. What is missing is one field, reach, since DistanceMeters currently means observation distance rather than visibility range; plus enforcement, since the delivery plan is advisory while the RANK is enforced at ZdoRedirectRunner.cs:337, which suggests a landmark exemption is a change to that predicate rather than a new subsystem; plus the proxy asset and swap rule, which is content work with no existing machinery; plus the earning mechanic. Separately, repaired 6 mojibake lines: 2 singly-encoded em-dashes in the volunteer platform plan and 4 doubly-encoded in ComfyNetworkSense.cs, left by earlier PowerShell round-trips - and one fresh instance I caused in this same session by doing exactly what lesson L-2026-07-21-9 forbids, an hour after grading that lesson as held.
Lumberjacks/docs/network/landmark-reach-design.mdImpact: The findings record had the what and the how but not the why, and the why changes the design. Three player-facing limitations motivate all of it, in Derek's words: multi-person combat and exploring through an event; skirting the coast into the unknown fast enough that the world cannot keep up, where the failure is not a stutter but losing a character to terrain that had not arrived; and visiting the fantastical builds the community makes, where load time means the best thing the community produces is the hardest to share. The sharpest requirement is a lighthouse on the coast visible at distance, and it is a requirement rather than an anecdote because it isolates which of the two systems is at fault. A lighthouse barely needs updates - it does not move - so it is not a datagram-filtering problem; it needs to exist in the world at range, which is ZDO load order. The classifier already ranks structural_anchor at 2, above doors and chests and decoration, so System B already knows a tower outranks a rug. But InterestManager's Far band is dropped and the model's own third interest_bucket is far_suppressed, so past MidRadius nothing expresses that a particular object matters at range. Rank and distance never meet - the same gap the findings record identified, arriving from the opposite direction with an acceptance test a person can check from a boat. Re-read the recovered grid as a specification rather than a dataset: its three axes are exactly those three scenarios, its density bands are real sampled 500m cells rather than synthetic, its priority_expectation column is a five-level graded shedding ladder that the findings record had proposed as a new idea when it was specified in July, and its process_budget column is already three-state with 1,920 rows predicting yellow or red.
Lumberjacks/docs/network/area-of-interest-findings.md fieldlab/evidence/aoi-density-pressure-matrix-20260704/modeled-pressure-matrix.csvImpact: Second retro of the day, appended rather than overwriting. The through-line arrived unplanned: five independent systems that report success while producing nothing - deploy-gateway.ps1 hashing the files it had just shipped so its integrity check could not fail, rollback-gateway.ps1 mutating /opt before failing on a build the stack forbids, the lab compose still launching clients that idle at the menu, 998 AoI result rows with avg_fps constant at 60.0 and the single real capture reporting all-zero network fields from Solo mode, and the fleet assay grading two empty builds a B/70 off the checkout it was handed. That last one was this retro's own second opinion, reaped from the previous session. ADR 0009 states the rule the five share: a check that reads its own output is not a check, and a verification must compare against a source it did not produce. Follow-through on the morning retro's nine lessons is graded in the addendum; L-2026-07-21-2, do not state a cause you have not read the code path for, regressed three times and is escalated as L-2026-07-21-13 with a specific habit fix - before asserting an absence, name the boundary searched and ask what lies outside it. Derek corrected the sharpest instance: I wrote that the AoI dataset was gone, and he pointed out the repos we cloned to make this one still hold it, which was true. Memory retired-repos-are-the-archive records that scope correction.
fieldlab/retro/SESSION-RETRO-2026-07-21.md fieldlab/docs/adr/0009-verify-against-an-independent-source.mdImpact: Derek was right that nothing is ever lost: all three artifacts of the 2026-07-04 density campaign survived in the retired C:/work/comfy checkout, in a gitignored var dir, and are now committed under fieldlab/evidence/aoi-density-pressure-matrix-20260704. Recovering them replaced a guess with a finding. The model is substantial and complete - 9,600 rows spanning density bands, observer ranges and event profiles, predicting estimated_udp_kbps, interest_bucket and a process_budget classification - and not one row has ever been checked against an observation. The measured side barely started: 96 cells planned, 1 done, 94 pending; results.jsonl holds 1,000 rows of which 998 are synthetic stubs from sim-viking clients reporting avg_fps of exactly 60.0 and bytes_out_per_sec of ~18,000 regardless of density band OR observer range, and exactly one is a real capture whose rtt, bytes and packets are all zero because the client sat in Solo mode and never connected. So the campaign produced zero networked measurements - not neglect, an unfinished run. Tested the hypothesis that the synthetic rows could still serve as a load proxy: they cannot, because they show no sensitivity to either variable that would be tuned. Also corrected an error in the findings doc: the claim that a tuning campaign would be blind for lack of instrumentation is wrong at the system level. TickMetrics already carries a 50ms tick budget, a game.tick.overruns counter that is precisely a knee detector, a duration histogram tagged per phase that isolates interest-filter cost from send cost, and TickBroadcaster already records entitiesSent versus entitiesCulled - all exposed over HTTP at /tick. The experiment is therefore instrumented today and needs only a config sweep plus the existing load driver.
Lumberjacks/docs/network/aoi-knee-experiment-brief.md fieldlab/evidence/aoi-density-pressure-matrix-20260704/README.mdImpact: Months of AoI and priority measurement never changed the engine that would have used it, and the reason turns out to be structural rather than negligent: the repo holds TWO independent notions of what matters most, built three months apart, measured separately, connected by nothing. System A is the Lumberjacks spatial interest manager from ADR 0015, accepted 2026-03-28 - distance bands at 100 and 300 units with a mid-band tick divisor. System B is the Valheim ZDO tier model built in July - seven ranks from player_critical to decorative_far. interest-management.md already states that the gateway does not re-run InterestManager tiers over the Valheim ZDO stream, and names the unclosed action: the next AoI audit must measure Valheim relevance selection separately from Lumberjacks player-tier filtering before any multi-client scalability claim. That audit never happened. Verified against source rather than taken from the audit passes: InterestManager has no byte accounting, no priority ordering within a band, no boundary hysteresis (plain <= at both comparisons) and no adaptive radius, and its shedding is a binary mid-band switch rather than a budget; it also filters datagram-lane broadcasts only, never the reliable lane. The measured evidence that should have driven change is strong and survives - the P7 gold run put 57.1 percent of 83,220 redirected ZDOs into the fast lane, and the host-capacity benchmark found message volume rather than CPU is what bends, with the knee at 400 bots. The density-pressure matrix data is genuinely gone: results.jsonl and modeled-pressure-matrix.csv were never tracked, which is the concrete cost of writing results to a gitignored var dir. Also preserved the most reusable lesson, that stationary load-test bots never cross a tier boundary so a naive AoI load test measures nothing.
Lumberjacks/docs/network/area-of-interest-findings.md Lumberjacks/docs/benchmark-host-capacity-2026-07-12.mdImpact: The harness existed to run fleets of headless Valheim clients unattended during the independent-agent regime. Deleted rather than commented out, because git is the better archive - commented-out code rots silently, a commit SHA does not. Removed AutoCharacterSelectPatches.cs, which drove the character-select screen so a spawned container connected instead of idling at the menu, MatrixCheckinRunner.cs, which polled a gateway for benchmark cells and posted results back, the two auto-rehearsal wrappers in ComfyNetworkSense.cs, and 19 config keys across AutoJoin, Automation and Matrix. Two corrections surfaced while cutting, both against the audit's own grouping: RouteGodFlySafeguard was classified as swarm machinery but actually guards the MANUAL route walk from killing the character on a post-teleport fall, so it stayed; and the manual network_sense_rehearsal console command shares TryStartRehearsal and RunTeleportRoute with the auto path, so only the automatic wrappers went and the now-dead initiatedByAuto and autoRehearsal parameters were collapsed out of both signatures. The operator command is untouched. SWARM-HARNESS-REMOVED.md carries the recovery pointer, what stayed and why, the consumers left orphaned elsewhere - the autonomous compose files and the comfy-gateway matrix toolsurface, which is a registered MCP provider and must not be deleted casually - and the honest counter-argument that this was the only ready-made multi-client harness in the repo.
network/mod/ComfyNetworkSense/SWARM-HARNESS-REMOVED.md fieldlab/docs/config-surface-decisions.mdImpact: The first audit pass covered only 44 of the 107 ConfigEntry keys: it was given an 8000-token output budget and pro is a thinking model, so the thinking consumed the budget and the analysis sections never emitted. Re-run as three scoped passes with a 30000-token budget, splitting by property-name prefix so each thread owned a disjoint set. The 63 uncovered keys were the operationally important ones - ZdoRedirect, ZdoInjection, Ownership, HandshakeResponder and the Lumberjacks integration block. Two audit claims were checked and rejected. One said the ActiveSeconds timers are live time-bombs that drop the serving path 90 seconds in; ZdoRedirectRunner.cs:226-227 treats 0 as no cap and infra/gcp/p7/README.md:101 pins zdoRedirectActiveSeconds=0, so production is correctly configured - the real and narrower risk is that the safe value is recorded only in a runbook and in a .cfg that lives on the VM, with no reference production config tracked in this repo. The other recommended flipping the serving-path flags to default true; ZdoRedirectRunner.cs:50 states that zdoRedirectEnabled=false IS the standing rollback, and defaulting them on would mean a mod dropped into any server hijacks world sync on load. Recorded a better answer than either default: keep the flags off, flip the ActiveSeconds default from 90 to 0 so the safe value is the default and the finite lab window is opt-in, and version-control a reference production .cfg so the posture stops living only as VM state. Eight decisions, each with the strongest case against it stated rather than implied; acting on the three clean ones removes 40 of 107 keys without touching the serving path.
fieldlab/docs/config-surface-decisions.md fieldlab/docs/audit-2026-07-21-conditional-logic.svgImpact: Six gemini-pro threads over the mod, gateway, P7 deploy, release scripting and the parallel infra stacks, looking for conditional logic that only ever served the unattended-agent regime. Every finding was re-checked against the code before acting, and three did not survive: the release-cut scripts were reported as holding stale split-repo paths but resolve correctly to the merged root, the dashboard IP was reported stale but is a reserved static that answers TCP, and zone A never finished its analysis. Deleted rollback-gateway.ps1, which ran a docker compose build the P7 stack structurally forbids, after already copying source onto /opt, with a SourceRoot default pointing at a frozen historical commit; the P7 README now sends gateway rollback to the drill's phase 3, which re-pins the image and verifies both health and the exact image id. Deleted configure-player-gateway.sh for the same forbidden build plus a hardcoded public IP. The gateway rate limiter keyed its partitions on the caller's own X-Lumberjacks-Enrollment-Id header, which UseRateLimiter reads before ValheimClientAccessMiddleware has verified anything, so a caller could mint a fresh bucket per request and defeat the only limits bounding unauthenticated abuse; it now keys on the connection address, the only value that cannot be forged over the wire at that point. The omen-dashboard proxy pointed at the VM's public player port, which capped what it could ever show, because admin and dev surfaces are bound to the VM's loopback deliberately and are not published there at all; it now follows the SSH/IAP tunnel that start-gateway-tunnel.ps1 already opened, so the allowlist could widen to the live stats surfaces without the VM publishing anything new. Enrollment listing, handshake config and the join flow stay unforwarded. The audit is drawn up as an SVG for posterity.
fieldlab/docs/audit-2026-07-21-conditional-logic.svg Lumberjacks/tools/omen-dashboard/nginx.conf fieldlab/DECISIONS-PENDING.mdImpact: The telemetry endpoint returned 409 for a lumberjacks-primary heartbeat before calling Record, so a rejected beat never advanced _lastSeen. Under sustained load with peers connected - exactly when a session is busiest - every beat is rejected, the 15s staleness clock runs out, and the dashboard goes stale. What actually degraded was narrower and stranger than going blind: CutoverSnapshot reads its queue counters live from the redirect and consumer services, so pending, active_consumers and consumer_draining kept updating, while everything sourced from the last admitted beat - coverage_total, coverage_lumberjacks, coverage_native_only, mode, mod_version - froze. The coverage figures that prove the cutover is working were the ones that stopped moving, next to queue counters that visibly did not. The gate itself was left alone: a backlogged primary genuinely is not a fully authoritative window, and the 409 is the honest answer. RecordAndAdmit now records liveness and then answers admissibility, and the endpoint calls that one method rather than ordering two calls itself, because line order inside a lambda is what regressed here. Malformed beats are still never recorded - the 400 checks run ahead of admission. Both community pages already preferred consumer_draining over the stale headline, so they were written expecting a state the gate had made unreachable. Checked before landing that nothing gates on EnrollmentSnapshot.state, which now reads advertised rather than stale during backlog.
fieldlab/docs/adr/0008-liveness-is-not-admission.md Lumberjacks/src/Game.Gateway/Valheim/ValheimTelemetryHeartbeatService.cs Lumberjacks/tests/Game.Gateway.Tests/ValheimZdoAuthoritativeTelemetryTests.csImpact: The cutover left 30 copy-pasteable commands across seven docs, plus four executable scripts, still aimed at C:\work\comfy and C:\work\lumberjacks. Those roots still exist on disk holding pre-cutover content, so the commands do not fail - they succeed quietly against stale code. The sharpest case was deploy-gateway.ps1, whose LocalRoot defaulted to C:\work\lumberjacks: it tars, hashes and ships two gateway source files, and both of them differ between that root and baseline, so running the documented deploy would have reverted the telemetry-heartbeat fix while its own hash check passed, because it hashes what it shipped. All four scripts (deploy-gateway.ps1, capture-release-manifest.ps1, fieldlab/scripts/start-comfy-gateway.ps1, network/mcp/etc/start-comfy-gateway.cmd) now derive their roots from their own location. The P7 runbook had warned at the top that both roots were retired while hardcoding them in eleven command blocks below; that contradiction is gone. Root AGENTS.md still described the retired two-repo roadmap ceremony and now defers to Lumberjacks/AGENTS.md. Separately, RoadmapViewEndpoints resolved its asset through a single string with an embedded forward slash, which Path.Combine preserves - green on Linux, two failures on Windows; it now combines two segments and the suite is 525/525.
infra/gcp/p7/scripts/deploy-gateway.ps1 AGENTS.md fieldlab/DECISIONS-PENDING.mdImpact: Session retrospective for the baseline cutover step-6 close and the repo prune. Three durable decisions became ADRs: 0005 carries an unreproducible release artifact forward with explicit provenance rather than rebuilding it into untested bytes, because the .NET 8 SDK embeds the git HEAD sha in the PDB; 0006 moves repo history to the credential-free P7 VM by git bundle rather than installing a token; 0007 sets prune-signal discipline after both git-history staleness and basename-orphan detection proved actively misleading in a subtree-merged monorepo. plan-baseline-cutover.md gains a section 7 recording that all six steps closed and that two of the plan's own assumptions were wrong. Five open decisions were appended to DECISIONS-PENDING: the VM's running cost, the reproducibility remedy, whether the VM gets a deploy key, whether the telemetry gate should tolerate load-induced backlog, and strict-roster posture for future acceptance windows.
fieldlab/retro/SESSION-RETRO-2026-07-21.md fieldlab/docs/adr/README.md fieldlab/DECISIONS-PENDING.mdImpact: The consolidation carried across everything both source repos held, including a large body of content with no consumer in the merged program. Seven zones were reviewed in parallel, each packed through HEARTH to gcp-gemini-pro, with every proposed deletion re-examined by a skeptic agent that grepped for inbound references; 62 verdicts were overturned that way. Removed: the handoff tree including a second Valheim mod (comfy-control-surface) and a camera-flythrough exploration, community and strategy essays under docs, a generated repo-map snapshot and its generator, a Discord/Sheets harvest side project, rank-ladder recipes, a community-systems kit, and finished fieldlab experiment plans, scenarios and evidence. Lumberjacks/src and network/mod were excluded from review entirely, being the code that builds the five images serving production. Two signals were rejected as misleading: git-history staleness (the subtree merges date every file to the consolidation) and basename-orphan detection (196 of 199 apparent orphans were live C# referenced by namespace). A second pass removed 11 further orphans left by cross-zone inconsistency, and tests/test_entrypoint_links.py now discovers entrypoints instead of hardcoding them, so it no longer goes red whenever a directory is removed for unrelated reasons. Everything remains recoverable from git history and from the still-existing C:/work/comfy and C:/work/lumberjacks.
Lumberjacks/docs/roadmap/prune-audit-20260721.jsonImpact: The mod logs 'Lumberjacks telemetry heartbeat failed: HTTP/1.1 409 Conflict' during play. Not a fault: ValheimTelemetryHeartbeatService.CanAcceptPrimaryHeartbeat refuses any lumberjacks-primary heartbeat while a peer is connected unless the authoritative window is fully applied (IsAuthoritativeComplete requires redirect.Pending == 0 and consumer.Pending == 0). Any queue backlog therefore rejects the heartbeat by design, and it succeeds again once drained. Two mod-side defects make this look like a failure: LumberjacksTelemetryHeartbeatRunner reads only the first 256 bytes and parses the status line, discarding the gateway's explanatory body, and it logs at LogWarning so designed backpressure reads as an error. A third, larger question is a design wrinkle rather than a bug: the health signal is gated on a condition that load makes temporarily false, so a sustained busy session could exceed the 15s staleness window and show the dashboard as stale while the system is healthy. DEFERRED DELIBERATELY: any fix changes the mod, which is a frozen release artifact, so it would invalidate the world-tested clean_build_sha256 035faa87. Cheapest fix next cut: surface the response body and log at info. The staleness-under-load question needs a decision, not just a patch.
Lumberjacks/src/Game.Gateway/Valheim/ValheimTelemetryHeartbeatService.cs network/mod/ComfyNetworkSense/Core/Services/LumberjacksTelemetryHeartbeatRunner.csImpact: Closes plan step 6. A real player session against the re-provisioned P7 VM produced a coherent closure sample meeting every README section 9 criterion: 100 percent coverage over 148892 ZDOs, zero native-only, zero fallbacks, receipts equal to acknowledgements at 75112 with zero pending, complete true, persistence healthy, and zero rejected/duplicate/retried. The stack under test had all five services pinned by digest from a validated v3 bundle, a deployment source cut over from the retired comfy repo to a baseline checkout, and pins already proven across a systemd restart. The v2 manifest's reproducibility_gap is now closed in practice rather than on paper.
Lumberjacks/docs/roadmap/m5-v3-acceptance-receipt.json Lumberjacks/docs/roadmap/m5-v3-reprovision-receipt.jsonImpact: Plan step 6. The VM's deployment source was a checkout of the RETIRED comfy repo at 8ca27eda with 471 dirty files, and its compose still built eventlog/progression/operatorapi from VM-local source - so the five-service release gate existed in the repo but had never existed on the VM. /opt/comfy is now a baseline checkout at ecbd6e3, compose pins all five by digest with no build: fallback, and the three sibling images were transported as OCI archives from the v3 bundle. The VM has no GitHub credentials, so history moved as a 24 MB incremental git bundle rather than a fetch - 8ca27eda turned out to be a genuine ancestor of baseline main, 232 commits back. Cut a v3 manifest for the release: gateway image and mod DLL are the original m5 artifacts carried forward unchanged, since the .NET 8 SDK embeds the git HEAD sha in the PDB and the mod therefore cannot be rebuilt to its shipped hash at any later commit.
Lumberjacks/docs/roadmap/m5-v3-reprovision-receipt.json Lumberjacks/docs/roadmap/m5-recipients-build-candidate-v3.jsonImpact: The cold-start walkthrough claimed eventlog/progression/operatorapi expose no health endpoint. Probing the live P7 VM showed all three return 200 on /health at 4002/4003/4004. The drill still gates on identity rather than liveness for those three, which is the accurate reason, so the behaviour is unchanged and only the justification was wrong.
infra/gcp/p7/PROMOTION-DRILL.mdImpact: build-release-bundle.ps1 has always saved four OCI archives but run-promotion-drill.ps1 only scp+docker-loaded the gateway one. Harmless while eventlog/progression/operatorapi still built from VM-local source; a hard 'docker compose up' failure since the m5 cutover pinned them by digest with no build: stanza. Cold start now loads and tags all four and pins the three siblings in docker-compose.release.yml, whose lifetime is the release (phases 3-4 inherit it untouched, since only the gateway has a rollback identity). -Finalize retires both overrides and pins all four env vars, closing a silent-revert on the systemd reboot path. Also fixed roadmap.mjs checkStaged(), which compared repoRoot-relative paths against git's repo-root-relative output and so rejected correctly-staged commits under the monorepo layout.
infra/gcp/p7/scripts/run-promotion-drill.ps1 infra/gcp/p7/PROMOTION-DRILL.md Lumberjacks/scripts/roadmap.mjsImpact: program-status.json (the I0-I7 ladder's machine-readable status) still advertised an M4-unification stage as clear to run after later stages had already landed - a second surface competing with this one, stale in a way nothing caught. Its needs_derek/next_derek_touchpoint fields are now short pointers back here; phases/trust/infra stay intact as an accurate P0-P6 record, not deleted. Its dashboard artifact now shows a retirement banner instead of stale content.
fieldlab/status/program-status.json fieldlab/status/README.mdImpact: eventlog/progression/operatorapi built from build: context: ${LUMBERJACKS_ROOT:-/opt/lumberjacks} on the VM - whatever source happened to be checked out there, no release identity, no gate, no hash, drift raising no error. They are now pinned by image digest like gateway (build+hash+pin, no admission check - they have nothing to admit, unlike gateway/mod), with matching manifest schema v3 fields (schema bumped from v2's two-repo source.comfy_commit+lumberjacks_commit to one source.baseline_commit, following the cutover).
infra/gcp/p7/docker-compose.yml infra/gcp/p7/scripts/build-release-bundle.ps1Impact: The 2026-07-21T05:08 decision note recorded RollbackImageId/RollbackModSha256 as hardcoded M0-era values that PROMOTION-DRILL.md's own Phase 3 command never overrode, and warned the stale defaults remain in the repo and will catch the next operator. They now have no default at all and are required with -Execute, matching -RollbackModBackupPath's existing pattern; PROMOTION-DRILL.md's commands pass its own already-documented section-3 values explicitly instead of relying on a default that goes stale the moment the next release ships.
infra/gcp/p7/scripts/run-promotion-drill.ps1 infra/gcp/p7/PROMOTION-DRILL.mdImpact: comfy and Lumberjacks were two repos independently pinning the same release (source.comfy_commit + source.lumberjacks_commit), fighting over ownership of docker-compose.yml and the VM env-file template, and citing each other by absolute workstation path. All of that is now structural: comfy's history landed unmodified at the new repo's root (git show 433f1cc3 still resolves), Lumberjacks' full history landed under Lumberjacks/ via git subtree (preserved as the merge's second parent), and the ~30 files hardcoding a sibling-checkout path got PSScriptRoot-relative or repo-relative fixes. Evidence paths from here on are baseline-relative, not repo-name-prefixed - there is only one repo to be relative to.
fieldlab/plan-baseline-cutover.md README.mdImpact: A cross-repo audit found that the P7 stack pins only the gateway to a release image. eventlog, progression and operatorapi are built from source at whatever happens to sit in the VM Lumberjacks root, so they carry no release identity, no admission gate, and no hash in any manifest. The m5 manifest asserted a coherent release; it described one service out of five. That claim is now qualified in place rather than left standing. Neither repo had documented this, and no gate would surface it: a contract drift between the pinned gateway and an unpinned sibling produces no error and no reject, only wrong behaviour.
docs/roadmap/m5-recipients-build-candidate.jsonImpact: The cut that carried recipient-scoped delivery into production existed only as artifacts on one workstation and a hand-touched VM. The manifest now lives in git next to the M0 candidate, recording both source commits, the mod hash, the gateway image id, and the two runtime settings the image does not carry: ProducerEmitsRecipients, and the strict roster flag that is in-memory and dies on any container recreate. It also records the honest deployment method, which was manual image save/scp/load plus a copied compose file, and states plainly that rebuilding the VM from either repo would not reproduce the state this release was world-tested in. That gap is now written down rather than known only to whoever ran the window.
docs/roadmap/m5-recipients-build-candidate.jsonImpact: Stage 3 and Stage 4 both landed in one window and legacy is no longer the only partition. The mod now stamps the destination peer Steam identity read off the socket at the per-peer sync-list boundary, and the Gateway translates that to its own opaque recipient on ingest, because the producer can only know a Steam identity and must not name a partition it cannot see. Cut m5-recipients-20260720-r1 both sides, deployed to P7, flipped ProducerEmitsRecipients. A real player session then produced real game ZDOs stamped with the joining player identity, and that enrolled client polled and received them under its own opaque recipient rather than legacy. Two consequences: M4a exit criteria finally have partitions to test against, and the correlated trace Stage 2 needed now exists, since correlation ids are populated on every submission where the frozen producer sent none.
comfy infra/gcp/p7/docker-compose.ymlImpact: The roadmap described recipient isolation as not started while its Gateway was cut, promoted, and serving live traffic on P7 with the F1 property proven against the public endpoint. Queued was misleading to anyone reading the board. M4a is not complete and cannot be: its exit criteria are the N=2 and N=10 isolation matrix and per-recipient conservation equations, and none of those can be exercised while ProducerEmitsRecipients stays false, because every envelope files under legacy and no per-recipient partition exists to isolate. Active with a stated Stage 3 dependency is the honest position.
docs/roadmap/valheim-volunteer-roadmap.jsonImpact: run-promotion-drill.ps1 hardcodes RollbackImageId to an M0-era image and RollbackModSha256 to the historical runtime mod b31697d2, and the runbook Phase 3 command overrides neither. RollbackModBackupPath is mandatory with -Execute and the rollback phase is unconditional, so running the documented command would have copied the historical mod over the deployed frozen artifact 94a3843e and restarted the Valheim server to verify it had. That is the same hazard New-GatewayReleaseCut.ps1 exists to prevent, reached through a different door: it invalidates the artifact every distributed guest package is pinned to. The promotion was therefore done directly, re-pin plus recreate with no build, which touches no mod at all. Decision: prefer direct promotion for Gateway-only cuts, and treat the drill as needing correct explicit rollback arguments before it is run again. The stale defaults remain in the repo and will catch the next operator.
comfy infra/gcp/p7/scripts/run-promotion-drill.ps1Impact: plan-m4-unification.md models Stage 2 as a distinct engineering stage needing a harness change, because Invoke-ComfyLumberjacksIntegration.ps1 assumes it owns the server. This window showed the Stage 2 topology arising on its own out of ordinary play: the P7 server produced real ZDOs over loopback into p7-primary-v1 while a real enrolled principal authenticated from the public internet. The asymmetry that made Stage 2 look expensive, namely that the producer must be on loopback and the consumer must be public, is already satisfied by the P7 deployment shape rather than by anything the harness would build. What Stage 2 still cannot assert is the single correlated trace, and that is missing because the frozen 0.5.31 producer emits no correlation ids at all. The dependency therefore moves from harness work onto Stage 3 producer emission, and Stage 2 should be re-costed downward and re-sequenced behind Stage 3 instead of ahead of it.
docs/plan-m4-unification.mdImpact: The recipient work stopped being theoretical. Gateway image m4-clean-20260720-r1 was cut, transferred, and promoted on the P7 VM, and the F1 property was proven against the live public endpoint for the first time: an enrolled consumer on the public internet drained the frozen 0.5.31 producer recipient-less envelopes from the legacy partition and acknowledged them. Before the recipient fix this returned empty and the lane was dead. The frozen mod artifact was never touched.
comfy fieldlab/runs/releases/m4-clean-20260720-r1Impact: The roadmap still described the guest package as not started while the artifact was built, committed, and review-closed. Comfy fe812c4 shipped the immutable self-verifying guest package and c101d4c closed the review follow-up; the generated pack exists at fieldlab/handoffs/guest-client-pack/comfy-guest-m1-clean-20260717-r1/ with a guide, manifest, and index. Three of the four tracked build steps are done. The status is now active rather than complete because the gate that matters is unchanged and still open: a non-developer completing enrollment in ten minutes without editing config or sending a secret. That gate needs a real human, and no synthetic fixture can close it.
docs/roadmap/valheim-volunteer-roadmap.jsonImpact: The program held two halves that had never met: a local Docker slice that closed the full correlated ZDO runtime but resolved every actor to private-plane, and an unexecuted runbook that can test enrollment identity but exercises no game runtime. The asymmetry is structural - ValheimClientAccessMiddleware.Resolve() checks source IP first, so loopback and RFC1918 short-circuit before enrollment headers are read - and no re-run of either harness closes it. The new plan also inverts the obvious unification: POST /receipts requires the Producer capability that public callers never get, so the producer must stay on the Gateway loopback and it is the CONSUMER that moves remote. M4a stage 1 is recorded as landed and correctly disabled: ProducerEmitsRecipients defaults false, which keeps delivery working under the frozen 0.5.31 mod, so two simultaneous players remain gated on the stage-3 producer emitter in Comfy rather than on M4a.
docs/plan-m4-unification.md docs/runbook-m4a-stage1-live-test.mdImpact: Three source-derived public-safe SVGs make the runtime seam, local-versus-P7 topology, contracts, recurring jobs, operator pipeline, and proof harnesses reviewable without changing runtime state.
Comfy fieldlab/integration/diagrams/README.mdImpact: A committed hash-inventoried packet now makes the local correlated runtime proof, partial receipt and acknowledgement snapshot, rollback state, readiness limits, and remaining risks durable without changing runtime code.
Comfy fieldlab/integration/COMFY-LUMBERJACKS-ACCEPTANCE.mdImpact: Importance-approved work now carries explicit schema, release, recipient, and correlation metadata through the Gateway to the real authoritative consumer; Importance-rejected work stays on Valheim's native path. This was local only; no GCP start or deployment occurred.
Comfy fieldlab/integration/comfy-lumberjacks-seam.md Comfy fieldlab/scripts/Invoke-ComfyLumberjacksIntegration.ps1Impact: The Gateway now authenticates producer identity, enforces the baked mod release for schema 2, honors the intended recipient, and exposes correlated consumer outcomes while retaining the frozen schema-1 rollback path.
Comfy fieldlab/scripts/Invoke-ComfyLumberjacksIntegration.ps1Impact: Three independent no-cache builds show the shipped Game.Gateway.dll and pdb are byte-identical across two different HEADs, and all 48 published files identical for equivalent source. The image is declared the authoritative release artifact and local bin/Release non-authoritative. Image ids and the final layer digest remain nondeterministic even with identical payload; that boundary is documented rather than treated as a failure.
docs/decision-release-reproducibility-risk-12.mdImpact: The image build context excludes .git, so no HEAD sha reaches the shipped DLL and the build-then-commit ordering defect applies only to the advisory bin/Release path. Proposes declaring the image the reproducibility unit; decides nothing until the acceptance test passes.
docs/decision-release-reproducibility-risk-12.mdImpact: The baked release gate was inert on every deployed Gateway: the Dockerfile predated the mechanism and never passed the MSBuild property, so images carried the dev sentinel that ValheimReleaseIdentity maps to null. Arming StrictReleaseEnabled would have done nothing. The image now carries the value and a promotable build fails closed without it.
fieldlab/evidence/p7-session-20260719-release-gate-defect/deployment-identifiers.mdImpact: The unsafe recipient branch can no longer be selected by omitting an argument; both Gateway call sites already passed the configured value, so deployed behavior is unchanged and the frozen producer's delivery lane is unaffected.
docs/runbook-m4a-stage1-live-test.mdImpact: Replaces the prose guest handoff with a deterministic, reversible package, installer, preflight, diagnostics, and receipt-driven uninstall; human enrollment through READY TO JOIN remains open.
fieldlab/evidence/m2-guest-package/README.mdImpact: Default-off producer recipient emission keeps enrolled consumers draining the legacy bucket until the stage-3 producer cut; opt-in recipient partitioning remains available. Removed tautological Eligible/Durable proof and disclosed the deployment coupling.
docs/handoffs/AGENT-QUESTIONS.mdImpact: Adds server-derived recipient isolation, named legacy compatibility, recipient-keyed leases, additive WAL replay, and synthetic N=2/N=10 proof; remains undeployed with producer outbox open.
docs/plan-m4a-recipient-isolation.mdImpact: package-lock.json carried 13 entries marked extraneous for packages/* and services/* workspaces that were deleted when package.json narrowed its workspaces to clients/*, plus the orphaned optional-peer @types/node and undici-types records nothing depended on. npm install regenerated the lockfile as 151 pure deletions: no real dependency changed version, and the manifest again matches the two clients/* workspaces that actually exist.
package-lock.jsonImpact: An expired setup code no longer strands its volunteer behind an admin revoke plus re-invite. GET /join/reissue redoes the Steam OpenID sign-in - the identity root that created the enrollment - and a SteamID whose Active enrollment is still credential-less gets a fresh single-use code for the same enrollment. Designed with Derek before building, four decisions: Steam re-sign-in authenticates (not the expired code itself, which would have turned the browser artifact stage 4 neutralized into a long-lived re-issue credential, and not an operator-signed link, which is not self-serve); pending-only scope, so once the installer has minted a credential re-issue answers already_installed and recovery stays admin revoke + re-invite; the public join IP limiter plus a per-enrollment cooldown (LUMBERJACKS_REISSUE_COOLDOWN_MINUTES, default 15) and a lifetime chain cap (LUMBERJACKS_REISSUE_MAX_BOOTSTRAPS, default 10); and the enrollment is reused, not rotated - same EnrollmentId and RecipientId, so nothing downstream churns. The prior unused code is deleted from the store rather than flagged: a deleted record answers bootstrap_invalid under every past and future binary, so a rollback cannot resurrect a superseded code, and at most one bootstrap is live per enrollment. The chain is counted in a new BootstrapIssueCount enrollment field, additive on schema v3 - pre-existing records read 0 and get one spare re-issue, fine because the cap is an abuse bound, not a security invariant. The OpenID verification is extracted into one helper shared by both callbacks rather than duplicated, and the handoff text now points the volunteer at the re-issue URL instead of ask-the-operator. Gateway-only and undeployed, like the rest of stage 4; StrictRoster and stage-3 deploy state untouched.
src/Game.Gateway/Valheim/SteamEnrollmentService.cs src/Game.Gateway/Valheim/SteamEnrollmentEndpoints.cs tests/Game.Gateway.Tests/SteamEnrollmentServiceTests.cs docs/plan-m1-strict-admission.mdImpact: The roadmap no longer claims TLS is blocked on DNS or that the roster gate awaits real-join verification - gate 3 closed live 2026-07-17 and comfy-p7.duckdns.org points at the reserved static address; what remains is the ACME contact on the VM and the stage-3 cut, plus fail-closed admission in the next mod release.
docs/roadmap/valheim-volunteer-roadmap.jsonImpact: The plan no longer claims a DNS A record blocks stage 3 - comfy-p7.duckdns.org has pointed at the reserved static address since 2026-07-17; the sole remaining human input is the ACME contact address, set on the VM at next boot.
docs/plan-m1-strict-admission.mdImpact: The release identity gate is now demonstrated in both directions (refuse and pass), and rebuild-to-verify's blocker is a named, reproducible decision: the SDK embeds git HEAD in the PDB, so the artifact hash moves with every commit and a cut built pre-commit can never be rebuilt from its release commit.
docs/plan-m1-strict-admission.md comfy commits 877ff11 + 554488dImpact: Redeeming an invite no longer hands the browser a reusable secret. The Steam callback returned the config snippet with lumberjacksClientAccessKey in it, so the volunteer's long-lived credential landed in browser history, screenshots, and anything watching a plaintext response. It now returns a single-use setup code, and POST /join/bootstrap exchanges that code for the config exactly once. The access token is minted at consumption rather than parked in the store waiting to be collected, so it never exists at rest in any form, and an enrollment carries no credential at all until the installer acts - Verify answers bootstrap_pending and authenticates nothing, so a pending enrollment fails closed. POST rather than GET means the code cannot be spent by pasting a URL into a browser and stays out of history, referers, and access logs. The endpoint is public and rate-limited under the join limiter, deliberately outside the capability gate, because an installer has no credential to present yet. The store goes v2 to v3 in place on first save; v2 enrollments keep their token hash and keep verifying, so the deployed roster is unaffected. It does not close M1 gate 4 alone: the access token still crosses a plaintext link at consumption until stage 3 brings TLS. An expired bootstrap strands its volunteer, since one-active-per-SteamID refuses a second enrollment and re-issuing needs an admin revoke plus a fresh invite; the 24h TTL makes that unlikely rather than impossible, and self-serve re-issue is not built.
src/Game.Gateway/Valheim/SteamEnrollmentService.cs src/Game.Gateway/Valheim/SteamEnrollmentEndpoints.cs tests/Game.Gateway.Tests/SteamEnrollmentServiceTests.csImpact: The repository had no .gitattributes, so roadmap.html's bytes depended on the accident of how a given checkout was made. scripts/roadmap.mjs writes LF; with core.autocrlf=true, the Windows default, a fresh clone checks the artifact out as CRLF, which changes the bytes. Three things then break at once: roadmap:check compares a CRLF file against a fresh LF render and fails with a spurious stale, telling the operator to regenerate a page that was never wrong; X-Roadmap-Sha256 stops matching the committed artifact, so the served page can no longer be verified byte-for-byte against the tree, which is the whole point of reporting it; and every render rewrites the files back to LF as permanent working-tree churn. This machine only avoided it because the generator wrote the files and git had not yet touched them. The two JSON sources are pinned for the same reason: the script writes them LF and would fight the checkout on every note. Comfy already pins its evidence folder this way.
.gitattributesImpact: M1's exit gate now requires an invited, enrolled, compatible account, and no longer requires a fresh readiness lease or a stale-lease reject. lease_stale was blocked rather than deferred: nothing issues a readiness lease - no endpoint, no record, no field - because M1 named it as a deliverable without ever saying who mints one, what it attests, or how long it lives. It was undefined in M1 because M1 has no consumer for it: M4a already owns exact per-peer readiness and reconnect/takeover rules, already requires an exact per-peer readiness lease in its work, and already tests lease takeover at its exit. M1 was holding a contract on M4a's behalf, so M4a's inputs stop claiming a readiness lease among the contracts M1 delivers, and M1's does_not_own gains volunteer readiness scheduling. Building it inside M1 would have hard-coded an identity model the stage-3 mod cut then inherits, to satisfy a gate whose only reader specifies the lease differently and per peer.
docs/roadmap/valheim-volunteer-roadmap.json docs/plan-m1-strict-admission.mdImpact: Drill phases 2-4 pin the Gateway through docker-compose.promotion.yml, which compose does not auto-load, while LUMBERJACKS_GATEWAY_IMAGE in the host environment is never touched. A drill therefore ended with the candidate running, every receipt green, and the reboot path still resolving the previous release: the systemd unit runs plain docker compose up -d, which would revert the Gateway with nothing to indicate it happened. Hit for real promoting m1-clean-20260717-r1 - the container was on the candidate while the env still pinned the drill's M0 image - and caught only by checking the durable pin rather than the running container, which is exactly the check nobody performs when four receipts say ok. An earlier commit retired the override once, but the drill silently re-creates it every run, so the trap resets after each promotion. The new -Finalize switch executes the runbook's step 3 instead of leaving it a manual footnote: back up environment and override, point the pin at the promoted tag, delete the override, then prove the reboot path resolves the candidate and answers health. It stays a switch rather than an automatic step because drill-only runs prove rollback without promoting. Either way the restore receipt now records durable_pin, durable_pin_matches_candidate and override_retired, and a mismatch prints a warning naming the stale pin and what will happen on reboot.
infra/gcp/p7/scripts/run-promotion-drill.ps1Impact: P7 now runs the M1 Gateway cut rather than m0-clean-20260716-r2. It is Gateway-only - the mod stays frozen at ComfyNetworkSense 0.5.31 - so the hashed-at-rest enrollment store, the capability split, per-surface rate limits, the one-seat reservation, the strict-admission roster gate, and the credential-derived consumer recipient are all live without a mod release. This retires the standing risk that stage 1's enrollment-store migration had never executed against real data: it has now run against the real store. StrictRosterEnabled ships default off, so strict roster admission is deployed but not enforcing; a roster miss refuses a join, so it stays opt-in per window until it is verified against real joins and can be flipped with a way back. The drill proved cold-start, rollback to the historical release, and restore, each health-checked and identity-verified; the durable environment pin was finalized by hand afterwards, because the drill at that time left the pin stale while the container ran the candidate.
docs/plan-m1-strict-admission.mdImpact: Phase 1 archived all of the Valheim config directory, including the server's own hourly world zips under config/backups, so the snapshot scaled with backup history rather than world size: 44 GB across 75 files by 2026-07-17, against 8.6 GB of live worlds. Caught executing the drill for m1-clean-20260717-r1 with the server stopped for the whole gzip - 12 minutes in, 20.8 GB written and nowhere near done - and the archive heading for a volume with 58 GB free that also holds postgres, the ZDO WAL and the enrollment store. Filling it would have traded a stopped game server for a downed Gateway and a corrupted queue, so the drill was aborted, the partial archive removed and valheim-server restarted; nothing had been promoted, because phase 1 only reads and it never reached cold-start. It worked for M0/A4 only because config/backups was small then, and would have failed worse on every future release. Excluding them is safe precisely because they are backups: this drill snapshots the state a rollback needs, the live worlds plus the BepInEx runtime and config, and restoring one of the server's own zips has never been part of it. Not fixed: the drill still has no pre-flight disk check, so an oversized snapshot fails by filling the disk rather than by refusing.
infra/gcp/p7/scripts/run-promotion-drill.ps1Impact: A client can no longer select which recipient it is recorded as. The consumer_id on the /consumer heartbeat is a GUID the client picks for itself, so every consumer telemetry key was a value the caller chose; where the caller presents an enrollment, the server-derived RecipientId now replaces it. It overrides rather than rejects on mismatch, because the frozen 0.5.31 mod never reads the value back and always sends its own GUID, so a mismatch is the normal case and rejecting it would refuse every real heartbeat. Callers with no enrollment keep the value they sent, since there is nothing to derive from. This was written off as needing the stage-3 mod cut and turned out Gateway-only. It is a precondition for M4a: when the queue becomes recipient-scoped, the recipient it is scoped by must already be server-derived, or isolation is enforced against a name the client chose.
src/Game.Gateway/Valheim/ValheimZdoRedirectEndpoints.cs docs/plan-m1-strict-admission.mdImpact: The public roadmap no longer announces stale milestone state between releases. Republishing is one file copy into a mounted directory with no image rebuild and no restart, and X-Roadmap-Sha256 lets the served page be verified byte-for-byte against the committed artifact. The page itself stays deterministic, self-contained, and script-free: the drift was in how the Gateway read the asset, not in the asset.
src/Game.Gateway/Endpoints/RoadmapViewEndpoints.cs tests/Game.Gateway.Tests/RoadmapViewEndpointsTests.cs docs/roadmap/README.mdImpact: Admission can consult the enrollment roster on the Gateway alone, without waiting for a mod release. An earlier plan revision had deferred this to the mod cut after concluding that no Steam identity reached the Gateway; the live handshake capture disproved that, because the dedicated server forwards the account identity it authenticates itself. The seat lease is refreshed by the authoritative consumer's own poll traffic rather than a fixed timer, so a holder who crashed or was overturned after admission cannot keep the single seat, and a volunteer reconnecting keeps their own.
docs/plan-m1-strict-admission.mdImpact: A public consumer credential can no longer reach producer, admin, reset, or compaction operations; secrets no longer exist in plaintext at rest; a v1 store migrates in place so the frozen 0.5.31 mod keeps working unchanged.
tests/Game.Gateway.Tests/ValheimClientAccessMiddlewareTests.cs docs/plan-m1-strict-admission.mdImpact: M1 work can start with a fixed order and a declared release-cut budget; the fail-open handshake, plaintext credential echo, and client-chosen consumer id are now named defects with stages that remove them.
docs/plan-m1-strict-admission.mdImpact: The frozen release survives VM reboots under an exact image pin, VM-side gateway rebuilds fail closed, and platform work moves to authoritative identity and admission.
docs/roadmap/m0-a4-promotion-drill-receipt.json comfy infra/gcp/p7/PROMOTION-DRILL.md section 7 (retirement procedure and receipt)Impact: The full M0 ladder A1-A5 is complete: frozen source, reproducible clean candidate, validated release bundle, passed promotion drill, and published hash-bound evidence. The volunteer-platform work (M1 strict admission) is unblocked.
https://github.com/djcdevelopment/comfy/blob/433f1cc33605561ae1287db9cd8f37125d795c5d/fieldlab/evidence/p7-gold-run-20260716-011112-authoritative-priority-cutover/PUBLICATION.md docs/roadmap/m0-a4-promotion-drill-receipt.jsonImpact: A4, the last active M0 checkpoint, is complete; M0 closure now needs only the owner pushes and the golden_proof.publication flip per the A5 receipt.
docs/roadmap/m0-a4-promotion-drill-receipt.json Comfy fieldlab/evidence/m0-a4-promotion-drill-20260716 @ e6a1402Impact: Staged the sanitized gold FieldLab run packet in the Comfy repository and committed the A5 publication receipt. Fixed a latent A3 byte-stability defect where line-ending normalization caused checkout hash mismatches by explicitly marking the hash-bound evidence set with -text. A5 closure remains pending until the A4 drill passes, the owner pushes the Comfy revision to the remote, and the roadmap publication status flips.
docs/roadmap/m0-a5-publication-receipt.json Comfy fieldlab/evidence/p7-gold-run-20260716-011112-authoritative-priority-cutover/ (PUBLICATION.md + report.md + acceptance-snapshot.json) Comfy fieldlab/.gitattributes Comfy commits e9f9fe3 + 433f1ccImpact: Closed the A3 checkpoint: the sanitized release-bundle receipt is committed, the FieldLab run catalog classifies every run folder with the fixed evidence vocabulary, and the A4 no-build snapshot/rollback drill is prepared as a plan-only script and runbook awaiting the scheduled GCP window.
docs/roadmap/m0-a3-release-bundle-receipt.json Comfy fieldlab/runs/index.json + CATALOG.md Comfy infra/gcp/p7/PROMOTION-DRILL.md + scripts/run-promotion-drill.ps1 Comfy commit 582a0e0Impact: Added fail-closed bundle tooling and produced the r2 candidate bundle with an immutable manifest reference, mod DLL, OCI Gateway archive, source inputs, and per-file SHA-256 inventory.
Comfy commit 0cd40f4 local bundle label m0-clean-20260716-r2Impact: Clean tagged checkouts now produce a repeatable mod candidate and Gateway image under pinned deterministic build flags; the candidate is deliberately not promoted over the historical runtime until the release package and rollback drill pass.
docs/roadmap/m0-clean-build-candidate-r2.json Comfy commit b32bb5e Lumberjacks commit a7c47b5Impact: Pinned CI/deterministic compiler identity and a stable source map for the mod and Gateway builds; this creates a reproducible candidate path without promoting the historical runtime artifact.
Comfy commit b32bb5e Directory.Build.props staged belowImpact: Produced a clean-checkout Gateway image and mod candidate manifest without touching GCP or the proven runtime; M0/A2 remains open because the clean mod PE identity differs from the historical DLL.
docs/roadmap/m0-clean-build-candidate.json Comfy commit 408018f Lumberjacks commit 1eaadd8Impact: Captured the audited FieldLab evidence, MCP visibility, GCP topology, tunnel lifecycle, deployment, rollback, and invite scripts while preserving the generated identity-bearing historical dashboard outside the release.
Comfy commit 408018f infra/gcp/p7/README.mdImpact: Captured the P7 network overview, volunteer execution plan, evidence boundaries, interest-management boundary, dashboard viewing instructions, and local OMEN roadmap serving contract without widening any proof claim.
docs/network/valheim-volunteer-platform-plan.md tools/omen-dashboard/nginx.confImpact: Captured the tested Gateway queue, priority ordering, retained telemetry, enrollment, client-access middleware, and dashboard liveness lineage as one-owner release code; volunteer admission and durable per-run proof remain gated by M1 and M3.
Lumberjacks Gateway runtime commit staged below Comfy runtime commit 26bb55bImpact: Captured the tested mod source lineage that produced the aligned 0.5.31 artifact; the image and DLL remain rollback/runtime references until clean release packaging is complete.
Comfy commit 26bb55b network/mod/ComfyNetworkSense/manifest.jsonImpact: Separates live delivery from sealed proof, records the reset-erased receipt defect, and makes M0/A1 source freeze the active checkpoint.
docs/network/valheim-volunteer-platform-plan.md src/Game.Gateway/Community/roadmap.html fieldlab/evidence/p7-primary-v1-authoritative-priority-zdo-20260716-v0531.md