{
  "as_of": "2026-08-12T10:08:02.365Z",
  "audiences": [
    {
      "id": "curious",
      "label": "Just curious",
      "order": 10,
      "promise": "Outcomes and honest boundaries first; machinery only when you ask for it.",
      "question": "What is this, what is real today, and why might I care?",
      "short_label": "Curious"
    },
    {
      "id": "player-tester",
      "label": "Player or tester",
      "order": 20,
      "promise": "Runnable experiences, access requirements, and a short path to reporting what happened.",
      "question": "What can I try, and where does useful feedback go?",
      "short_label": "Player / tester"
    },
    {
      "id": "creator",
      "label": "Creator or GM",
      "order": 30,
      "promise": "Creation workflows and visible results before implementation detail.",
      "question": "How can I make quests, stories, places, and player experiences?",
      "short_label": "Creator / GM"
    },
    {
      "id": "moderator",
      "label": "Moderator or community lead",
      "order": 40,
      "promise": "Queues, evidence, consent, privacy, and human decision points.",
      "question": "How does this reduce review work while keeping people in control?",
      "short_label": "Mod / community"
    },
    {
      "id": "admin",
      "label": "Admin or server operator",
      "order": 50,
      "promise": "Dependencies, operational truth, privacy boundaries, failure modes, and recovery paths.",
      "question": "What runs, what does it cost, and how do I operate or recover it?",
      "short_label": "Admin / operator"
    },
    {
      "id": "modder",
      "label": "Valheim modder",
      "order": 60,
      "promise": "Game seams, event contracts, packaging boundaries, and reproducible test surfaces.",
      "question": "Where does this touch Valheim, BepInEx, Harmony, and game state?",
      "short_label": "Modder"
    },
    {
      "id": "developer",
      "label": "Developer or integrator",
      "order": 70,
      "promise": "Architecture and evidence with direct routes into code and deterministic artifacts.",
      "question": "What are the contracts, APIs, source paths, and verification seams?",
      "short_label": "Developer"
    },
    {
      "id": "contributor",
      "label": "Contributor or future owner",
      "order": 80,
      "promise": "Bounded first tasks, ownership state, and explicit completion destinations.",
      "question": "What is a useful first contribution, and what responsibility follows it?",
      "short_label": "Contributor"
    }
  ],
  "build_fingerprint": "62c42f3b2f01b9510d069745332413468cf0cc63ef8dec77d3e1363df303b3fb",
  "generated_by": "tools/corpus/build.py",
  "notice": "GENERATED acceleration structure. Rebuild from authoritative artifacts; do not edit.",
  "records": [
    {
      "audiences": [
        "curious"
      ],
      "data": {
        "attachments": [],
        "audiences": [
          "curious"
        ],
        "author": {
          "bot": true,
          "global_name": null,
          "id": "1531921451765071942",
          "username": "Baseline-helper"
        },
        "content": "Baseline is a public workbench for agentic collaboration and Valheim community tooling. The same body of work looks different depending on why you arrived, so start from the lane that sounds like you.\n\nChoose your lens: https://djcdevelopment.github.io/baseline/\nExplore everything: https://djcdevelopment.github.io/baseline/explore/\nOpen the live Community Workbench: https://am4.tail8e749c.ts.net/workbench\nFollow public dispatches: https://djcdevelopment.github.io/baseline/updates/\n\nCreator, admin, moderator, modder, developer, player/tester, contributor, or just curious: each lens gives you a shorter table of contents, then lets you cross lanes without hiding the rest.\n\nThis forum is the source of truth for public dispatches. Each starter post flows to the website, RSS, and JSON Feed. Replies stay here as conversation.\n\nTell us what brought you here, what you expected to find, and where the map still feels wrong.",
        "content_sha256": "10910b65528d87c49f0b7e410826f389557c47e5b9ca87472a9041c97c8898d6",
        "created_at": "2026-08-08T12:53:16.973000+00:00",
        "edited_at": null,
        "embeds": [
          {
            "content_scan_version": 0,
            "description": "Identity, telemetry and testing as first-class parts of a Valheim server stack instead of afterthoughts. Tools you can run on your own machine tonight, and honest notes about what is not ready.",
            "provider": {
              "name": "Baseline"
            },
            "title": "Baseline — a toolkit to build a Valheim community on",
            "type": "link",
            "url": "https://djcdevelopment.github.io/baseline/"
          },
          {
            "content_scan_version": 0,
            "description": "Cross every audience lane in the Baseline corpus.",
            "title": "Explore all - Baseline",
            "type": "link",
            "url": "https://djcdevelopment.github.io/baseline/explore/"
          },
          {
            "content_scan_version": 0,
            "description": "Discord dispatches and the Baseline engineering journal, with their authorities kept distinct.",
            "title": "Updates - Baseline",
            "type": "link",
            "url": "https://djcdevelopment.github.io/baseline/updates/"
          }
        ],
        "format": "invitation",
        "message_id": "1535631989556781156",
        "projection_errors": [],
        "publishable": true,
        "reply_count": 0,
        "tags": [
          "curious",
          "invitation"
        ],
        "thread_id": "1535631989556781156",
        "title": "Start here: choose your way into Baseline",
        "url": "https://discord.com/channels/1531911987074957442/1535631989556781156"
      },
      "facets": {
        "format": "invitation",
        "tags": [
          "curious",
          "invitation"
        ]
      },
      "id": "dispatch:1535631989556781156",
      "kind": "dispatch",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-08T12:53:16.973000+00:00",
      "source": {
        "authority": "discord-forum-starter-post",
        "locator": "discord://1531911987074957442/1535631989556781156/1535631989556781156",
        "mirror": "corpus/mirrors/discord/dispatches.json",
        "sha256": "574dbfd0553ed248575fb24fbbc969b7348c606516fe8b359dd1228d9497d8b4"
      },
      "summary": "Baseline is a public workbench for agentic collaboration and Valheim community tooling. The same body of work looks different depending on why you arrived, so start from the lane that sounds like you. Choose your lens: https://djcdevelopment.github.io/baseline/ Explore everyth...",
      "title": "Start here: choose your way into Baseline",
      "updated_at": "2026-08-08T12:53:16.973000+00:00",
      "url": "https://discord.com/channels/1531911987074957442/1535631989556781156"
    },
    {
      "audiences": [
        "curious",
        "player-tester",
        "creator",
        "moderator",
        "admin",
        "modder",
        "developer",
        "contributor"
      ],
      "data": {
        "$schema": "../../corpus/schemas/artifact.schema.json",
        "audiences": {
          "primary": [
            "curious"
          ],
          "relevant": [
            "player-tester",
            "creator",
            "moderator",
            "admin",
            "modder",
            "developer",
            "contributor"
          ]
        },
        "canonical_url": "https://djcdevelopment.github.io/baseline/",
        "facets": {
          "durable": true,
          "surface": "github-pages"
        },
        "id": "portal:baseline",
        "kind": "portal",
        "published_at": "2026-08-06T00:00:00-07:00",
        "schema_version": 1,
        "source_files": [
          "landing.html",
          "build_landing.py",
          "tokens.css"
        ],
        "summary": "The public hub for the repository map, durable decisions, evidence, corpus, and discovery surfaces of the Valheim project fleet.",
        "title": "Baseline"
      },
      "facets": {
        "durable": true,
        "surface": "github-pages"
      },
      "id": "portal:baseline",
      "kind": "portal",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-06T00:00:00-07:00",
      "source": {
        "authority": "colocated-artifact",
        "files": [
          "tools/site/landing.html",
          "tools/site/build_landing.py",
          "tools/site/tokens.css"
        ],
        "locator": "tools/site/artifact.json",
        "sha256": "7a433b9c110b7e11be65367f92dd5754445c123d094bcba26474ce62f42b79f0"
      },
      "summary": "The public hub for the repository map, durable decisions, evidence, corpus, and discovery surfaces of the Valheim project fleet.",
      "title": "Baseline",
      "updated_at": "2026-08-06T00:00:00-07:00",
      "url": "https://djcdevelopment.github.io/baseline/"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-15T23:35:00-07:00",
        "author": "Codex",
        "evidence": [
          "docs/network/valheim-volunteer-platform-plan.md",
          "src/Game.Gateway/Community/roadmap.html",
          "fieldlab/evidence/p7-primary-v1-authoritative-priority-zdo-20260716-v0531.md"
        ],
        "id": "20260715T233500-roadmap-and-owner-observation",
        "impact": "Separates live delivery from sealed proof, records the reset-erased receipt defect, and makes M0/A1 source freeze the active checkpoint.",
        "kind": "planning",
        "milestones": [
          "M0",
          "M1",
          "M2",
          "M3",
          "M4a",
          "M4b",
          "M5",
          "M6",
          "M7"
        ],
        "repository": "Lumberjacks + Comfy FieldLab",
        "schema_version": 1,
        "summary": "Established the evidence-first volunteer roadmap and recorded the latest owner session.",
        "verification": [
          "Historical P7 baseline remains 83,220 of 83,220 with zero eligible native ZDO sends.",
          "Owner session closed 81,241 of 81,241 eligible revisions with zero pending or eligible native sends; Gateway reset erased the live denominator, so the formal verdict is INCONCLUSIVE.",
          "OMEN, GCP, and runtime 0.5.31 identities align, but the image was built outside a clean Git checkout and remains rollback-only until M0 creates a reproducible release.",
          "Roadmap rendering, dependency, no-secret, staged-policy, HTTP, and served-byte checks pass."
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "M0",
          "M1",
          "M2",
          "M3",
          "M4a",
          "M4b",
          "M5",
          "M6",
          "M7"
        ]
      },
      "id": "roadmap:20260715T233500-roadmap-and-owner-observation",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-07-15T23:35:00-07:00",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L1",
        "sha256": "4061d3b4b5a987335fc4ecd6c37b59f225fd73f337831d26a12b0d4fd009c4b0"
      },
      "summary": "Separates live delivery from sealed proof, records the reset-erased receipt defect, and makes M0/A1 source freeze the active checkpoint.",
      "title": "Established the evidence-first volunteer roadmap and recorded the latest owner session.",
      "updated_at": "2026-07-15T23:35:00-07:00",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260715T233500-roadmap-and-owner-observation"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-15T23:40:00-07:00",
        "author": "Codex",
        "evidence": [
          "Comfy commit 26bb55b",
          "network/mod/ComfyNetworkSense/manifest.json"
        ],
        "id": "20260715T234000-comfy-runtime-freeze",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Comfy",
        "schema_version": 1,
        "summary": "Freeze ComfyNetworkSense 0.5.31 runtime",
        "verification": [
          "Clean isolated Release build passed with zero warnings and zero errors.",
          "Output DLL version is 0.5.31 and SHA-256 matches the aligned runtime artifact b31697d2...d7b.",
          "No Steam identity or credential was added to the public journal."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260715T234000-comfy-runtime-freeze",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-15T23:40:00-07:00",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L2",
        "sha256": "ca58dad07c84a552a449460b5690b95acc0a6144582ff6b251b5d0d776292dbf"
      },
      "summary": "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.",
      "title": "Freeze ComfyNetworkSense 0.5.31 runtime",
      "updated_at": "2026-07-15T23:40:00-07:00",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260715T234000-comfy-runtime-freeze"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-15T23:50:00-07:00",
        "author": "Codex",
        "evidence": [
          "Lumberjacks Gateway runtime commit staged below",
          "Comfy runtime commit 26bb55b"
        ],
        "id": "20260715T235000-gateway-runtime-freeze",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Freeze Gateway authoritative runtime and pilot enrollment",
        "verification": [
          "Docker .NET 9 SDK test run passed all 46 Game.Gateway.Tests tests; host .NET 8 is retained and does not claim a net9 build.",
          "Sanitized the enrollment test to use a synthetic Steam identity and found no Steam identity in the staged diff.",
          "Current relaxed completion and broad pilot access are recorded as known M3/M1 boundaries, not volunteer readiness."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260715T235000-gateway-runtime-freeze",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-15T23:50:00-07:00",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L3",
        "sha256": "baf4b7d706fb1c391e010e231387c3b2da401aebb88fe6bf36fd045a72ac1df4"
      },
      "summary": "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.",
      "title": "Freeze Gateway authoritative runtime and pilot enrollment",
      "updated_at": "2026-07-15T23:50:00-07:00",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260715T235000-gateway-runtime-freeze"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-16T03:20:00-07:00",
        "author": "Claude",
        "evidence": [
          "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 582a0e0"
        ],
        "id": "20260716032000-publish-m0-a3-bundle-receipt-and-fieldlab-catalo",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks + Comfy",
        "schema_version": 1,
        "summary": "Publish M0/A3 bundle receipt and FieldLab catalog",
        "verification": [
          "Bundle m0-clean-20260716-r2 re-validated valid at 2026-07-16T10:15:55Z; the receipt records the manifest hash, all seven per-file bundle hashes, and catalog hashes.",
          "The FieldLab catalog classifies all 125 run folders (1 gold, 17 negative, 37 superseded, 70 historical); every supersession reference resolves to a newer run of the same scenario.",
          "Secret scan over the manifest, receipt, and catalog found no SteamID or credential-shaped values; the A4 drill ran plan-only and produced drill-plan.json without any GCP mutation."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260716032000-publish-m0-a3-bundle-receipt-and-fieldlab-catalo",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-16T03:20:00-07:00",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L10",
        "sha256": "2fd05b7ac773a213c3d636b842e8ebfa033fc06cf2425ee954930a268182b9c1"
      },
      "summary": "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.",
      "title": "Publish M0/A3 bundle receipt and FieldLab catalog",
      "updated_at": "2026-07-16T03:20:00-07:00",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716032000-publish-m0-a3-bundle-receipt-and-fieldlab-catalo"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-16T11:44:30.100Z",
        "author": "Codex",
        "evidence": [
          "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 + 433f1cc"
        ],
        "id": "20260716114430-stage-m0-a5-publication-set-and-fix-byte-stabili",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks + Comfy",
        "schema_version": 1,
        "summary": "Stage M0/A5 publication set and fix byte-stability defect",
        "verification": [
          "The staged publication set hashes match the M0/A5 receipt, including the byte-identical acceptance snapshot.",
          "A two-pass secret scan (deterministic regex and independent semantic LLM review) confirmed the publication set is clean, with the deployment IPv4 redacted as <gcp-public-ip>.",
          "The .gitattributes fix makes Git blob bytes, working-tree bytes, and recorded SHA-256 hashes identical for all six hash-bound files regardless of checkout configuration."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260716114430-stage-m0-a5-publication-set-and-fix-byte-stabili",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-16T11:44:30.100Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L11",
        "sha256": "94470464baabce2d385106b33f9364d4e07b53a755c1007d025d5ffd2ecfc24a"
      },
      "summary": "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.",
      "title": "Stage M0/A5 publication set and fix byte-stability defect",
      "updated_at": "2026-07-16T11:44:30.100Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716114430-stage-m0-a5-publication-set-and-fix-byte-stabili"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-16T14:17:15.576Z",
        "author": "Codex",
        "evidence": [
          "docs/roadmap/m0-a4-promotion-drill-receipt.json",
          "Comfy fieldlab/evidence/m0-a4-promotion-drill-20260716 @ e6a1402"
        ],
        "id": "20260716141715-m0-a4-promotion-drill-passed-cold-start-from-pre",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "M0/A4 promotion drill passed: cold start from prebuilt artifacts, artifact-only rollback, restore — all receipts green",
        "verification": [
          "Four drill receipts green (snapshot 51GB archive hashed, cold start 14:02:43Z, rollback 14:04:51Z, restore 14:07:06Z), exact image IDs and mod SHA-256 verified at both paths each transition, gateway health ok, owner live-validated the promoted server post-restore."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260716141715-m0-a4-promotion-drill-passed-cold-start-from-pre",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-16T14:17:15.576Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L12",
        "sha256": "4711fce7c362a226dce66eeacb2f1c447ef65a29e7000142a0a83501439a22b1"
      },
      "summary": "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.",
      "title": "M0/A4 promotion drill passed: cold start from prebuilt artifacts, artifact-only rollback, restore — all receipts green",
      "updated_at": "2026-07-16T14:17:15.576Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716141715-m0-a4-promotion-drill-passed-cold-start-from-pre"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-16T14:23:37.263Z",
        "author": "Codex",
        "evidence": [
          "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.json"
        ],
        "id": "20260716142337-m0-closed-golden-proof-publication-flipped-to-pu",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "M0 CLOSED: golden-proof publication flipped to published; evidence public and immutable on GitHub",
        "verification": [
          "Comfy main and Lumberjacks master pushed; A5 PUBLICATION.md permalink at 433f1cc and A4 README permalink at e6a1402 both resolve on GitHub, and the published raw bytes re-hash to the recorded SHA-256 values."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260716142337-m0-closed-golden-proof-publication-flipped-to-pu",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-16T14:23:37.263Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L13",
        "sha256": "cdd72d9e4dae0666bd56a8cffbffe3afd2f4b0d065ec0e89eff4b4fdf1cced56"
      },
      "summary": "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.",
      "title": "M0 CLOSED: golden-proof publication flipped to published; evidence public and immutable on GitHub",
      "updated_at": "2026-07-16T14:23:37.263Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716142337-m0-closed-golden-proof-publication-flipped-to-pu"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-16T15:28:16.206Z",
        "author": "Claude",
        "evidence": [
          "docs/roadmap/m0-a4-promotion-drill-receipt.json",
          "comfy infra/gcp/p7/PROMOTION-DRILL.md section 7 (retirement procedure and receipt)"
        ],
        "id": "20260716152816-finalized-the-r2-promotion-and-opened-m1-the-p7-",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M0",
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Finalized the r2 promotion and opened M1: the P7 compose override is retired in favor of a durable environment image pin, current_release now records m0-clean-20260716-r2, M0 is complete, and M1 strict admission is active.",
        "verification": [
          "Base-compose-only up left the running gateway untouched at image sha256:141bd9e5a2ce with health ok; the systemd reboot path resolved the promoted pin from the host environment; the retired override is backed up on the VM."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M0",
          "M1"
        ]
      },
      "id": "roadmap:20260716152816-finalized-the-r2-promotion-and-opened-m1-the-p7-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-16T15:28:16.206Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L14",
        "sha256": "dbf7ce703ae2c18740ce13bb53c5840005300b0fba128f958abec01d23856f01"
      },
      "summary": "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.",
      "title": "Finalized the r2 promotion and opened M1: the P7 compose override is retired in favor of a durable environment image pin, current_release now records m0-clean-20260716-r2, M0 is complete, and M1 strict admission is active.",
      "updated_at": "2026-07-16T15:28:16.206Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716152816-finalized-the-r2-promotion-and-opened-m1-the-p7-"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-16T15:34:21.912Z",
        "author": "Claude",
        "evidence": [
          "docs/plan-m1-strict-admission.md"
        ],
        "id": "20260716153421-m1-kickoff-plan-committed-at-docs-plan-m1-strict",
        "impact": "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.",
        "kind": "planning",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "M1 kickoff plan committed at docs/plan-m1-strict-admission.md: current-state map of enrollment/admission/transport, gap table against the M1 gate, four implementation stages grouped into two Gateway release cuts plus one mod cut, and the admission acceptance matrix skeleton.",
        "verification": [
          "Survey drafted via a HEARTH-routed large-context pass over Gateway and mod sources; fail-open PassThrough, http-only transport guard, client-side consumer id, and the hardcoded capacity were each re-verified by hand at exact source lines."
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260716153421-m1-kickoff-plan-committed-at-docs-plan-m1-strict",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-07-16T15:34:21.912Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L15",
        "sha256": "a5175ecb95ad22f564fd0144ef48ce67f212addfb57ad0422563d02cd81806eb"
      },
      "summary": "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.",
      "title": "M1 kickoff plan committed at docs/plan-m1-strict-admission.md: current-state map of enrollment/admission/transport, gap table against the M1 gate, four implementation stages grouped into two Gateway release cuts plus one mod cut, and the admission acceptance matrix skeleton.",
      "updated_at": "2026-07-16T15:34:21.912Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716153421-m1-kickoff-plan-committed-at-docs-plan-m1-strict"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-16T16:43:36.981Z",
        "author": "Claude",
        "evidence": [
          "tests/Game.Gateway.Tests/ValheimClientAccessMiddlewareTests.cs",
          "docs/plan-m1-strict-admission.md"
        ],
        "id": "20260716164336-m1-stage-1-landed-hashed-at-rest-enrollment-stor",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "M1 stage 1 landed: hashed-at-rest enrollment store with unique-active-SteamID, revoke/expiry/last-used/audit and server-derived recipient_id; capability split (admin/producer/consumer/telemetry) replacing the global shared-key grant; per-surface rate limits; admin list/revoke and /enrollment/me endpoints.",
        "verification": [
          "79/79 Gateway tests pass including 16 new store/capability-matrix tests; live container smoke booted the Gateway and exercised invite, list, revoke, and consumer surfaces with the store confirmed hash-only on disk; two pre-existing Game.Simulation TelemetryV0 failures reproduced at clean HEAD and are tracked separately."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260716164336-m1-stage-1-landed-hashed-at-rest-enrollment-stor",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-16T16:43:36.981Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L16",
        "sha256": "3a28bbcc08252049fb2ae92fbf422ebb5d9f2bccdcb7aff40e1b12009a5e6ee2"
      },
      "summary": "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.",
      "title": "M1 stage 1 landed: hashed-at-rest enrollment store with unique-active-SteamID, revoke/expiry/last-used/audit and server-derived recipient_id; capability split (admin/producer/consumer/telemetry) replacing the global shared-key grant; per-surface rate limits; admin list/revoke and /enrollment/me endpoints.",
      "updated_at": "2026-07-16T16:43:36.981Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716164336-m1-stage-1-landed-hashed-at-rest-enrollment-stor"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-16T19:12:52.149Z",
        "author": "Claude",
        "evidence": [
          "docs/plan-m1-strict-admission.md"
        ],
        "id": "20260716191252-m1-stage-2-landed-a-one-seat-reservation-and-a-s",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "M1 stage 2 landed: a one-seat reservation, and a strict-admission roster gate keyed on the actual joining Steam account. Both are Gateway-only and ship disabled or defaulted safe; neither is deployed yet.",
        "verification": [
          "469 solution tests pass, 13 of them new admission tests. Each gate was mutation-verified: stubbing it out fails only the intended cases, and forcing liveness never to expire fails only the expiry cases."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260716191252-m1-stage-2-landed-a-one-seat-reservation-and-a-s",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-16T19:12:52.149Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L17",
        "sha256": "9435cbaee222445163e5deb309e2ced8867a18e1bb58074b9ded5178c85634f4"
      },
      "summary": "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.",
      "title": "M1 stage 2 landed: a one-seat reservation, and a strict-admission roster gate keyed on the actual joining Steam account. Both are Gateway-only and ship disabled or defaulted safe; neither is deployed yet.",
      "updated_at": "2026-07-16T19:12:52.149Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716191252-m1-stage-2-landed-a-one-seat-reservation-and-a-s"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-16T20:15:43.650Z",
        "author": "Claude",
        "evidence": [
          "src/Game.Gateway/Endpoints/RoadmapViewEndpoints.cs",
          "tests/Game.Gateway.Tests/RoadmapViewEndpointsTests.cs",
          "docs/roadmap/README.md"
        ],
        "id": "20260716201543-gateway-roadmap-re-reads-its-generated-asset-per",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Gateway /roadmap re-reads its generated asset per request and reports the served bytes' SHA-256",
        "verification": [
          "109 of 109 Game.Gateway.Tests pass, including six new RoadmapViewEndpointsTests covering per-request refresh, an identical-length rewrite, BOM stripping, the fallback page, and mount resolution preferring a mounted asset only once present."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260716201543-gateway-roadmap-re-reads-its-generated-asset-per",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-16T20:15:43.650Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L18",
        "sha256": "17b4029fbcdb688beb15645dc050ada025f4ad7127a28e126ce08520396012d2"
      },
      "summary": "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.",
      "title": "Gateway /roadmap re-reads its generated asset per request and reports the served bytes' SHA-256",
      "updated_at": "2026-07-16T20:15:43.650Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716201543-gateway-roadmap-re-reads-its-generated-asset-per"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-16T21:17:27.000Z",
        "author": "Claude",
        "evidence": [
          "src/Game.Gateway/Valheim/ValheimZdoRedirectEndpoints.cs",
          "docs/plan-m1-strict-admission.md"
        ],
        "id": "20260716211727-derive-the-consumer-s-recipient-from-its-credent",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M4a"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Derive the consumer's recipient from its credential, not its own claim",
        "verification": [
          "469 of 469 solution tests pass."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M4a"
        ]
      },
      "id": "roadmap:20260716211727-derive-the-consumer-s-recipient-from-its-credent",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-16T21:17:27.000Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L19",
        "sha256": "6f3d1668638b2ba772a2fa76c16112a47a8d71c6f0493cafec65351a2de6723c"
      },
      "summary": "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.",
      "title": "Derive the consumer's recipient from its credential, not its own claim",
      "updated_at": "2026-07-16T21:17:27.000Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716211727-derive-the-consumer-s-recipient-from-its-credent"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-16T00:00:00-07:00",
        "author": "Codex",
        "evidence": [
          "docs/network/valheim-volunteer-platform-plan.md",
          "tools/omen-dashboard/nginx.conf"
        ],
        "id": "20260716T000000-docs-and-operator-surfaces",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Freeze cutover topology, evidence, and operator surfaces",
        "verification": [
          "Documentation candidates contain no Steam identities or credential-shaped values.",
          "The plan records the 81,241 live-complete but formally INCONCLUSIVE owner observation and the M0/A1-to-M0/A5 execution sequence.",
          "Roadmap HTML and OMEN dashboard configuration remain self-contained and local-only."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0",
          "M3"
        ]
      },
      "id": "roadmap:20260716T000000-docs-and-operator-surfaces",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-16T00:00:00-07:00",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L4",
        "sha256": "ca56c0d49c6652338ba7ab0808d65ae35f0a45c975da044a4e857e1b5e3b82c8"
      },
      "summary": "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.",
      "title": "Freeze cutover topology, evidence, and operator surfaces",
      "updated_at": "2026-07-16T00:00:00-07:00",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716T000000-docs-and-operator-surfaces"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-16T00:15:00-07:00",
        "author": "Codex",
        "evidence": [
          "Comfy commit 408018f",
          "infra/gcp/p7/README.md"
        ],
        "id": "20260716T001500-comfy-p7-ops-freeze",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Comfy",
        "schema_version": 1,
        "summary": "Record P7 evidence and operator deployment surfaces",
        "verification": [
          "PowerShell scripts parse; Terraform formatting, MCP JSON parsing, and Python compilation pass.",
          "No credential-shaped values were found in the staged ops/evidence candidates.",
          "The existing manifest and rollback rebuild gaps remain explicit M0/A2 work; no GCP mutation was performed."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260716T001500-comfy-p7-ops-freeze",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-16T00:15:00-07:00",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L5",
        "sha256": "78352a600f71e65d2e30ad519e6611fb82b6de88d1245bac26a680ff1aa031fc"
      },
      "summary": "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.",
      "title": "Record P7 evidence and operator deployment surfaces",
      "updated_at": "2026-07-16T00:15:00-07:00",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716T001500-comfy-p7-ops-freeze"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-16T01:15:00-07:00",
        "author": "Codex",
        "evidence": [
          "docs/roadmap/m0-clean-build-candidate.json",
          "Comfy commit 408018f",
          "Lumberjacks commit 1eaadd8"
        ],
        "id": "20260716T011500-m0-clean-candidate-build",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks + Comfy",
        "schema_version": 1,
        "summary": "Build and record clean M0 candidate artifacts",
        "verification": [
          "Detached clean commits built successfully: ComfyNetworkSense 0.5.31 and Gateway image 8444c761...caf39.",
          "Clean Gateway test suite passed 46/46 in the .NET 9 SDK container; an isolated container returned /health 200 with local PostgreSQL.",
          "Clean mod IL is equal to the historical runtime, but its 72-byte PE timestamp/MVID/debug identity differs; no promotion or redeploy occurred."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260716T011500-m0-clean-candidate-build",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-16T01:15:00-07:00",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L6",
        "sha256": "ac21a59210ba8a385875b9331d4760ae71b0cbf3b48363a8b0346c62cd509994"
      },
      "summary": "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.",
      "title": "Build and record clean M0 candidate artifacts",
      "updated_at": "2026-07-16T01:15:00-07:00",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716T011500-m0-clean-candidate-build"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-16T01:30:00-07:00",
        "author": "Codex",
        "evidence": [
          "Comfy commit b32bb5e",
          "Directory.Build.props staged below"
        ],
        "id": "20260716T013000-reproducible-build-flags",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Comfy + Lumberjacks",
        "schema_version": 1,
        "summary": "Make clean artifact builds byte-reproducible",
        "verification": [
          "Two consecutive mod Release builds now produce identical SHA-256 f725e252...c667c.",
          "The build flags do not change the 0.5.31 IL; they stabilize PE timestamp/MVID/debug identity.",
          "Gateway source build properties are committed for the next clean Docker candidate; no GCP mutation occurred."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260716T013000-reproducible-build-flags",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-16T01:30:00-07:00",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L7",
        "sha256": "a0e23fcf447ca13a4c99924111307055237208f1b45cfe38d9cb4612c383cd63"
      },
      "summary": "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.",
      "title": "Make clean artifact builds byte-reproducible",
      "updated_at": "2026-07-16T01:30:00-07:00",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716T013000-reproducible-build-flags"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-16T01:45:00-07:00",
        "author": "Codex",
        "evidence": [
          "docs/roadmap/m0-clean-build-candidate-r2.json",
          "Comfy commit b32bb5e",
          "Lumberjacks commit a7c47b5"
        ],
        "id": "20260716T014500-m0-reproducible-candidate-r2",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks + Comfy",
        "schema_version": 1,
        "summary": "Record reproducible M0 candidate r2",
        "verification": [
          "Two clean Comfy builds produced identical SHA-256 94a3843e...0ba3a8; Gateway candidate image is 141bd9e5...e86fb.",
          "Clean Gateway tests passed 46/46 and the candidate image passed a local dependency-backed /health smoke.",
          "Candidate r2 records all eleven Valheim/BepInEx assembly hashes and both repository commits; no GCP mutation occurred."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260716T014500-m0-reproducible-candidate-r2",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-16T01:45:00-07:00",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L8",
        "sha256": "f5d19ae33b4747ddc43e2ba3bd4d9da1ff953d027ffd57aca11c991476f0d274"
      },
      "summary": "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.",
      "title": "Record reproducible M0 candidate r2",
      "updated_at": "2026-07-16T01:45:00-07:00",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716T014500-m0-reproducible-candidate-r2"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-16T02:00:00-07:00",
        "author": "Codex",
        "evidence": [
          "Comfy commit 0cd40f4",
          "local bundle label m0-clean-20260716-r2"
        ],
        "id": "20260716T020000-m0-a3-release-bundle",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Comfy",
        "schema_version": 1,
        "summary": "Build and validate the local M0 release bundle",
        "verification": [
          "Bundle validator passed for release m0-clean-20260716-r2 and the standalone manifest passed schema, source, hash, and no-secret checks.",
          "Bundle includes the 94a3843e...0ba3a8 mod, Gateway OCI image 141bd9e5...e86fb, Docker/build inputs, and a 96 MB image archive.",
          "Builder refused dirty/mismatched sources by contract; no GCP mutation or live artifact replacement occurred."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260716T020000-m0-a3-release-bundle",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-16T02:00:00-07:00",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L9",
        "sha256": "258f140106ec73fd104b8901487bb5b6a816b9e2915b7989f8cc20512912f273"
      },
      "summary": "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.",
      "title": "Build and validate the local M0 release bundle",
      "updated_at": "2026-07-16T02:00:00-07:00",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260716T020000-m0-a3-release-bundle"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-17T05:18:15.000Z",
        "author": "Claude",
        "evidence": [
          "infra/gcp/p7/scripts/run-promotion-drill.ps1"
        ],
        "id": "20260717051815-stop-the-promotion-drill-snapshotting-backups-of",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Comfy",
        "schema_version": 1,
        "summary": "Stop the promotion drill snapshotting backups of backups",
        "verification": [
          "Verified on the VM that the archive scope goes 54 GB to 9.3 GB, and that a real tar with the exclude pattern emits zero members under config/backups/."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260717051815-stop-the-promotion-drill-snapshotting-backups-of",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-17T05:18:15.000Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L20",
        "sha256": "24eb60fb095846021aab77b8c0b2b7f15a083b0afbb7b532869b917506176e89"
      },
      "summary": "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.",
      "title": "Stop the promotion drill snapshotting backups of backups",
      "updated_at": "2026-07-17T05:18:15.000Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260717051815-stop-the-promotion-drill-snapshotting-backups-of"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-17T05:34:10.000Z",
        "author": "Claude",
        "evidence": [
          "docs/plan-m1-strict-admission.md"
        ],
        "id": "20260717053410-promote-m1-clean-20260717-r1-to-p7-m1-s-gateway-",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Promote m1-clean-20260717-r1 to P7: M1's Gateway work is live, roster gate still off",
        "verification": [
          "Verified from the release tag on db45cf2, the bundle manifest, and the drill's restore receipt dated 2026-07-17T05:34:10Z recording gateway_health=ok, gateway_image=sha256:3576d8e0, mod_runtime_hash=match and mod_fallback_hash=match. Not re-verified live: the P7 VM is currently TERMINATED, so the running image, the durable pin, and the migration's collapse outcome are asserted from receipts rather than observed."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260717053410-promote-m1-clean-20260717-r1-to-p7-m1-s-gateway-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-17T05:34:10.000Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L21",
        "sha256": "5360f8bf44b3f44286e0fc46e9dce814cf1f509f70a0a30ff74369a796921e74"
      },
      "summary": "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.",
      "title": "Promote m1-clean-20260717-r1 to P7: M1's Gateway work is live, roster gate still off",
      "updated_at": "2026-07-17T05:34:10.000Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260717053410-promote-m1-clean-20260717-r1-to-p7-m1-s-gateway-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-17T05:41:10.000Z",
        "author": "Claude",
        "evidence": [
          "infra/gcp/p7/scripts/run-promotion-drill.ps1"
        ],
        "id": "20260717054110-make-the-drill-finalize-the-durable-pin-or-say-l",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Comfy",
        "schema_version": 1,
        "summary": "Make the drill finalize the durable pin, or say loudly that it did not",
        "verification": [
          "The script parses and both switches are declared, but -Finalize was not exercised end to end: P7 had already been finalized by hand, and re-running the drill would have stopped a server with a player about to connect. The shell it emits is the same sequence proven by hand minutes earlier."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260717054110-make-the-drill-finalize-the-durable-pin-or-say-l",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-17T05:41:10.000Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L22",
        "sha256": "ee521fd97da615faa89b2fa239f13874dfa86a83c6979534986fd93c61eb4624"
      },
      "summary": "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.",
      "title": "Make the drill finalize the durable pin, or say loudly that it did not",
      "updated_at": "2026-07-17T05:41:10.000Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260717054110-make-the-drill-finalize-the-durable-pin-or-say-l"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-17T10:56:54.213Z",
        "author": "Claude",
        "evidence": [
          "docs/roadmap/valheim-volunteer-roadmap.json",
          "docs/plan-m1-strict-admission.md"
        ],
        "id": "20260717105654-cut-the-readiness-lease-from-m1-s-exit-gate-its-",
        "impact": "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.",
        "kind": "planning",
        "milestones": [
          "M1",
          "M4a"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Cut the readiness lease from M1's exit gate; its only consumer is M4a, which already owns and defines it",
        "verification": [
          "Every edit was applied against exact-match source text, so a criterion that had drifted would have failed the amendment rather than being silently rewritten; roadmap check passes with the amended gate rendered. The destination was corrected before commit: an earlier revision moved the lease to M5, which the roadmap's own graph refutes - M4a depends on M1 alone, so a lease owned by M5 would make M4a wait on a milestone it does not depend on. Every surviving readiness-lease reference was re-read: M4a work and inputs, current_focus, and the concurrent-volunteers readiness requirement, which gates on M4a and M4b rather than on M1."
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "M1",
          "M4a"
        ]
      },
      "id": "roadmap:20260717105654-cut-the-readiness-lease-from-m1-s-exit-gate-its-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-07-17T10:56:54.213Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L23",
        "sha256": "ccf867b3f59266c1f9b810d814f1ddf3fbacc89c3723cc018726da5f7e93ec89"
      },
      "summary": "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.",
      "title": "Cut the readiness lease from M1's exit gate; its only consumer is M4a, which already owns and defines it",
      "updated_at": "2026-07-17T10:56:54.213Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260717105654-cut-the-readiness-lease-from-m1-s-exit-gate-its-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-17T11:29:50.925Z",
        "author": "Claude",
        "evidence": [
          ".gitattributes"
        ],
        "id": "20260717112950-pin-the-roadmap-artifact-and-its-sources-to-lf-s",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Pin the roadmap artifact and its sources to LF so a fresh clone cannot break byte verification",
        "verification": [
          "git check-attr reports text unset for all three paths, the LF-to-CRLF warnings they previously emitted are gone, and the artifact's SHA-256 is unchanged at cd808269, so the pin renormalizes nothing that was already committed. Roadmap check still passes."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260717112950-pin-the-roadmap-artifact-and-its-sources-to-lf-s",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-17T11:29:50.925Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L24",
        "sha256": "2db9a9a8a28c260dfc33b8463e4411351294244c27296b5a8e9bd97178bf0d9c"
      },
      "summary": "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.",
      "title": "Pin the roadmap artifact and its sources to LF so a fresh clone cannot break byte verification",
      "updated_at": "2026-07-17T11:29:50.925Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260717112950-pin-the-roadmap-artifact-and-its-sources-to-lf-s"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-17T11:47:10.960Z",
        "author": "Claude",
        "evidence": [
          "src/Game.Gateway/Valheim/SteamEnrollmentService.cs",
          "src/Game.Gateway/Valheim/SteamEnrollmentEndpoints.cs",
          "tests/Game.Gateway.Tests/SteamEnrollmentServiceTests.cs"
        ],
        "id": "20260717114710-m1-stage-4-a-one-use-bootstrap-replaces-the-plai",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "M1 stage 4: a one-use bootstrap replaces the plaintext credential echo",
        "verification": [
          "480 of 480 solution tests pass, 114 of them Gateway (109 baseline + 5 new), built and run in a .NET 9 SDK container. The single-use claim is mutation-verified rather than merely green: disabling the bootstrap.Used gate fails exactly Bootstrap_IsSingleUse and no other test. Coverage also asserts that the browser's code authenticates nothing (bootstrap_pending), that a revoke between invite and install beats a volunteer still holding the code, that expiry rejects, that a revoke-and-re-invite cycle mints a different token rather than resurrecting the old one, that neither the bootstrap nor the access token ever appears in the store file, and that a migrated v2 store still verifies its frozen-mod credential and rewrites as v3. Not deployed and not exercised against a real Steam callback."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260717114710-m1-stage-4-a-one-use-bootstrap-replaces-the-plai",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-17T11:47:10.960Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L25",
        "sha256": "e37b6fd71e8edab3282290fc3e0cd5ac87c687d7fa9b40f5e4b91dbda451e733"
      },
      "summary": "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.",
      "title": "M1 stage 4: a one-use bootstrap replaces the plaintext credential echo",
      "updated_at": "2026-07-17T11:47:10.960Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260717114710-m1-stage-4-a-one-use-bootstrap-replaces-the-plai"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-18T23:36:32.404Z",
        "author": "Codex",
        "evidence": [
          "docs/plan-m1-strict-admission.md",
          "comfy commits 877ff11 + 554488d"
        ],
        "id": "20260718233632-proved-the-release-cut-s-pass-verdict-and-solved",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Proved the release cut's pass verdict and solved risk 12's clone-vs-worktree mystery.",
        "verification": [
          "Rehearsal cut m1-rehearsal-20260718-r1 (full non-WhatIf run, then reverted) returned OK with both DLLs agreeing; EnableSourceControlManagerQueries=false made a local clone and the working tree build byte-identical DLLs."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260718233632-proved-the-release-cut-s-pass-verdict-and-solved",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-18T23:36:32.404Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L26",
        "sha256": "d2af6c4f8ab8b9adf1b6f652fe2a081839889ab51b7807630cae3d30858ead3a"
      },
      "summary": "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.",
      "title": "Proved the release cut's pass verdict and solved risk 12's clone-vs-worktree mystery.",
      "updated_at": "2026-07-18T23:36:32.404Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260718233632-proved-the-release-cut-s-pass-verdict-and-solved"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-19T00:32:32.438Z",
        "author": "Codex",
        "evidence": [
          "docs/plan-m1-strict-admission.md"
        ],
        "id": "20260719003232-corrected-stage-3-s-blocker-list-dns-and-firewal",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Corrected stage 3's blocker list: DNS and firewall are done, only the ACME contact remains.",
        "verification": [
          "comfy 29326eb records the name and public-resolver verification; comfy 2765ff9 opened 80/443."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260719003232-corrected-stage-3-s-blocker-list-dns-and-firewal",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-19T00:32:32.438Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L27",
        "sha256": "fd90e6c14e9a947dd762f666dcc6ded477106e8e64ae4244f90704466b0aa687"
      },
      "summary": "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.",
      "title": "Corrected stage 3's blocker list: DNS and firewall are done, only the ACME contact remains.",
      "updated_at": "2026-07-19T00:32:32.438Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719003232-corrected-stage-3-s-blocker-list-dns-and-firewal"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-19T00:38:47.481Z",
        "author": "Codex",
        "evidence": [
          "docs/roadmap/valheim-volunteer-roadmap.json"
        ],
        "id": "20260719003847-current-focus-text-caught-up-roster-gate-verifie",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Current-focus text caught up: roster gate verified live, DNS name exists.",
        "verification": [
          "LJ 4c0897e records the live strict-window accept and the in-memory flag reverting on restart; comfy 29326eb records the DNS name and resolver verification."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260719003847-current-focus-text-caught-up-roster-gate-verifie",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-19T00:38:47.481Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L28",
        "sha256": "437fdadf8713afc87eab8fe245c5bbff83fcbc349a9339efe7f60cdd8f1808e0"
      },
      "summary": "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.",
      "title": "Current-focus text caught up: roster gate verified live, DNS name exists.",
      "updated_at": "2026-07-19T00:38:47.481Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719003847-current-focus-text-caught-up-roster-gate-verifie"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-19T00:42:05.484Z",
        "author": "Claude",
        "evidence": [
          "src/Game.Gateway/Valheim/SteamEnrollmentService.cs",
          "src/Game.Gateway/Valheim/SteamEnrollmentEndpoints.cs",
          "tests/Game.Gateway.Tests/SteamEnrollmentServiceTests.cs",
          "docs/plan-m1-strict-admission.md"
        ],
        "id": "20260719004205-m1-stage-4-gap-closed-self-serve-bootstrap-re-is",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "M1 stage 4 gap closed: self-serve bootstrap re-issue via Steam re-sign-in",
        "verification": [
          "504 of 504 solution tests pass in the .NET 9 SDK container (Gateway 138 = 132 baseline + 6 new; Contracts 120; Simulation 246). All four re-issue guards are mutation-verified rather than merely green: disabling supersede-deletion fails exactly Reissue_MintsAFreshCodeAndKillsThePriorOne, the chain cap exactly Reissue_ChainCapExhausts, the cooldown exactly Reissue_CooldownBlocksAnImmediateRepeat, and the pending-only check exactly Reissue_RefusesOnceInstalled - one guard, one test, no overlap. Coverage also proves an expired bootstrap recovers across a service restart (two service instances on one store), that unknown and revoked SteamIDs refuse with distinct reasons, that exhaustion refuses new codes without damaging the pending one, and that the re-issued token never appears in the store file. The two RoadmapViewEndpointsTests failures on the Windows host are pre-existing path-separator issues, absent in the container, unrelated. Not exercised against a real Steam callback - the OpenID verify is the same code the enrollment callback has always used."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260719004205-m1-stage-4-gap-closed-self-serve-bootstrap-re-is",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-19T00:42:05.484Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L29",
        "sha256": "da1c8aa1a3568e447216826348d83b385c1d8f1b120a288678e49f8874b740ab"
      },
      "summary": "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.",
      "title": "M1 stage 4 gap closed: self-serve bootstrap re-issue via Steam re-sign-in",
      "updated_at": "2026-07-19T00:42:05.484Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719004205-m1-stage-4-gap-closed-self-serve-bootstrap-re-is"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-19T01:23:38.843Z",
        "author": "Claude",
        "evidence": [
          "package-lock.json"
        ],
        "id": "20260719012338-lockfile-sheds-13-extraneous-entries-left-over-f",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Lockfile sheds 13 extraneous entries left over from the deleted npm workspaces",
        "verification": [
          "npm install reported up to date and rewrote only the stale records; npm ls exits 0 with no extraneous or missing packages; git diff on package-lock.json shows 151 deletions, 0 additions, and no version movement on any surviving entry."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260719012338-lockfile-sheds-13-extraneous-entries-left-over-f",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-19T01:23:38.843Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L30",
        "sha256": "d0d53df1f67ebd09634a8a2a077fec79e1686661330336a8fafbc1414f7dc987"
      },
      "summary": "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.",
      "title": "Lockfile sheds 13 extraneous entries left over from the deleted npm workspaces",
      "updated_at": "2026-07-19T01:23:38.843Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719012338-lockfile-sheds-13-extraneous-entries-left-over-f"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-19T04:33:53.367Z",
        "author": "Codex",
        "evidence": [
          "docs/plan-m4a-recipient-isolation.md"
        ],
        "id": "20260719043353-gateway-recipient-scoped-durable-delivery-stage-",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M4a"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Gateway recipient-scoped durable delivery stage 1",
        "verification": [
          "dotnet9 Gateway 153 total, 151 passing, 2 pre-existing Windows path failures",
          "sdk:9.0 container 519/519 passing",
          "Mutation proof: scope 4 failures, lease 2 failures, WAL version 1 failure"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M4a"
        ]
      },
      "id": "roadmap:20260719043353-gateway-recipient-scoped-durable-delivery-stage-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-19T04:33:53.367Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L31",
        "sha256": "4954659622c9690b0aa813a516926adebfb3c1b78c46f8f97fdefadfc9b5f988"
      },
      "summary": "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.",
      "title": "Gateway recipient-scoped durable delivery stage 1",
      "updated_at": "2026-07-19T04:33:53.367Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719043353-gateway-recipient-scoped-durable-delivery-stage-"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-19T05:25:14.274Z",
        "author": "Codex",
        "evidence": [
          "docs/handoffs/AGENT-QUESTIONS.md"
        ],
        "id": "20260719052514-fix-frozen-producer-delivery-compatibility-and-c",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M4a"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Fix frozen producer delivery compatibility and conservation proof",
        "verification": [
          "dotnet9 Gateway 154 total, 152 passing, 2 pre-existing Windows path failures",
          "sdk:9.0 container 520/520 passing",
          "FrozenProducerEnvelope_IsStillDrainedByAnEnrolledConsumer passed in frozen and recipient-emitting modes"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M4a"
        ]
      },
      "id": "roadmap:20260719052514-fix-frozen-producer-delivery-compatibility-and-c",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-19T05:25:14.274Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L32",
        "sha256": "d04027a74dcb178bb9ce75d0f2642eb2733bfa72e7ecaed4cba5b778c2f7deb2"
      },
      "summary": "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.",
      "title": "Fix frozen producer delivery compatibility and conservation proof",
      "updated_at": "2026-07-19T05:25:14.274Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719052514-fix-frozen-producer-delivery-compatibility-and-c"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-19T05:38:35.405Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/m2-guest-package/README.md"
        ],
        "id": "20260719053835-immutable-self-verifying-guest-package-shipped",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M2"
        ],
        "repository": "Comfy",
        "schema_version": 1,
        "summary": "Immutable self-verifying guest package shipped",
        "verification": [
          "13 Comfy unittest tests passed; both promoted release bundles validated; eight injected fault verdicts each named a check and remedy; live plugin LastWriteTime unchanged."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260719053835-immutable-self-verifying-guest-package-shipped",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-19T05:38:35.405Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L33",
        "sha256": "f823014ae8eefaddb79985e89ed97c5a7b6d97f2712df4533a2119eb743a14c1"
      },
      "summary": "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.",
      "title": "Immutable self-verifying guest package shipped",
      "updated_at": "2026-07-19T05:38:35.405Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719053835-immutable-self-verifying-guest-package-shipped"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-19T06:26:38.007Z",
        "author": "Codex",
        "evidence": [
          "docs/runbook-m4a-stage1-live-test.md"
        ],
        "id": "20260719062638-recipient-scope-resolution-requires-an-explicit-",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M4a"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Recipient scope resolution requires an explicit producer-emission argument",
        "verification": [
          "sdk:9.0 container 520/520 passing; both production call sites unchanged; test call sites now state producerEmitsRecipients explicitly."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M4a"
        ]
      },
      "id": "roadmap:20260719062638-recipient-scope-resolution-requires-an-explicit-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-19T06:26:38.007Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L34",
        "sha256": "e971a076c8b6dd5147dd46b91de0abe8fff6eb19259841713dcc258a47b76690"
      },
      "summary": "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.",
      "title": "Recipient scope resolution requires an explicit producer-emission argument",
      "updated_at": "2026-07-19T06:26:38.007Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719062638-recipient-scope-resolution-requires-an-explicit-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-19T07:09:30.538Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/p7-session-20260719-release-gate-defect/deployment-identifiers.md"
        ],
        "id": "20260719070930-release-identity-is-verified-from-the-shipped-im",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Release identity is verified from the shipped image, not a DLL that never ships",
        "verification": [
          "Three regression cases green: a promotable build's id reaches the image, an uncut image is rejected by name, and a promotable build refuses both the sentinel and a malformed id. Confirmed against the live P7 container that the shipped DLL carried no attribute at all."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260719070930-release-identity-is-verified-from-the-shipped-im",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-19T07:09:30.538Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L35",
        "sha256": "a798ff665028e02b89d3c0d160d60075b681f7d3bb3e238be815734a1ec66010"
      },
      "summary": "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.",
      "title": "Release identity is verified from the shipped image, not a DLL that never ships",
      "updated_at": "2026-07-19T07:09:30.538Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719070930-release-identity-is-verified-from-the-shipped-im"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-19T07:13:04.066Z",
        "author": "Codex",
        "evidence": [
          "docs/decision-release-reproducibility-risk-12.md"
        ],
        "id": "20260719071304-risk-12-documented-the-shipped-gateway-image-bui",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Risk 12 documented: the shipped Gateway image build cannot see git",
        "verification": [
          "Deduced from .dockerignore and the Dockerfile COPY set; the two-build acceptance test is specified in the document and has not yet been run."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260719071304-risk-12-documented-the-shipped-gateway-image-bui",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-19T07:13:04.066Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L36",
        "sha256": "a8917021598d886edde00ad68fd4f2eab46c3bf7b9d61145665c6c5d48bfea7a"
      },
      "summary": "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.",
      "title": "Risk 12 documented: the shipped Gateway image build cannot see git",
      "updated_at": "2026-07-19T07:13:04.066Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719071304-risk-12-documented-the-shipped-gateway-image-bui"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-19T07:17:56.421Z",
        "author": "Codex",
        "evidence": [
          "docs/decision-release-reproducibility-risk-12.md"
        ],
        "id": "20260719071756-risk-12-decided-the-docker-image-payload-is-the-",
        "impact": "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.",
        "kind": "decision",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Risk 12 decided: the Docker image payload is the reproducibility unit",
        "verification": [
          "A vs B (different HEADs): 47/48 identical, sole difference the regenerated Community/roadmap.html, a Content item that cannot reach the assembly. B vs C (identical source): 48/48 identical. Baked release id m9-repro-20260719-r1 read from all three images, verifier exit 0. Runtime config inputs identical across all three."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260719071756-risk-12-decided-the-docker-image-payload-is-the-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-19T07:17:56.421Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L37",
        "sha256": "f747ed6abb6e54039a04d041bbc21679eda4ca573ccf27c2a51032788fccb414"
      },
      "summary": "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.",
      "title": "Risk 12 decided: the Docker image payload is the reproducibility unit",
      "updated_at": "2026-07-19T07:17:56.421Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719071756-risk-12-decided-the-docker-image-payload-is-the-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-19T15:32:22.005Z",
        "author": "Codex",
        "evidence": [
          "Comfy fieldlab/scripts/Invoke-ComfyLumberjacksIntegration.ps1"
        ],
        "id": "20260719153222-admitted-correlated-importance-approved-zdo-work",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Admitted correlated Importance-approved ZDO work on the existing Gateway path.",
        "verification": [
          "159 Gateway tests passed in the Linux SDK container.",
          "A real local dedicated-server slice authenticated private-plane, admitted release m4-integration-20260719-r1, routed legacy, and recorded an applied correlated result."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a"
        ]
      },
      "id": "roadmap:20260719153222-admitted-correlated-importance-approved-zdo-work",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-19T15:32:22.005Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L38",
        "sha256": "ce97b332457df0669dc2c225897c709bc917899c149ac118cfe1fa9c152f58b5"
      },
      "summary": "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.",
      "title": "Admitted correlated Importance-approved ZDO work on the existing Gateway path.",
      "updated_at": "2026-07-19T15:32:22.005Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719153222-admitted-correlated-importance-approved-zdo-work"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-19T15:36:26.229Z",
        "author": "Codex",
        "evidence": [
          "Comfy fieldlab/integration/comfy-lumberjacks-seam.md",
          "Comfy fieldlab/scripts/Invoke-ComfyLumberjacksIntegration.ps1"
        ],
        "id": "20260719153626-proved-one-real-comfy-server-originated-zdo-acro",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M1",
          "M3",
          "M4a"
        ],
        "repository": "Comfy",
        "schema_version": 1,
        "summary": "Proved one real Comfy server-originated ZDO across the existing Lumberjacks boundary.",
        "verification": [
          "15 Comfy contract tests and 13 repository tests passed.",
          "The real dedicated-server and headless-client harness observed the correlated positive sequence and proved a rejected correlation absent from Gateway and consumer logs."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M1",
          "M3",
          "M4a"
        ]
      },
      "id": "roadmap:20260719153626-proved-one-real-comfy-server-originated-zdo-acro",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-19T15:36:26.229Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L39",
        "sha256": "e735c14d5cd10bb79cfaa7dc01cb0440dca0fe699a52034fac576612010d3fbc"
      },
      "summary": "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.",
      "title": "Proved one real Comfy server-originated ZDO across the existing Lumberjacks boundary.",
      "updated_at": "2026-07-19T15:36:26.229Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260719153626-proved-one-real-comfy-server-originated-zdo-acro"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-20T03:09:41.825Z",
        "author": "Codex",
        "evidence": [
          "Comfy fieldlab/integration/COMFY-LUMBERJACKS-ACCEPTANCE.md"
        ],
        "id": "20260720030941-preserved-the-audited-comfy-to-lumberjacks-accep",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M1",
          "M3",
          "M4a"
        ],
        "repository": "Comfy",
        "schema_version": 1,
        "summary": "Preserved the audited Comfy-to-Lumberjacks acceptance evidence.",
        "verification": [
          "Acceptance reran 15 Comfy contract tests, 13 Comfy repository tests, 159 Gateway tests, and the compact positive/negative correlation verifier.",
          "Artifact metadata, source and curated hashes, rollback inputs, repository state, and temporary-container cleanup reconciled."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M1",
          "M3",
          "M4a"
        ]
      },
      "id": "roadmap:20260720030941-preserved-the-audited-comfy-to-lumberjacks-accep",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-20T03:09:41.825Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L40",
        "sha256": "1a03e3f43cdec732b201d7ba1c1be8eb08dbc91ccc52f0eb1f9827d555e4047a"
      },
      "summary": "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.",
      "title": "Preserved the audited Comfy-to-Lumberjacks acceptance evidence.",
      "updated_at": "2026-07-20T03:09:41.825Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260720030941-preserved-the-audited-comfy-to-lumberjacks-accep"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-20T03:47:25.227Z",
        "author": "Codex",
        "evidence": [
          "Comfy fieldlab/integration/diagrams/README.md"
        ],
        "id": "20260720034725-mapped-the-accepted-comfy-to-lumberjacks-archite",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M1",
          "M3",
          "M4a"
        ],
        "repository": "Comfy",
        "schema_version": 1,
        "summary": "Mapped the accepted Comfy-to-Lumberjacks architecture.",
        "verification": [
          "Three SVGs parsed as XML and passed full-size headless render inspection; 13 Comfy repository tests and public-safety scans passed."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1",
          "M3",
          "M4a"
        ]
      },
      "id": "roadmap:20260720034725-mapped-the-accepted-comfy-to-lumberjacks-archite",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-20T03:47:25.227Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L41",
        "sha256": "4c92469e651e63fd4d1be9c1356aa81a005b026214d915e97826e2ac7414fc49"
      },
      "summary": "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.",
      "title": "Mapped the accepted Comfy-to-Lumberjacks architecture.",
      "updated_at": "2026-07-20T03:47:25.227Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260720034725-mapped-the-accepted-comfy-to-lumberjacks-archite"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T03:48:57.042Z",
        "author": "Claude",
        "evidence": [
          "docs/plan-m4-unification.md",
          "docs/runbook-m4a-stage1-live-test.md"
        ],
        "id": "20260721034857-joined-the-local-runtime-proof-and-the-remote-de",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M1",
          "M4a",
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Joined the local runtime proof and the remote deployment into one sequenced path",
        "verification": [
          "Read the deployed admission path: ValheimZdoRedirectAdmissionPolicy.Evaluate returns allowed for schema 1 unconditionally, and ValheimZdoRedirectEndpoints validates only seq on the schema-1 branch, so the runbook Phase 5a seed still works verbatim after the schema-2 work.",
          "Confirmed ProducerEmitsRecipients defaults false at both production call sites (ValheimZdoRedirectEndpoints.cs:258, ValheimZdoInjectionEndpoints.cs:62).",
          "gcloud reports comfy-lumberjacks-p7 TERMINATED; the 07-19 integration evidence contains zero references to the P7 address, DuckDNS name, or project id, corroborating the local-only scope claim."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1",
          "M4a",
          "M4b"
        ]
      },
      "id": "roadmap:20260721034857-joined-the-local-runtime-proof-and-the-remote-de",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T03:48:57.042Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L42",
        "sha256": "0bb9bdbda9e9341ed0a2a113d33483acd6675faa13eb42fdd041bcbbde94e45f"
      },
      "summary": "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.",
      "title": "Joined the local runtime proof and the remote deployment into one sequenced path",
      "updated_at": "2026-07-21T03:48:57.042Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721034857-joined-the-local-runtime-proof-and-the-remote-de"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T03:49:34.527Z",
        "author": "Claude",
        "evidence": [
          "docs/roadmap/valheim-volunteer-roadmap.json"
        ],
        "id": "20260721034934-m2-status-corrected-from-queued-to-active",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "M2 status corrected from queued to active",
        "verification": [
          "Guest pack artifacts present on disk (GUEST-GUIDE.md, manifest.json, guest-index.json, guest-package-inputs.json); roadmap check passes with the corrected status."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260721034934-m2-status-corrected-from-queued-to-active",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T03:49:34.527Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L43",
        "sha256": "110765dfb4cae3de5a902efae86a78d97cfd6e6b8823a1ff30ef45b72fd4f944"
      },
      "summary": "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.",
      "title": "M2 status corrected from queued to active",
      "updated_at": "2026-07-21T03:49:34.527Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721034934-m2-status-corrected-from-queued-to-active"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T05:07:41.693Z",
        "author": "Claude",
        "evidence": [
          "comfy fieldlab/runs/releases/m4-clean-20260720-r1"
        ],
        "id": "20260721050741-m4a-recipient-isolation-gateway-deployed-to-p7-a",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M4a",
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "M4a recipient-isolation Gateway deployed to P7 and F1 closed live",
        "verification": [
          "Cut identity verified from the shipped image rather than bin/Release: Test-GatewayImageRelease.ps1 read /app/Game.Gateway.dll out of the built image and confirmed admitted mod release m1-clean-20260717-r1",
          "validate-release-bundle.ps1 returned status valid; OCI archive sha256 2ec2503b matched byte-for-byte after transfer to the VM",
          "Phase 4 both halves: running container image sha256:0d99e547 equals the manifest gateway.image_id, and the durable pin in /etc/comfy-p7/environment names m4-clean-20260720-r1",
          "Phase 5d live: pending/m4a-live-test-v1 returned recipient_id legacy with seq 900001 and 900002; ack returned acknowledged 2 unknown 0; re-poll empty",
          "Deployed server mod hash unchanged at 94a3843e before and after the promotion"
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M4a",
          "M1"
        ]
      },
      "id": "roadmap:20260721050741-m4a-recipient-isolation-gateway-deployed-to-p7-a",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-21T05:07:41.693Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L44",
        "sha256": "ebbeb06b32c1c4c1ff787f6721e3caacf9027f02d89472cfcfbdebe94d511be5"
      },
      "summary": "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.",
      "title": "M4a recipient-isolation Gateway deployed to P7 and F1 closed live",
      "updated_at": "2026-07-21T05:07:41.693Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721050741-m4a-recipient-isolation-gateway-deployed-to-p7-a"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T05:07:54.285Z",
        "author": "Claude",
        "evidence": [
          "docs/plan-m4-unification.md"
        ],
        "id": "20260721050754-stage-2-unification-is-gated-on-producer-instrum",
        "impact": "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.",
        "kind": "planning",
        "milestones": [
          "M4a",
          "M4b",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Stage 2 unification is gated on producer instrumentation, not harness engineering",
        "verification": [
          "Gateway logs during a real player session, repeated continuously while the player was in world: ZDO submission accepted caller_identity=private-plane mod_release=(null) window_id=p7-primary-v1 recipients=legacy",
          "Enrolled principal reaching the Gateway from the public internet proven separately at Phase 5c: /api/v0/valheim/enrollment/me returned the enrollment instead of 401 credentials_required, so the caller resolved as enrollment and not private-plane",
          "mod_release=(null) on every real submission confirms the frozen producer sends no release identity, which is the designed absence-is-the-signal behaviour and not a fault",
          "NOT PROVEN and still owed for Stage 2: that the player own client was the consumer draining p7-primary-v1 during play. That was inferred from an empty poll, not observed. The correlated eight-step trace remains unproven because correlations was empty on every real submission."
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "M4a",
          "M4b",
          "M3"
        ]
      },
      "id": "roadmap:20260721050754-stage-2-unification-is-gated-on-producer-instrum",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-07-21T05:07:54.285Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L45",
        "sha256": "fa050546166b3f671bb2ab962c4391b7e30f9284de5af97a522e3c63c15899bc"
      },
      "summary": "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.",
      "title": "Stage 2 unification is gated on producer instrumentation, not harness engineering",
      "updated_at": "2026-07-21T05:07:54.285Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721050754-stage-2-unification-is-gated-on-producer-instrum"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T05:08:06.768Z",
        "author": "Claude",
        "evidence": [
          "comfy infra/gcp/p7/scripts/run-promotion-drill.ps1"
        ],
        "id": "20260721050806-promotion-drill-rollback-defaults-are-stale-and-",
        "impact": "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.",
        "kind": "decision",
        "milestones": [
          "M1",
          "M4a"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Promotion drill rollback defaults are stale and would overwrite the frozen mod",
        "verification": [
          "Drill plan recorded rollback.image_id sha256:358f5e11 while the VM was actually running sha256:3576d8e0, the m1 image; 358f5e11 does not exist in the local Docker image store at all",
          "Deployed server mod read live from the VM as 94a3843e while the drill RollbackModSha256 default is b31697d2",
          "run-promotion-drill.ps1 line 241 fails without RollbackModBackupPath when -Execute is passed, so the mod rollback phase cannot be skipped",
          "Direct promotion verified clean: running image equals manifest image_id, durable pin updated, mod hash unchanged, and a real player session joined and produced traffic afterwards"
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "M1",
          "M4a"
        ]
      },
      "id": "roadmap:20260721050806-promotion-drill-rollback-defaults-are-stale-and-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-21T05:08:06.768Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L46",
        "sha256": "7451ce78a88f1ac4442dabc82a6b91c057f6983f9097ed4c2b1abf503a6ce956"
      },
      "summary": "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.",
      "title": "Promotion drill rollback defaults are stale and would overwrite the frozen mod",
      "updated_at": "2026-07-21T05:08:06.768Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721050806-promotion-drill-rollback-defaults-are-stale-and-"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T05:08:46.123Z",
        "author": "Claude",
        "evidence": [
          "docs/roadmap/valheim-volunteer-roadmap.json"
        ],
        "id": "20260721050846-m4a-status-corrected-from-queued-to-active",
        "impact": "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.",
        "kind": "planning",
        "milestones": [
          "M4a"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "M4a status corrected from queued to active",
        "verification": [
          "Gateway image m4-clean-20260720-r1 running on P7, durable pin set, F1 proven live at Phase 5d",
          "Isolation exit criteria remain unexercised: the flag is off by design and the frozen producer emits no recipient_id, so the enrollment partition is empty by construction"
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "M4a"
        ]
      },
      "id": "roadmap:20260721050846-m4a-status-corrected-from-queued-to-active",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-07-21T05:08:46.123Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L47",
        "sha256": "ffb131cf84367a48a0281199fe9092412f63f97bcdfdc160d515b5d26e6c4fbe"
      },
      "summary": "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.",
      "title": "M4a status corrected from queued to active",
      "updated_at": "2026-07-21T05:08:46.123Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721050846-m4a-status-corrected-from-queued-to-active"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T05:44:32.340Z",
        "author": "Claude",
        "evidence": [
          "comfy infra/gcp/p7/docker-compose.yml"
        ],
        "id": "20260721054432-recipient-scoped-delivery-is-live-a-real-player-",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M4a",
          "M4b",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Recipient-scoped delivery is live: a real player drained his own partition",
        "verification": [
          "Gateway log during live play now reads mod_release=m5-recipients-20260720-r1, window_id=p7-primary-v1, a per-peer recipient, and a populated correlations list. Before this cut the same line read recipients=legacy, mod_release=(null), and an empty correlations list.",
          "Enrolled consumer poll returned its own opaque recipient id rather than legacy, carrying real envelopes: sequences in the 35xxx range with populated prefab ids, correlation ids, and importance_class structural_anchor",
          "Flag confirmed inside the container via printenv rather than from the env file, because the env file is read by the compose process and reaches nothing without a compose reference",
          "NOT PROVEN: cross-delivery isolation with two simultaneous consumers, and behaviour under player_critical traffic. All observed envelopes were structural_anchor and only one consumer existed. Untested, not blocked."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M4a",
          "M4b",
          "M3"
        ]
      },
      "id": "roadmap:20260721054432-recipient-scoped-delivery-is-live-a-real-player-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-21T05:44:32.340Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L48",
        "sha256": "e24b01b1630846c56e196dc2f21a490de4a0e41435095ad51b3745797b1ed218"
      },
      "summary": "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.",
      "title": "Recipient-scoped delivery is live: a real player drained his own partition",
      "updated_at": "2026-07-21T05:44:32.340Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721054432-recipient-scoped-delivery-is-live-a-real-player-"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T06:01:52.506Z",
        "author": "Claude",
        "evidence": [
          "docs/roadmap/m5-recipients-build-candidate.json"
        ],
        "id": "20260721060152-release-m5-recipients-20260720-r1-recorded-inclu",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M4a",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Release m5-recipients-20260720-r1 recorded, including how it was deployed by hand",
        "verification": [
          "validate-release-bundle.ps1 returned status valid for the bundle at comfy fieldlab/runs/releases/m5-recipients-20260720-r1",
          "Both repos clean and at the manifest commits when the bundle was built; the bundle step refuses otherwise",
          "Manifest records the superseded mod hash so the unfreeze of the previously frozen 0.5.31 artifact is traceable rather than silent"
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M4a",
          "M3"
        ]
      },
      "id": "roadmap:20260721060152-release-m5-recipients-20260720-r1-recorded-inclu",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-21T06:01:52.506Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L49",
        "sha256": "ba57c992d98624999280cd26bd907d3d33c677a2c2b45478cc87f2cc7db75883"
      },
      "summary": "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.",
      "title": "Release m5-recipients-20260720-r1 recorded, including how it was deployed by hand",
      "updated_at": "2026-07-21T06:01:52.506Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721060152-release-m5-recipients-20260720-r1-recorded-inclu"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T06:04:23.018Z",
        "author": "Claude",
        "evidence": [
          "docs/roadmap/m5-recipients-build-candidate.json"
        ],
        "id": "20260721060423-the-release-gate-covers-one-of-five-services",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M4a",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The release gate covers one of five services",
        "verification": [
          "comfy infra/gcp/p7/docker-compose.yml pins gateway to the release image while eventlog, progression and operatorapi use build: context LUMBERJACKS_ROOT",
          "Lumberjacks has no release tooling of its own: every cut, verify, promote and rollback script for the Gateway artifact lives in the comfy repo"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M4a",
          "M3"
        ]
      },
      "id": "roadmap:20260721060423-the-release-gate-covers-one-of-five-services",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-21T06:04:23.018Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L50",
        "sha256": "6102bac8abc3c7c550e24c5a494685c6cacdf88a7efa71c6d93bd74ba6508f7c"
      },
      "summary": "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.",
      "title": "The release gate covers one of five services",
      "updated_at": "2026-07-21T06:04:23.018Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721060423-the-release-gate-covers-one-of-five-services"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T07:12:24.493Z",
        "author": "Claude",
        "evidence": [
          "fieldlab/plan-baseline-cutover.md",
          "README.md"
        ],
        "id": "20260721071224-landed-baseline-comfy-and-lumberjacks-merged-int",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Comfy + Lumberjacks",
        "schema_version": 1,
        "summary": "Landed baseline: comfy and Lumberjacks merged into one repo, history preserved",
        "verification": [
          "git log shows both original histories reachable; grep for the old absolute paths returns zero hits outside historical GitHub blob-SHA citations"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721071224-landed-baseline-comfy-and-lumberjacks-merged-int",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-21T07:12:24.493Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L51",
        "sha256": "ea5c87425cb7b26b8269899532995c9bfb5077b13c8ba02e0cde426b16604b51"
      },
      "summary": "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.",
      "title": "Landed baseline: comfy and Lumberjacks merged into one repo, history preserved",
      "updated_at": "2026-07-21T07:12:24.493Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721071224-landed-baseline-comfy-and-lumberjacks-merged-int"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T07:13:15.579Z",
        "author": "Claude",
        "evidence": [
          "infra/gcp/p7/scripts/run-promotion-drill.ps1",
          "infra/gcp/p7/PROMOTION-DRILL.md"
        ],
        "id": "20260721071315-fixed-the-flagged-stale-rollback-defaults-in-run",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Comfy + Lumberjacks",
        "schema_version": 1,
        "summary": "Fixed the flagged stale rollback defaults in run-promotion-drill.ps1",
        "verification": [
          "PowerShell parser check passes on the edited script"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721071315-fixed-the-flagged-stale-rollback-defaults-in-run",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-21T07:13:15.579Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L52",
        "sha256": "261d51866d8ac93ae5f8bf6898353f9d4fa30b677846de900b95c7ef0aec11aa"
      },
      "summary": "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.",
      "title": "Fixed the flagged stale rollback defaults in run-promotion-drill.ps1",
      "updated_at": "2026-07-21T07:13:15.579Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721071315-fixed-the-flagged-stale-rollback-defaults-in-run"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T07:13:34.856Z",
        "author": "Claude",
        "evidence": [
          "infra/gcp/p7/docker-compose.yml",
          "infra/gcp/p7/scripts/build-release-bundle.ps1"
        ],
        "id": "20260721071334-extended-the-release-gate-from-gateway-alone-to-",
        "impact": "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).",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Comfy + Lumberjacks",
        "schema_version": 1,
        "summary": "Extended the release gate from gateway alone to all five P7 services",
        "verification": [
          "docker compose config resolves all four required image vars; all four Dockerfile targets build clean against the merged tree; a full v3 manifest built from real artifacts round-tripped through build-release-bundle.ps1 and validate-release-bundle.ps1 end to end, status: valid"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721071334-extended-the-release-gate-from-gateway-alone-to-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-21T07:13:34.856Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L53",
        "sha256": "c9a3b76cc67bdbae1af503694c54b0fab9deb811ef2ca63be2a8c6370190a78d"
      },
      "summary": "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).",
      "title": "Extended the release gate from gateway alone to all five P7 services",
      "updated_at": "2026-07-21T07:13:34.856Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721071334-extended-the-release-gate-from-gateway-alone-to-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T07:13:50.830Z",
        "author": "Claude",
        "evidence": [
          "fieldlab/status/program-status.json",
          "fieldlab/status/README.md"
        ],
        "id": "20260721071350-retired-program-status-json-this-roadmap-is-the-",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "Comfy + Lumberjacks",
        "schema_version": 1,
        "summary": "Retired program-status.json; this roadmap is the one status surface now",
        "verification": [
          "program-status.json still parses as valid JSON; dashboard.html regenerated and redeployed"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721071350-retired-program-status-json-this-roadmap-is-the-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T07:13:50.830Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L54",
        "sha256": "a4743d785b29a38409740dc0424ab03e4da6ae690e55dfbf9130ffa364690000"
      },
      "summary": "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.",
      "title": "Retired program-status.json; this roadmap is the one status surface now",
      "updated_at": "2026-07-21T07:13:50.830Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721071350-retired-program-status-json-this-roadmap-is-the-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T07:44:51.429Z",
        "author": "Claude",
        "evidence": [
          "infra/gcp/p7/scripts/run-promotion-drill.ps1",
          "infra/gcp/p7/PROMOTION-DRILL.md",
          "Lumberjacks/scripts/roadmap.mjs"
        ],
        "id": "20260721074451-promotion-drill-now-transports-all-four-gated-im",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Promotion drill now transports all four gated images, not just the gateway",
        "verification": [
          "Plan-only drill run against a synthetic v3 fixture bundle records all four identities in drill-plan.json",
          "A bundle carrying only the gateway archive fails closed: 'bundle is missing eventlog/eventlog.oci.tar'",
          "Generated remote bash/YAML payloads rendered and inspected via AST extraction; no VM contact",
          "roadmap:check passes; git rev-parse --show-prefix confirms the Lumberjacks/ prefix that broke --staged"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721074451-promotion-drill-now-transports-all-four-gated-im",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-21T07:44:51.429Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L55",
        "sha256": "87dd750bda07ee9b5d514f33c65619883232e016f237ff2918f0ccd01f3ab07c"
      },
      "summary": "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.",
      "title": "Promotion drill now transports all four gated images, not just the gateway",
      "updated_at": "2026-07-21T07:44:51.429Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721074451-promotion-drill-now-transports-all-four-gated-im"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T07:59:22.211Z",
        "author": "Claude",
        "evidence": [
          "infra/gcp/p7/PROMOTION-DRILL.md"
        ],
        "id": "20260721075922-corrected-the-drill-runbook-the-three-sibling-se",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Corrected the drill runbook: the three sibling services do serve /health",
        "verification": [
          "curl against 127.0.0.1:4002-4004/health on comfy-lumberjacks-p7 returned 200 for all three"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721075922-corrected-the-drill-runbook-the-three-sibling-se",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T07:59:22.211Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L56",
        "sha256": "646acea2bfacaa6e1ed48ae2e9ce2e9d2761c6994f3e72a3acfff969a612de25"
      },
      "summary": "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.",
      "title": "Corrected the drill runbook: the three sibling services do serve /health",
      "updated_at": "2026-07-21T07:59:22.211Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721075922-corrected-the-drill-runbook-the-three-sibling-se"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T08:08:24.863Z",
        "author": "Claude",
        "evidence": [
          "Lumberjacks/docs/roadmap/m5-v3-reprovision-receipt.json",
          "Lumberjacks/docs/roadmap/m5-recipients-build-candidate-v3.json"
        ],
        "id": "20260721080824-re-provisioned-comfy-lumberjacks-p7-from-baselin",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Re-provisioned comfy-lumberjacks-p7 from baseline; all five services now gated",
        "verification": [
          "All four gated services report the exact manifest image ids after a systemctl restart, which is the reboot path (docker compose up -d, EnvironmentFile= only, no override file)",
          "Mod DLL is 035faa87 at both the runtime and fallback paths, matching the world-tested artifact",
          "Gateway health ok internally and publicly; eventlog/progression/operatorapi all 200; four dashboards 200",
          "Authoritative window empty and healthy: persistence_healthy true, 0 receipts, 0 pending, 0 consumers"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721080824-re-provisioned-comfy-lumberjacks-p7-from-baselin",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-21T08:08:24.863Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L57",
        "sha256": "c33505cd851394e92cf8e78ffcaa1b2c28d9d9ab8565644945cab8bfe68fb76f"
      },
      "summary": "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.",
      "title": "Re-provisioned comfy-lumberjacks-p7 from baseline; all five services now gated",
      "updated_at": "2026-07-21T08:08:24.863Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721080824-re-provisioned-comfy-lumberjacks-p7-from-baselin"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T08:31:14.768Z",
        "author": "Claude",
        "evidence": [
          "Lumberjacks/docs/roadmap/m5-v3-acceptance-receipt.json",
          "Lumberjacks/docs/roadmap/m5-v3-reprovision-receipt.json"
        ],
        "id": "20260721083114-world-tested-the-baseline-re-provision-m5-accept",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "World-tested the baseline re-provision: m5 acceptance passes on all eight criteria",
        "verification": [
          "Sample captured while the player was still connected; the window auto-resets when the server empties, so it cannot be reconstructed after the fact",
          "Workload was real: applied=61096, superseded=14016, including a dense-construction castle load"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721083114-world-tested-the-baseline-re-provision-m5-accept",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-21T08:31:14.768Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L58",
        "sha256": "991d4645b6f40616709a6b2a50b9bb55fdedab26fe96c8bc76640d385284b336"
      },
      "summary": "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.",
      "title": "World-tested the baseline re-provision: m5 acceptance passes on all eight criteria",
      "updated_at": "2026-07-21T08:31:14.768Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721083114-world-tested-the-baseline-re-provision-m5-accept"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T09:07:58.329Z",
        "author": "Claude",
        "evidence": [
          "Lumberjacks/src/Game.Gateway/Valheim/ValheimTelemetryHeartbeatService.cs",
          "network/mod/ComfyNetworkSense/Core/Services/LumberjacksTelemetryHeartbeatRunner.cs"
        ],
        "id": "20260721090758-root-caused-the-telemetry-heartbeat-409-deferred",
        "impact": "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.",
        "kind": "planning",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Root-caused the telemetry heartbeat 409; deferred the fix to the next release cut",
        "verification": [
          "Traced end to end: ValheimTelemetryHeartbeatEndpoints.cs line 42 returns Results.Conflict, gated by CanAcceptPrimaryHeartbeat at ValheimTelemetryHeartbeatService.cs line 168",
          "Matches observation: 409s appeared only while a peer was connected with pending greater than zero; heartbeat_stale stayed false throughout and the acceptance sample was captured with pending at zero"
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721090758-root-caused-the-telemetry-heartbeat-409-deferred",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-07-21T09:07:58.329Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L59",
        "sha256": "519c4d4d5e5dc73ea537c9823be16eb2f0555feb045cd2fd9b10891231c3b68a"
      },
      "summary": "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.",
      "title": "Root-caused the telemetry heartbeat 409; deferred the fix to the next release cut",
      "updated_at": "2026-07-21T09:07:58.329Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721090758-root-caused-the-telemetry-heartbeat-409-deferred"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T09:17:43.731Z",
        "author": "Claude",
        "evidence": [
          "Lumberjacks/docs/roadmap/prune-audit-20260721.json"
        ],
        "id": "20260721091743-pruned-279-of-1045-tracked-files-after-a-gemini-",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Pruned 279 of 1045 tracked files after a Gemini-backed per-zone audit",
        "verification": [
          "Release pipeline intact after the prune: v3 bundle still validates, run-promotion-drill.ps1 plan-only still resolves all four gated identities, and docker compose config still resolves all five service images",
          "roadmap:check passes; test_entrypoint_links passes with zero dangling links across every surviving README",
          "The 5 test_guest_package failures are pre-existing and reproduce identically on main; confirmed by checking out main and re-running"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721091743-pruned-279-of-1045-tracked-files-after-a-gemini-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-21T09:17:43.731Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L60",
        "sha256": "fe1399f470bf1fc0267b644f1d1bf75a2ecbcd67f7107e0a818f8b2df7a2ae1d"
      },
      "summary": "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.",
      "title": "Pruned 279 of 1045 tracked files after a Gemini-backed per-zone audit",
      "updated_at": "2026-07-21T09:17:43.731Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721091743-pruned-279-of-1045-tracked-files-after-a-gemini-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T09:31:15.358Z",
        "author": "Claude",
        "evidence": [
          "fieldlab/retro/SESSION-RETRO-2026-07-21.md",
          "fieldlab/docs/adr/README.md",
          "fieldlab/DECISIONS-PENDING.md"
        ],
        "id": "20260721093115-closed-out-the-session-retro-three-adrs-plan-out",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Closed out the session: retro, three ADRs, plan outcome, decisions register",
        "verification": [
          "roadmap:check passes; ADR index updated with 0005-0007; every relative link in the retro and ADRs resolves"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721093115-closed-out-the-session-retro-three-adrs-plan-out",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T09:31:15.358Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L61",
        "sha256": "6e3ec94c5c7d86b3f8bfc3fb9ef00141b315dc572506ce8c9f3b45d31e851427"
      },
      "summary": "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.",
      "title": "Closed out the session: retro, three ADRs, plan outcome, decisions register",
      "updated_at": "2026-07-21T09:31:15.358Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721093115-closed-out-the-session-retro-three-adrs-plan-out"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T10:07:33.502Z",
        "author": "Codex",
        "evidence": [
          "infra/gcp/p7/scripts/deploy-gateway.ps1",
          "AGENTS.md",
          "fieldlab/DECISIONS-PENDING.md"
        ],
        "id": "20260721100733-repointed-every-retired-checkout-root-reference-",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Repointed every retired-checkout-root reference at the merged repo",
        "verification": [
          "dotnet test Game.sln: 525/525 pass, up from 523/525",
          "All four repointed scripts parse clean and resolve to C:\\work\\baseline roots",
          "Repo-wide grep leaves only intentional prose, new explanatory comments, and frozen evidence archives"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721100733-repointed-every-retired-checkout-root-reference-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-21T10:07:33.502Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L62",
        "sha256": "1a308ed57086a3705e922a2705b93f6e4bf1bb0751aed4c65a2cf310d560923d"
      },
      "summary": "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.",
      "title": "Repointed every retired-checkout-root reference at the merged repo",
      "updated_at": "2026-07-21T10:07:33.502Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721100733-repointed-every-retired-checkout-root-reference-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T10:17:52.113Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/docs/adr/0008-liveness-is-not-admission.md",
          "Lumberjacks/src/Game.Gateway/Valheim/ValheimTelemetryHeartbeatService.cs",
          "Lumberjacks/tests/Game.Gateway.Tests/ValheimZdoAuthoritativeTelemetryTests.cs"
        ],
        "id": "20260721101752-separated-heartbeat-liveness-from-primary-admiss",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Separated heartbeat liveness from primary admission; the gate stays strict",
        "verification": [
          "New test RejectedPrimaryHeartbeatStillRefreshesLiveness was run against the old gate-then-record order and fails there (stale was True), so it catches the regression rather than merely passing",
          "dotnet test Game.sln: 528/528 pass, up from 525/525 with three new tests",
          "Grepped every consumer of stale/heartbeat_stale/advertised across cs, ts, js, html and py: no caller gates on the enrollment state string"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260721101752-separated-heartbeat-liveness-from-primary-admiss",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-21T10:17:52.113Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L63",
        "sha256": "e8b8a7f438acbda1c895279c519b2d80d76ddba0fdaa8025ab352899a518ad45"
      },
      "summary": "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.",
      "title": "Separated heartbeat liveness from primary admission; the gate stays strict",
      "updated_at": "2026-07-21T10:17:52.113Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721101752-separated-heartbeat-liveness-from-primary-admiss"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T10:48:03.344Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/docs/audit-2026-07-21-conditional-logic.svg",
          "Lumberjacks/tools/omen-dashboard/nginx.conf",
          "fieldlab/DECISIONS-PENDING.md"
        ],
        "id": "20260721104803-audited-the-accreted-conditional-logic-deleted-t",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Audited the accreted conditional logic; deleted two broken deploy scripts and repointed the local dashboard at the tunnel",
        "verification": [
          "dotnet test Game.sln: 528/528 pass, unchanged by the limiter change",
          "nginx -t against the real nginx:1.27-alpine image: configuration syntax is ok",
          "Every widened proxy route was checked to exist in the gateway's endpoint map first; each carries limit_except GET because the same prefixes also hold reset, compact and stage"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721104803-audited-the-accreted-conditional-logic-deleted-t",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-21T10:48:03.344Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L64",
        "sha256": "daea243aadbdc7dd8112a08cdb9edcef7acfc7a7c0dbb515f53b6159b0b224a3"
      },
      "summary": "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.",
      "title": "Audited the accreted conditional logic; deleted two broken deploy scripts and repointed the local dashboard at the tunnel",
      "updated_at": "2026-07-21T10:48:03.344Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721104803-audited-the-accreted-conditional-logic-deleted-t"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T10:58:13.345Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/docs/config-surface-decisions.md",
          "fieldlab/docs/audit-2026-07-21-conditional-logic.svg"
        ],
        "id": "20260721105813-completed-the-mod-config-inventory-and-turned-it",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Completed the mod config inventory and turned it into decisions with counter-reasons",
        "verification": [
          "All 107 keys accounted for across three disjoint passes; counted against the ConfigEntry declarations in PluginConfig.cs",
          "The auto-disarm semantics were read directly from ZdoRedirectRunner.cs rather than taken from the audit, and the production override was located in the P7 runbook"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721105813-completed-the-mod-config-inventory-and-turned-it",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T10:58:13.345Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L65",
        "sha256": "50a6a3b54707dca051f7ab9aa0809ef89f19eae8e9d0199f704c1c8a80050800"
      },
      "summary": "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.",
      "title": "Completed the mod config inventory and turned it into decisions with counter-reasons",
      "updated_at": "2026-07-21T10:58:13.345Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721105813-completed-the-mod-config-inventory-and-turned-it"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T11:11:01.958Z",
        "author": "Codex",
        "evidence": [
          "network/mod/ComfyNetworkSense/SWARM-HARNESS-REMOVED.md",
          "fieldlab/docs/config-surface-decisions.md"
        ],
        "id": "20260721111101-removed-the-swarm-unattended-client-harness-from",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Removed the swarm/unattended-client harness from the mod; 107 config keys down to 88",
        "verification": [
          "Mod builds 0 warnings 0 errors after removal; Game.sln still 528/528",
          "git grep for MatrixCheckinRunner, AutoCharacterSelectPatches, TryStartAutoRehearsal and TryCoupleAutoRehearsal across all .cs returns nothing",
          "ConfigEntry declarations and config.Bind calls both counted at 88, down from 107, and RouteGodFlySafeguard confirmed retained"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721111101-removed-the-swarm-unattended-client-harness-from",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-21T11:11:01.958Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L66",
        "sha256": "807871c084597d5274133598d08e16b568b46869d51d514b6c23a9c401c3999d"
      },
      "summary": "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.",
      "title": "Removed the swarm/unattended-client harness from the mod; 107 config keys down to 88",
      "updated_at": "2026-07-21T11:11:01.958Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721111101-removed-the-swarm-unattended-client-harness-from"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T11:28:59.719Z",
        "author": "Codex",
        "evidence": [
          "Lumberjacks/docs/network/area-of-interest-findings.md",
          "Lumberjacks/docs/benchmark-host-capacity-2026-07-12.md"
        ],
        "id": "20260721112859-wrote-the-area-of-interest-findings-record-what-",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Wrote the area-of-interest findings record: what the testing learned and why none of it reached the code",
        "verification": [
          "Every file and line citation in the document was resolved against the working tree; both line citations land on the intended code (InterestManager.cs:113 the near-band comparison, ZdoRedirectRunner.cs:337 the ImportanceAllows gate)",
          "Four errors from the parallel passes were caught and are recorded in the document's provenance section rather than propagated - two files reported missing that exist but were unpacked, one advisory-vs-enforced conflation, and two evidence files reported missing including the strongest measured artifact we hold"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721112859-wrote-the-area-of-interest-findings-record-what-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T11:28:59.719Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L67",
        "sha256": "1c93643ec1f3923164129a62d356bc254065998c621ebfcac132440a289ba4b4"
      },
      "summary": "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.",
      "title": "Wrote the area-of-interest findings record: what the testing learned and why none of it reached the code",
      "updated_at": "2026-07-21T11:28:59.719Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721112859-wrote-the-area-of-interest-findings-record-what-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T11:42:24.157Z",
        "author": "Codex",
        "evidence": [
          "Lumberjacks/docs/network/aoi-knee-experiment-brief.md",
          "fieldlab/evidence/aoi-density-pressure-matrix-20260704/README.md"
        ],
        "id": "20260721114224-recovered-the-aoi-density-pressure-dataset-and-w",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Recovered the AoI density-pressure dataset and wrote the knee-experiment brief",
        "verification": [
          "Every file and line citation in both new documents resolved against the working tree, including TickMetrics.cs:31 the budget constant, TickMetrics.cs:205 the overrun branch, TickBroadcaster.cs:342 the sent/culled record, and InterestManager.cs:16 the datagram-lane-only scope note",
          "The load-proxy hypothesis was tested by grouping all 998 synthetic rows by density_band and by observer_range; bytes_out_per_sec varies 0.2 percent across the full range from empty control to extreme density and avg_fps is constant at 60.0, so sensitivity is nil"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721114224-recovered-the-aoi-density-pressure-dataset-and-w",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T11:42:24.157Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L68",
        "sha256": "b8a124c9c68d9aa39c5e3a8b783b162097edcc41400b3c4d61aeef2d681d2c90"
      },
      "summary": "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.",
      "title": "Recovered the AoI density-pressure dataset and wrote the knee-experiment brief",
      "updated_at": "2026-07-21T11:42:24.157Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721114224-recovered-the-aoi-density-pressure-dataset-and-w"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T11:49:53.803Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/retro/SESSION-RETRO-2026-07-21.md",
          "fieldlab/docs/adr/0009-verify-against-an-independent-source.md"
        ],
        "id": "20260721114953-closed-the-audit-session-retro-addendum-adr-0009",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Closed the audit session: retro addendum, ADR 0009, decisions register, memory",
        "verification": [
          "Retro appended to the existing 2026-07-21 file, not overwritten; ADR index updated with 0009; every relative link in the addendum resolves",
          "Fleet second opinion hearth-retro-20260721-baseline-618dfd6e reaped and recorded as no-verdict with the empty_build evidence"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721114953-closed-the-audit-session-retro-addendum-adr-0009",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T11:49:53.803Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L69",
        "sha256": "a172ad36443a98179cf8d85188886708228d348469e13219cf28edb9f604d315"
      },
      "summary": "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.",
      "title": "Closed the audit session: retro addendum, ADR 0009, decisions register, memory",
      "updated_at": "2026-07-21T11:49:53.803Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721114953-closed-the-audit-session-retro-addendum-adr-0009"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T11:52:23.487Z",
        "author": "Codex",
        "evidence": [
          "Lumberjacks/docs/network/area-of-interest-findings.md",
          "fieldlab/evidence/aoi-density-pressure-matrix-20260704/modeled-pressure-matrix.csv"
        ],
        "id": "20260721115223-recorded-the-player-facing-goals-behind-the-aoi-",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Recorded the player-facing goals behind the AoI work, and read the 9,600-row grid as the specification it is",
        "verification": [
          "Every axis value quoted was read from the recovered CSV: six density_bands with real-cell labels, four observer_ranges, four event_profiles, three interest_buckets, five priority_expectations, three process_budgets, and 1,920 non-green rows split 480 per observer range",
          "The structural_anchor rank of 2 was read from LumberjacksPriorityClassifier, and the Far-band drop from InterestManager"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721115223-recorded-the-player-facing-goals-behind-the-aoi-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T11:52:23.487Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L70",
        "sha256": "d143c91e8355cc0c4c0a9c7b57c91c554499e596c21822b91556bd671b34b67c"
      },
      "summary": "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.",
      "title": "Recorded the player-facing goals behind the AoI work, and read the 9,600-row grid as the specification it is",
      "updated_at": "2026-07-21T11:52:23.487Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721115223-recorded-the-player-facing-goals-behind-the-aoi-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T12:03:02.762Z",
        "author": "Codex",
        "evidence": [
          "Lumberjacks/docs/network/landmark-reach-design.md"
        ],
        "id": "20260721120302-captured-the-landmark-reach-design-repaired-the-",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Captured the landmark-reach design; repaired the mojibake, including a fresh instance I caused",
        "verification": [
          "Mod builds clean after the comment repair; repo-wide grep for mojibake byte sequences now returns nothing across all .md and .cs",
          "The corrupted README was reverted via git checkout and re-edited with the Edit tool; em-dash count verified at 8 with 0 mojibake sequences before proceeding",
          "The repair targeted two codepoint-exact sequences measured from the actual files after a character-class heuristic silently matched nothing"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721120302-captured-the-landmark-reach-design-repaired-the-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T12:03:02.762Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L71",
        "sha256": "331790d685f3a1fd92c9703a18b6aa1f217c9a00eb556fd1a6f7ed37df48d51f"
      },
      "summary": "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.",
      "title": "Captured the landmark-reach design; repaired the mojibake, including a fresh instance I caused",
      "updated_at": "2026-07-21T12:03:02.762Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721120302-captured-the-landmark-reach-design-repaired-the-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T12:07:19.494Z",
        "author": "Codex",
        "evidence": [
          "Lumberjacks/docs/network/aoi-knee-experiment-brief.md",
          "Lumberjacks/docs/network/landmark-reach-design.md"
        ],
        "id": "20260721120719-pre-registered-the-three-tier-radius-sweep-and-s",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Pre-registered the three-tier radius sweep, and settled that landmark discovery needs a parallel channel",
        "verification": [
          "The band asymmetry was read from the recovered modeled-pressure-matrix.csv at density_band=extreme and event_profile=combat_build; far reports 0.00 updates per second and 0.00 kbps on every row",
          "The 64m zone alignment was confirmed from the mod's own radius defaults and its use of ZoneSystem.GetZone and IsZoneLoaded",
          "The broadcast endpoint and the mod-side manifest listener were both confirmed present, and InterestManager references neither, before the parallel-channel claim was written"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721120719-pre-registered-the-three-tier-radius-sweep-and-s",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T12:07:19.494Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L72",
        "sha256": "b2922b031c477f522c97e5672310526d37dc3d6bebf032d5c2bd5b4c0f77afcb"
      },
      "summary": "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.",
      "title": "Pre-registered the three-tier radius sweep, and settled that landmark discovery needs a parallel channel",
      "updated_at": "2026-07-21T12:07:19.494Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721120719-pre-registered-the-three-tier-radius-sweep-and-s"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T12:09:09.297Z",
        "author": "Codex",
        "evidence": [
          "Lumberjacks/docs/network/landmark-reach-design.md",
          "Lumberjacks/docs/network/aoi-knee-experiment-brief.md"
        ],
        "id": "20260721120909-corrected-the-landmark-discovery-answer-the-dual",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Corrected the landmark discovery answer: the dual-channel lane split already solved it",
        "verification": [
          "InterestManager's scope comment and the ReliableTiers set were both read directly before the correction was written; structural_anchor is confirmed present in ReliableTiers"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721120909-corrected-the-landmark-discovery-answer-the-dual",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T12:09:09.297Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L73",
        "sha256": "f289ce6844b2f1bfad04f7a3443cd78d42f657e933960665ed6e00571d3767f9"
      },
      "summary": "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.",
      "title": "Corrected the landmark discovery answer: the dual-channel lane split already solved it",
      "updated_at": "2026-07-21T12:09:09.297Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721120909-corrected-the-landmark-discovery-answer-the-dual"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T12:21:09.251Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/docs/config-surface-decisions.md",
          "fieldlab/docs/adr/0009-verify-against-an-independent-source.md"
        ],
        "id": "20260721122109-executed-the-safe-recommendations-and-withdrew-t",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Executed the safe recommendations and withdrew the unsafe ones after re-examination",
        "verification": [
          "Mod builds 0 warnings 0 errors; Game.sln 528/528; comfy_gateway.toolsurface.valheim imports cleanly with the dead autonomous_route profile removed; key count holds at 88; both ActiveSeconds defaults confirmed at 0.0f",
          "docker ps confirmed comfy-valheim-lab-comfy-gateway-1 and comfy-valheim-lab-valheim-server-1 are running from the compose file before it was restored"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721122109-executed-the-safe-recommendations-and-withdrew-t",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-21T12:21:09.251Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L74",
        "sha256": "2ecc4999f97d12c62303320e1ecdbd1291db3dfe1a6a260195adaad7d53fc4fe"
      },
      "summary": "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.",
      "title": "Executed the safe recommendations and withdrew the unsafe ones after re-examination",
      "updated_at": "2026-07-21T12:21:09.251Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721122109-executed-the-safe-recommendations-and-withdrew-t"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-21T12:35:05.438Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/docs/config-surface-decisions.md",
          "fieldlab/DECISIONS-PENDING.md"
        ],
        "id": "20260721123505-retired-the-matrix-mcp-surface-and-removed-the-p",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Retired the matrix MCP surface and removed the P3/P5 lab experiments; 88 config keys down to 73",
        "verification": [
          "Mod builds 0 warnings 0 errors; 73 declarations and 73 binds, down from 88; TryEnsurePrimaryRedirect confirmed still present and wired",
          "comfy_gateway kernel plus both surviving toolsurfaces import cleanly after matrix.py removal; no live reference to toolsurface.matrix remains outside frozen docs and evidence",
          "A pre-cut assertion that the excised block must not contain TryEnsurePrimaryRedirect aborted the first attempt and prevented deleting the production arming path",
          "Game.sln 528/528 across three consecutive runs; one earlier run showed a single Game.Simulation.Tests failure that did not reproduce in four subsequent runs and could not have been caused by this change set, since the mod is not part of Game.sln - filed as a flake to chase separately"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721123505-retired-the-matrix-mcp-surface-and-removed-the-p",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-21T12:35:05.438Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L75",
        "sha256": "5499d6c438cea25a04c62cc7877aa9c024bd42bd4957153891667d10d827d679"
      },
      "summary": "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.",
      "title": "Retired the matrix MCP surface and removed the P3/P5 lab experiments; 88 config keys down to 73",
      "updated_at": "2026-07-21T12:35:05.438Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721123505-retired-the-matrix-mcp-surface-and-removed-the-p"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T12:41:40.904Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/docs/audit-2026-07-21-the-twists.svg"
        ],
        "id": "20260721124140-drew-the-sixteen-twists-of-the-audit-and-its-fol",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Drew the sixteen twists of the audit and its follow-through",
        "verification": [
          "SVG parses as XML, all sixteen numbered nodes present and sequential, no coordinates outside the 1440x1810 canvas, no mojibake"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721124140-drew-the-sixteen-twists-of-the-audit-and-its-fol",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T12:41:40.904Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L76",
        "sha256": "653d166f709d688230f65fa70ff44a1f41f8c410c8d15358a9a15833038cbea4"
      },
      "summary": "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.",
      "title": "Drew the sixteen twists of the audit and its follow-through",
      "updated_at": "2026-07-21T12:41:40.904Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721124140-drew-the-sixteen-twists-of-the-audit-and-its-fol"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T12:55:47.805Z",
        "author": "Codex",
        "evidence": [
          "Lumberjacks/docs/network/aoi-knee-experiment-brief.md"
        ],
        "id": "20260721125547-redefined-the-aoi-knee-by-variance-onset-rather-",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Redefined the AoI knee by variance onset rather than failure onset",
        "verification": [
          "TickMetrics already keeps p50/p99/max per phase over a rolling ~100-tick window, so both curves come from the same endpoint read at no extra instrumentation cost"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721125547-redefined-the-aoi-knee-by-variance-onset-rather-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T12:55:47.805Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L77",
        "sha256": "cdada5a095ae3965653243fda7e38634cce769fbfa3557a24541360ebe127d6f"
      },
      "summary": "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.",
      "title": "Redefined the AoI knee by variance onset rather than failure onset",
      "updated_at": "2026-07-21T12:55:47.805Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721125547-redefined-the-aoi-knee-by-variance-onset-rather-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T12:59:39.107Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/docs/adr/0010-consistency-is-predictability.md",
          "Lumberjacks/docs/network/aoi-knee-experiment-brief.md"
        ],
        "id": "20260721125939-adr-0010-consistency-means-predictable-not-invar",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "ADR 0010: consistency means predictable, not invariant",
        "verification": [
          "AdaptiveDegrade.cs:22-23 confirmed to state no cooldown and no hysteresis; its default is false; InterestManager.cs:113 and :118 confirmed to use plain <= against nearRadiusSq and midRadiusSq with no dead-band"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721125939-adr-0010-consistency-means-predictable-not-invar",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T12:59:39.107Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L78",
        "sha256": "a17b18a07aa4dc9f56b6a57b3ba582fdb07354206c8033139a5333ff016909b3"
      },
      "summary": "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.",
      "title": "ADR 0010: consistency means predictable, not invariant",
      "updated_at": "2026-07-21T12:59:39.107Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721125939-adr-0010-consistency-means-predictable-not-invar"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T13:06:01.362Z",
        "author": "Codex",
        "evidence": [
          "HANDOFF.md"
        ],
        "id": "20260721130601-wrote-the-session-handoff-corrected-the-push-sta",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Wrote the session handoff; corrected the push state I had been misreporting",
        "verification": [
          "All nine relative links in HANDOFF.md resolve; key count confirmed at 73; origin/main tip confirmed f945562 with 2 local commits ahead; the flake fix commit d5bed21 is present in history"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721130601-wrote-the-session-handoff-corrected-the-push-sta",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T13:06:01.362Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L79",
        "sha256": "1036298a767a87b66cc0069d125616023cac0c6368963412c65289c4fc361a5e"
      },
      "summary": "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.",
      "title": "Wrote the session handoff; corrected the push state I had been misreporting",
      "updated_at": "2026-07-21T13:06:01.362Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721130601-wrote-the-session-handoff-corrected-the-push-sta"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T13:11:18.019Z",
        "author": "Codex",
        "evidence": [
          "HANDOFF.md"
        ],
        "id": "20260721131118-rewrote-the-handoff-as-an-ordered-ten-task-queue",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Rewrote the handoff as an ordered ten-task queue with why and how-to-test on each",
        "verification": [
          "All nine relative links resolve; all six code citations checked against the working tree and land on the intended lines, including ValheimHandshakeService.cs:546, ValheimZdoRedirectAdmissionPolicy.cs:30, ZdoRedirectRunner.cs:337 and both InterestManager band comparisons; ten task headings present; no mojibake"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721131118-rewrote-the-handoff-as-an-ordered-ten-task-queue",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-21T13:11:18.019Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L80",
        "sha256": "bdace44c98fc5fd503b20d7da7d2bcb0327a82d2b9d14a4ea736532a81650ce4"
      },
      "summary": "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.",
      "title": "Rewrote the handoff as an ordered ten-task queue with why and how-to-test on each",
      "updated_at": "2026-07-21T13:11:18.019Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721131118-rewrote-the-handoff-as-an-ordered-ten-task-queue"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-21T18:30:00.000Z",
        "author": "Claude",
        "evidence": [
          "fieldlab/evidence/aoi-band-shaping-p7-baseline-20260721/README.md",
          "fieldlab/docs/adr/0011-aoi-lives-on-the-producer.md"
        ],
        "id": "20260721183000-shipped-distance-band-aoi-band-shaping-to-produc",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M0"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Shipped distance-band AoI band-shaping to production P7 and armed it as normal play",
        "verification": [
          "P7 window p7-primary-v1: consumer applied 46900 = acknowledged 46900, superseded/rejected/native/pending/duplicates all 0; band-decision jsonl Drop:EmitThinned:EmitFull ~= 85:13:3; mod builds net48 0 warnings; ZdoBandPolicy unit tests green"
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260721183000-shipped-distance-band-aoi-band-shaping-to-produc",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-21T18:30:00.000Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L81",
        "sha256": "4db4b52fbbd6da9e6252c542ffa1443ad0768a39e25975bb7e8b5d47e421a32d"
      },
      "summary": "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.",
      "title": "Shipped distance-band AoI band-shaping to production P7 and armed it as normal play",
      "updated_at": "2026-07-21T18:30:00.000Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260721183000-shipped-distance-band-aoi-band-shaping-to-produc"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-22T09:08:53.927Z",
        "author": "Codex",
        "evidence": [
          "Lumberjacks/docs/roadmap/valheim-volunteer-roadmap.json"
        ],
        "id": "20260722090853-recorded-trusted-alpha-boundary-hardening-and-ap",
        "impact": "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.",
        "kind": "planning",
        "milestones": [
          "M1",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Recorded trusted-alpha boundary hardening and append-only contract history",
        "verification": [
          "Roadmap source validates and generated HTML is current."
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "M1",
          "M3"
        ]
      },
      "id": "roadmap:20260722090853-recorded-trusted-alpha-boundary-hardening-and-ap",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-07-22T09:08:53.927Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L82",
        "sha256": "a716544bdeed1ccbbcfc64e5fd0095cbc5952624b9eff93553298f8695c3bd87"
      },
      "summary": "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.",
      "title": "Recorded trusted-alpha boundary hardening and append-only contract history",
      "updated_at": "2026-07-22T09:08:53.927Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722090853-recorded-trusted-alpha-boundary-hardening-and-ap"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-22T09:18:38.738Z",
        "author": "Codex",
        "evidence": [
          "Lumberjacks/docs/roadmap/valheim-volunteer-roadmap.json"
        ],
        "id": "20260722091838-reduced-the-first-boundary-event-slice-to-four-e",
        "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.",
        "kind": "planning",
        "milestones": [
          "M1",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Reduced the first boundary-event slice to four events and simple rotation",
        "verification": [
          "Roadmap source validates and generated HTML is current."
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "M1",
          "M3"
        ]
      },
      "id": "roadmap:20260722091838-reduced-the-first-boundary-event-slice-to-four-e",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-07-22T09:18:38.738Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L83",
        "sha256": "1b871103edfb93322f92badc14015b4aeccd89b2c84bebedf6bed6746ad6f86e"
      },
      "summary": "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.",
      "title": "Reduced the first boundary-event slice to four events and simple rotation",
      "updated_at": "2026-07-22T09:18:38.738Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722091838-reduced-the-first-boundary-event-slice-to-four-e"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-22T09:28:24.806Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260722092824-added-the-reduced-boundary-event-stream-four-ver",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Added the reduced boundary-event stream: four versioned JSONL events, bounded rotating writer, access observations, ZDO batch timing, and a basic check/summarize analyzer; P7 compose now has an opt-in durable volume.",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260722092824-added-the-reduced-boundary-event-stream-four-ver",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-22T09:28:24.806Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L84",
        "sha256": "bbda98014461be43ac6b9ae6a309bbe56f07abf74651fe588c1e917d891145d6"
      },
      "summary": "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.",
      "title": "Added the reduced boundary-event stream: four versioned JSONL events, bounded rotating writer, access observations, ZDO batch timing, and a basic check/summarize analyzer; P7 compose now has an opt-in durable volume.",
      "updated_at": "2026-07-22T09:28:24.806Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722092824-added-the-reduced-boundary-event-stream-four-ver"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-22T09:38:57.277Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260722093857-unified-the-net-build-and-release-path-around-lu",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Unified the .NET build and release path around Lumberjacks/Dockerfile: solution restore, compilation, and tests now run in the SDK 9 verify stage inherited by shipping images; removed the redundant advisory Gateway SDK-container build and added the build/release runbook.",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260722093857-unified-the-net-build-and-release-path-around-lu",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-22T09:38:57.277Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L85",
        "sha256": "a35a27bdc1d9056c68b0c85146689bde9fd7bfc2a1a7f1cb715bdf5a4733f844"
      },
      "summary": "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.",
      "title": "Unified the .NET build and release path around Lumberjacks/Dockerfile: solution restore, compilation, and tests now run in the SDK 9 verify stage inherited by shipping images; removed the redundant advisory Gateway SDK-container build and added the build/release runbook.",
      "updated_at": "2026-07-22T09:38:57.277Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722093857-unified-the-net-build-and-release-path-around-lu"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-22T09:40:05.496Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260722094005-added-scripts-build-ps1-and-the-containerized-bu",
        "impact": "Operators have one repeatable PowerShell entry point and a checked-in procedure for the SDK 9 build, test, release identity, and image promotion boundaries.",
        "kind": "documentation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Added scripts/build.ps1 and the containerized build-release runbook so Verify, GatewayImage, and AllImages use the same Dockerfile targets.",
        "verification": []
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260722094005-added-scripts-build-ps1-and-the-containerized-bu",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-22T09:40:05.496Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L86",
        "sha256": "7f61b8fc8639facb736c648fecd2b29c17fd489b0615fd1f71906a3d8075f059"
      },
      "summary": "Operators have one repeatable PowerShell entry point and a checked-in procedure for the SDK 9 build, test, release identity, and image promotion boundaries.",
      "title": "Added scripts/build.ps1 and the containerized build-release runbook so Verify, GatewayImage, and AllImages use the same Dockerfile targets.",
      "updated_at": "2026-07-22T09:40:05.496Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722094005-added-scripts-build-ps1-and-the-containerized-bu"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-22T09:59:08.083Z",
        "author": "Codex",
        "evidence": [
          "docs/build-release-runbook.md",
          "docs/roadmap/valheim-volunteer-roadmap.json"
        ],
        "id": "20260722095908-promote-boundary-event-gateway-to-p7-and-reprodu",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M1",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Promote boundary-event Gateway to P7 and reproduce the Caddy authority boundary",
        "verification": [
          "Docker image verifier read the shipped Gateway image and confirmed admitted mod release m5-recipients-20260720-r1; P7 health reports ok and the durable env pin names lumberjacks-gateway:m3-boundary-20260722-r1.",
          "Boundary-event analyzer checked a complete-row P7 snapshot: 3586 rows, zero malformed, zero truncated, and all four event families present including zdo.batch.queued.",
          "Direct public /api/v0/enrollment returned 401 while the same route through Caddy/TLS returned 200, reproducing proxy private-plane capability inheritance without exposing credentials."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1",
          "M3"
        ]
      },
      "id": "roadmap:20260722095908-promote-boundary-event-gateway-to-p7-and-reprodu",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-22T09:59:08.083Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L87",
        "sha256": "b790bdf3d025bb1213f51a566fb3cd81103922caad0435257a427b018b617282"
      },
      "summary": "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.",
      "title": "Promote boundary-event Gateway to P7 and reproduce the Caddy authority boundary",
      "updated_at": "2026-07-22T09:59:08.083Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722095908-promote-boundary-event-gateway-to-p7-and-reprodu"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-22T10:41:22.755Z",
        "author": "Codex",
        "evidence": [
          "network/mod/ComfyNetworkSense/Core/Services/ZdoRedirectRunner.cs",
          "network/mod/ComfyNetworkSense/Core/Services/ZdoSendCadenceOverride.cs",
          "fieldlab/docs/runbook-alpha-player-motion-fast-lane.md"
        ],
        "id": "20260722104122-add-player-motion-fast-lane-and-measured-send-ca",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add player-motion fast lane and measured send-cadence lever",
        "verification": [
          "ComfyNetworkSense.Tests passed 71 tests.",
          "ComfyNetworkSense Release build completed with zero warnings and zero errors."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260722104122-add-player-motion-fast-lane-and-measured-send-ca",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-22T10:41:22.755Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L88",
        "sha256": "828dc9f5c140ec1f4fa08b02cf1a47df23b971d18665dc09bd8994e5f6dbda3f"
      },
      "summary": "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.",
      "title": "Add player-motion fast lane and measured send-cadence lever",
      "updated_at": "2026-07-22T10:41:22.755Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722104122-add-player-motion-fast-lane-and-measured-send-ca"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-22T10:52:25.391Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260722105225-add-admin-rescue-mod-pack-download",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add admin rescue mod-pack download",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260722105225-add-admin-rescue-mod-pack-download",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-22T10:52:25.391Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L89",
        "sha256": "9d73008849f79548f9df1d05bc40dea5820201e3d63d4796453ec4a8a0f92b50"
      },
      "summary": "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.",
      "title": "Add admin rescue mod-pack download",
      "updated_at": "2026-07-22T10:52:25.391Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722105225-add-admin-rescue-mod-pack-download"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-22T10:59:27.801Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260722105927-deploy-admin-rescue-gateway-and-refresh-p7-mod-p",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Deploy admin rescue Gateway and refresh P7 mod-pack template",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260722105927-deploy-admin-rescue-gateway-and-refresh-p7-mod-p",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-22T10:59:27.801Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L90",
        "sha256": "88d7d8b898273121712f37b7b5becebed5d57b6e1d76f22eb90e07b251a64dae"
      },
      "summary": "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.",
      "title": "Deploy admin rescue Gateway and refresh P7 mod-pack template",
      "updated_at": "2026-07-22T10:59:27.801Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722105927-deploy-admin-rescue-gateway-and-refresh-p7-mod-p"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-22T11:30:57.308Z",
        "author": "Codex",
        "evidence": [
          "src/Game.Gateway/Valheim/ValheimHandshakeStartup.cs",
          "infra/gcp/p7/docker-compose.yml",
          "fieldlab/docs/runbook-copresence-fanout-live-test.md"
        ],
        "id": "20260722113057-make-p7-alpha-seat-override-durable-across-gatew",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make P7 alpha seat override durable across Gateway restarts",
        "verification": [
          "Docker verify target built the full solution and ran 551 .NET 9 tests successfully.",
          "The shipped Gateway image admits frozen mod release m5-recipients-20260720-r1 and P7 reports image sha256:fe9f7e8652ab3858f8d767c7ca98888ea33f9b67f6414201ba56de5964447d8f.",
          "After Gateway recreate plus restart, /valheim/handshake/status/p7-primary-v1 returned seat_capacity 0 over the public TLS endpoint."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260722113057-make-p7-alpha-seat-override-durable-across-gatew",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-22T11:30:57.308Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L91",
        "sha256": "50ff1e2169734a1426cdec10bc5139111511bd835680df6ce8c33106cd250f35"
      },
      "summary": "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.",
      "title": "Make P7 alpha seat override durable across Gateway restarts",
      "updated_at": "2026-07-22T11:30:57.308Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722113057-make-p7-alpha-seat-override-durable-across-gatew"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-22T11:45:49.987Z",
        "author": "Codex",
        "evidence": [
          "src/Game.Gateway/BoundaryEvents/BoundaryEventDiagnostics.cs",
          "src/Game.Gateway/Community/boundary.html",
          "tools/omen-dashboard/nginx.conf"
        ],
        "id": "20260722114549-deploy-operator-boundary-diagnostics-dashboard",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M1",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Deploy operator boundary diagnostics dashboard",
        "verification": [
          "Docker verify target built the full solution and ran 553 .NET 9 tests successfully.",
          "Gateway-only image m7-boundarydash-20260722-r1 admits frozen mod release m5-recipients-20260720-r1 and is live on P7 as sha256:42c7df07e84f746d98d2821307df0cdeb05eed7aaa2e496985eaf7bc485cdfb9.",
          "P7 /ops/boundary/summary over loopback returned boundary rows with zero writer drops/faults; simulated public X-Forwarded-For was refused with 403; OMEN proxy returned 200 for /ops/boundary."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1",
          "M3"
        ]
      },
      "id": "roadmap:20260722114549-deploy-operator-boundary-diagnostics-dashboard",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-22T11:45:49.987Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L92",
        "sha256": "1d76431a558bd546bc896963f58e8900ad7c031b88c7ff7e1f150cb7055c384f"
      },
      "summary": "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.",
      "title": "Deploy operator boundary diagnostics dashboard",
      "updated_at": "2026-07-22T11:45:49.987Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722114549-deploy-operator-boundary-diagnostics-dashboard"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-22T12:04:36.460Z",
        "author": "Codex",
        "evidence": [
          "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.yml"
        ],
        "id": "20260722120436-deploy-rough-zdo-movement-dashboard-and-alpha-zi",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M2",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Deploy rough ZDO movement dashboard and alpha zip surface",
        "verification": [
          "Docker verify passed: 557 tests across contracts, simulation, and gateway suites.",
          "P7 runs Gateway image sha256:b3b351e13a56039e314dd17458d1ce301a82bb81cd215659041a8b0bb463dd4c as m8-zdostreamdash-20260722-r3 while admitting frozen mod release m5-recipients-20260720-r1 and preserving the disabled alpha seat gate.",
          "OMEN /ops/boundary serves the new ZDO panels; public TLS /ops/boundary still returns 403."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M2",
          "M3"
        ]
      },
      "id": "roadmap:20260722120436-deploy-rough-zdo-movement-dashboard-and-alpha-zi",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-22T12:04:36.460Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L93",
        "sha256": "d0ce8e079dac8b1727096ab2f359bbfcbae4f8ae2089cb84fab7ef6487f08ae8"
      },
      "summary": "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.",
      "title": "Deploy rough ZDO movement dashboard and alpha zip surface",
      "updated_at": "2026-07-22T12:04:36.460Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722120436-deploy-rough-zdo-movement-dashboard-and-alpha-zi"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-22T12:29:19.868Z",
        "author": "Codex",
        "evidence": [
          "src/Game.Gateway/Community/community.html",
          "docs/dashboard/viewing-the-surfaces.md"
        ],
        "id": "20260722122919-compact-community-dashboard-with-live-trace-rail",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Compact community dashboard with live trace rail",
        "verification": [
          "Docker Gateway release cut passed 557 tests; P7 runs m9-communitytrace-20260722-r1 as sha256:20bd957b44813dbdd457cdea489ffccc0eb4566807e969d1d70708e10fca8661 while admitting frozen mod m5-recipients-20260720-r1; OMEN /community serves the compact trace view through the operator tunnel."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260722122919-compact-community-dashboard-with-live-trace-rail",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-22T12:29:19.868Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L94",
        "sha256": "cc89ba40ce4e74bc880a9a1e81f5f973e9a99f026f61e33d4a872d683f2d2a54"
      },
      "summary": "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.",
      "title": "Compact community dashboard with live trace rail",
      "updated_at": "2026-07-22T12:29:19.868Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722122919-compact-community-dashboard-with-live-trace-rail"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-22T12:39:16.122Z",
        "author": "Codex",
        "evidence": [
          "src/Game.Gateway/Valheim/ValheimHandshakeService.cs",
          "src/Game.Gateway/Valheim/ValheimTelemetryHeartbeatService.cs",
          "src/Game.Gateway/Community/community.html",
          "docs/dashboard/viewing-the-surfaces.md"
        ],
        "id": "20260722123916-show-valheim-player-names-on-the-community-dashb",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Show Valheim player names on the community dashboard",
        "verification": [
          "Docker Gateway release cut passed 559 tests; P7 runs m10-playernames-20260722-r1 as sha256:004bebddc5c74924c36942684f5b184bd510dd6aba9aa9bec73dd544eb8ab46d while admitting frozen mod m5-recipients-20260720-r1; OMEN /community serves the player-name aware script."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260722123916-show-valheim-player-names-on-the-community-dashb",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-22T12:39:16.122Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L95",
        "sha256": "309b5e43a6a7b77a823509188c4631680fb1b097e760ace75d8a5e55bf995eec"
      },
      "summary": "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.",
      "title": "Show Valheim player names on the community dashboard",
      "updated_at": "2026-07-22T12:39:16.122Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722123916-show-valheim-player-names-on-the-community-dashb"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-22T13:28:13.178Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260722132813-expose-the-live-valheim-lumberjacks-transport-bo",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Expose the live Valheim/Lumberjacks transport boundary",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260722132813-expose-the-live-valheim-lumberjacks-transport-bo",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-22T13:28:13.178Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L96",
        "sha256": "bcaf94cf002d8e0a612627f87abb51309cd6ff658125af2839c710ca32283c84"
      },
      "summary": "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.",
      "title": "Expose the live Valheim/Lumberjacks transport boundary",
      "updated_at": "2026-07-22T13:28:13.178Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722132813-expose-the-live-valheim-lumberjacks-transport-bo"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-22T13:55:30.835Z",
        "author": "Codex",
        "evidence": [
          "docs/roadmap/m11-transport-build-candidate-v3.json"
        ],
        "id": "20260722135530-promoted-the-transport-boundary-release-to-p7",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Promoted the transport-boundary release to P7",
        "verification": [
          "Validated release bundle; cold-start, rollback, restore and image/hash checks passed; P7 heartbeat reports 0.5.32 ready."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260722135530-promoted-the-transport-boundary-release-to-p7",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-22T13:55:30.835Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L97",
        "sha256": "3f8aa17992799ad00a3bfb491498848759e338fd53b7548b045d4fbf40a0c78f"
      },
      "summary": "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.",
      "title": "Promoted the transport-boundary release to P7",
      "updated_at": "2026-07-22T13:55:30.835Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722135530-promoted-the-transport-boundary-release-to-p7"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-22T14:54:22.850Z",
        "author": "Codex",
        "evidence": [
          "infra/gcp/p7/VALHEIM-MOTION-CANARY.md"
        ],
        "id": "20260722145422-build-authenticated-lumberjacks-player-motion-la",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Build authenticated Lumberjacks player-motion lane",
        "verification": [
          "75 mod tests and 563 containerized .NET tests pass; independent mod and Gateway codecs match the same exact 50-byte fixture; Terraform and Compose validate."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260722145422-build-authenticated-lumberjacks-player-motion-la",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-22T14:54:22.850Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L98",
        "sha256": "4db288f8e27b3383fe0f8e18f1c80159dd7e06671ac4734f120bf48aad36b5fe"
      },
      "summary": "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.",
      "title": "Build authenticated Lumberjacks player-motion lane",
      "updated_at": "2026-07-22T14:54:22.850Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722145422-build-authenticated-lumberjacks-player-motion-la"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-22T15:33:29.787Z",
        "author": "Codex",
        "evidence": [
          "infra/gcp/p7/PROMOTION-DRILL.md"
        ],
        "id": "20260722153329-preserve-enrollment-identity-through-tls-proxy",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Preserve enrollment identity through TLS proxy",
        "verification": [
          "Container verification passed 564 tests, including private-proxy enrollment precedence."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M7"
        ]
      },
      "id": "roadmap:20260722153329-preserve-enrollment-identity-through-tls-proxy",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-22T15:33:29.787Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L99",
        "sha256": "68addf11ca69728e78f76b32530ddfca09adcf9bcd313fb385be31acab938b5f"
      },
      "summary": "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.",
      "title": "Preserve enrollment identity through TLS proxy",
      "updated_at": "2026-07-22T15:33:29.787Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260722153329-preserve-enrollment-identity-through-tls-proxy"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T06:45:52.427Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723064552-resolve-enrolled-identity-before-websocket-motio",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Resolve enrolled identity before WebSocket motion sessions",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723064552-resolve-enrolled-identity-before-websocket-motio",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T06:45:52.427Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L100",
        "sha256": "8350b60d88c650552558a2826ab9f99218ed32bb5346870a0b957024e3264169"
      },
      "summary": "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.",
      "title": "Resolve enrolled identity before WebSocket motion sessions",
      "updated_at": "2026-07-23T06:45:52.427Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723064552-resolve-enrolled-identity-before-websocket-motio"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T06:49:00.384Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723064900-pin-the-committed-websocket-motion-gateway-on-p7",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Pin the committed WebSocket motion Gateway on P7",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723064900-pin-the-committed-websocket-motion-gateway-on-p7",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T06:49:00.384Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L101",
        "sha256": "5187946e7f032d52d12738210efb0c5308a2082555e8ba70320830a98eae1ad9"
      },
      "summary": "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.",
      "title": "Pin the committed WebSocket motion Gateway on P7",
      "updated_at": "2026-07-23T06:49:00.384Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723064900-pin-the-committed-websocket-motion-gateway-on-p7"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T07:49:39.360Z",
        "author": "Codex",
        "evidence": [
          "src/Game.Gateway/Valheim/SteamEnrollmentEndpoints.cs",
          "src/Game.Gateway/Valheim/ModPackBuilder.cs",
          "infra/gcp/p7/VOLUNTEER-ENDPOINT.md"
        ],
        "id": "20260723074939-added-steam-bound-latest-mod-update-downloads-th",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Added Steam-bound latest mod update downloads that preserve installed client config.",
        "verification": [
          "Gateway test project passed in the .NET 9 SDK container after adding config-preserving pack and enrollment lookup coverage."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723074939-added-steam-bound-latest-mod-update-downloads-th",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T07:49:39.360Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L102",
        "sha256": "da5b7c91b05b5c37565f36acb6b7d9a9ee7a6ba9fd720fb3861b91f18bbdfef0"
      },
      "summary": "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.",
      "title": "Added Steam-bound latest mod update downloads that preserve installed client config.",
      "updated_at": "2026-07-23T07:49:39.360Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723074939-added-steam-bound-latest-mod-update-downloads-th"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T08:03:31.651Z",
        "author": "Codex",
        "evidence": [
          "docs/roadmap/m13-portal-gateway-release.json",
          "infra/gcp/p7/docker-compose.yml"
        ],
        "id": "20260723080331-deployed-the-steam-bound-portal-update-gateway-i",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Deployed the Steam-bound portal update Gateway image to P7.",
        "verification": [
          "P7 health returned ok, the running Gateway image matched sha256:9a64656971151987af409676921fc8b476a852dbfea0f8b24e784e338dff3fd4, /join/update returned 200, and /api/v0/valheim/modpack/manifest reported release m13-portal-20260723-r1."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723080331-deployed-the-steam-bound-portal-update-gateway-i",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T08:03:31.651Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L103",
        "sha256": "0dcb03344002fe3d2890b5b2c8a47808e26f2c844ea7969a73e45ae97d5e479b"
      },
      "summary": "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.",
      "title": "Deployed the Steam-bound portal update Gateway image to P7.",
      "updated_at": "2026-07-23T08:03:31.651Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723080331-deployed-the-steam-bound-portal-update-gateway-i"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T08:29:06.179Z",
        "author": "Codex",
        "evidence": [
          "docs/roadmap/m14-hudtoggle-server-mod-deploy.json",
          "fieldlab/docs/runbook-transport-truth-strip.md"
        ],
        "id": "20260723082906-deploy-collapsible-transport-strip-release-to-p7",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Deploy collapsible transport strip release to P7",
        "verification": [
          "New-ReleaseCut.ps1 confirmed the mod DLL and Gateway image both carry m14-hudtoggle-20260723-r1; the P7 Valheim server reported ready on DLL sha256:a357cbd4feb1a889c82b05205e73d5309bb63dfad78a868e325f5c3bfa74ad39; the public modpack manifest reported release/admitted-mod m14-hudtoggle-20260723-r1 and package sha256:a1597bc98cd454ddc2f10bfa6767ce1c0d2af8f36bb8c14f88c5fad28ab06d74."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723082906-deploy-collapsible-transport-strip-release-to-p7",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T08:29:06.179Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L104",
        "sha256": "c7d0723e095677649b20156510f190be4abae2149a3a8ed64ebea61bec8d0ede"
      },
      "summary": "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.",
      "title": "Deploy collapsible transport strip release to P7",
      "updated_at": "2026-07-23T08:29:06.179Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723082906-deploy-collapsible-transport-strip-release-to-p7"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T08:52:00.950Z",
        "author": "Codex",
        "evidence": [
          "docs/roadmap/m15-hudrecover-server-mod-deploy.json",
          "fieldlab/docs/runbook-transport-truth-strip.md"
        ],
        "id": "20260723085200-deploy-transport-strip-recovery-release-to-p7",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Deploy transport strip recovery release to P7",
        "verification": [
          "New-ReleaseCut.ps1 confirmed the mod DLL and Gateway image both carry m15-hudrecover-20260723-r1; the P7 Valheim server reported ready on DLL sha256:9a8ea06923d711f97f275506cbf14969ee06dc81376e97ad97493f53b32d26d2; the public modpack manifest reported release/admitted-mod m15-hudrecover-20260723-r1 and package sha256:c847ae5787b1a6b8b3f67072509c1422fbf43a79d1219f93628ba98fea462b76."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723085200-deploy-transport-strip-recovery-release-to-p7",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T08:52:00.950Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L105",
        "sha256": "7b1b3ee8a478e997c5817538e98cca453cafd781a3d1a905b42ed37a6562d39b"
      },
      "summary": "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.",
      "title": "Deploy transport strip recovery release to P7",
      "updated_at": "2026-07-23T08:52:00.950Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723085200-deploy-transport-strip-recovery-release-to-p7"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T09:14:35.092Z",
        "author": "Codex",
        "evidence": [
          "docs/roadmap/m16-updatehistory-gateway-release.json",
          "src/Game.Gateway/Valheim/EnrollmentPages.cs"
        ],
        "id": "20260723091435-show-recent-releases-on-the-update-page",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Show recent releases on the update page",
        "verification": [
          "Gateway-only cut m16-updatehistory-20260723-r1 admits frozen mod m15-hudrecover-20260723-r1; Docker build passed 123 contract, 250 simulation, and 194 gateway tests; public /join/update returned 200 with Cache-Control: no-store, max-age=0 and showed m16 as the current release; public manifest reported release m16-updatehistory-20260723-r1 and mod_release m15-hudrecover-20260723-r1."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723091435-show-recent-releases-on-the-update-page",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T09:14:35.092Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L106",
        "sha256": "daee9fbdfdd1af35b8c4d45376a91dd1269c7fc7130b65aa3f1e3538a891bff5"
      },
      "summary": "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.",
      "title": "Show recent releases on the update page",
      "updated_at": "2026-07-23T09:14:35.092Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723091435-show-recent-releases-on-the-update-page"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T09:27:18.175Z",
        "author": "Codex",
        "evidence": [
          "docs/roadmap/m17-updatefilename-gateway-release.json",
          "src/Game.Gateway/Valheim/SteamEnrollmentEndpoints.cs",
          "src/Game.Gateway/Valheim/EnrollmentPages.cs"
        ],
        "id": "20260723092718-version-post-steam-update-download-filenames",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Version post-Steam update download filenames",
        "verification": [
          "Gateway image build passed 123 contract, 250 simulation, and 194 Gateway tests; P7 public manifest reports m17-updatefilename-20260723-r1 with mod_release m15-hudrecover-20260723-r1; public /join/update returns Cache-Control: no-store and shows m17 as the current release row."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723092718-version-post-steam-update-download-filenames",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T09:27:18.175Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L107",
        "sha256": "e40746ade2c0360e8fd544b45ba9a495fa2a9fc8ad471951fd6bf6b98ba93b20"
      },
      "summary": "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.",
      "title": "Version post-Steam update download filenames",
      "updated_at": "2026-07-23T09:27:18.175Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723092718-version-post-steam-update-download-filenames"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T10:06:19.158Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723100619-add-local-companion-and-client-pull-modpack-rele",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add local Companion and client-pull modpack release pointer",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723100619-add-local-companion-and-client-pull-modpack-rele",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T10:06:19.158Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L108",
        "sha256": "b7ae186163289f42c9c98c0c815382c54c9507c8e966170ab9c083d31b2b76c9"
      },
      "summary": "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.",
      "title": "Add local Companion and client-pull modpack release pointer",
      "updated_at": "2026-07-23T10:06:19.158Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723100619-add-local-companion-and-client-pull-modpack-rele"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T10:14:59.625Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723101459-deploy-companion-client-pull-gateway-and-publish",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Deploy Companion client-pull Gateway and publish the first runtime pointer",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723101459-deploy-companion-client-pull-gateway-and-publish",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T10:14:59.625Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L109",
        "sha256": "d5413c7209d43a70fb0d83e63a92943706e37cd72ff69921e68c54f006db6f57"
      },
      "summary": "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.",
      "title": "Deploy Companion client-pull Gateway and publish the first runtime pointer",
      "updated_at": "2026-07-23T10:14:59.625Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723101459-deploy-companion-client-pull-gateway-and-publish"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T10:16:42.776Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723101642-replace-omen-loopback-dashboard-with-the-compani",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Replace OMEN loopback dashboard with the Companion",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723101642-replace-omen-loopback-dashboard-with-the-compani",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T10:16:42.776Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L110",
        "sha256": "7932b7013d468b5466f871c80cbdcf021497c449f53e5297f244e1d389918a2c"
      },
      "summary": "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.",
      "title": "Replace OMEN loopback dashboard with the Companion",
      "updated_at": "2026-07-23T10:16:42.776Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723101642-replace-omen-loopback-dashboard-with-the-compani"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T10:34:24.580Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723103424-make-the-companion-updater-workflow-explicit",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make the Companion updater workflow explicit",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723103424-make-the-companion-updater-workflow-explicit",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T10:34:24.580Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L111",
        "sha256": "5cefd7741f03b851c621078e715cd58ecbd4cdf0cf89e336660a5bac1f9acc53"
      },
      "summary": "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.",
      "title": "Make the Companion updater workflow explicit",
      "updated_at": "2026-07-23T10:34:24.580Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723103424-make-the-companion-updater-workflow-explicit"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T10:37:52.694Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723103752-accept-package-metadata-during-companion-install",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Accept package metadata during Companion installs",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723103752-accept-package-metadata-during-companion-install",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T10:37:52.694Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L112",
        "sha256": "02e2c7bfa0d9f8fe8f16921c1f9169b03b74c596370d4b42dfc3f220cf34d6a2"
      },
      "summary": "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.",
      "title": "Accept package metadata during Companion installs",
      "updated_at": "2026-07-23T10:37:52.694Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723103752-accept-package-metadata-during-companion-install"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T12:02:20.792Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723120220-companion-uses-compact-readiness-checkboxes",
        "impact": "Docker-backed local updates require an explicit game-closed confirmation before install, avoiding a false host-process signal while preserving immediate release feedback.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Companion uses compact readiness checkboxes",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723120220-companion-uses-compact-readiness-checkboxes",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T12:02:20.792Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L113",
        "sha256": "23d6377b14c005c75acb03b2bf9573a622f02824f70c7e59767f61c7faa5719f"
      },
      "summary": "Docker-backed local updates require an explicit game-closed confirmation before install, avoiding a false host-process signal while preserving immediate release feedback.",
      "title": "Companion uses compact readiness checkboxes",
      "updated_at": "2026-07-23T12:02:20.792Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723120220-companion-uses-compact-readiness-checkboxes"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T12:13:50.068Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723121350-companion-enforces-game-closed-confirmation-for-",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Companion enforces game-closed confirmation for writes",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723121350-companion-enforces-game-closed-confirmation-for-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T12:13:50.068Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L114",
        "sha256": "844f4c469aa7f775b974efe1ff08d9f31a788b59b3b53d1f78b8a09be0b6dc23"
      },
      "summary": "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.",
      "title": "Companion enforces game-closed confirmation for writes",
      "updated_at": "2026-07-23T12:13:50.068Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723121350-companion-enforces-game-closed-confirmation-for-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T12:16:29.117Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723121629-documented-i5-companion-logon-recovery",
        "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.",
        "kind": "documentation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Documented i5 Companion logon recovery",
        "verification": []
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723121629-documented-i5-companion-logon-recovery",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-23T12:16:29.117Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L115",
        "sha256": "df53623a19fc2fa9dcb48d2f90a3ff8a2353714116091467adcd7d0e85e7f846"
      },
      "summary": "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.",
      "title": "Documented i5 Companion logon recovery",
      "updated_at": "2026-07-23T12:16:29.117Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723121629-documented-i5-companion-logon-recovery"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T12:22:08.017Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723122208-added-a-generic-windows-docker-companion-bootstr",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Added a generic Windows Docker Companion bootstrap bundle.",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723122208-added-a-generic-windows-docker-companion-bootstr",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T12:22:08.017Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L116",
        "sha256": "f2effcb1c45f6e6fe0bad738b568c3e833fa7456511698b74eb11511045de544"
      },
      "summary": "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.",
      "title": "Added a generic Windows Docker Companion bootstrap bundle.",
      "updated_at": "2026-07-23T12:22:08.017Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723122208-added-a-generic-windows-docker-companion-bootstr"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T12:25:25.519Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723122525-hardened-companion-bootstrap-discovery-and-surfa",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Hardened Companion bootstrap discovery and surfaced local updater version.",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723122525-hardened-companion-bootstrap-discovery-and-surfa",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T12:25:25.519Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L117",
        "sha256": "25cb94803c3d5aba4368ec9f6b0f6de0d2e3d8621bc7cb886e3536ed885d7c02"
      },
      "summary": "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.",
      "title": "Hardened Companion bootstrap discovery and surfaced local updater version.",
      "updated_at": "2026-07-23T12:25:25.519Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723122525-hardened-companion-bootstrap-discovery-and-surfa"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T12:28:33.861Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723122833-added-immutable-github-publishing-for-the-compan",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Added immutable GitHub publishing for the Companion bootstrap bundle.",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723122833-added-immutable-github-publishing-for-the-compan",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T12:28:33.861Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L118",
        "sha256": "d298b33e1f1c20bee2c8345b3448ab56f6d2cad508615a7bae01d1fc691e2551"
      },
      "summary": "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.",
      "title": "Added immutable GitHub publishing for the Companion bootstrap bundle.",
      "updated_at": "2026-07-23T12:28:33.861Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723122833-added-immutable-github-publishing-for-the-compan"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T12:29:06.373Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723122906-handle-missing-github-releases-during-companion-",
        "impact": "The immutable bootstrap publisher now treats an absent release as the expected creation path on Windows PowerShell instead of failing before upload.",
        "kind": "implementation",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Handle missing GitHub releases during Companion publish preflight.",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723122906-handle-missing-github-releases-during-companion-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T12:29:06.373Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L119",
        "sha256": "2d75564d34442977e8533c1cb55ae73f24daa9ef969fdad5c4927ef13bacd617"
      },
      "summary": "The immutable bootstrap publisher now treats an absent release as the expected creation path on Windows PowerShell instead of failing before upload.",
      "title": "Handle missing GitHub releases during Companion publish preflight.",
      "updated_at": "2026-07-23T12:29:06.373Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723122906-handle-missing-github-releases-during-companion-"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T12:29:28.037Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723122928-published-the-first-immutable-companion-bootstra",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Published the first immutable Companion bootstrap release.",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723122928-published-the-first-immutable-companion-bootstra",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T12:29:28.037Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L120",
        "sha256": "0274742d2623af719c149008ca9f65b11a8e596e35cd92cba9db01d68a9b7045"
      },
      "summary": "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.",
      "title": "Published the first immutable Companion bootstrap release.",
      "updated_at": "2026-07-23T12:29:28.037Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723122928-published-the-first-immutable-companion-bootstra"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T12:30:44.435Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723123044-refocused-boundary-diagnostics-on-the-live-appen",
        "impact": "The operator page now foregrounds recent normalized events and compact health signals, while open-segment tails are labeled separately from malformed records.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Refocused boundary diagnostics on the live append-only evidence stream.",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723123044-refocused-boundary-diagnostics-on-the-live-appen",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T12:30:44.435Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L121",
        "sha256": "83cda9c13fe2444bb250b8fb703573dab293231b40241762ffabe6ee9fb4e28b"
      },
      "summary": "The operator page now foregrounds recent normalized events and compact health signals, while open-segment tails are labeled separately from malformed records.",
      "title": "Refocused boundary diagnostics on the live append-only evidence stream.",
      "updated_at": "2026-07-23T12:30:44.435Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723123044-refocused-boundary-diagnostics-on-the-live-appen"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T12:35:09.458Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723123509-add-p7-gateway-image-promotion-lane",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add P7 Gateway image promotion lane",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260723123509-add-p7-gateway-image-promotion-lane",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T12:35:09.458Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L122",
        "sha256": "8b4e917740ccae072f0d0ee5e9698c33896eb115c51bd1a078601e48be53788c"
      },
      "summary": "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.",
      "title": "Add P7 Gateway image promotion lane",
      "updated_at": "2026-07-23T12:35:09.458Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723123509-add-p7-gateway-image-promotion-lane"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T12:39:59.451Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723123959-add-companion-trace-url-alias",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add Companion trace URL alias",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723123959-add-companion-trace-url-alias",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T12:39:59.451Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L123",
        "sha256": "f1f2df149b78b81f130bc47cfa9272cd6ade61b87bf8ed071e20eea39d298bf1"
      },
      "summary": "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.",
      "title": "Add Companion trace URL alias",
      "updated_at": "2026-07-23T12:39:59.451Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723123959-add-companion-trace-url-alias"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T12:44:51.611Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723124451-add-public-data-and-trust-page",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add public data and trust page",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723124451-add-public-data-and-trust-page",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T12:44:51.611Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L124",
        "sha256": "c57ad83c6108ed13c32a3719a6bea1e84d89cddf1c9a8ffaa5722fee0c3a961f"
      },
      "summary": "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.",
      "title": "Add public data and trust page",
      "updated_at": "2026-07-23T12:44:51.611Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723124451-add-public-data-and-trust-page"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T12:48:05.562Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723124805-align-data-trust-wording-with-event-contract",
        "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.",
        "kind": "documentation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Align data trust wording with event contract",
        "verification": []
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723124805-align-data-trust-wording-with-event-contract",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-23T12:48:05.562Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L125",
        "sha256": "299ae149dee325132e8fcb8fdfee5cfbe7de51bcf36e73e069b21d641fa99e8d"
      },
      "summary": "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.",
      "title": "Align data trust wording with event contract",
      "updated_at": "2026-07-23T12:48:05.562Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723124805-align-data-trust-wording-with-event-contract"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T12:56:12.250Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723125612-add-companion-moving-parts-panel-and-version-pin",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M0",
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add Companion moving-parts panel and version-pin repair",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0",
          "M2"
        ]
      },
      "id": "roadmap:20260723125612-add-companion-moving-parts-panel-and-version-pin",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T12:56:12.250Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L126",
        "sha256": "d1539fe26379fc3e4eaafe6c033dc4d6730deb6ee5a8f5b2390bad67e953f890"
      },
      "summary": "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.",
      "title": "Add Companion moving-parts panel and version-pin repair",
      "updated_at": "2026-07-23T12:56:12.250Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723125612-add-companion-moving-parts-panel-and-version-pin"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T12:57:56.122Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723125756-publish-companion-bootstrap-r2",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish Companion bootstrap r2",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723125756-publish-companion-bootstrap-r2",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T12:57:56.122Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L127",
        "sha256": "b6b6c01c3ebe9be9eb868290c24cf2d08beb9ab8ab36367820b173c15760c8ca"
      },
      "summary": "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.",
      "title": "Publish Companion bootstrap r2",
      "updated_at": "2026-07-23T12:57:56.122Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723125756-publish-companion-bootstrap-r2"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T13:02:59.566Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723130259-expose-motion-counters-in-companion-moving-parts",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M2",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Expose motion counters in Companion moving-parts panel",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2",
          "M3"
        ]
      },
      "id": "roadmap:20260723130259-expose-motion-counters-in-companion-moving-parts",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T13:02:59.566Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L128",
        "sha256": "4c3fcee312c204bf24a0348fcb94e788a136986d1131bb707efa6fc153285d78"
      },
      "summary": "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.",
      "title": "Expose motion counters in Companion moving-parts panel",
      "updated_at": "2026-07-23T13:02:59.566Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723130259-expose-motion-counters-in-companion-moving-parts"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T13:08:37.766Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723130837-add-companion-current-read-transport-evidence",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M2",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add Companion current-read transport evidence",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2",
          "M3"
        ]
      },
      "id": "roadmap:20260723130837-add-companion-current-read-transport-evidence",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T13:08:37.766Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L129",
        "sha256": "04e7dfb3ace277d37c914185172121ff2eb7bc6f56cde7d64d35972b5b2ec6af"
      },
      "summary": "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.",
      "title": "Add Companion current-read transport evidence",
      "updated_at": "2026-07-23T13:08:37.766Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723130837-add-companion-current-read-transport-evidence"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T13:12:34.547Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723131234-add-transport-truth-capture-script",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add transport-truth capture script",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723131234-add-transport-truth-capture-script",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T13:12:34.547Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L130",
        "sha256": "6ded45edbff3b8f4440959fa90e698fad98d6ee5171b7ef81614014619c0f33f"
      },
      "summary": "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.",
      "title": "Add transport-truth capture script",
      "updated_at": "2026-07-23T13:12:34.547Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723131234-add-transport-truth-capture-script"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T13:19:49.232Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723131949-add-one-button-companion-transport-capture",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M2",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add one-button Companion transport capture",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2",
          "M3"
        ]
      },
      "id": "roadmap:20260723131949-add-one-button-companion-transport-capture",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T13:19:49.232Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L131",
        "sha256": "d605101b5c812bd7d5cf226c6a60f86e4e5b9a685021b51016a912955f428d50"
      },
      "summary": "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.",
      "title": "Add one-button Companion transport capture",
      "updated_at": "2026-07-23T13:19:49.232Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723131949-add-one-button-companion-transport-capture"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T13:22:47.672Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723132247-list-recent-companion-transport-captures",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M2",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "List recent Companion transport captures",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2",
          "M3"
        ]
      },
      "id": "roadmap:20260723132247-list-recent-companion-transport-captures",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T13:22:47.672Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L132",
        "sha256": "828dd71b3b5a414ee527c404b328ae7d289c2e4c23f660a2cf1ee0cb7c569e6a"
      },
      "summary": "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.",
      "title": "List recent Companion transport captures",
      "updated_at": "2026-07-23T13:22:47.672Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723132247-list-recent-companion-transport-captures"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T13:26:18.882Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723132618-add-capture-verdict-summaries",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M2",
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add capture verdict summaries",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2",
          "M3"
        ]
      },
      "id": "roadmap:20260723132618-add-capture-verdict-summaries",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T13:26:18.882Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L133",
        "sha256": "98edf3aacf361a4085e437bfe62f19ccd4ed3c10b8a16cbe1452e93065e2eda3"
      },
      "summary": "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.",
      "title": "Add capture verdict summaries",
      "updated_at": "2026-07-23T13:26:18.882Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723132618-add-capture-verdict-summaries"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T13:33:12.791Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723133312-add-latest-companion-bootstrap-pointer",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add latest Companion bootstrap pointer",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723133312-add-latest-companion-bootstrap-pointer",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T13:33:12.791Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L134",
        "sha256": "5f15b5785140dd200cd4969f8c6bbd67abdd231e304f14c823a828237a3a3b17"
      },
      "summary": "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.",
      "title": "Add latest Companion bootstrap pointer",
      "updated_at": "2026-07-23T13:33:12.791Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723133312-add-latest-companion-bootstrap-pointer"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T13:44:03.844Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723134403-serve-companion-bootstrap-from-public-p7-artifac",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Serve Companion bootstrap from public P7 artifact lane",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723134403-serve-companion-bootstrap-from-public-p7-artifac",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T13:44:03.844Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L135",
        "sha256": "bda389b342766a6119c74bbbb013b1846b55516dec31f7f1fef5321957a384b1"
      },
      "summary": "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.",
      "title": "Serve Companion bootstrap from public P7 artifact lane",
      "updated_at": "2026-07-23T13:44:03.844Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723134403-serve-companion-bootstrap-from-public-p7-artifac"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T13:45:44.649Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723134544-point-companion-bootstrap-discovery-at-public-p7",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Point Companion bootstrap discovery at public P7 lane",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723134544-point-companion-bootstrap-discovery-at-public-p7",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T13:45:44.649Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L136",
        "sha256": "634afcb983e68608298c56c0933ccb82b4c94e0b5f4c2d344b1b3818abf3e2e6"
      },
      "summary": "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.",
      "title": "Point Companion bootstrap discovery at public P7 lane",
      "updated_at": "2026-07-23T13:45:44.649Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723134544-point-companion-bootstrap-discovery-at-public-p7"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T13:50:58.474Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723135058-show-companion-bootstrap-freshness-locally",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Show Companion bootstrap freshness locally",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260723135058-show-companion-bootstrap-freshness-locally",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T13:50:58.474Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L137",
        "sha256": "12b3048f3833c560d0b06c43fd9836f6f350564578d3adeba8efaec7c2704df8"
      },
      "summary": "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.",
      "title": "Show Companion bootstrap freshness locally",
      "updated_at": "2026-07-23T13:50:58.474Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723135058-show-companion-bootstrap-freshness-locally"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T13:53:48.251Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723135348-add-companion-live-signal-stream",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add Companion live signal stream",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723135348-add-companion-live-signal-stream",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T13:53:48.251Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L138",
        "sha256": "67a990bf775a383451b73e130246c0f4f20229eff7501a75ff75145a331f4867"
      },
      "summary": "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.",
      "title": "Add Companion live signal stream",
      "updated_at": "2026-07-23T13:53:48.251Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723135348-add-companion-live-signal-stream"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T13:56:45.826Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723135645-enrich-companion-transport-capture-summaries",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Enrich Companion transport capture summaries",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723135645-enrich-companion-transport-capture-summaries",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T13:56:45.826Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L139",
        "sha256": "f9b362cfa09b4a4451290d5d9aae990c65c1df76225fbec68b7ef32ec7a70c80"
      },
      "summary": "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.",
      "title": "Enrich Companion transport capture summaries",
      "updated_at": "2026-07-23T13:56:45.826Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723135645-enrich-companion-transport-capture-summaries"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T13:59:17.720Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723135917-read-nested-valheim-heartbeat-peers-in-companion",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Read nested Valheim heartbeat peers in Companion evidence",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723135917-read-nested-valheim-heartbeat-peers-in-companion",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T13:59:17.720Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L140",
        "sha256": "0ff1845c869fe6653e7a5883eaadc3365ecfadbd43d0e51ded2e08b7bd2ceca3"
      },
      "summary": "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.",
      "title": "Read nested Valheim heartbeat peers in Companion evidence",
      "updated_at": "2026-07-23T13:59:17.720Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723135917-read-nested-valheim-heartbeat-peers-in-companion"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T14:02:12.439Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723140212-stamp-release-identity-into-companion-captures",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Stamp release identity into Companion captures",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723140212-stamp-release-identity-into-companion-captures",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T14:02:12.439Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L141",
        "sha256": "04d39ab3f480258e4a47a8c919b920520daee64e7a0d1268cb5b423d4cbbbe90"
      },
      "summary": "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.",
      "title": "Stamp release identity into Companion captures",
      "updated_at": "2026-07-23T14:02:12.439Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723140212-stamp-release-identity-into-companion-captures"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T14:08:54.874Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723140854-add-companion-capture-interpretation",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add Companion capture interpretation",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723140854-add-companion-capture-interpretation",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T14:08:54.874Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L142",
        "sha256": "f5f8c7117ba2e0b2330b8b0fac9044abf3ce30a051bad82024327e6aef1019bc"
      },
      "summary": "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.",
      "title": "Add Companion capture interpretation",
      "updated_at": "2026-07-23T14:08:54.874Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723140854-add-companion-capture-interpretation"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T14:11:40.274Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723141140-add-companion-transport-capture-presets",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add Companion transport capture presets",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723141140-add-companion-transport-capture-presets",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T14:11:40.274Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L143",
        "sha256": "e771be8366a84d97225dce3c5d4904f72e3a2c4e77efbd1d1680aeeeaa0e8e5f"
      },
      "summary": "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.",
      "title": "Add Companion transport capture presets",
      "updated_at": "2026-07-23T14:11:40.274Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723141140-add-companion-transport-capture-presets"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T14:15:56.218Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723141556-add-one-click-companion-evidence-bundles",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add one-click Companion evidence bundles",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723141556-add-one-click-companion-evidence-bundles",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T14:15:56.218Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L144",
        "sha256": "2d01979c148ab02418dcde8ec0073d272c2f1804a639a0a8bc8681b7a6792ea7"
      },
      "summary": "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.",
      "title": "Add one-click Companion evidence bundles",
      "updated_at": "2026-07-23T14:15:56.218Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723141556-add-one-click-companion-evidence-bundles"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T14:20:10.469Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723142010-add-companion-live-transport-readout",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add Companion live transport readout",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723142010-add-companion-live-transport-readout",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T14:20:10.469Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L145",
        "sha256": "b66f26e55a82d9a6f93151d4310a0f81456052648de6f9e41e6fdbbe6a35998a"
      },
      "summary": "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.",
      "title": "Add Companion live transport readout",
      "updated_at": "2026-07-23T14:20:10.469Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723142010-add-companion-live-transport-readout"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T14:25:23.426Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723142523-show-runtime-modpack-truth-on-latest-update-page",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Show runtime modpack truth on latest-update page",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723142523-show-runtime-modpack-truth-on-latest-update-page",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T14:25:23.426Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L146",
        "sha256": "4657d2fe100465f9d09d4994df29c3cbb0fc71ba0cd62f26f87a9273dba381f1"
      },
      "summary": "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.",
      "title": "Show runtime modpack truth on latest-update page",
      "updated_at": "2026-07-23T14:25:23.426Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723142523-show-runtime-modpack-truth-on-latest-update-page"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T14:28:57.980Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723142857-add-redacted-companion-diagnostics",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add redacted Companion diagnostics",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723142857-add-redacted-companion-diagnostics",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T14:28:57.980Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L147",
        "sha256": "3e55cca373dedf5fa97cdda946a74571d77eeff2d1d4474cb1de4bcaa7e5367a"
      },
      "summary": "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.",
      "title": "Add redacted Companion diagnostics",
      "updated_at": "2026-07-23T14:28:57.980Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723142857-add-redacted-companion-diagnostics"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T14:49:35.242Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723144935-explain-read-only-companion-mode",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Explain read-only Companion mode",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723144935-explain-read-only-companion-mode",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T14:49:35.242Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L148",
        "sha256": "5b54a27b9ce40b9dbb1c56b2ed656534606417dafc722736afc19c47d696ef95"
      },
      "summary": "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.",
      "title": "Explain read-only Companion mode",
      "updated_at": "2026-07-23T14:49:35.242Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723144935-explain-read-only-companion-mode"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T15:10:26.205Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723151026-publish-burst-capture-companion-bootstrap",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish burst-capture Companion bootstrap",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260723151026-publish-burst-capture-companion-bootstrap",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T15:10:26.205Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L149",
        "sha256": "24996924344a594b50c9620b62996783afe962e3a275afbb5793512b2c531ba5"
      },
      "summary": "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.",
      "title": "Publish burst-capture Companion bootstrap",
      "updated_at": "2026-07-23T15:10:26.205Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723151026-publish-burst-capture-companion-bootstrap"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T15:24:08.166Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723152408-expose-lumberjacks-motion-lane-state-in-alpha-te",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Expose Lumberjacks motion lane state in alpha telemetry",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723152408-expose-lumberjacks-motion-lane-state-in-alpha-te",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T15:24:08.166Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L150",
        "sha256": "f7653d588f9cd0e8ef1e7dd46b9b5e25a875aadbbecaa6d3d955287091a0072a"
      },
      "summary": "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.",
      "title": "Expose Lumberjacks motion lane state in alpha telemetry",
      "updated_at": "2026-07-23T15:24:08.166Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723152408-expose-lumberjacks-motion-lane-state-in-alpha-te"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T15:26:43.007Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723152643-publish-motion-state-client-pull-modpack",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish motion-state client-pull modpack",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723152643-publish-motion-state-client-pull-modpack",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T15:26:43.007Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L151",
        "sha256": "04e84de0dd39ec1e197aaedb9796ca102365155c344646ea209b097055bf80c5"
      },
      "summary": "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.",
      "title": "Publish motion-state client-pull modpack",
      "updated_at": "2026-07-23T15:26:43.007Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723152643-publish-motion-state-client-pull-modpack"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T15:34:30.876Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723153430-promote-motion-state-gateway-and-current-head-mo",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Promote motion-state Gateway and current-head modpack",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723153430-promote-motion-state-gateway-and-current-head-mo",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T15:34:30.876Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L152",
        "sha256": "a46237100eb34d3f6d67e24579f08bca71c111db2209de9a10dd943d085703e8"
      },
      "summary": "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.",
      "title": "Promote motion-state Gateway and current-head modpack",
      "updated_at": "2026-07-23T15:34:30.876Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723153430-promote-motion-state-gateway-and-current-head-mo"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T15:35:24.500Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723153524-add-a1-a6-adoption-milestone-track-to-the-volunt",
        "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.",
        "kind": "documentation",
        "milestones": [
          "A2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add A1-A6 adoption milestone track to the volunteer roadmap",
        "verification": []
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A2"
        ]
      },
      "id": "roadmap:20260723153524-add-a1-a6-adoption-milestone-track-to-the-volunt",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-23T15:35:24.500Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L153",
        "sha256": "e47261c2c06afdd478475c22425063c50c957cc9a118a0322de87a0281cfeb14"
      },
      "summary": "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.",
      "title": "Add A1-A6 adoption milestone track to the volunteer roadmap",
      "updated_at": "2026-07-23T15:35:24.500Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723153524-add-a1-a6-adoption-milestone-track-to-the-volunt"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T15:36:46.831Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723153646-show-motion-client-state-in-builder-dashboards",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Show motion client state in builder dashboards",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723153646-show-motion-client-state-in-builder-dashboards",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T15:36:46.831Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L154",
        "sha256": "97e2d9247f3d81d8108a825a7fb54a3edcc65d13ae472f14792887b436c0affd"
      },
      "summary": "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.",
      "title": "Show motion client state in builder dashboards",
      "updated_at": "2026-07-23T15:36:46.831Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723153646-show-motion-client-state-in-builder-dashboards"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T15:39:01.620Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723153901-publish-motion-state-companion-bootstrap",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish motion-state Companion bootstrap",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723153901-publish-motion-state-companion-bootstrap",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T15:39:01.620Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L155",
        "sha256": "4d1ec5087e051b17854f7c68002fa5fa7d83726016584ddb41019a6433ef12e4"
      },
      "summary": "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.",
      "title": "Publish motion-state Companion bootstrap",
      "updated_at": "2026-07-23T15:39:01.620Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723153901-publish-motion-state-companion-bootstrap"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T15:40:03.901Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723154003-promote-motion-state-dashboard-gateway",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Promote motion-state dashboard Gateway",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723154003-promote-motion-state-dashboard-gateway",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T15:40:03.901Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L156",
        "sha256": "b523e72811f6767a367f8bad95d3a405b8a8cf4a5cd1eccad5dcc0f8a746876a"
      },
      "summary": "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.",
      "title": "Promote motion-state dashboard Gateway",
      "updated_at": "2026-07-23T15:40:03.901Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723154003-promote-motion-state-dashboard-gateway"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T15:45:53.535Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723154553-session-retro-2026-07-23-and-pending-decisions-r",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Session retro 2026-07-23 and pending-decisions register",
        "verification": []
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A2"
        ]
      },
      "id": "roadmap:20260723154553-session-retro-2026-07-23-and-pending-decisions-r",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-23T15:45:53.535Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L157",
        "sha256": "a2a0000d033ed382dc79a69edbaf853a0374160c1c85c3a3f8491bfdcd0468ab"
      },
      "summary": "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.",
      "title": "Session retro 2026-07-23 and pending-decisions register",
      "updated_at": "2026-07-23T15:45:53.535Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723154553-session-retro-2026-07-23-and-pending-decisions-r"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T15:57:15.193Z",
        "author": "Codex",
        "evidence": [
          "commits 8afe022 and 2fe26e9"
        ],
        "id": "20260723155715-publish-companion-r25-capture-truth-contract",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M1",
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish Companion r25 capture-truth contract",
        "verification": [
          "OMEN and i5 report companion-bootstrap-20260723-r25; a five-second two-client idle smoke produced zero bad samples on both machines."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M1",
          "M7"
        ]
      },
      "id": "roadmap:20260723155715-publish-companion-r25-capture-truth-contract",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-23T15:57:15.193Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L158",
        "sha256": "48df250124fb80dd161ecc3a7de8fca4b95cc7351ea8b81fa410c8a07ccd8f63"
      },
      "summary": "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.",
      "title": "Publish Companion r25 capture-truth contract",
      "updated_at": "2026-07-23T15:57:15.193Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723155715-publish-companion-r25-capture-truth-contract"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T16:02:55.633Z",
        "author": "Codex",
        "evidence": [
          "image digest sha256:4e2262f3a6aa108136239be14dd87b914abe90ff976aafc385ac6e9081e86745"
        ],
        "id": "20260723160255-promote-release-history-gateway-m26",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Promote release-history Gateway m26",
        "verification": [
          "Gateway telemetry reports m26; the public update page reports m26 and lists m17-motionstate first; current modpack manifest remains m17-motionstate."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723160255-promote-release-history-gateway-m26",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T16:02:55.633Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L159",
        "sha256": "908aaefada67aa8d618e1c0032e95a7286791df77dc77621b6c011a2602d690b"
      },
      "summary": "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.",
      "title": "Promote release-history Gateway m26",
      "updated_at": "2026-07-23T16:02:55.633Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723160255-promote-release-history-gateway-m26"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T16:06:34.671Z",
        "author": "Codex",
        "evidence": [
          "image digest sha256:4181681d014844e6476b4a96a05c029b11a93f702a546c40fc985f99bdb13f0c"
        ],
        "id": "20260723160634-make-public-release-history-follow-the-runtime-m",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make public release history follow the runtime modpack pointer",
        "verification": [
          "Gateway m27 passed the image gate and the full container suite; the live page reports m17-motionstate first and retains the prior release row."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723160634-make-public-release-history-follow-the-runtime-m",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T16:06:34.671Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L160",
        "sha256": "f5b41ba4fcf38c42a358cf43abb775bf2e8f7125b607188375f6f4927fe5f035"
      },
      "summary": "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.",
      "title": "Make public release history follow the runtime modpack pointer",
      "updated_at": "2026-07-23T16:06:34.671Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723160634-make-public-release-history-follow-the-runtime-m"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T16:07:41.662Z",
        "author": "Codex",
        "evidence": [
          "commit pending"
        ],
        "id": "20260723160741-verify-runtime-driven-release-history",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Verify runtime-driven release history",
        "verification": [
          "Live page reports Gateway m27, first history row m17-motionstate, and current manifest m17-motionstate."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723160741-verify-runtime-driven-release-history",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-23T16:07:41.662Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L161",
        "sha256": "60c28e856a46a5d840d4f7a8dc17a146414503683daadb8ecf2aece9268bb4b9"
      },
      "summary": "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.",
      "title": "Verify runtime-driven release history",
      "updated_at": "2026-07-23T16:07:41.662Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723160741-verify-runtime-driven-release-history"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T16:10:36.888Z",
        "author": "Codex",
        "evidence": [
          "image digest sha256:eafabacad2842267c09b0a74fd2b4f4a4abe89d9260befe33581045ae65a24dd"
        ],
        "id": "20260723161036-mark-the-runtime-modpack-as-current-in-release-h",
        "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.",
        "kind": "verification",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Mark the runtime modpack as current in release history",
        "verification": [
          "Live P7 m28 page marks m17-motionstate as current; runtime modpack manifest and first history row agree."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723161036-mark-the-runtime-modpack-as-current-in-release-h",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-23T16:10:36.888Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L162",
        "sha256": "76ba1e012999bb9384d1a682613408f78f31650e4ea07c252db450599bcf7234"
      },
      "summary": "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.",
      "title": "Mark the runtime modpack as current in release history",
      "updated_at": "2026-07-23T16:10:36.888Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723161036-mark-the-runtime-modpack-as-current-in-release-h"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T16:11:15.991Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723161115-accept-the-background-git-automation-solo-open-s",
        "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.",
        "kind": "decision",
        "milestones": [
          "A2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Accept the background git automation (solo open-source sample)",
        "verification": []
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "A2"
        ]
      },
      "id": "roadmap:20260723161115-accept-the-background-git-automation-solo-open-s",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T16:11:15.991Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L163",
        "sha256": "9691e3d873016e920e6f8ffcb4439c6179065c10be55310f99d408f3ffff7dc0"
      },
      "summary": "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.",
      "title": "Accept the background git automation (solo open-source sample)",
      "updated_at": "2026-07-23T16:11:15.991Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723161115-accept-the-background-git-automation-solo-open-s"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T16:44:07.477Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723164407-add-bounded-companion-driven-motion-test-control",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add bounded Companion-driven motion test control and honest counter classification",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723164407-add-bounded-companion-driven-motion-test-control",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T16:44:07.477Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L164",
        "sha256": "98132b36a4111111870e6f485bc58dcd92a0bee3ee4fbcca08e4fd3aebab8327"
      },
      "summary": "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.",
      "title": "Add bounded Companion-driven motion test control and honest counter classification",
      "updated_at": "2026-07-23T16:44:07.477Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723164407-add-bounded-companion-driven-motion-test-control"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T17:31:08.210Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723173108-add-zdo-object-fallback-for-lumberjacks-motion-p",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add ZDO-object fallback for Lumberjacks motion presentation lookup",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723173108-add-zdo-object-fallback-for-lumberjacks-motion-p",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T17:31:08.210Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L165",
        "sha256": "ab82412f72a1110ceb87b5349f0f747d119473342f5086630b5b421c3e36a83d"
      },
      "summary": "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.",
      "title": "Add ZDO-object fallback for Lumberjacks motion presentation lookup",
      "updated_at": "2026-07-23T17:31:08.210Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723173108-add-zdo-object-fallback-for-lumberjacks-motion-p"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T17:42:59.821Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723174259-cut-and-align-m19-zdo-resolution-release-across-",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Cut and align m19 ZDO-resolution release across Gateway, server, clients, and Companion lanes",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723174259-cut-and-align-m19-zdo-resolution-release-across-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T17:42:59.821Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L166",
        "sha256": "72065065dfcfa0d18be7feb7cb100294d042748aa42b5c7e26329ae277204aba"
      },
      "summary": "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.",
      "title": "Cut and align m19 ZDO-resolution release across Gateway, server, clients, and Companion lanes",
      "updated_at": "2026-07-23T17:42:59.821Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723174259-cut-and-align-m19-zdo-resolution-release-across-"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T17:55:31.411Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723175531-deploy-m20-player-object-index-fallback-and-comp",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Deploy m20 player-object index fallback and Companion r20",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723175531-deploy-m20-player-object-index-fallback-and-comp",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T17:55:31.411Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L167",
        "sha256": "c4f2879cca4f2b8af189fad5597569a45e2b40f93ed8f5d940bee79f6fd13a66"
      },
      "summary": "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.",
      "title": "Deploy m20 player-object index fallback and Companion r20",
      "updated_at": "2026-07-23T17:55:31.411Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723175531-deploy-m20-player-object-index-fallback-and-comp"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T18:08:06.460Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723180806-added-preemptive-alpha-seam-receipts-client-loca",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Added preemptive alpha seam receipts: client-local motion readiness is separated from Gateway relay deltas, and the motion mod reports direct ZDO, ZDO-object, player-index, unresolved, and index-rebuild resolution counters.",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723180806-added-preemptive-alpha-seam-receipts-client-loca",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T18:08:06.460Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L168",
        "sha256": "6c76bd4ba50dabe7b302e4bf5fbf0415c5438d860e96d21920b0ec7191d57af0"
      },
      "summary": "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.",
      "title": "Added preemptive alpha seam receipts: client-local motion readiness is separated from Gateway relay deltas, and the motion mod reports direct ZDO, ZDO-object, player-index, unresolved, and index-rebuild resolution counters.",
      "updated_at": "2026-07-23T18:08:06.460Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723180806-added-preemptive-alpha-seam-receipts-client-loca"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T18:43:01.559Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723184301-name-valheim-heartbeat-age-separately-from-rtt",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Name Valheim heartbeat age separately from RTT",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723184301-name-valheim-heartbeat-age-separately-from-rtt",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T18:43:01.559Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L169",
        "sha256": "b8e92dee0aea9a8d52cb7bfb7cc98b21c26cf3be052dabd2ae12df7bca23fe40"
      },
      "summary": "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.",
      "title": "Name Valheim heartbeat age separately from RTT",
      "updated_at": "2026-07-23T18:43:01.559Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723184301-name-valheim-heartbeat-age-separately-from-rtt"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T21:08:30.776Z",
        "author": "Codex",
        "evidence": [
          "network/mod/ComfyNetworkSense/ComfyNetworkSense.cs",
          "tools/modpack/New-AlphaModpack.ps1"
        ],
        "id": "20260723210830-cut-heartbeat-age-mod-release",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Cut heartbeat-age mod release",
        "verification": [
          "dotnet build network/mod/ComfyNetworkSense/ComfyNetworkSense.csproj -c Release succeeded",
          "Test-GatewayImageRelease.ps1 confirmed lumberjacks-gateway:m29-heartbeatage-20260723-r1 admits m29-heartbeatage-20260723-r1",
          "New-AlphaModpack.ps1 produced Comfy-P7-Alpha-Mods-m29-heartbeatage-20260723-r1.zip sha256:c192ba6980286899243d915d728dd6b3a870ac9cd9243d549ed9d99ffa7f7d2b"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723210830-cut-heartbeat-age-mod-release",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T21:08:30.776Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L170",
        "sha256": "c35e15202ed5127c508a721080e75de9ce8898697332d29a7b31f1760eaacda6"
      },
      "summary": "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.",
      "title": "Cut heartbeat-age mod release",
      "updated_at": "2026-07-23T21:08:30.776Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723210830-cut-heartbeat-age-mod-release"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T21:17:39.796Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723211739-deploy-heartbeat-age-release-to-p7-and-omen",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Deploy heartbeat-age release to P7 and OMEN",
        "verification": [
          "Promote-GatewayImage.ps1 reported status=promoted and running image sha256:7de2f45200b0da97f34dbce8b9f08b70ea931c6bfe1a991e8b3d568e706d5a35",
          "deploy-network-sense.ps1 reported ModReady=True and ServerReady=True with runtime and cold-start DLL sha256 697f318f9dda7d5273253b787549de16c89abc9f1c365970c8944d917bc08424",
          "Public /api/v0/valheim/modpack/manifest reports release and mod_release m29-heartbeatage-20260723-r1 with package sha256 2b3cbb54eccc1860a3e93bc01586c17878cbc5e5ffd6e7d37f0c51cbca256475",
          "OMEN Companion install returned ok=true for release m29-heartbeatage-20260723-r1",
          "tools/i5/Test-I5Link.ps1 reported i5 lane DOWN; offline is normal for the roaming laptop"
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723211739-deploy-heartbeat-age-release-to-p7-and-omen",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T21:17:39.796Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L171",
        "sha256": "df3e9e84bfe7674d71d2803c7bfbbf2da61e1c129509120ed3922f418c099b3c"
      },
      "summary": "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.",
      "title": "Deploy heartbeat-age release to P7 and OMEN",
      "updated_at": "2026-07-23T21:17:39.796Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723211739-deploy-heartbeat-age-release-to-p7-and-omen"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T21:21:28.021Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723212128-smoke-m29-telemetry-without-players",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Smoke m29 telemetry without players",
        "verification": [
          "Companion diagnostics reported local installed_release m29-heartbeatage-20260723-r1 and public Gateway m29-heartbeatage-20260723-r1",
          "Transport capture 20260723-212034-m29-post-companion-rebuild-smoke returned bad_sample_count=0, verdict no_peer_window, and capture_identity.gateway_version m29-heartbeatage-20260723-r1",
          "The same capture emitted final_local_motion.server_ping_age_ms and server_ping_age_jitter_ms instead of legacy-only rtt/jitter names",
          "i5 remained offline, so no two-client or i5 install proof was attempted"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723212128-smoke-m29-telemetry-without-players",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-23T21:21:28.021Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L172",
        "sha256": "d80384bf6fc156632b381ef4ca9062c5c3659461b218e42be6e4f6e45e1fe934"
      },
      "summary": "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.",
      "title": "Smoke m29 telemetry without players",
      "updated_at": "2026-07-23T21:21:28.021Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723212128-smoke-m29-telemetry-without-players"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T21:33:31.817Z",
        "author": "Codex",
        "evidence": [
          "tests/Game.Gateway.Tests/ValheimMotionRelayTests.cs"
        ],
        "id": "20260723213331-add-synthetic-valheim-motion-relay-proof",
        "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.",
        "kind": "verification",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add synthetic Valheim motion relay proof",
        "verification": [
          "Docker .NET 9 SDK focused Gateway test run passed ValheimMotionRelayTests: 6 total, 6 passing."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260723213331-add-synthetic-valheim-motion-relay-proof",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-23T21:33:31.817Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L173",
        "sha256": "0eafedd811ad099b1a39d0feea8745ee12cf941969baf6c7cef28c7fef312fb9"
      },
      "summary": "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.",
      "title": "Add synthetic Valheim motion relay proof",
      "updated_at": "2026-07-23T21:33:31.817Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723213331-add-synthetic-valheim-motion-relay-proof"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T22:06:12.757Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723220612-add-bounded-companion-apply-role-control-for-wav",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add bounded Companion apply-role control for Wave 0 live gate",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260723220612-add-bounded-companion-apply-role-control-for-wav",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T22:06:12.757Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L174",
        "sha256": "e563ee9e830b33e0ee6504762ceeaeb6ea5c4373148fb7a3fbbb7cb0329c23ae"
      },
      "summary": "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.",
      "title": "Add bounded Companion apply-role control for Wave 0 live gate",
      "updated_at": "2026-07-23T22:06:12.757Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723220612-add-bounded-companion-apply-role-control-for-wav"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T22:10:53.783Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723221053-cut-m30-role-control-release-candidate",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Cut m30 role-control release candidate",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260723221053-cut-m30-role-control-release-candidate",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T22:10:53.783Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L175",
        "sha256": "c96fc36346f1d9c2e976eb7d8375a1bb3554cf4d9fea741e3223961734adebf6"
      },
      "summary": "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.",
      "title": "Cut m30 role-control release candidate",
      "updated_at": "2026-07-23T22:10:53.783Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723221053-cut-m30-role-control-release-candidate"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T22:14:43.767Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723221443-record-m30-role-control-release-candidate-artifa",
        "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.",
        "kind": "verification",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Record m30 role-control release candidate artifacts",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260723221443-record-m30-role-control-release-candidate-artifa",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-23T22:14:43.767Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L176",
        "sha256": "f000e4c22cdb1d75daced18c59c1a5be2e94655512edf9c89a559cbffd9ae015"
      },
      "summary": "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.",
      "title": "Record m30 role-control release candidate artifacts",
      "updated_at": "2026-07-23T22:14:43.767Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723221443-record-m30-role-control-release-candidate-artifa"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T22:23:03.581Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723222303-deploy-m30-role-control-release-to-p7-omen-and-i",
        "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.",
        "kind": "deployment",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Deploy m30 role-control release to P7, OMEN, and i5",
        "verification": []
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260723222303-deploy-m30-role-control-release-to-p7-omen-and-i",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-23T22:23:03.581Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L177",
        "sha256": "482929edc072a2e6480389d2db3f62abec7c34976fa63c318d97772a611f3ae1"
      },
      "summary": "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.",
      "title": "Deploy m30 role-control release to P7, OMEN, and i5",
      "updated_at": "2026-07-23T22:23:03.581Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723222303-deploy-m30-role-control-release-to-p7-omen-and-i"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T22:31:56.761Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723223156-align-living-roadmap-current-release-with-m30-ru",
        "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.",
        "kind": "verification",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Align living roadmap current release with m30 runtime",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260723223156-align-living-roadmap-current-release-with-m30-ru",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-23T22:31:56.761Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L178",
        "sha256": "398ffd601ba5a2cb91c4d3339177266b08bb43652d4aaa666aec757de1646c8f"
      },
      "summary": "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.",
      "title": "Align living roadmap current release with m30 runtime",
      "updated_at": "2026-07-23T22:31:56.761Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723223156-align-living-roadmap-current-release-with-m30-ru"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T22:43:05.275Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723224305-record-p7-cost-hygiene-infra-defaults",
        "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.",
        "kind": "documentation",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Record P7 cost-hygiene infra defaults",
        "verification": []
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260723224305-record-p7-cost-hygiene-infra-defaults",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-23T22:43:05.275Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L179",
        "sha256": "475caeb41d09c98459c207f6bb3d01db76933ccac906b5d462d1dba706bed3a1"
      },
      "summary": "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.",
      "title": "Record P7 cost-hygiene infra defaults",
      "updated_at": "2026-07-23T22:43:05.275Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723224305-record-p7-cost-hygiene-infra-defaults"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T22:58:51.950Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723225851-expose-wave-0-live-gate-status-in-companion",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Expose Wave 0 live-gate status in Companion",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260723225851-expose-wave-0-live-gate-status-in-companion",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T22:58:51.950Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L180",
        "sha256": "d195e27e68bdcf4b0ea81684d7b5dfb1a062ecb35e8bed8a9bf65fe0be9f1cb9"
      },
      "summary": "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.",
      "title": "Expose Wave 0 live-gate status in Companion",
      "updated_at": "2026-07-23T22:58:51.950Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723225851-expose-wave-0-live-gate-status-in-companion"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T23:03:12.403Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723230312-publish-companion-bootstrap-with-wave-0-panel",
        "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.",
        "kind": "verification",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish Companion bootstrap with Wave 0 panel",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260723230312-publish-companion-bootstrap-with-wave-0-panel",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-23T23:03:12.403Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L181",
        "sha256": "7d03f0ca89fd12eb625926f817679e257c24ceb00db51be755af6d4cd2bfc26a"
      },
      "summary": "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.",
      "title": "Publish Companion bootstrap with Wave 0 panel",
      "updated_at": "2026-07-23T23:03:12.403Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723230312-publish-companion-bootstrap-with-wave-0-panel"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T23:14:55.618Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723231455-expose-complete-wave-0-command-chain-in-companio",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Expose complete Wave 0 command chain in Companion",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260723231455-expose-complete-wave-0-command-chain-in-companio",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T23:14:55.618Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L182",
        "sha256": "73110fb19884722c2cc1809a5b538993a517660c4b56c49226289e8ef1bd06db"
      },
      "summary": "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.",
      "title": "Expose complete Wave 0 command chain in Companion",
      "updated_at": "2026-07-23T23:14:55.618Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723231455-expose-complete-wave-0-command-chain-in-companio"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T23:17:16.717Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723231716-publish-companion-bootstrap-with-complete-wave-0",
        "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.",
        "kind": "verification",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish Companion bootstrap with complete Wave 0 command chain",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260723231716-publish-companion-bootstrap-with-complete-wave-0",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-23T23:17:16.717Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L183",
        "sha256": "351fd8b401be3a4b05740d29a4eed8a53f528999a291bdc7e1af06e791e62899"
      },
      "summary": "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.",
      "title": "Publish Companion bootstrap with complete Wave 0 command chain",
      "updated_at": "2026-07-23T23:17:16.717Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723231716-publish-companion-bootstrap-with-complete-wave-0"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-23T23:26:24.137Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723232624-expose-wave-0-defect-fallback-in-companion",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Expose Wave 0 defect fallback in Companion",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260723232624-expose-wave-0-defect-fallback-in-companion",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-23T23:26:24.137Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L184",
        "sha256": "29318c65bfe24473675d448cbfa9e6c16f9bceefae4d097da543bc0436870f6e"
      },
      "summary": "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.",
      "title": "Expose Wave 0 defect fallback in Companion",
      "updated_at": "2026-07-23T23:26:24.137Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723232624-expose-wave-0-defect-fallback-in-companion"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-23T23:31:15.931Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260723233115-publish-companion-bootstrap-with-wave-0-defect-f",
        "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.",
        "kind": "verification",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish Companion bootstrap with Wave 0 defect fallback",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260723233115-publish-companion-bootstrap-with-wave-0-defect-f",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-23T23:31:15.931Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L185",
        "sha256": "b017c8b71e99261909d56546d033e4a18fe2890c69f3fc28c02e8319b69ffd65"
      },
      "summary": "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.",
      "title": "Publish Companion bootstrap with Wave 0 defect fallback",
      "updated_at": "2026-07-23T23:31:15.931Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260723233115-publish-companion-bootstrap-with-wave-0-defect-f"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T01:51:10.289Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724015110-add-companion-wave-0-handoff-packet",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add Companion Wave 0 handoff packet",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260724015110-add-companion-wave-0-handoff-packet",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T01:51:10.289Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L186",
        "sha256": "751d88bd198becf5479381d5fb8081277f94443258dcddfb91c95f92971ef21d"
      },
      "summary": "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.",
      "title": "Add Companion Wave 0 handoff packet",
      "updated_at": "2026-07-24T01:51:10.289Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724015110-add-companion-wave-0-handoff-packet"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-24T01:57:29.333Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724015729-publish-companion-bootstrap-r24",
        "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.",
        "kind": "verification",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish Companion bootstrap r24",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260724015729-publish-companion-bootstrap-r24",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-24T01:57:29.333Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L187",
        "sha256": "8ddce90b01a8c05c9b3c743e762ef76b8a79631b86b7fbf38935bd6fa7a98e69"
      },
      "summary": "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.",
      "title": "Publish Companion bootstrap r24",
      "updated_at": "2026-07-24T01:57:29.333Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724015729-publish-companion-bootstrap-r24"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T02:18:14.243Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724021814-add-i5-docker-recovery-lane",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add i5 Docker recovery lane",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260724021814-add-i5-docker-recovery-lane",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T02:18:14.243Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L188",
        "sha256": "3538d887d1722464d6f4fcd423aceb52b663c4521f05ede688e91d2c761b8a0c"
      },
      "summary": "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.",
      "title": "Add i5 Docker recovery lane",
      "updated_at": "2026-07-24T02:18:14.243Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724021814-add-i5-docker-recovery-lane"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T02:30:25.219Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724023025-add-wave-0-auto-wait-live-gate",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add Wave 0 auto-wait live gate",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260724023025-add-wave-0-auto-wait-live-gate",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T02:30:25.219Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L189",
        "sha256": "16304f31907c621290d8001b456209e6349fa0decae134c6ef2ad6ca4928b45c"
      },
      "summary": "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.",
      "title": "Add Wave 0 auto-wait live gate",
      "updated_at": "2026-07-24T02:30:25.219Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724023025-add-wave-0-auto-wait-live-gate"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-24T02:34:24.555Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724023424-publish-companion-bootstrap-r26-with-operator-sc",
        "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.",
        "kind": "verification",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish Companion bootstrap r26 with operator scripts",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260724023424-publish-companion-bootstrap-r26-with-operator-sc",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-24T02:34:24.555Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L190",
        "sha256": "161fa2e197abb73e0819b2f6128e444372722145f7e7a4a8bfcfb3289ad4286b"
      },
      "summary": "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.",
      "title": "Publish Companion bootstrap r26 with operator scripts",
      "updated_at": "2026-07-24T02:34:24.555Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724023424-publish-companion-bootstrap-r26-with-operator-sc"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T02:41:16.459Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724024116-verify-companion-bootstrap-command-coverage",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Verify Companion bootstrap command coverage",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260724024116-verify-companion-bootstrap-command-coverage",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T02:41:16.459Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L191",
        "sha256": "36a5018917425d89ed4c75a7d76be417910e7a318e29d1032db2018d15cd1aff"
      },
      "summary": "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.",
      "title": "Verify Companion bootstrap command coverage",
      "updated_at": "2026-07-24T02:41:16.459Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724024116-verify-companion-bootstrap-command-coverage"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-24T02:53:49.626Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724025349-refresh-public-roadmap-current-release-truth",
        "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.",
        "kind": "documentation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Refresh public roadmap current release truth",
        "verification": [
          "P7 manifest and i5 link checks verified r26 bootstrap availability and the awake i5 lane before the roadmap refresh."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260724025349-refresh-public-roadmap-current-release-truth",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-24T02:53:49.626Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L192",
        "sha256": "41f41721817ecf7d59f10761d4b6a872412b739403064fc4d45d619d0628df65"
      },
      "summary": "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.",
      "title": "Refresh public roadmap current release truth",
      "updated_at": "2026-07-24T02:53:49.626Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724025349-refresh-public-roadmap-current-release-truth"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T03:00:37.326Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724030037-add-wave-0-roadmap-freshness-gate",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add Wave 0 roadmap freshness gate",
        "verification": [
          "Test-Wave0RoadmapFreshness.ps1 returned wave0_roadmap_freshness_passed, and Test-Wave0Prelive.ps1 returned ready_for_derek_two_client_join with the new roadmap-freshness step included."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260724030037-add-wave-0-roadmap-freshness-gate",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T03:00:37.326Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L193",
        "sha256": "ca1a06557bf8275c7f708aa9214246cdda976081a4c070abdc78b876a6ed35e2"
      },
      "summary": "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.",
      "title": "Add Wave 0 roadmap freshness gate",
      "updated_at": "2026-07-24T03:00:37.326Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724030037-add-wave-0-roadmap-freshness-gate"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T03:08:39.964Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724030839-expand-wave-0-return-packet-evidence",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Expand Wave 0 return packet evidence",
        "verification": [
          "New-Wave0ReturnPacket.ps1 generated ready_for_derek_two_client_join with the expanded evidence rows, and Test-Wave0Prelive.ps1 returned ready_for_derek_two_client_join using the expanded return packet."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260724030839-expand-wave-0-return-packet-evidence",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T03:08:39.964Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L194",
        "sha256": "3f59de530228abe5991d6fbd7d9ba707d569414bdc9d470ffcb88a204d2834de"
      },
      "summary": "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.",
      "title": "Expand Wave 0 return packet evidence",
      "updated_at": "2026-07-24T03:08:39.964Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724030839-expand-wave-0-return-packet-evidence"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T03:13:12.990Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724031312-classify-wave-0-defect-fallback",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Classify Wave 0 defect fallback",
        "verification": [
          "Test-Wave0DefectPacketFixtures.ps1 classified the bad role-reversal fixture as role_reversal_failed, and Test-Wave0Prelive.ps1 returned ready_for_derek_two_client_join with the classifier command in the return packet."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260724031312-classify-wave-0-defect-fallback",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T03:13:12.990Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L195",
        "sha256": "e045e012174afdb5915f40a742ef3a078d060e1f298314d266100a109508f7be"
      },
      "summary": "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.",
      "title": "Classify Wave 0 defect fallback",
      "updated_at": "2026-07-24T03:13:12.990Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724031312-classify-wave-0-defect-fallback"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T04:41:27.757Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724044127-parameterize-p7-valheim-world-backups",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Parameterize P7 Valheim world backups",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260724044127-parameterize-p7-valheim-world-backups",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T04:41:27.757Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L196",
        "sha256": "4afb98ca3d5f3f19782ff6446916278c781981f91f9f7a2dd15698406a32392d"
      },
      "summary": "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.",
      "title": "Parameterize P7 Valheim world backups",
      "updated_at": "2026-07-24T04:41:27.757Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724044127-parameterize-p7-valheim-world-backups"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T07:04:36.837Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724070436-start-the-deterministic-m7-authority-experiment-",
        "impact": "Adds synthetic E00-E03 receipts, bounded failure evidence, linked policy decisions, and discovery status tooling before any live authority promotion.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Start the deterministic M7 authority experiment lab",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260724070436-start-the-deterministic-m7-authority-experiment-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T07:04:36.837Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L197",
        "sha256": "4cb875ee7f46841f1af044b80d0b6bd1df200d09915bc527132e75420326185c"
      },
      "summary": "Adds synthetic E00-E03 receipts, bounded failure evidence, linked policy decisions, and discovery status tooling before any live authority promotion.",
      "title": "Start the deterministic M7 authority experiment lab",
      "updated_at": "2026-07-24T07:04:36.837Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724070436-start-the-deterministic-m7-authority-experiment-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T07:37:27.968Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724073727-add-gateway-backed-m7-authority-experiment-drive",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add Gateway-backed M7 authority experiment drivers",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260724073727-add-gateway-backed-m7-authority-experiment-drive",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T07:37:27.968Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L198",
        "sha256": "390a06935238734d539aab9f91f5bb35f1161a09fe6ee0174e092183207530c5"
      },
      "summary": "Runs E02 recipient queue and E03 motion relay through real Gateway WebSocket, WAL restart, and bound UDP seams before native capture or P7 promotion.",
      "title": "Add Gateway-backed M7 authority experiment drivers",
      "updated_at": "2026-07-24T07:37:27.968Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724073727-add-gateway-backed-m7-authority-experiment-drive"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T08:15:08.198Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724081508-add-bounded-disposable-lab-client-automation-mcp",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add bounded disposable lab-client automation, MCP motion mailbox, and native candidate replay",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260724081508-add-bounded-disposable-lab-client-automation-mcp",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T08:15:08.198Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L199",
        "sha256": "805e10e72246782a3ce769d86941d5ab8eeb43a5d3983a492bed336a7b364d36"
      },
      "summary": "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.",
      "title": "Add bounded disposable lab-client automation, MCP motion mailbox, and native candidate replay",
      "updated_at": "2026-07-24T08:15:08.198Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724081508-add-bounded-disposable-lab-client-automation-mcp"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T08:34:46.254Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724083446-add-operator-touch-gate-and-closed-lab-capture-w",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add operator-touch gate and closed lab capture wrapper",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260724083446-add-operator-touch-gate-and-closed-lab-capture-w",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T08:34:46.254Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L200",
        "sha256": "d8ccafecb58565a5242a33f10ec55e723e1cf9cb629036ce97064209fa0db61a"
      },
      "summary": "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.",
      "title": "Add operator-touch gate and closed lab capture wrapper",
      "updated_at": "2026-07-24T08:34:46.254Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724083446-add-operator-touch-gate-and-closed-lab-capture-w"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T08:52:14.069Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724085214-add-atomic-multi-client-disposable-lab-coordinat",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add atomic multi-client disposable lab coordinator",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260724085214-add-atomic-multi-client-disposable-lab-coordinat",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T08:52:14.069Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L201",
        "sha256": "809e8507e46783c1606ff894bfa2af759cdb8285b25d90388961525b33f79a74"
      },
      "summary": "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.",
      "title": "Add atomic multi-client disposable lab coordinator",
      "updated_at": "2026-07-24T08:52:14.069Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724085214-add-atomic-multi-client-disposable-lab-coordinat"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T09:12:01.017Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724091201-add-a-low-touch-physical-two-client-feel-window",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add a low-touch physical two-client feel window",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260724091201-add-a-low-touch-physical-two-client-feel-window",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T09:12:01.017Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L202",
        "sha256": "af92e79672ba0b9087debcebdb0eb28b60508bbb9b550b6af929c296e6800ea1"
      },
      "summary": "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.",
      "title": "Add a low-touch physical two-client feel window",
      "updated_at": "2026-07-24T09:12:01.017Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724091201-add-a-low-touch-physical-two-client-feel-window"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T09:25:47.355Z",
        "author": "Codex",
        "evidence": [
          "LICENSE.md"
        ],
        "id": "20260724092547-adopt-community-first-source-licensing-boundarie",
        "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.",
        "kind": "decision",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Adopt community-first source licensing boundaries",
        "verification": [
          "Root and standalone Lumberjacks license terms agree on community, commercial, source-offer, and Change Date boundaries."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260724092547-adopt-community-first-source-licensing-boundarie",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-24T09:25:47.355Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L203",
        "sha256": "b9b1b7543e9348c90286b82a97eb520531ba3e752b6588846836b26db2f781b2"
      },
      "summary": "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.",
      "title": "Adopt community-first source licensing boundaries",
      "updated_at": "2026-07-24T09:25:47.355Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724092547-adopt-community-first-source-licensing-boundarie"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T09:46:23.191Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724094623-make-the-local-companion-a-source-aware-reconstr",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make the local Companion a source-aware reconstruction workbench",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260724094623-make-the-local-companion-a-source-aware-reconstr",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T09:46:23.191Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L204",
        "sha256": "1685751fdc7bea9f59737e973beffc9ec94252c0e7c89d30f626bd314f8c679e"
      },
      "summary": "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.",
      "title": "Make the local Companion a source-aware reconstruction workbench",
      "updated_at": "2026-07-24T09:46:23.191Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724094623-make-the-local-companion-a-source-aware-reconstr"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T10:14:33.358Z",
        "author": "Codex",
        "evidence": [
          "LICENSE.md"
        ],
        "id": "20260724101433-allow-small-community-stewards-to-earn-bounded-p",
        "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.",
        "kind": "decision",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Allow small community stewards to earn bounded profit",
        "verification": [
          "Root and standalone Lumberjacks licenses carry matching steward, scale, revenue, source-offer, aggregation, and large-organization boundaries."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260724101433-allow-small-community-stewards-to-earn-bounded-p",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-24T10:14:33.358Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L205",
        "sha256": "d7601eb7ec67a04b6c6b362c2b12269e068f9a04d6fa719de1f5921b67ea2b22"
      },
      "summary": "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.",
      "title": "Allow small community stewards to earn bounded profit",
      "updated_at": "2026-07-24T10:14:33.358Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724101433-allow-small-community-stewards-to-earn-bounded-p"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T11:45:32.371Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724114532-publish-the-transparent-stewardship-framework",
        "impact": "Defines public evidence, private-person defaults, configurable delayed aggregate trends, and a narrow independent-review path for community trust.",
        "kind": "decision",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish the transparent stewardship framework",
        "verification": []
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260724114532-publish-the-transparent-stewardship-framework",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-24T11:45:32.371Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L206",
        "sha256": "ff32e2e729cf4ea9f157f067aeaedf468df6cec18850c116948fe6887cd2c5b0"
      },
      "summary": "Defines public evidence, private-person defaults, configurable delayed aggregate trends, and a narrow independent-review path for community trust.",
      "title": "Publish the transparent stewardship framework",
      "updated_at": "2026-07-24T11:45:32.371Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724114532-publish-the-transparent-stewardship-framework"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T12:07:54.388Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260724120754-add-quiet-provenance-and-license-links-to-public",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "A1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add quiet provenance and license links to public surfaces",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A1"
        ]
      },
      "id": "roadmap:20260724120754-add-quiet-provenance-and-license-links-to-public",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T12:07:54.388Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L207",
        "sha256": "6ddfb5eadd5dcbf1bf21b6b0db70aba224853f5378922403399f3024f3c353a4"
      },
      "summary": "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.",
      "title": "Add quiet provenance and license links to public surfaces",
      "updated_at": "2026-07-24T12:07:54.388Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724120754-add-quiet-provenance-and-license-links-to-public"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-24T13:41:25.097Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/experiments/creative-runtime/cre-e01-runtime-envelope/runs/pure-20260724T133947Z/receipt.json"
        ],
        "id": "20260724134125-add-a-deterministic-creative-runtime-envelope-ex",
        "impact": "Proves bounded selective degradation and semantic routing in pure lab runs without changing Valheim authority.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add a deterministic creative runtime envelope experiment",
        "verification": [
          "Two 38-row receipts validated, normalized comparison matched, and AuthorityLab tests passed 7 of 7."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260724134125-add-a-deterministic-creative-runtime-envelope-ex",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-24T13:41:25.097Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L208",
        "sha256": "bbfa9ec6473dd9e47738ed30a1c1e44b79b1ee10737523bcb29c4de24a4890fd"
      },
      "summary": "Proves bounded selective degradation and semantic routing in pure lab runs without changing Valheim authority.",
      "title": "Add a deterministic creative runtime envelope experiment",
      "updated_at": "2026-07-24T13:41:25.097Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724134125-add-a-deterministic-creative-runtime-envelope-ex"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-24T14:13:58.582Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/experiments/creative-runtime/cre-e02-gateway-pressure-route/runs/gateway_udp-20260724T141258Z/receipt.json"
        ],
        "id": "20260724141358-route-the-runtime-envelope-through-real-gateway-",
        "impact": "Proves selected presentation work reaches WebSocket fallback and bound UDP while deferred and dropped work remains absent, without changing Valheim authority.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Route the runtime envelope through real Gateway transport",
        "verification": [
          "Both 47-row receipts validated; each path delivered 9 of 9 selected frames in sequence and suppressed 23 of 23 non-selected decisions."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260724141358-route-the-runtime-envelope-through-real-gateway-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-24T14:13:58.582Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L209",
        "sha256": "708f63ccb5f44f7ede95d46177a9236db1f748047c12fbe4bfea442c354cd5a7"
      },
      "summary": "Proves selected presentation work reaches WebSocket fallback and bound UDP while deferred and dropped work remains absent, without changing Valheim authority.",
      "title": "Route the runtime envelope through real Gateway transport",
      "updated_at": "2026-07-24T14:13:58.582Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260724141358-route-the-runtime-envelope-through-real-gateway-"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-25T02:46:08.634Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260725024608-measured-motion-fault-and-fanout-behavior",
        "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.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Measured motion fault and fanout behavior",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260725024608-measured-motion-fault-and-fanout-behavior",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-25T02:46:08.634Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L210",
        "sha256": "03e45bd3435bbbf91d980c79e17f80048d87801366a025b29777de4977fb8e61"
      },
      "summary": "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.",
      "title": "Measured motion fault and fanout behavior",
      "updated_at": "2026-07-25T02:46:08.634Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260725024608-measured-motion-fault-and-fanout-behavior"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-25T02:56:25.740Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260725025625-bounded-transient-presentation-consumption",
        "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.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Bounded transient presentation consumption",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260725025625-bounded-transient-presentation-consumption",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-25T02:56:25.740Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L211",
        "sha256": "a978c4b628df59fe7c43f51540d4c5035731a8f7ed082cfc54d37bbca7a48356"
      },
      "summary": "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.",
      "title": "Bounded transient presentation consumption",
      "updated_at": "2026-07-25T02:56:25.740Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260725025625-bounded-transient-presentation-consumption"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-25T03:06:12.715Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260725030612-modeled-the-current-motion-apply-loop",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Modeled the current motion apply loop",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260725030612-modeled-the-current-motion-apply-loop",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-25T03:06:12.715Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L212",
        "sha256": "721682608ba430e5308478641386222561c26d5e9624491a79b4f07a613069e3"
      },
      "summary": "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.",
      "title": "Modeled the current motion apply loop",
      "updated_at": "2026-07-25T03:06:12.715Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260725030612-modeled-the-current-motion-apply-loop"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-25T03:20:25.626Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/experiments/creative-runtime/cre-e06-motion-phase-rollups/experiment.md"
        ],
        "id": "20260725032025-add-bounded-client-motion-phase-rollups",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add bounded client motion phase rollups",
        "verification": [
          "ComfyNetworkSense Release build passed; CRE-E06 fixture assertions passed; two-client phase orchestration dry-run passed."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260725032025-add-bounded-client-motion-phase-rollups",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-25T03:20:25.626Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L213",
        "sha256": "d2d169f925a388bf41a5b6611a76bea468cc3678e53cd54aec0099b8835a1c29"
      },
      "summary": "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.",
      "title": "Add bounded client motion phase rollups",
      "updated_at": "2026-07-25T03:20:25.626Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260725032025-add-bounded-client-motion-phase-rollups"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-25T03:37:54.639Z",
        "author": "Codex",
        "evidence": [
          "docs/roadmap/m31-motionphase-client-package.json"
        ],
        "id": "20260725033754-publish-motion-phase-client-package",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish motion phase client package",
        "verification": [
          "Public manifest matched m31 package SHA-256 ef5ced82655f; both Companion installs succeeded; both client DLLs matched SHA-256 1e875984fde1; both games remained closed."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260725033754-publish-motion-phase-client-package",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-25T03:37:54.639Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L214",
        "sha256": "438d8c6f6eb6546f431d7eff572a61b6c2fd7ce7f66472105cf3b3e014e7c90f"
      },
      "summary": "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.",
      "title": "Publish motion phase client package",
      "updated_at": "2026-07-25T03:37:54.639Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260725033754-publish-motion-phase-client-package"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-25T03:41:35.507Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/docs/runbook-headless-valheim-lab.md"
        ],
        "id": "20260725034135-pin-disposable-clients-to-exact-mod-artifacts",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Pin disposable clients to exact mod artifacts",
        "verification": [
          "PowerShell syntax passed; clean artifact refresh staged SHA-256 1e875984fde1; preflight matched that hash and stopped before launch because the disposable Steam install/profile is not seeded."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260725034135-pin-disposable-clients-to-exact-mod-artifacts",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-25T03:41:35.507Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L215",
        "sha256": "92f84d634e72241b8b95e28e5a4b392691831328557e459ec6e6d990c46e27c3"
      },
      "summary": "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.",
      "title": "Pin disposable clients to exact mod artifacts",
      "updated_at": "2026-07-25T03:41:35.507Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260725034135-pin-disposable-clients-to-exact-mod-artifacts"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-25T03:44:59.809Z",
        "author": "Codex",
        "evidence": [
          "tools/i5/Test-Wave0Readiness.ps1"
        ],
        "id": "20260725034459-separate-package-and-admitted-mod-readiness",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Separate package and admitted mod readiness",
        "verification": [
          "The corrected audit returned ready_for_two_client_gate for package m31, admitted/Gateway mod m30, matching OMEN/i5 package hashes, profiles, configs, P7 readiness, and readable telemetry."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260725034459-separate-package-and-admitted-mod-readiness",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-25T03:44:59.809Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L216",
        "sha256": "26920674629709c59f6af074c96659b5181a9db78cb8e945dd87f9059b2a5563"
      },
      "summary": "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.",
      "title": "Separate package and admitted mod readiness",
      "updated_at": "2026-07-25T03:44:59.809Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260725034459-separate-package-and-admitted-mod-readiness"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-25T03:56:40.476Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/experiments/creative-runtime/cre-e06-motion-phase-rollups/Test-BundleAdapter.ps1; fieldlab/scripts/Summarize-TwoClientMotionPhaseBundles.ps1; tools/i5/Start-TwoClientCapture.ps1"
        ],
        "id": "20260725035640-unify-two-client-motion-phase-evidence",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Unify two-client motion phase evidence",
        "verification": [
          "Bundle adapter fixtures, bounded-command contracts, live-gate fixtures, expected-result-grid fixtures, and PowerShell parse checks passed."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260725035640-unify-two-client-motion-phase-evidence",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-25T03:56:40.476Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L217",
        "sha256": "bf80871cecbdde62882ee5bac3408f892a8b54e98a43f73552fc0f9363d9b0e3"
      },
      "summary": "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.",
      "title": "Unify two-client motion phase evidence",
      "updated_at": "2026-07-25T03:56:40.476Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260725035640-unify-two-client-motion-phase-evidence"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-25T04:11:16.306Z",
        "author": "Codex",
        "evidence": [
          "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.json"
        ],
        "id": "20260725041116-reject-fixed-motion-interpolation-delay",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Reject fixed motion interpolation delay",
        "verification": [
          "Final 60-row run and repeat normalized equal; four safety invariants passed; AuthorityLab build and all seven tests passed in the .NET 9 container."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260725041116-reject-fixed-motion-interpolation-delay",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-25T04:11:16.306Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L218",
        "sha256": "cd1b24b854079b959e6176e26a4d9c3218a0395fb68409ac2b206708c460bd12"
      },
      "summary": "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.",
      "title": "Reject fixed motion interpolation delay",
      "updated_at": "2026-07-25T04:11:16.306Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260725041116-reject-fixed-motion-interpolation-delay"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-25T04:20:47.419Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/experiments/creative-runtime/cre-e06-motion-phase-rollups/experiment.md"
        ],
        "id": "20260725042047-attribute-motion-phase-evidence-by-client-role",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Attribute motion phase evidence by client role",
        "verification": [
          "Role-attribution fixtures passed for either-machine APPLY, setup role transitions, ambiguous roles, contradictory OBSERVE activity, and missing-client rejection; PowerShell parse checks passed."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260725042047-attribute-motion-phase-evidence-by-client-role",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-25T04:20:47.419Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L219",
        "sha256": "b6910521670a9ae6a0a6d537bf0632cf5ca8818947561ad738e569cbdb465b36"
      },
      "summary": "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.",
      "title": "Attribute motion phase evidence by client role",
      "updated_at": "2026-07-25T04:20:47.419Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260725042047-attribute-motion-phase-evidence-by-client-role"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-25T04:41:16.647Z",
        "author": "Codex",
        "evidence": [
          "tools/i5/Repair-I5DockerDesktop.ps1; tools/i5/README.md"
        ],
        "id": "20260725044116-recover-the-i5-workbench-after-sleep",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Recover the i5 workbench after sleep",
        "verification": [
          "Post-SSH Companion status remained readable; readiness returned ready_for_two_client_gate; the scheduled task permits battery operation, does not stop on battery, starts when available, and has no execution time limit."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260725044116-recover-the-i5-workbench-after-sleep",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-25T04:41:16.647Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L220",
        "sha256": "3c184ac648fc81c67d212fdf2a8506317a36732f5e138d9177c2667105d0bff3"
      },
      "summary": "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.",
      "title": "Recover the i5 workbench after sleep",
      "updated_at": "2026-07-25T04:41:16.647Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260725044116-recover-the-i5-workbench-after-sleep"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-25T04:56:01.777Z",
        "author": "Codex",
        "evidence": [
          "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.json"
        ],
        "id": "20260725045601-derive-an-adaptive-motion-playout-candidate",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Derive an adaptive motion playout candidate",
        "verification": [
          "Both 180-row v2 runs normalized equal; five safety invariants and all seven AuthorityLab tests passed; the retained v1 run documents the rejected floor."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260725045601-derive-an-adaptive-motion-playout-candidate",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-25T04:56:01.777Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L221",
        "sha256": "672c7a3cdf9cb549ad904a2ea52d6e15d96b466eeae2eeea03514a65a7e5c567"
      },
      "summary": "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.",
      "title": "Derive an adaptive motion playout candidate",
      "updated_at": "2026-07-25T04:56:01.777Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260725045601-derive-an-adaptive-motion-playout-candidate"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T00:23:58.695Z",
        "author": "Claude",
        "evidence": [
          "fieldlab/docs/harmony-patch-policy.md"
        ],
        "id": "20260729002358-adopt-a-harmony-patch-policy",
        "impact": "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.",
        "kind": "decision",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Adopt a Harmony patch policy",
        "verification": [
          "Policy patterns cross-checked against the mod: the ZdoSendCadenceOverride transpiler, ZdoRedirect/NetcodeProbe priority ordering, and UnpatchSelf teardown all match the written rules."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260729002358-adopt-a-harmony-patch-policy",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-29T00:23:58.695Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L222",
        "sha256": "d093cdce5b7f4b0c91682bd15c97566cbc3572be3df6ba06a6441f13b5de5ae5"
      },
      "summary": "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.",
      "title": "Adopt a Harmony patch policy",
      "updated_at": "2026-07-29T00:23:58.695Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729002358-adopt-a-harmony-patch-policy"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T00:24:25.438Z",
        "author": "Claude",
        "evidence": [
          "fieldlab/docs/runbook-patchload-ab-benchmark.md; fieldlab/experiments/patchload-ab/patchload-lab.cfg; network/mod/ComfyNetworkSense/CHANGELOG.md"
        ],
        "id": "20260729002425-stage-the-patch-load-a-b-rollup-built-but-never-",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Stage the patch-load A/B rollup, built but never run",
        "verification": [
          "Mod compiled clean (Release, net48) with the plugin-copy guard; the new key defaults off; no benchmark run or evidence folder exists yet and the runbook says so."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260729002425-stage-the-patch-load-a-b-rollup-built-but-never-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T00:24:25.438Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L223",
        "sha256": "6311f5b905b4069292ee29c0becdbd5aaf37bd3ee34a33d612fedc6cc587ee92"
      },
      "summary": "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.",
      "title": "Stage the patch-load A/B rollup, built but never run",
      "updated_at": "2026-07-29T00:24:25.438Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729002425-stage-the-patch-load-a-b-rollup-built-but-never-"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T00:32:31.013Z",
        "author": "Claude",
        "evidence": [
          "fieldlab/PINNED-networking-lane-2026-07.md; fieldlab/retro/SESSION-RETRO-2026-07-28.md; plans/remaining-human-tests.md"
        ],
        "id": "20260729003231-pin-the-networking-lane-and-open-the-community-w",
        "impact": "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.",
        "kind": "decision",
        "milestones": [
          "M7",
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Pin the networking lane and open the Community Workbench milestone",
        "verification": [
          "Working tree clean except docs/audit (deliberately held for review); every path the pin document references resolves; roadmap render and staged checks green."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "M7",
          "A7"
        ]
      },
      "id": "roadmap:20260729003231-pin-the-networking-lane-and-open-the-community-w",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-29T00:32:31.013Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L224",
        "sha256": "ff88a60952725dbe25e3dd86ae6d71253faed9b1697838224b57835d80084f8d"
      },
      "summary": "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.",
      "title": "Pin the networking lane and open the Community Workbench milestone",
      "updated_at": "2026-07-29T00:32:31.013Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729003231-pin-the-networking-lane-and-open-the-community-w"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T00:43:33.657Z",
        "author": "Claude",
        "evidence": [
          "tools/guest-package/README.md; docs/quest-vertical-slice-architecture.md; network/mcp/etc/start-comfy-gateway.cmd; recipes/quest-catalogs/sources.json"
        ],
        "id": "20260729004333-fix-the-share-blockers-ahead-of-the-workbench-ca",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Fix the share-blockers ahead of the Workbench catalog",
        "verification": [
          "Every path in the banner verified against the tree by the fixing agent; sources.json re-validated as JSON; no binding or behavior changes to the gateway."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729004333-fix-the-share-blockers-ahead-of-the-workbench-ca",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T00:43:33.657Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L225",
        "sha256": "5700b0d5f3b9ea105a2b8f70e34d6a02e55fecbb35bd45fe7a87ee4d6b5760d2"
      },
      "summary": "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.",
      "title": "Fix the share-blockers ahead of the Workbench catalog",
      "updated_at": "2026-07-29T00:43:33.657Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729004333-fix-the-share-blockers-ahead-of-the-workbench-ca"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T01:01:44.427Z",
        "author": "Claude",
        "evidence": [
          "Lumberjacks/docs/workbench/workbench.json; Lumberjacks/scripts/workbench.mjs; Lumberjacks/src/Game.Gateway/Endpoints/WorkbenchViewEndpoints.cs"
        ],
        "id": "20260729010144-open-the-workbench-catalog-surface",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Open the /workbench catalog surface",
        "verification": [
          "workbench:check green (7 tools, validators proven fail-closed via 16 mutation tests); Gateway built clean in the sdk:9.0 container with 6/6 roadmap endpoint tests passing; roadmap re-rendered after the nav change."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729010144-open-the-workbench-catalog-surface",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T01:01:44.427Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L226",
        "sha256": "f77e38de7bf9554d01892c84deedb65d243165a45deab8d6dced571b77122308"
      },
      "summary": "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.",
      "title": "Open the /workbench catalog surface",
      "updated_at": "2026-07-29T01:01:44.427Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729010144-open-the-workbench-catalog-surface"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T01:03:14.328Z",
        "author": "Claude",
        "evidence": [
          "Lumberjacks/scripts/roadmap.mjs; LICENSING.md"
        ],
        "id": "20260729010314-correct-the-licensing-term-on-the-public-journal",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Correct the licensing term on the public journal",
        "verification": [
          "Guard proven fail-closed: a deliberately mislabeled test note was rejected before any file was written; render and check pass with the glossary entry present."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729010314-correct-the-licensing-term-on-the-public-journal",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T01:03:14.328Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L227",
        "sha256": "b97522b2299b3d8d883a858c41448b04d91c6090e7d37bb48563dfbb2bea7ee3"
      },
      "summary": "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.",
      "title": "Correct the licensing term on the public journal",
      "updated_at": "2026-07-29T01:03:14.328Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729010314-correct-the-licensing-term-on-the-public-journal"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T01:06:34.895Z",
        "author": "Claude",
        "evidence": [
          "tools/workbench/Test-WorkbenchZipPrivacy.ps1; tools/workbench/New-WorkbenchZip.ps1; recipes/quest-catalogs/render_quest_picker.py; Lumberjacks/docs/workbench/tools/quest-picker.md"
        ],
        "id": "20260729010634-ship-the-cold-start-kits-behind-a-privacy-gate",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Ship the cold-start kits behind a privacy gate",
        "verification": [
          "Scanner self-test passes all 12 rules on clean and poisoned fixtures; both zips built CLEAN through the gate; the quest-picker zip extracted and ran cold in a fresh directory, and the rendered picker carries the corrected config path with zero stale references."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729010634-ship-the-cold-start-kits-behind-a-privacy-gate",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T01:06:34.895Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L228",
        "sha256": "8aa8925deab2bd14658844797301338a1a3ddfd0b6b0084943aae09f0d9a9244"
      },
      "summary": "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.",
      "title": "Ship the cold-start kits behind a privacy gate",
      "updated_at": "2026-07-29T01:06:34.895Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729010634-ship-the-cold-start-kits-behind-a-privacy-gate"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T01:06:53.374Z",
        "author": "Claude",
        "evidence": [
          "Lumberjacks/docs/workbench/discord/00-announcement.md; Lumberjacks/docs/workbench/OWNERS.md; DEREK-BATCH-1.md"
        ],
        "id": "20260729010653-stage-the-discord-seeds-and-the-ownership-ledger",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Stage the Discord seeds and the ownership ledger",
        "verification": [
          "Every status claim in the drafts traces to a repo path the drafting agent read; tone checked against the positioning and adoption strategy docs; no post was made anywhere."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729010653-stage-the-discord-seeds-and-the-ownership-ledger",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T01:06:53.374Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L229",
        "sha256": "565caa029645673eccaa94470c3632a2b199d0db41e263c1ed3e38e02ed68dc6"
      },
      "summary": "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.",
      "title": "Stage the Discord seeds and the ownership ledger",
      "updated_at": "2026-07-29T01:06:53.374Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729010653-stage-the-discord-seeds-and-the-ownership-ledger"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T01:49:15.474Z",
        "author": "Claude",
        "evidence": [
          "plans/cognitive-lift-portfolio.md; tools/workbench/new_announcement_draft.py; tools/workbench/distill_feedback.py; Lumberjacks/docs/workbench/discord/07-forum-tags-setup.md"
        ],
        "id": "20260729014915-build-the-top-of-the-cognitive-lift-portfolio",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Build the top of the cognitive-lift portfolio",
        "verification": [
          "Drafter self-test 11 of 11 and distiller self-test 15 of 15 green; the drafter ran against the real journal and produced the first draft covering this session's eight entries; DiscordChatExporter schema verified from that project's source before the distiller was written."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729014915-build-the-top-of-the-cognitive-lift-portfolio",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T01:49:15.474Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L230",
        "sha256": "d1e46c74535c3e8bf1f19d7593e12dad0fc9752bbc00b0cba01ef7e511de51b7"
      },
      "summary": "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.",
      "title": "Build the top of the cognitive-lift portfolio",
      "updated_at": "2026-07-29T01:49:15.474Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729014915-build-the-top-of-the-cognitive-lift-portfolio"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T03:29:06.450Z",
        "author": "Claude",
        "evidence": [
          "HANDOFF-2026-07-29.md"
        ],
        "id": "20260729032906-land-the-cold-pickup-handoff",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Land the cold-pickup handoff",
        "verification": [
          "Every path the handoff cites was existence-checked before writing; git state cross-checked against the doc's claims (HEAD c6314d3, only docs/audit untracked)."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729032906-land-the-cold-pickup-handoff",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T03:29:06.450Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L231",
        "sha256": "0ef5cd224123abc8176bcd882a3fc8365f96d40f78b4d859f63908859808e5ae"
      },
      "summary": "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.",
      "title": "Land the cold-pickup handoff",
      "updated_at": "2026-07-29T03:29:06.450Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729032906-land-the-cold-pickup-handoff"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T05:16:56.169Z",
        "author": "Claude",
        "evidence": [
          "docs/baseline-vision-and-boundary.md; HANDOFF-2026-07-29.md"
        ],
        "id": "20260729051656-record-the-product-boundary-baseline-is-the-tool",
        "impact": "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.",
        "kind": "decision",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Record the product boundary: Baseline is the toolkit, HEARTH is the lab",
        "verification": [
          "Boundary audited against everything shipped this session: no HEARTH endpoints, keys, or lab paths in the zips, the Workbench page, or the one-pagers; both new automation scripts are deterministic and LLM-free by design."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729051656-record-the-product-boundary-baseline-is-the-tool",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-29T05:16:56.169Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L232",
        "sha256": "665463921352a0c391f78ab193506066f1bea42fb8046adb83bb43ee3507cbeb"
      },
      "summary": "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.",
      "title": "Record the product boundary: Baseline is the toolkit, HEARTH is the lab",
      "updated_at": "2026-07-29T05:16:56.169Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729051656-record-the-product-boundary-baseline-is-the-tool"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T05:25:16.613Z",
        "author": "Claude",
        "evidence": [
          "AGENTS.md; CLAUDE.md; DECISIONS-PENDING.md"
        ],
        "id": "20260729052516-arm-tonight-s-operator-in-the-seat-test-rule-and",
        "impact": "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.",
        "kind": "decision",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Arm tonight's operator-in-the-seat test rule and queue the GCP lever decision",
        "verification": [
          "Rule carries its own expiry and deletion instruction; register entry names the live-game-server constraint explicitly."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729052516-arm-tonight-s-operator-in-the-seat-test-rule-and",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-29T05:25:16.613Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L233",
        "sha256": "8a9562fab9c5c37cff3576e19295a71af1ece4db7a600004abe46608bbc96fb9"
      },
      "summary": "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.",
      "title": "Arm tonight's operator-in-the-seat test rule and queue the GCP lever decision",
      "updated_at": "2026-07-29T05:25:16.613Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729052516-arm-tonight-s-operator-in-the-seat-test-rule-and"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T05:28:44.923Z",
        "author": "Claude",
        "evidence": [
          "infra/gcp/p7/RUNBOOK-cost-and-cycle.md; docs/audit/2026-07-25-gcp-burn-rate-review.md"
        ],
        "id": "20260729052844-stage-the-gcp-cost-and-cycle-time-runbook",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Stage the GCP cost and cycle-time runbook",
        "verification": [
          "Every dollar figure traces to the burn memo; project, VM, zone, and service names traced to infra docs; restart-predictability claim checked against the systemd unit and compose restart policies with the first real scheduled restart hedged as the remaining live proof."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729052844-stage-the-gcp-cost-and-cycle-time-runbook",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T05:28:44.923Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L234",
        "sha256": "eea40f6a8da0c9c099541a4d352ceffe4c54ae855e58a2c91fd5ed37ea4a8498"
      },
      "summary": "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.",
      "title": "Stage the GCP cost and cycle-time runbook",
      "updated_at": "2026-07-29T05:28:44.923Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729052844-stage-the-gcp-cost-and-cycle-time-runbook"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T05:38:43.959Z",
        "author": "Claude",
        "evidence": [
          "infra/gcp/p7/RUNBOOK-cost-and-cycle.md; DECISIONS-PENDING.md"
        ],
        "id": "20260729053843-correct-the-cost-runbook-to-operator-truth",
        "impact": "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.",
        "kind": "decision",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Correct the cost runbook to operator truth",
        "verification": [
          "Every changed dollar figure either traces to the memo or is explicitly deferred to invoiced data; the backup lever stages an on-box grep before any env change and preserves the atomic world-save mechanism untouched."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729053843-correct-the-cost-runbook-to-operator-truth",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-29T05:38:43.959Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L235",
        "sha256": "85ae5979540865c17a6020731f3d60025c5a4d0aab6513a94394201e944e3419"
      },
      "summary": "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.",
      "title": "Correct the cost runbook to operator truth",
      "updated_at": "2026-07-29T05:38:43.959Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729053843-correct-the-cost-runbook-to-operator-truth"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T06:14:39.231Z",
        "author": "Claude",
        "evidence": [
          "START-HERE.md; BUILDING.md; GLOSSARY.md; fieldlab/docs/adr/README.md"
        ],
        "id": "20260729061439-run-the-contributor-onboarding-cleanup-batch",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Run the contributor-onboarding cleanup batch",
        "verification": [
          "Banner edits verified insert-only below each notice; the links pass documented 17 skips with reasons and kept two recovery mechanisms distinct; both new reference docs cite a repo source per claim."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729061439-run-the-contributor-onboarding-cleanup-batch",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T06:14:39.231Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L236",
        "sha256": "a608bf960307391a44616e2159d76ae73634f1b0b143ba5f4800578c738d772b"
      },
      "summary": "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.",
      "title": "Run the contributor-onboarding cleanup batch",
      "updated_at": "2026-07-29T06:14:39.231Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729061439-run-the-contributor-onboarding-cleanup-batch"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T06:35:49.149Z",
        "author": "Claude",
        "evidence": [
          "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.md"
        ],
        "id": "20260729063549-commit-the-held-audit-trail",
        "impact": "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.",
        "kind": "decision",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Commit the held audit trail",
        "verification": [
          "Four files, docs-only, previously untracked by explicit design; no content edited on the way in."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729063549-commit-the-held-audit-trail",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-29T06:35:49.149Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L237",
        "sha256": "8fd8c09ae933bbfdd5c04782af972c0cd3448c56f31be3b93a1de4a7753c2444"
      },
      "summary": "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.",
      "title": "Commit the held audit trail",
      "updated_at": "2026-07-29T06:35:49.149Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729063549-commit-the-held-audit-trail"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T06:44:08.930Z",
        "author": "Claude",
        "evidence": [
          "CONTRIBUTING.md; Lumberjacks/docs/workbench/workbench.json; DECISIONS-PENDING.md"
        ],
        "id": "20260729064408-open-pull-requests-and-rename-the-ladder-stage-t",
        "impact": "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.",
        "kind": "decision",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Open pull requests and rename the ladder stage to Contributor",
        "verification": [
          "Rename applied contextually across ten ladder artifacts with product, license, and persona usages preserved and documented per file; workbench render and check green after the JSON edit; register and checklist entries carry the operator's rationale verbatim where it matters."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729064408-open-pull-requests-and-rename-the-ladder-stage-t",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-29T06:44:08.930Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L238",
        "sha256": "394475e90b3365b8d6f5df76930aa19ce3cf218944d8ce3a23b2f909b2ed134c"
      },
      "summary": "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.",
      "title": "Open pull requests and rename the ladder stage to Contributor",
      "updated_at": "2026-07-29T06:44:08.930Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729064408-open-pull-requests-and-rename-the-ladder-stage-t"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T07:02:31.338Z",
        "author": "Claude",
        "evidence": [
          "tools/workbench/discord/; Lumberjacks/docs/workbench/discord/09-discord-bot-setup.md; tools/workbench/discord/receipts/2026-07-29-plan-offline.md"
        ],
        "id": "20260729070231-provision-the-workbench-forum-from-the-repositor",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Provision the workbench forum from the repository",
        "verification": [
          "64 of 64 self-test assertions pass offline against a simulated guild: taxonomy parsing, the placeholder guard, message chunking, a full greenfield provisioning run, idempotent re-plan, drift detection and repair, refusal to mangle a hand-pasted post, and the export handing off cleanly into the feedback distiller. Two dry-run receipts generated for operator approval; nothing has been written to any live server."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729070231-provision-the-workbench-forum-from-the-repositor",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T07:02:31.338Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L239",
        "sha256": "24905d9df7d478f43c5846d5ce9025f85a7fee7fa7ffbda6e8130445472f0577"
      },
      "summary": "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.",
      "title": "Provision the workbench forum from the repository",
      "updated_at": "2026-07-29T07:02:31.338Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729070231-provision-the-workbench-forum-from-the-repositor"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T07:05:12.788Z",
        "author": "Claude",
        "evidence": [
          "tools/workbench/discord/workbench_discord.py"
        ],
        "id": "20260729070512-make-forum-provisioning-survive-a-lost-state-fil",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make forum provisioning survive a lost state file",
        "verification": [
          "69 of 69 self-test assertions, including a new case that wipes the state record, adds a member reply to a two-message post, and asserts the next plan is a no-op with the reply intact. The approval receipt's plan hash is unchanged, so the dry run already approved still applies."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729070512-make-forum-provisioning-survive-a-lost-state-fil",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T07:05:12.788Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L240",
        "sha256": "dfb8b1800167ef82a1b207bdf6b5e29f8d8ca9c1d972714acea9b77bfc0202ce"
      },
      "summary": "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.",
      "title": "Make forum provisioning survive a lost state file",
      "updated_at": "2026-07-29T07:05:12.788Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729070512-make-forum-provisioning-survive-a-lost-state-fil"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T07:09:32.827Z",
        "author": "Claude",
        "evidence": [
          "tools/workbench/discord/WORKBOOK.md"
        ],
        "id": "20260729070932-write-the-wrap-up-workbook-for-the-forum-rollout",
        "impact": "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.",
        "kind": "planning",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Write the wrap-up workbook for the forum rollout",
        "verification": [
          "Steps cross-checked against the tool's own subcommands and the plan hash on the approved dry-run receipt; the seven-tools-to-six-posts mapping and the unthreaded tool are stated explicitly rather than left to be rediscovered."
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729070932-write-the-wrap-up-workbook-for-the-forum-rollout",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-07-29T07:09:32.827Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L241",
        "sha256": "b86773f67c34c19a8100a927aa681f5b8cbe5ccdb9f46f25902d09bcfca9ea50"
      },
      "summary": "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.",
      "title": "Write the wrap-up workbook for the forum rollout",
      "updated_at": "2026-07-29T07:09:32.827Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729070932-write-the-wrap-up-workbook-for-the-forum-rollout"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T07:19:51.408Z",
        "author": "Claude",
        "evidence": [
          "tools/workbench/discord/WORKBOOK.md; Lumberjacks/docs/workbench/discord/09-discord-bot-setup.md"
        ],
        "id": "20260729071951-write-the-operator-s-runnable-steps-in-his-own-s",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Write the operator's runnable steps in his own shell",
        "verification": [
          "Every fenced command block across the three documents re-audited programmatically for shell-and separators and unix-only commands; token loading exercised against all three byte layouts a Windows operator can produce - mark plus carriage returns, bare ascii, plain newline - all three now yield the same token. Self-test still 69 of 69."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729071951-write-the-operator-s-runnable-steps-in-his-own-s",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T07:19:51.408Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L242",
        "sha256": "ffb74cb2a2d12ab28f4b224fbe41f753ac576540724c2f6271f53bdb241b8322"
      },
      "summary": "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.",
      "title": "Write the operator's runnable steps in his own shell",
      "updated_at": "2026-07-29T07:19:51.408Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729071951-write-the-operator-s-runnable-steps-in-his-own-s"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T07:26:18.615Z",
        "author": "Claude",
        "evidence": [
          "tools/workbench/discord/workbench_discord.py; .gitignore"
        ],
        "id": "20260729072618-accept-the-operator-s-own-credential-file-and-pr",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Accept the operator's own credential file and prove it before use",
        "verification": [
          "85 of 85 self-test assertions, including ten credential-file layouts a Windows operator can produce and four malformed ones that must be refused. Verified live against the real credential: identity confirmed read-only, no writes attempted, and the tool correctly reported that the bot has not yet been authorized onto the server."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729072618-accept-the-operator-s-own-credential-file-and-pr",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T07:26:18.615Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L243",
        "sha256": "897a90bbcae0763101126abfa3d13d3afd5ba89a0c8ac632ff583e6bfc23fafc"
      },
      "summary": "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.",
      "title": "Accept the operator's own credential file and prove it before use",
      "updated_at": "2026-07-29T07:26:18.615Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729072618-accept-the-operator-s-own-credential-file-and-pr"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T07:32:37.414Z",
        "author": "Claude",
        "evidence": [
          "tools/workbench/discord/receipts/2026-07-29-plan.md; tools/workbench/discord/provision-state.json"
        ],
        "id": "20260729073237-open-the-community-workbench-forum",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Open the community workbench forum",
        "verification": [
          "Confirmed against the live server after the run rather than trusting the tool's own report: channel type, required-tags flag, sort order and guidelines text read back as configured, all eight tags present with the four status tags correctly restricted, both posts present with the pinned one pinned. A second plan comes back with no work to do, which is the idempotence claim holding on real infrastructure instead of a fixture."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729073237-open-the-community-workbench-forum",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-29T07:32:37.414Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L244",
        "sha256": "bbe0569305979ce842b395ed355a821459d9f6d3a08b9eb4e1816ecd3149bacd"
      },
      "summary": "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.",
      "title": "Open the community workbench forum",
      "updated_at": "2026-07-29T07:32:37.414Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729073237-open-the-community-workbench-forum"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T07:36:20.270Z",
        "author": "Claude",
        "evidence": [
          "tools/workbench/discord/WORKBOOK.md"
        ],
        "id": "20260729073620-refresh-the-forum-handoff-with-what-is-actually-",
        "impact": "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.",
        "kind": "planning",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Refresh the forum handoff with what is actually live",
        "verification": [
          "Message counts, author identity and reply counts read back from the live server; the generator's link allowlist read out of its source rather than assumed; downstream file state checked on disk."
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729073620-refresh-the-forum-handoff-with-what-is-actually-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-07-29T07:36:20.270Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L245",
        "sha256": "1a4a9c5d3598391e62b0c4dab437fb2879531ffe3438333fc42b77b55f013b9f"
      },
      "summary": "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.",
      "title": "Refresh the forum handoff with what is actually live",
      "updated_at": "2026-07-29T07:36:20.270Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729073620-refresh-the-forum-handoff-with-what-is-actually-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T07:53:52.378Z",
        "author": "Claude",
        "evidence": [
          ".gitignore"
        ],
        "id": "20260729075352-name-the-credential-file-in-the-ignore-rules",
        "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Name the credential file in the ignore rules",
        "verification": [
          "Ignore rules exercised against the filename at the root, nested under the tool directory, and at arbitrary depth, plus the two wildcards, each reporting which rule catches it. History checked four ways - index, full-history path log across all refs, an object listing of every blob path ever recorded, and a content search of every reference for the value itself."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729075352-name-the-credential-file-in-the-ignore-rules",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T07:53:52.378Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L246",
        "sha256": "310c0261493df7cbd3117b9a1696147c0e63469cf3ccac4c7b26b12421b05b0d"
      },
      "summary": "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.",
      "title": "Name the credential file in the ignore rules",
      "updated_at": "2026-07-29T07:53:52.378Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729075352-name-the-credential-file-in-the-ignore-rules"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T08:09:03.405Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260729080903-rework-the-community-workbench-page-for-first-ti",
        "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",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Rework the Community Workbench page for first-time volunteers: tools before ladder, a scannable tool index, promoted access and first-result, and two native details disclosures per card",
        "verification": [
          "npm run workbench:render && npm run workbench:check; zero-loss sweep over 222 content strings; browser pass at 1280x800 and narrow width confirming the index clears the fold and all 7 status_detail blocks render uncollapsed"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729080903-rework-the-community-workbench-page-for-first-ti",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T08:09:03.405Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L247",
        "sha256": "08c2053e17ada21f4bdb0f1323e048540dfd556921523ea0540e15bb716fee60"
      },
      "summary": "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",
      "title": "Rework the Community Workbench page for first-time volunteers: tools before ladder, a scannable tool index, promoted access and first-result, and two native details disclosures per card",
      "updated_at": "2026-07-29T08:09:03.405Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729080903-rework-the-community-workbench-page-for-first-ti"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T08:48:49.387Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260729084849-correct-the-workbench-source-claims-baseline-is-",
        "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",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Correct the workbench source claims: baseline is public, so three cards no longer say private-until-claimed and ladder stage 3 grants commit access rather than the ability to read the code",
        "verification": [
          "gh repo view confirmed baseline, comfy, ComfyStewardView and Lumberjacks are all PUBLIC; all four linked source paths verified to exist; npm run workbench:render && npm run workbench:check; zero-loss sweep over 225 content strings; zero residual private-until-claimed or stage-3-access strings in source or rendered HTML"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729084849-correct-the-workbench-source-claims-baseline-is-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T08:48:49.387Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L248",
        "sha256": "7086a1729656495ce66437cf7ef249edd0cc9274d2e25301e3268498e1d8056b"
      },
      "summary": "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",
      "title": "Correct the workbench source claims: baseline is public, so three cards no longer say private-until-claimed and ladder stage 3 grants commit access rather than the ability to read the code",
      "updated_at": "2026-07-29T08:48:49.387Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729084849-correct-the-workbench-source-claims-baseline-is-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T09:08:51.568Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260729090851-close-four-workbench-trust-gaps-a-real-discord-i",
        "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",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Close four workbench trust gaps: a real Discord invite so member-only links are no longer the only way in, git-derived freshness replacing the hand-entered timestamp, OWNERS.md linked everywhere it is promised, and stage-three contribution rights declared per tool",
        "verification": [
          "Six new guards each negative-tested to confirm they fail: missing invite, proprietary tool claiming code contributions, ladder promising commit access globally, reintroduced updated_at, stage_3_reward contradicting code_contributions, and a tool missing contribution. npm run workbench:render and workbench:check green; zero-loss sweep over 235 content strings; five inert discussion placeholders confirmed still inert and confirmed not to trip the invite rule"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729090851-close-four-workbench-trust-gaps-a-real-discord-i",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T09:08:51.568Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L249",
        "sha256": "d5c124d2c72e02f7678be5220dba5b09c1faa3b63232820ff6dfa406f6127e98"
      },
      "summary": "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",
      "title": "Close four workbench trust gaps: a real Discord invite so member-only links are no longer the only way in, git-derived freshness replacing the hand-entered timestamp, OWNERS.md linked everywhere it is promised, and stage-three contribution rights declared per tool",
      "updated_at": "2026-07-29T09:08:51.568Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729090851-close-four-workbench-trust-gaps-a-real-discord-i"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T09:40:15.062Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260729094015-rehearse-the-workbench-deploy-on-local-hardware-",
        "impact": "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",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Rehearse the workbench deploy on local hardware instead of GCP, and fix the download pointer key mismatch it exposed",
        "verification": [
          "Gateway image m31-workbench-20260729-r1 cut locally and verified from the shipped /app/Game.Gateway.dll (admits frozen mod m30-rolecontrol-20260723-r1). Deployed to local hardware over the tailnet: all seven Community routes return 200, X-Workbench-Sha256 matches the published artifact, and after the pointer fix both downloads stream 200 with X-Download-Sha256 equal to the sha256 the catalog page advertises"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729094015-rehearse-the-workbench-deploy-on-local-hardware-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-29T09:40:15.062Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L250",
        "sha256": "f5ce69d2522f0062dc92126ac09579aa0d7f66ff1173fb4fee17ab0b5d51aeff"
      },
      "summary": "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",
      "title": "Rehearse the workbench deploy on local hardware instead of GCP, and fix the download pointer key mismatch it exposed",
      "updated_at": "2026-07-29T09:40:15.062Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729094015-rehearse-the-workbench-deploy-on-local-hardware-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T09:43:14.897Z",
        "author": "Claude",
        "evidence": [
          "HANDOFF-2026-07-29.md; DEREK-BATCH-1.md; DECISIONS-PENDING.md"
        ],
        "id": "20260729094314-reconcile-the-gate-files-to-the-post-builder-sta",
        "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Reconcile the gate files to the post-builder state",
        "verification": [
          "VM status from a read-only gcloud describe; visibility from gh repo view; transcript absence from git log across all refs; the workbench Discord wiring was already completed by the builder sessions and needed no edits."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729094314-reconcile-the-gate-files-to-the-post-builder-sta",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T09:43:14.897Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L251",
        "sha256": "61cfcd1f1ec67443626684bb295cf7dfa3cf1e584ed2b2b67248f65904b378a8"
      },
      "summary": "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.",
      "title": "Reconcile the gate files to the post-builder state",
      "updated_at": "2026-07-29T09:43:14.897Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729094314-reconcile-the-gate-files-to-the-post-builder-sta"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T09:53:33.038Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729095333-pin-the-workbench-download-pointer-contract-with",
        "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",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Pin the workbench download pointer contract with tests so producer and consumer cannot drift again",
        "verification": [
          "Full solution suite green in the sdk:9.0 container (580 passed, 0 failed; Game.Gateway.Tests 200 to 207). Proven load-bearing by mutation: renaming the consumer record's downloads field to tools fails compilation, and the revert rebuilt byte-identical to the passing layer digest. The publish gate was exercised by extracting its shipped text and running it under PowerShell 5.1 - 'downloads' accepted, 'tools' refused, malformed sha256 refused"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729095333-pin-the-workbench-download-pointer-contract-with",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T09:53:33.038Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L252",
        "sha256": "98fa4e789acfd85728b40bf52828bf562ce01c5f430971eb1116a743b40d8045"
      },
      "summary": "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",
      "title": "Pin the workbench download pointer contract with tests so producer and consumer cannot drift again",
      "updated_at": "2026-07-29T09:53:33.038Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729095333-pin-the-workbench-download-pointer-contract-with"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T10:03:27.130Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260729100327-normalise-crlf-before-base64-encoding-the-remote",
        "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",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Normalise CRLF before base64-encoding the remote bash script in the three publish scripts that were missing it",
        "verification": [
          "Reproduced on a real publish once git rewrote Publish-WorkbenchAssets.ps1 to CRLF (163 CR-bearing lines); after the fix the same publish completes and all three gates pass. Gateway image m31-workbench-20260729-r2 cut against HEAD, deployed, and re-verified: seven Community routes 200 and both downloads stream with X-Download-Sha256 equal to the catalog's claim"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729100327-normalise-crlf-before-base64-encoding-the-remote",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T10:03:27.130Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L253",
        "sha256": "dd6ea609b672931d0aaacf412e820733277dd8703bf1933c803ab67a4a992f83"
      },
      "summary": "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",
      "title": "Normalise CRLF before base64-encoding the remote bash script in the three publish scripts that were missing it",
      "updated_at": "2026-07-29T10:03:27.130Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729100327-normalise-crlf-before-base64-encoding-the-remote"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T10:05:56.928Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260729100556-close-the-print-question-honestly-the-rule-meant",
        "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",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Close the print question honestly: the rule meant to force disclosures open does not work, so remove it and say so on the printed page",
        "verification": [
          "Probe compared three states on the real page: collapsed (not visible, 0 chars), collapsed with the print rule applied (not visible, 0 chars), genuinely open (visible, 392 chars). Print note confirmed display:none on screen; 7 status_detail blocks still render with 0 inside a disclosure; workbench:check green and zero-loss holds at 235 strings"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729100556-close-the-print-question-honestly-the-rule-meant",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-29T10:05:56.928Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L254",
        "sha256": "76d786c5b80b0c473931058abc76ab1a84bee9ac301a258edbf5d21817269570"
      },
      "summary": "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",
      "title": "Close the print question honestly: the rule meant to force disclosures open does not work, so remove it and say so on the printed page",
      "updated_at": "2026-07-29T10:05:56.928Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729100556-close-the-print-question-honestly-the-rule-meant"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T10:11:37.556Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260729101137-verify-the-discord-invite-against-the-api-and-ad",
        "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",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Verify the Discord invite against the API and add a build guard for its expiry",
        "verification": [
          "GET /invites/TSHTD38yV confirmed VALID, guild 1531911987074957442, lands in #general, expires_at 2026-08-28T06:33:12+00:00. Guard negative-tested on all three branches: 4 days out warns and passes, an expired date fails with the regenerate instruction, null passes silently"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729101137-verify-the-discord-invite-against-the-api-and-ad",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-29T10:11:37.556Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L255",
        "sha256": "0a76cc2f6d8f187863cc6c9157242b2ab9ce007fdc649d34c6bd83e8ee272280"
      },
      "summary": "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",
      "title": "Verify the Discord invite against the API and add a build guard for its expiry",
      "updated_at": "2026-07-29T10:11:37.556Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729101137-verify-the-discord-invite-against-the-api-and-ad"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T10:29:27.053Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260729102927-resolve-the-valheim-server-password-question-acc",
        "impact": "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",
        "kind": "decision",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Resolve the Valheim server password question: accept open direct-join with no password while the cohort is the operator and name-known friends",
        "verification": [
          "Confirmed nothing is joinable today regardless of the setting: the P7 VM is TERMINATED and the local host runs the Gateway container only, no Valheim server. New sentence renders outside any disclosure, workbench:check green, zero-loss holds at 235 strings, and the page republished to the local host"
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729102927-resolve-the-valheim-server-password-question-acc",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-29T10:29:27.053Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L256",
        "sha256": "1c410cdaca3df322f713a51610d639e973a2f7e675d24b5a784be9b14143701b"
      },
      "summary": "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",
      "title": "Resolve the Valheim server password question: accept open direct-join with no password while the cohort is the operator and name-known friends",
      "updated_at": "2026-07-29T10:29:27.053Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729102927-resolve-the-valheim-server-password-question-acc"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T10:36:15.076Z",
        "author": "Claude",
        "evidence": [
          "HANDOFF-2026-07-29.md; tools/workbench/Publish-WorkbenchAssets.ps1; Lumberjacks/docs/workbench/workbench.json"
        ],
        "id": "20260729103615-confirm-every-workbench-loop-on-the-am4-local-la",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Confirm every Workbench loop on the AM4 local lane",
        "verification": [
          "All checks executed from a second machine over the tailnet against the running container; page and zip hashes compared against the repo's own values, not self-reported ones."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729103615-confirm-every-workbench-loop-on-the-am4-local-la",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-29T10:36:15.076Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L257",
        "sha256": "b0974e0c274f0f96977f7f05333414b5da6a7426205486b28542b3eadd6faaa8"
      },
      "summary": "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.",
      "title": "Confirm every Workbench loop on the AM4 local lane",
      "updated_at": "2026-07-29T10:36:15.076Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729103615-confirm-every-workbench-loop-on-the-am4-local-la"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T10:45:44.822Z",
        "author": "Claude",
        "evidence": [
          "HANDOFF-2026-07-29.md; Lumberjacks/docs/workbench/workbench.json; Lumberjacks/scripts/workbench.mjs"
        ],
        "id": "20260729104544-take-the-workbench-public-on-the-am4-funnel",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Take the Workbench public on the AM4 funnel",
        "verification": [
          "Public sweep from outside the tailnet path: root 302 to the storefront, all community surfaces 200 without credentials, the served page hash equals the repo render through the funnel, the download is hash-exact with a correct integrity header, ops returns 403, gallery surfaces return 401 without credentials, junk paths 404; the updated page republished as a file copy and re-verified by served hash."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729104544-take-the-workbench-public-on-the-am4-funnel",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T10:45:44.822Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L258",
        "sha256": "bcee2e51d2713f1cbee52b41301b739da255351e9380ac7fe34f7e1f21c54bd9"
      },
      "summary": "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.",
      "title": "Take the Workbench public on the AM4 funnel",
      "updated_at": "2026-07-29T10:45:44.822Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729104544-take-the-workbench-public-on-the-am4-funnel"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T10:53:43.346Z",
        "author": "Claude",
        "evidence": [
          "tools/workbench/discord/provision-state.json; Lumberjacks/docs/workbench/workbench.json; Lumberjacks/docs/workbench/discord/drafts/00-announcement-READY-20260729.md"
        ],
        "id": "20260729105343-post-the-four-tool-threads-and-wire-the-loop-clo",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Post the four tool threads and wire the loop closed",
        "verification": [
          "Apply matched the reviewed plan hash exactly and reported four creates and nothing else; thread URLs recorded in provisioning state; the page re-rendered, republished by file copy, and re-verified by served hash through the public edge."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729105343-post-the-four-tool-threads-and-wire-the-loop-clo",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T10:53:43.346Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L259",
        "sha256": "1a5765ed2e35e28d0e43d45d3c45c1be1eb69ca4897f20b8d6b471387036e8b3"
      },
      "summary": "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.",
      "title": "Post the four tool threads and wire the loop closed",
      "updated_at": "2026-07-29T10:53:43.346Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729105343-post-the-four-tool-threads-and-wire-the-loop-clo"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T11:00:37.607Z",
        "author": "Claude",
        "evidence": [
          "Lumberjacks/docs/workbench/discord/drafts/00-announcement-SHORT-20260729.md"
        ],
        "id": "20260729110037-cut-the-announcement-to-a-length-people-read",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Cut the announcement to a length people read",
        "verification": [
          "All links in the short form resolve against the live site and forum; the long draft is retained beside it for the record."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729110037-cut-the-announcement-to-a-length-people-read",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T11:00:37.607Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L260",
        "sha256": "ccae22459f97bc8affc5bc80d04b079951af65246c4060a56c243dcd56260941"
      },
      "summary": "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.",
      "title": "Cut the announcement to a length people read",
      "updated_at": "2026-07-29T11:00:37.607Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729110037-cut-the-announcement-to-a-length-people-read"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T11:05:18.796Z",
        "author": "Claude",
        "evidence": [
          "Lumberjacks/docs/workbench/discord/drafts/00-announcement-SHORT-20260729.md"
        ],
        "id": "20260729110518-rewrite-the-announcement-in-the-operator-s-own-w",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Rewrite the announcement in the operator's own words",
        "verification": [
          "Opening kept nearly verbatim from the operator's draft; links verified against the live site and forum."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729110518-rewrite-the-announcement-in-the-operator-s-own-w",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T11:05:18.796Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L261",
        "sha256": "3a621e4eb9b1c301255951575d9da001ca1f79ecd7e973d5d06974cdaabf21ff"
      },
      "summary": "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.",
      "title": "Rewrite the announcement in the operator's own words",
      "updated_at": "2026-07-29T11:05:18.796Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729110518-rewrite-the-announcement-in-the-operator-s-own-w"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T11:07:52.387Z",
        "author": "Claude",
        "evidence": [
          "Lumberjacks/docs/workbench/discord/05-pinned-how-this-works.md; Lumberjacks/docs/workbench/workbench.json"
        ],
        "id": "20260729110752-make-every-reply-rhythm-promise-match-reality",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make every reply-rhythm promise match reality",
        "verification": [
          "Bot plan reports Discord matches the repo after the update; served page hash equals the local render through the public edge."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729110752-make-every-reply-rhythm-promise-match-reality",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T11:07:52.387Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L262",
        "sha256": "1833089f62d05c20b015201b381ab74b4b3fc7ca84b1db804382d3bdde83e867"
      },
      "summary": "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.",
      "title": "Make every reply-rhythm promise match reality",
      "updated_at": "2026-07-29T11:07:52.387Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729110752-make-every-reply-rhythm-promise-match-reality"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T11:45:13.929Z",
        "author": "Claude",
        "evidence": [
          "recipes/quest-submission-bridge/PROVENANCE.md"
        ],
        "id": "20260729114513-land-the-quest-submission-bridge-raw-material-by",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Land the quest-submission-bridge raw material byte-exact from the archive",
        "verification": [
          "All 15 landed files' index shas equal the archive source blob shas; archive handoffs tree at ae81c83 is tree-identical to baseline pre-prune 57654fd:handoffs."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729114513-land-the-quest-submission-bridge-raw-material-by",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T11:45:13.929Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L263",
        "sha256": "2b2a2a7caac7b35672bf31d125b5190b3cbd10a5631e53a79afd75acb285153c"
      },
      "summary": "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.",
      "title": "Land the quest-submission-bridge raw material byte-exact from the archive",
      "updated_at": "2026-07-29T11:45:13.929Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729114513-land-the-quest-submission-bridge-raw-material-by"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T11:47:13.847Z",
        "author": "Claude",
        "evidence": [
          "recipes/camera-gallery/PROVENANCE.md"
        ],
        "id": "20260729114713-land-the-camera-gallery-raw-material-byte-exact-",
        "impact": "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Land the camera-gallery raw material byte-exact from the archive",
        "verification": [
          "All 9 landed files' index shas equal the archive source blob shas; video_to_gallery.py argparse confirms the documented --dry-run and --duration flags."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729114713-land-the-camera-gallery-raw-material-byte-exact-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T11:47:13.847Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L264",
        "sha256": "5acbd9d05e65e6570b97255a61c1a733811209bc66ab5b2d946bdc7c9bbd65e2"
      },
      "summary": "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.",
      "title": "Land the camera-gallery raw material byte-exact from the archive",
      "updated_at": "2026-07-29T11:47:13.847Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729114713-land-the-camera-gallery-raw-material-byte-exact-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T11:50:33.245Z",
        "author": "Claude",
        "evidence": [
          "Lumberjacks/docs/workbench/workbench.json"
        ],
        "id": "20260729115033-point-the-workbench-truthfully-at-the-re-landed-",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Point the workbench truthfully at the re-landed recoverable raw material",
        "verification": [
          "npm run workbench:render and workbench:check pass: 7 tools, 2 recoverable, generated HTML current."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729115033-point-the-workbench-truthfully-at-the-re-landed-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T11:50:33.245Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L265",
        "sha256": "7c0ae4577a009b8f26007c4569104937318bc538e71ccca971e17443d5a4396b"
      },
      "summary": "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.",
      "title": "Point the workbench truthfully at the re-landed recoverable raw material",
      "updated_at": "2026-07-29T11:50:33.245Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729115033-point-the-workbench-truthfully-at-the-re-landed-"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T11:52:37.134Z",
        "author": "Claude",
        "evidence": [
          "plans/recoverable-pieces-landing-workbook.md"
        ],
        "id": "20260729115237-write-the-find-land-document-workbook-for-recove",
        "impact": "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.",
        "kind": "planning",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Write the find-land-document workbook for recoverable pieces",
        "verification": [
          "Workbook cross-checked against the executed run: every command in F1-F3 is the one actually run, with its recorded output."
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729115237-write-the-find-land-document-workbook-for-recove",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-07-29T11:52:37.134Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L266",
        "sha256": "63a950f8fa4d0f3f449c0fcb89ab45a4dcb0547ba09490263b7ab23bbd236ab7"
      },
      "summary": "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.",
      "title": "Write the find-land-document workbook for recoverable pieces",
      "updated_at": "2026-07-29T11:52:37.134Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729115237-write-the-find-land-document-workbook-for-recove"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T11:54:40.022Z",
        "author": "Claude",
        "evidence": [
          "plans/recoverable-pieces-landing-workbook.md"
        ],
        "id": "20260729115440-prove-the-landed-recoverable-raw-material-byte-e",
        "impact": "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.",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Prove the landed recoverable raw material byte-exact and runnable",
        "verification": [
          "24/24 sha equality; 5/5 py_compile; bridge smoke assertions green; fixtures smoke green; video_to_gallery --dry-run exit 0; unittest tests.test_entrypoint_links OK; git status empty."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729115440-prove-the-landed-recoverable-raw-material-byte-e",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-29T11:54:40.022Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L267",
        "sha256": "5d25d1388fcd91842d090883a45868a309339967a313c9645ab23e096a57b163"
      },
      "summary": "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.",
      "title": "Prove the landed recoverable raw material byte-exact and runnable",
      "updated_at": "2026-07-29T11:54:40.022Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729115440-prove-the-landed-recoverable-raw-material-byte-e"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T11:58:12.584Z",
        "author": "Claude",
        "evidence": [
          "tools/workbench/discord/receipts/2026-07-29-plan.md"
        ],
        "id": "20260729115812-stage-the-recoverable-pieces-thread-update-for-o",
        "impact": "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.",
        "kind": "planning",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Stage the Recoverable-pieces thread update for operator approval",
        "verification": [
          "workbench_discord.py plan wrote the receipt; plan hash ba37ecab31d2; nothing was written to Discord."
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729115812-stage-the-recoverable-pieces-thread-update-for-o",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-07-29T11:58:12.584Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L268",
        "sha256": "8c5850e2f703d96d60f21f8ad1b1676eb5b861c3a6a0d3cc0004a66c3125eb19"
      },
      "summary": "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.",
      "title": "Stage the Recoverable-pieces thread update for operator approval",
      "updated_at": "2026-07-29T11:58:12.584Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729115812-stage-the-recoverable-pieces-thread-update-for-o"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T12:00:17.270Z",
        "author": "Claude",
        "evidence": [
          "tools/workbench/discord/receipts/2026-07-29-plan.md"
        ],
        "id": "20260729120017-sync-the-recoverable-pieces-thread-to-the-re-lan",
        "impact": "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.",
        "kind": "deployment",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Sync the Recoverable-pieces thread to the re-landed raw material",
        "verification": [
          "workbench_discord.py plan after apply reports no pending change for the thread; provision-state.json records the applied content."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729120017-sync-the-recoverable-pieces-thread-to-the-re-lan",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-29T12:00:17.270Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L269",
        "sha256": "1c4ab2c5f42cf9d79884e9e748243952f488ffea0f57ae2545976571c7d9e9bc"
      },
      "summary": "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.",
      "title": "Sync the Recoverable-pieces thread to the re-landed raw material",
      "updated_at": "2026-07-29T12:00:17.270Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729120017-sync-the-recoverable-pieces-thread-to-the-re-lan"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T12:08:47.795Z",
        "author": "Claude",
        "evidence": [
          "fieldlab/retro/SESSION-RETRO-2026-07-29.md"
        ],
        "id": "20260729120847-retro-the-recoverable-pieces-landing-session",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Retro the recoverable-pieces landing session",
        "verification": [
          "Lesson follow-through table reconciled against SESSION-RETRO-2026-07-28.md; commit ledger reconciled against git log on both repos."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729120847-retro-the-recoverable-pieces-landing-session",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T12:08:47.795Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L270",
        "sha256": "b2301d1f75eb9365e0f587e4c8ecaff7604839f2a759ec043157dc60601c603a"
      },
      "summary": "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.",
      "title": "Retro the recoverable-pieces landing session",
      "updated_at": "2026-07-29T12:08:47.795Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729120847-retro-the-recoverable-pieces-landing-session"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T12:14:28.145Z",
        "author": "Claude",
        "evidence": [
          "HANDOFF-2026-07-29.md"
        ],
        "id": "20260729121428-make-the-am4-roadmap-page-track-the-mount",
        "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.",
        "kind": "deployment",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make the am4 roadmap page track the mount",
        "verification": [
          "X-Roadmap-Sha256 equals the local render sha; X-Workbench-Sha256 unchanged and equal; /health /join /workbench/downloads/quest-picker all 200 post-recreate."
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729121428-make-the-am4-roadmap-page-track-the-mount",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-29T12:14:28.145Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L271",
        "sha256": "4b7075ff62fc530c315d7370574a28dda9baa14a2d68ce957f73efb3a386d07d"
      },
      "summary": "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.",
      "title": "Make the am4 roadmap page track the mount",
      "updated_at": "2026-07-29T12:14:28.145Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729121428-make-the-am4-roadmap-page-track-the-mount"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T12:51:18.676Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729125118-adopt-the-decision-lifecycle-and-seed-pd-1-and-p",
        "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Adopt the decision lifecycle and seed PD-1 and PD-2",
        "verification": []
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729125118-adopt-the-decision-lifecycle-and-seed-pd-1-and-p",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T12:51:18.676Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L272",
        "sha256": "07974dd3b4e9fd6bcd83ecbb80fc023b45f785ee2614707ec80e3b25e951a7b6"
      },
      "summary": "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.",
      "title": "Adopt the decision lifecycle and seed PD-1 and PD-2",
      "updated_at": "2026-07-29T12:51:18.676Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729125118-adopt-the-decision-lifecycle-and-seed-pd-1-and-p"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T15:18:44.773Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729151844-decide-the-delegated-governance-batch-and-ship-i",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Decide the delegated governance batch and ship its instruments",
        "verification": []
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729151844-decide-the-delegated-governance-batch-and-ship-i",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T15:18:44.773Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L273",
        "sha256": "91cbb3de0cf397df0db6c1c8afc69576c29bd51460e42d6a8b3f02de2032d855"
      },
      "summary": "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.",
      "title": "Decide the delegated governance batch and ship its instruments",
      "updated_at": "2026-07-29T15:18:44.773Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729151844-decide-the-delegated-governance-batch-and-ship-i"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T15:26:08.697Z",
        "author": "Claude",
        "evidence": [
          "fieldlab/retro/SESSION-RETRO-2026-07-29.md"
        ],
        "id": "20260729152608-retro-the-decision-lifecycle-and-delegated-gover",
        "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Retro the decision-lifecycle and delegated-governance session",
        "verification": [
          "Follow-through table reconciled against the morning retro's lessons; commit table reconciled against git log d8337dc..9fe12f1."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729152608-retro-the-decision-lifecycle-and-delegated-gover",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T15:26:08.697Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L274",
        "sha256": "f40ab4b2aabb88f1cfb17251780177b51bdf915c3b93d4bdfdca5b8c897b4022"
      },
      "summary": "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.",
      "title": "Retro the decision-lifecycle and delegated-governance session",
      "updated_at": "2026-07-29T15:26:08.697Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729152608-retro-the-decision-lifecycle-and-delegated-gover"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T15:34:50.061Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729153450-stamp-workbench-provenance-from-the-source-commi",
        "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).",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Stamp workbench provenance from the source commit, two-phase",
        "verification": [
          "npm run workbench:test 8/8 green; render and check exercised in preview, production, and no-git modes on fixture repos; publish script parse-checked."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729153450-stamp-workbench-provenance-from-the-source-commi",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T15:34:50.061Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L275",
        "sha256": "52e5167c8a212751227235949c6c0735a2065598bd3c0a5acbd04c2530f764df"
      },
      "summary": "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).",
      "title": "Stamp workbench provenance from the source commit, two-phase",
      "updated_at": "2026-07-29T15:34:50.061Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729153450-stamp-workbench-provenance-from-the-source-commi"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T15:35:32.322Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729153532-land-the-first-production-stamped-workbench-rend",
        "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.",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Land the first production-stamped workbench render",
        "verification": [
          "workbench:check green byte-for-byte including the stamp; stamp sha matches git log -1 over the provenance inputs."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729153532-land-the-first-production-stamped-workbench-rend",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-29T15:35:32.322Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L276",
        "sha256": "4d4a2a8860f1fcce72273c78b420f36c8ad5358f3403475e76cdc057fc6f822a"
      },
      "summary": "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.",
      "title": "Land the first production-stamped workbench render",
      "updated_at": "2026-07-29T15:35:32.322Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729153532-land-the-first-production-stamped-workbench-rend"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T15:46:44.712Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729154644-make-the-task-count-mean-actionable-now-and-fix-",
        "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make the task count mean actionable-now and fix the MC-1 contradiction",
        "verification": [
          "workbench:test 14/14 including negatives 1-3 and the completion derivation matrix; discord bot self-test 87/87; live catalog renders 11 actionable, MC-1 Discuss row resolves to the forum."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729154644-make-the-task-count-mean-actionable-now-and-fix-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T15:46:44.712Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L277",
        "sha256": "ee232ea7e1a86a7c87ace3c598b080854673de85fc4afbb6a6ef26a6842cbb7b"
      },
      "summary": "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.",
      "title": "Make the task count mean actionable-now and fix the MC-1 contradiction",
      "updated_at": "2026-07-29T15:46:44.712Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729154644-make-the-task-count-mean-actionable-now-and-fix-"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T15:47:10.174Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729154710-land-the-actionable-count-render-with-its-source",
        "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.",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Land the actionable-count render with its source stamp",
        "verification": [
          "workbench:check green byte-for-byte; hero anchor and Discuss row inspected in the rendered output."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729154710-land-the-actionable-count-render-with-its-source",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-29T15:47:10.174Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L278",
        "sha256": "2b220ee371e9abdd5d6be98b3ee1c582c9e4e679fa614da3d1bcb8ef323c9261"
      },
      "summary": "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.",
      "title": "Land the actionable-count render with its source stamp",
      "updated_at": "2026-07-29T15:47:10.174Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729154710-land-the-actionable-count-render-with-its-source"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T15:52:36.114Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729155236-verify-live-destinations-before-and-after-every-",
        "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Verify live destinations before and after every workbench publish",
        "verification": [
          "9 new node --test cases drive the verifier through a canned transport: green path, 404 deep link, expired invite, wrong-guild thread, wrong-digest and truncated downloads, missing-token fail-closed, off-origin redirect; workbench:test 23/23."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729155236-verify-live-destinations-before-and-after-every-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T15:52:36.114Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L279",
        "sha256": "22766a5f74782106c0439a955078de1989c4bd077c32e3e1a509282cf6760693"
      },
      "summary": "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.",
      "title": "Verify live destinations before and after every workbench publish",
      "updated_at": "2026-07-29T15:52:36.114Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729155236-verify-live-destinations-before-and-after-every-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T15:57:27.401Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729155727-derive-access-policy-from-the-schema-and-name-th",
        "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Derive access policy from the schema and name the operator by role",
        "verification": [
          "workbench:test 28/28 including the source-note contradiction, vocabulary ban, person-name ban, derived-line variants, and LICENSING parity negative; rendered page has zero person names, seven derived access lines, all LICENSING.md mentions linked."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729155727-derive-access-policy-from-the-schema-and-name-th",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T15:57:27.401Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L280",
        "sha256": "1915a8b06e1af1f16d40c772da5327e8d7f2bf258b545cfa2f65fdf5fb09a5c1"
      },
      "summary": "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.",
      "title": "Derive access policy from the schema and name the operator by role",
      "updated_at": "2026-07-29T15:57:27.401Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729155727-derive-access-policy-from-the-schema-and-name-th"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T15:57:40.762Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729155740-land-the-schema-derived-policy-render",
        "impact": "The public page now derives its access-policy sentences, links every LICENSING.md mention, says the project operator, and is published from a3e14a2.",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Land the schema-derived policy render",
        "verification": [
          "workbench:check green byte-for-byte."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729155740-land-the-schema-derived-policy-render",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-29T15:57:40.762Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L281",
        "sha256": "d4a4afd4311a5eb9dec25674f33b13213739bed623eb89539bf12765ca5549e0"
      },
      "summary": "The public page now derives its access-policy sentences, links every LICENSING.md mention, says the project operator, and is published from a3e14a2.",
      "title": "Land the schema-derived policy render",
      "updated_at": "2026-07-29T15:57:40.762Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729155740-land-the-schema-derived-policy-render"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T16:00:15.442Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729160015-resolve-the-verify-live-bot-token-exactly-as-the",
        "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Resolve the verify-live bot token exactly as the provisioning bot does",
        "verification": [
          "verify-live pre-publish PASS receipt at captures/workbench-verify-live.json, 2026-07-29T15:59Z; verifier suite 9/9."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729160015-resolve-the-verify-live-bot-token-exactly-as-the",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-29T16:00:15.442Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L282",
        "sha256": "e520e41c586e988c90ca9870ba8261562cbd18ceddcd37d875aecc5e79301f54"
      },
      "summary": "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.",
      "title": "Resolve the verify-live bot token exactly as the provisioning bot does",
      "updated_at": "2026-07-29T16:00:15.442Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729160015-resolve-the-verify-live-bot-token-exactly-as-the"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T16:03:36.464Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729160336-report-the-trust-review-completion-and-teach-the",
        "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Report the trust review completion and teach the new recipes",
        "verification": [
          "Fold inspected at 1280x800 via DOM measurement: stamp, counts, invite, and honesty content all above the fold; live pre-publish receipt PASS 60/0/0."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729160336-report-the-trust-review-completion-and-teach-the",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-29T16:03:36.464Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L283",
        "sha256": "e894d63befd5032eaf43a712b8d472ed9c932337eeb0dad6d5cdc7695145b546"
      },
      "summary": "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.",
      "title": "Report the trust review completion and teach the new recipes",
      "updated_at": "2026-07-29T16:03:36.464Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729160336-report-the-trust-review-completion-and-teach-the"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-29T17:49:09.607Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260729174909-make-the-guest-package-tests-runnable-on-a-fresh",
        "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.",
        "kind": "verification",
        "milestones": [
          "M2"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make the guest-package tests runnable on a fresh checkout",
        "verification": [
          "python -m unittest discover -s tests is green on a clean worktree: 9 tests, 7 run, 2 skip. Both sealed-release tests pass with the bundle restored, and a one-bit flip of the sealed DLL fails the hash check, so it is not vacuous. The generator built the real release end-to-end after the refactor. Privacy scan of tests/ is clean, and three C:\\Users\\derek findings in the old test file are gone."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M2"
        ]
      },
      "id": "roadmap:20260729174909-make-the-guest-package-tests-runnable-on-a-fresh",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-29T17:49:09.607Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L284",
        "sha256": "76b59c4a26812f1aa383dac0096a39d5c6eac48e0295e1df22071befbac3627e"
      },
      "summary": "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.",
      "title": "Make the guest-package tests runnable on a fresh checkout",
      "updated_at": "2026-07-29T17:49:09.607Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729174909-make-the-guest-package-tests-runnable-on-a-fresh"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-07-29T20:32:29.034Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260729203229-unblock-the-link-carrying-discord-posts-on-the-c",
        "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.",
        "kind": "decision",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Unblock the link-carrying Discord posts on the current funnel URL",
        "verification": [
          "Bot self-test 87/87; check reports all posts render clean with placeholders resolved."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260729203229-unblock-the-link-carrying-discord-posts-on-the-c",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-29T20:32:29.034Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L285",
        "sha256": "7afd2d2c3e246fc0565dbf720ac9b5ae0d6922f3e8425b1248224c3a434ce828"
      },
      "summary": "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.",
      "title": "Unblock the link-carrying Discord posts on the current funnel URL",
      "updated_at": "2026-07-29T20:32:29.034Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260729203229-unblock-the-link-carrying-discord-posts-on-the-c"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-30T07:16:51.392Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260730071651-make-the-p7-boot-path-deterministic-instead-of-h",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make the P7 boot path deterministic instead of hand-built",
        "verification": [
          "Staged and UNVERIFIED against the VM, which stays stopped. infra/gcp/p7/RUNBOOK-boot-determinism.md carries the diagnosis, the by-hand apply steps (the startup-script fix needs terraform, which is off the table from this checkout), and a next-boot procedure that captures the wedged-boot evidence before the fix destroys it. The README and cost-runbook claims that a systemctl restart proved the reboot path are marked falsified rather than replaced - a restart never exercises the mount race or the shutdown teardown."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260730071651-make-the-p7-boot-path-deterministic-instead-of-h",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-30T07:16:51.392Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L286",
        "sha256": "83c66a0c0883d24f4313aa0132cbd23e71c980f38fdc6e79fa267ecbb49cba8c"
      },
      "summary": "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.",
      "title": "Make the P7 boot path deterministic instead of hand-built",
      "updated_at": "2026-07-30T07:16:51.392Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730071651-make-the-p7-boot-path-deterministic-instead-of-h"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-30T07:21:46.223Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260730072146-clear-the-false-stale-render-reading-on-the-live",
        "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.",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Clear the false stale-render reading on the live workbench",
        "verification": [
          "Measured directly: the raw CRLF working copy hashed to 2bb23be9, the LF-normalized bytes to 976f51cc, and 976f51cc is exactly the value the live funnel reports in its X-Workbench-Sha256 header. After refreshing the working tree under the new attributes the local file hashes to 976f51cc and npm run workbench:verify-live -- --post-publish reports PASS, 69 checks, 0 failed, 0 warnings, including the served-page-hash-matches-local-render check that previously could not pass on this machine."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260730072146-clear-the-false-stale-render-reading-on-the-live",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-30T07:21:46.223Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L287",
        "sha256": "16d464da509f165c7017720c6243f0c240d3189c990525b35dedfaa13c73c4b7"
      },
      "summary": "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.",
      "title": "Clear the false stale-render reading on the live workbench",
      "updated_at": "2026-07-30T07:21:46.223Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730072146-clear-the-false-stale-render-reading-on-the-live"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-30T07:28:01.782Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260730072801-retro-the-live-demo-session-and-register-the-two",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Retro the live demo session and register the two questions it raised",
        "verification": [
          "Documentation only - no code, config, or infrastructure changed by this commit; roadmap check --staged green."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260730072801-retro-the-live-demo-session-and-register-the-two",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-30T07:28:01.782Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L288",
        "sha256": "3aa33ed299614dd8bddf40691971693719ad8eaff7f150c34918b00003062317"
      },
      "summary": "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.",
      "title": "Retro the live demo session and register the two questions it raised",
      "updated_at": "2026-07-30T07:28:01.782Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730072801-retro-the-live-demo-session-and-register-the-two"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-30T07:33:22.243Z",
        "author": "Claude",
        "evidence": [
          "infra/gcp/p7/RUNBOOK-schema-repair.md",
          "Lumberjacks/infra/docker/init.sql"
        ],
        "id": "20260730073322-apply-the-game-schema-on-every-stack-start-not-o",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Apply the game schema on every stack start, not once per volume",
        "verification": [
          "Reproduced the P7 state locally (existing cluster wiped to zero tables, both incident errors verbatim), then repaired it: dbschema exit 0, 13 tables, the regions SELECT returns 0 rows and the events INSERT returns INSERT 0 1.",
          "Schema applied three times consecutively at exit 0; docker compose config resolves both mounts to the real file with the gate on all four services.",
          "Game.Gateway builds Release with 0 warnings and 0 errors; Game.Gateway.Tests 207/207 pass."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260730073322-apply-the-game-schema-on-every-stack-start-not-o",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-30T07:33:22.243Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L289",
        "sha256": "49510a8522fd961174ef95730d0b65fe941d0aa23169c05139186d8fb69e80e9"
      },
      "summary": "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.",
      "title": "Apply the game schema on every stack start, not once per volume",
      "updated_at": "2026-07-30T07:33:22.243Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730073322-apply-the-game-schema-on-every-stack-start-not-o"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-30T07:36:48.872Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260730073648-record-the-boot-and-publish-gate-decisions-as-ad",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Record the boot and publish-gate decisions as ADRs and retro them",
        "verification": [
          "The append-only journal was reconciled across a concurrent branch by union on id ordered by timestamp, preserving each record's original bytes rather than re-serializing them - a first attempt reformatted all 288 historic records and was discarded and redone, and the journal now diffs against the concurrent branch as two insertions and zero removals. The generated HTML was re-rendered from the merged inputs rather than hand-resolved; roadmap check reports OK with generated HTML current. The ADR index lists both new records. Every boot claim in the new documents is labelled UNVERIFIED against the machine, which stays stopped by policy."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260730073648-record-the-boot-and-publish-gate-decisions-as-ad",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-30T07:36:48.872Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L290",
        "sha256": "c62c66c5e57e7d9a8aa6b2fb82443db2be3835d7cc8cd9bf12b9f9d003db573e"
      },
      "summary": "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.",
      "title": "Record the boot and publish-gate decisions as ADRs and retro them",
      "updated_at": "2026-07-30T07:36:48.872Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730073648-record-the-boot-and-publish-gate-decisions-as-ad"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-30T07:39:34.574Z",
        "author": "Claude",
        "evidence": [
          "infra/gcp/p7/RUNBOOK-schema-repair.md"
        ],
        "id": "20260730073934-retire-the-lumberjacks-root-declaration-that-not",
        "impact": "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.",
        "kind": "documentation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Retire the LUMBERJACKS_ROOT declaration that nothing reads",
        "verification": [
          "docker compose config parses the P7 stack with LUMBERJACKS_ROOT empty; every remaining mention in infra/ is historical prose, not a lookup."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260730073934-retire-the-lumberjacks-root-declaration-that-not",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-30T07:39:34.574Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L291",
        "sha256": "f679a3a684e34f58e1989d3c7beb6dd8fee979be6bc2af19c84c119fb4bb8ad5"
      },
      "summary": "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.",
      "title": "Retire the LUMBERJACKS_ROOT declaration that nothing reads",
      "updated_at": "2026-07-30T07:39:34.574Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730073934-retire-the-lumberjacks-root-declaration-that-not"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-30T07:58:12.521Z",
        "author": "Claude",
        "evidence": [
          "infra/gcp/p7/RUNBOOK-schema-repair.md"
        ],
        "id": "20260730075812-keep-the-schema-gate-from-boot-looping-the-stack",
        "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.",
        "kind": "implementation",
        "milestones": [
          "M3"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Keep the schema gate from boot-looping the stack under compose --wait",
        "verification": [
          "Reproduced the interaction: compose up -d --wait against a successful one-shot exits 1 with 'exited (0)'. With the profile applied, run --rm exits 0 and up -d --wait exits 0.",
          "docker compose config on the P7 stack: dbschema absent from the default and tls profiles, present under the schema profile; caddy's tls profile unaffected."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M3"
        ]
      },
      "id": "roadmap:20260730075812-keep-the-schema-gate-from-boot-looping-the-stack",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-30T07:58:12.521Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L292",
        "sha256": "2528f4d5432c2d90bec63525255ac51b2ee78a485b1dd150da09414d666fa0ec"
      },
      "summary": "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.",
      "title": "Keep the schema gate from boot-looping the stack under compose --wait",
      "updated_at": "2026-07-30T07:58:12.521Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730075812-keep-the-schema-gate-from-boot-looping-the-stack"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-30T08:56:34.807Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260730085634-wire-the-mcp-mod-channel-card-to-its-real-thread",
        "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Wire the MCP Mod Channel card to its real thread",
        "verification": [
          "Bot apply receipt + provision-state entry; workbench render/check green; verify-live confirms the new thread lives in the expected guild under the forum."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260730085634-wire-the-mcp-mod-channel-card-to-its-real-thread",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-30T08:56:34.807Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L293",
        "sha256": "1d2247dba971b74e80c49c59bbe2b681e264d8ef8aef40478b1a3eef7b8d98be"
      },
      "summary": "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.",
      "title": "Wire the MCP Mod Channel card to its real thread",
      "updated_at": "2026-07-30T08:56:34.807Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730085634-wire-the-mcp-mod-channel-card-to-its-real-thread"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-30T08:57:38.138Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260730085738-land-the-thread-wired-render",
        "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.",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Land the thread-wired render",
        "verification": [
          "workbench:check green byte-for-byte; both guard suites 28/28."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260730085738-land-the-thread-wired-render",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-30T08:57:38.138Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L294",
        "sha256": "c076cd0a98eb5b00fd6046cf28f7747681c4307c1e1d3b5addf0a748c7d33341"
      },
      "summary": "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.",
      "title": "Land the thread-wired render",
      "updated_at": "2026-07-30T08:57:38.138Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730085738-land-the-thread-wired-render"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-30T08:57:56.407Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260730085756-correct-the-trust-review-report-s-test-arithmeti",
        "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.",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Correct the trust-review report's test arithmetic",
        "verification": [
          "node --test over both suites: 28 tests, 28 pass."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260730085756-correct-the-trust-review-report-s-test-arithmeti",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-30T08:57:56.407Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L295",
        "sha256": "6971d90d08748e2749bc9c6aa537ca02c413ca707ffb692d4acf5a91ec64de57"
      },
      "summary": "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.",
      "title": "Correct the trust-review report's test arithmetic",
      "updated_at": "2026-07-30T08:57:56.407Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730085756-correct-the-trust-review-report-s-test-arithmeti"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-30T12:47:10.707Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260730124710-retire-the-invite-expiry-clock-with-a-never-expi",
        "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.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Retire the invite expiry clock with a never-expiring replacement",
        "verification": [
          "Bot self-test 93/93 including six new guild-invite checks (replacement on same channel, never expires, old invite never revoked, no-op when permanent); live mint verified via the Discord API."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260730124710-retire-the-invite-expiry-clock-with-a-never-expi",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-30T12:47:10.707Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L296",
        "sha256": "1ce8000e90f7d0bea657d1f9b5fd07a42c31ae16971ccee45db27a487f306792"
      },
      "summary": "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.",
      "title": "Retire the invite expiry clock with a never-expiring replacement",
      "updated_at": "2026-07-30T12:47:10.707Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730124710-retire-the-invite-expiry-clock-with-a-never-expi"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-30T12:47:25.358Z",
        "author": "Claude",
        "evidence": [],
        "id": "20260730124725-land-the-permanent-invite-render",
        "impact": "The public page now carries the never-expiring invite in both hero and footer, published from 6b38b3c.",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Land the permanent-invite render",
        "verification": [
          "workbench:check green byte-for-byte; invite renders in both slots."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260730124725-land-the-permanent-invite-render",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-30T12:47:25.358Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L297",
        "sha256": "f93a7d7a5d6c85deb2e520da70d8320e74d3e6a9bf8917b21ee88a42b46a2df4"
      },
      "summary": "The public page now carries the never-expiring invite in both hero and footer, published from 6b38b3c.",
      "title": "Land the permanent-invite render",
      "updated_at": "2026-07-30T12:47:25.358Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730124725-land-the-permanent-invite-render"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-30T17:55:36.922Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/NATIVE-NETWORK-LANDSCAPE-2026-07-30.md",
          "fieldlab/runs/native-valheim/native-20260730-172100-am4-touch/",
          "fieldlab/runs/native-valheim/native-20260730-173650-am4-handshake-delay/",
          "fieldlab/runs/native-valheim/native-20260730-174850-am4-runtime-control/",
          "fieldlab/runs/native-valheim/native-20260730-174910-am4-handshake-accept/"
        ],
        "id": "20260730175536-closed-unattended-native-client-fan-out-and-off-",
        "impact": "OMEN and i5 now launch native GPU-rendered Valheim, select persisted characters, and join without a Start click. On AM4, co-presence fan-out emitted every native-selected candidate and inventory pickups returned on both clients. Handshake authority I/O now waits on a worker: a 2,034 ms timeout produced no 250 ms wall hitch during the authority interval, while both fail-open and normal Lumberjacks ACCEPT reached world entry. A fixed allowlist applied rollback flags and a responder endpoint without restarting Valheim. P7 still runs the prior build; promotion is not claimed. Steam connection, routed and direct RPC, motion authority, ownership, world bootstrap, and zone lifecycle remain native or partial.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M4a",
          "M4b",
          "A4"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Closed unattended native-client, fan-out, and off-thread handshake blockers",
        "verification": [
          "Release build completed with zero warnings and zero errors",
          "Two unattended physical clients joined AM4 on RTX 5070 and Iris Xe; both inventory pickups succeeded",
          "Delayed authority wait was 2,034 ms with zero wall hitches at the configured 250 ms threshold; a normal ACCEPT joined after a 66 ms decision",
          "Runtime-control receipts reported old and effective values while container start time and PID remained unchanged"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M4a",
          "M4b",
          "A4"
        ]
      },
      "id": "roadmap:20260730175536-closed-unattended-native-client-fan-out-and-off-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-30T17:55:36.922Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L298",
        "sha256": "1876a38fe7a8aca8323c7c144794b889ea44d5922b3a645161aafed3bdf84bc9"
      },
      "summary": "OMEN and i5 now launch native GPU-rendered Valheim, select persisted characters, and join without a Start click. On AM4, co-presence fan-out emitted every native-selected candidate and inventory pickups returned on both clients. Handshake authority I/O now waits on a worker: a 2,034 ms timeout produced no 250 ms wall hitch during the authority interval, while both fail-open and normal Lumberjacks ACCEPT reached world entry. A fixed allowlist applied rollback flags and a responder endpoint without restarting Valheim. P7 still runs the prior build; promotion is not claimed. Steam connection, routed and direct RPC, motion authority, ownership, world bootstrap, and zone lifecycle remain native or partial.",
      "title": "Closed unattended native-client, fan-out, and off-thread handshake blockers",
      "updated_at": "2026-07-30T17:55:36.922Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730175536-closed-unattended-native-client-fan-out-and-off-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-30T18:14:04.354Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/plan-native-network-final-cutover.md"
        ],
        "id": "20260730181404-open-the-final-native-network-cutover-ladder",
        "impact": "The networking hold is superseded now that both physical clients run unattended. A sequenced plan defines zero-native completion across authenticated sessions, routed and direct control, ZDO selection and apply, ownership, world and zone synchronization, motion authority, and Steam-free cold join. Every slice requires real-client failure evidence on AM4 before P7 promotion; motion tuning stays gated until native use is zero.",
        "kind": "documentation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "M4b",
          "M7",
          "A4"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Open the final native-network cutover ladder",
        "verification": [
          "Plan reviewed against the current native-network landscape, netcode map, replacement worklog, and live client automation boundary."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "M4b",
          "M7",
          "A4"
        ]
      },
      "id": "roadmap:20260730181404-open-the-final-native-network-cutover-ladder",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-30T18:14:04.354Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L299",
        "sha256": "143a57bdd8874c69468caf1fb031e69534accd4ca59e4b21482b6147fcf756dd"
      },
      "summary": "The networking hold is superseded now that both physical clients run unattended. A sequenced plan defines zero-native completion across authenticated sessions, routed and direct control, ZDO selection and apply, ownership, world and zone synchronization, motion authority, and Steam-free cold join. Every slice requires real-client failure evidence on AM4 before P7 promotion; motion tuning stays gated until native use is zero.",
      "title": "Open the final native-network cutover ladder",
      "updated_at": "2026-07-30T18:14:04.354Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730181404-open-the-final-native-network-cutover-ladder"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-30T19:30:03.474Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/NATIVE-NETWORK-LANDSCAPE-2026-07-30.md",
          "fieldlab/runs/native-valheim/native-20260730-c0-clean/machine-summary.json",
          "fieldlab/runs/native-valheim/native-20260730-c0-poison/"
        ],
        "id": "20260730193003-add-native-network-poison-ledger-and-unattended-",
        "impact": "C0 now proves exact native funnel use and automated two-client reconnect on the AM4 development lane. The poison gate blocks forbidden native calls before their original methods run, so later native-zero claims are falsifiable; C1 durable Lumberjacks session work is next.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "M4b",
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add native-network poison ledger and unattended cutover driver",
        "verification": [
          "Release mod build: zero warnings and zero errors; both PowerShell client/scenario drivers parse; local compose resolves.",
          "Two physical clients joined AM4, moved, disconnected, relaunched, rejoined, and stopped under one manifest; all actor ledgers completed with zero writer loss.",
          "Poison proof blocked all 76 observed native calls at the first forbidden connection boundary."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "M4b",
          "A4"
        ]
      },
      "id": "roadmap:20260730193003-add-native-network-poison-ledger-and-unattended-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-30T19:30:03.474Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L300",
        "sha256": "f9376c6dde7b5763f4a483bf529985d9e8d529847e31b8028165045d4a0ec63c"
      },
      "summary": "C0 now proves exact native funnel use and automated two-client reconnect on the AM4 development lane. The poison gate blocks forbidden native calls before their original methods run, so later native-zero claims are falsifiable; C1 durable Lumberjacks session work is next.",
      "title": "Add native-network poison ledger and unattended cutover driver",
      "updated_at": "2026-07-30T19:30:03.474Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730193003-add-native-network-poison-ledger-and-unattended-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-30T20:02:38.903Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/plan-native-network-final-cutover.md",
          "fieldlab/runs/native-valheim/native-20260730-c1-final/c1-machine-summary.json"
        ],
        "id": "20260730200238-prove-one-durable-lumberjacks-game-session-and-r",
        "impact": "C1 now gives each client one bounded ordered Lumberjacks session with stable connection identity, acknowledgements, deduplication, backpressure, and socket resume. Two physical clients each replayed the same unacknowledged request after a forced disconnect, produced one accepted response, and reported a bounded withheld-receipt timeout without native control fallback. The mandatory replan puts a typed direct control pulse before routed RPC; no Valheim gameplay path is claimed replaced yet.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Prove one durable Lumberjacks game session and replan C2",
        "verification": [
          "Two unattended physical clients completed the C1 AM4 manifest and fresh-process Valheim resume.",
          "Both stable-id/epoch checks, exact sequence replays, single accepted responses, and no-receipt timeout checks passed in c1-machine-summary.json.",
          "Gateway container build completed with all solution projects and 580 checks green; the mod Release build completed with zero warnings and zero errors."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "A4"
        ]
      },
      "id": "roadmap:20260730200238-prove-one-durable-lumberjacks-game-session-and-r",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-30T20:02:38.903Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L301",
        "sha256": "22d8c76a89517b0475e3a3fc6c7503b90af30a072431a7dcbdad93c18b61852f"
      },
      "summary": "C1 now gives each client one bounded ordered Lumberjacks session with stable connection identity, acknowledgements, deduplication, backpressure, and socket resume. Two physical clients each replayed the same unacknowledged request after a forced disconnect, produced one accepted response, and reported a bounded withheld-receipt timeout without native control fallback. The mandatory replan puts a typed direct control pulse before routed RPC; no Valheim gameplay path is claimed replaced yet.",
      "title": "Prove one durable Lumberjacks game session and replan C2",
      "updated_at": "2026-07-30T20:02:38.903Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730200238-prove-one-durable-lumberjacks-game-session-and-r"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-30T20:27:58.782Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/NATIVE-NETWORK-LANDSCAPE-2026-07-30.md",
          "fieldlab/runs/native-valheim/native-20260730-c2a-final/c2a-machine-summary.json"
        ],
        "id": "20260730202758-prove-one-typed-direct-control-cutover-boundary",
        "impact": "C2a moves one selected post-join direct pulse onto the canonical reliable Lumberjacks session and applies it from Unity Update. In the accepted unattended AM4 pair run, both clients received one typed copy, both intentionally withheld copies became bounded stale results, and registered native tripwires received nothing while 107 of 107 selected native attempts were suppressed before ZRpc.Invoke. This is a partial direct-control boundary only; routed RPC, remaining control classes, ZDO selection and apply, ownership, world and zone synchronization, motion authority, handshake, and Steam transport remain native or partial. P7 was not changed.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Prove one typed direct-control cutover boundary",
        "verification": [
          "Both physical clients completed launch, join, typed delivery, withhold, fresh-process reconnect, and shutdown without operator input.",
          "c2a-machine-summary.json passed every client, suppression, disarm, artifact-hash, and Gateway-health check.",
          "Gateway Docker build completed through the canonical verified image; mod Release build completed with zero warnings and zero errors."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "A4"
        ]
      },
      "id": "roadmap:20260730202758-prove-one-typed-direct-control-cutover-boundary",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-30T20:27:58.782Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L302",
        "sha256": "ea1a72a3b40711b3535f4fe0b55241c9a9d5cfbc9f1058f17adcceff75977d9c"
      },
      "summary": "C2a moves one selected post-join direct pulse onto the canonical reliable Lumberjacks session and applies it from Unity Update. In the accepted unattended AM4 pair run, both clients received one typed copy, both intentionally withheld copies became bounded stale results, and registered native tripwires received nothing while 107 of 107 selected native attempts were suppressed before ZRpc.Invoke. This is a partial direct-control boundary only; routed RPC, remaining control classes, ZDO selection and apply, ownership, world and zone synchronization, motion authority, handshake, and Steam transport remain native or partial. P7 was not changed.",
      "title": "Prove one typed direct-control cutover boundary",
      "updated_at": "2026-07-30T20:27:58.782Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730202758-prove-one-typed-direct-control-cutover-boundary"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-30T21:15:21.544Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/NATIVE-NETWORK-LANDSCAPE-2026-07-30.md",
          "fieldlab/runs/native-valheim/native-20260730-c2b-final/c2b-machine-summary.json"
        ],
        "id": "20260730211521-prove-the-complete-routed-rpc-envelope-boundary",
        "impact": "C2b carries a fixed routed-method registry over the durable Lumberjacks session and dispatches it from Unity Update. Two unattended physical clients completed targeted request and response, server broadcast, a real zero-argument target-ZDO RPC_ResetCloth, deliberate withhold, and fresh-process reconnect. All 24 selected client attempts and all 19 selected server attempts were suppressed with zero native copies, duplicates, or dispatch failures. This proves the envelope shapes and selected registry only; unselected RPC methods, ZDO selection and apply, ownership, world and zone synchronization, motion authority, handshake, and Steam transport remain native or partial. P7 was not changed.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Prove the complete routed-RPC envelope boundary",
        "verification": [
          "The retained c2b-machine-summary.json passed every client, server-dispatch, suppression, cleanup, artifact-hash, and Gateway-health check.",
          "Gateway verified image completed all 580 checks; the mod Release build completed with zero warnings and zero errors."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "A4"
        ]
      },
      "id": "roadmap:20260730211521-prove-the-complete-routed-rpc-envelope-boundary",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-30T21:15:21.544Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L303",
        "sha256": "ce7642888a5c83033ce7c1763c01f881fe88d63c7353e9f84227c48e3c558046"
      },
      "summary": "C2b carries a fixed routed-method registry over the durable Lumberjacks session and dispatches it from Unity Update. Two unattended physical clients completed targeted request and response, server broadcast, a real zero-argument target-ZDO RPC_ResetCloth, deliberate withhold, and fresh-process reconnect. All 24 selected client attempts and all 19 selected server attempts were suppressed with zero native copies, duplicates, or dispatch failures. This proves the envelope shapes and selected registry only; unselected RPC methods, ZDO selection and apply, ownership, world and zone synchronization, motion authority, handshake, and Steam transport remain native or partial. P7 was not changed.",
      "title": "Prove the complete routed-RPC envelope boundary",
      "updated_at": "2026-07-30T21:15:21.544Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730211521-prove-the-complete-routed-rpc-envelope-boundary"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-30T22:32:43.383Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/NATIVE-NETWORK-LANDSCAPE-2026-07-30.md",
          "fieldlab/plan-native-network-final-cutover.md",
          "fieldlab/runs/native-valheim/native-20260730-c3-sixth/c3-machine-summary.json"
        ],
        "id": "20260730223243-prove-durable-lumberjacks-zdo-selection-and-type",
        "impact": "C3 now proves one authoritative ZDO semantic boundary independent of native CreateSyncList selection and network RPC_ZDOData apply. In an unattended AM4 pair run, the object survived a Gateway restart, reached late i5 as a snapshot, reached both clients as a valid delta and tombstone, rejected stale and malformed entries before mutation, and drained both isolated recipient queues. This is a run-tagged boundary proof, not general-prefab completion; ownership, world and zone synchronization, motion authority, cold join, Steam transport, and P7 promotion remain. The mandatory replan makes durable logical-peer identity and canonical-session semantic carriage the first C4 cell.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Prove durable Lumberjacks ZDO selection and typed apply",
        "verification": [
          "The retained c3-machine-summary.json passed every client, server, Gateway durability, acknowledgement, cleanup, artifact, and health check.",
          "Gateway verified image completed all 580 checks; the mod Release build completed with zero warnings and zero errors; all cutover PowerShell scripts parsed under PowerShell 5.1."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "A4"
        ]
      },
      "id": "roadmap:20260730223243-prove-durable-lumberjacks-zdo-selection-and-type",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-30T22:32:43.383Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L304",
        "sha256": "f15c5b12fb89a1cbbf42d9c069e8a6f9e14fea8384d7f43b2a293ec767886d02"
      },
      "summary": "C3 now proves one authoritative ZDO semantic boundary independent of native CreateSyncList selection and network RPC_ZDOData apply. In an unattended AM4 pair run, the object survived a Gateway restart, reached late i5 as a snapshot, reached both clients as a valid delta and tombstone, rejected stale and malformed entries before mutation, and drained both isolated recipient queues. This is a run-tagged boundary proof, not general-prefab completion; ownership, world and zone synchronization, motion authority, cold join, Steam transport, and P7 promotion remain. The mandatory replan makes durable logical-peer identity and canonical-session semantic carriage the first C4 cell.",
      "title": "Prove durable Lumberjacks ZDO selection and typed apply",
      "updated_at": "2026-07-30T22:32:43.383Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730223243-prove-durable-lumberjacks-zdo-selection-and-type"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-30T23:07:06.773Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/NATIVE-NETWORK-LANDSCAPE-2026-07-30.md",
          "fieldlab/plan-native-network-final-cutover.md",
          "fieldlab/runs/native-valheim/native-20260730-c4a-second/c4a-machine-summary.json"
        ],
        "id": "20260730230706-move-durable-zdo-semantics-onto-the-canonical-se",
        "impact": "C4a gives the Valheim server and each client a stable opaque logical-peer identity independent of transport incarnation, then carries C3 mutation, interest, delivery, receipt, and ACK frames on the authenticated reliable Lumberjacks session. In the accepted unattended AM4 pair run, Gateway restart and fresh Valheim processes changed connection ids without changing logical peers; six mutations were accepted, two recipient queues drained to zero, and no HTTP fallback row appeared. This proves identity and semantic carriage only; ownership leases, gameplay action authority, world and zone synchronization, motion authority, cold join, Steam transport, fallback deletion, and P7 promotion remain. P7 was not changed.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Move durable ZDO semantics onto the canonical session",
        "verification": [
          "The retained c4a-machine-summary.json passed every client, logical-identity, transport-incarnation, canonical-carriage, WAL-replay, typed-apply, acknowledgement, cleanup, artifact, renderer, and Gateway-health check.",
          "Both physical GPU clients completed launch, join, Gateway restart recovery, typed snapshot/delta/tombstone apply, fresh-process reconnect, and shutdown without operator input.",
          "Gateway verified image completed all 580 checks; ComfyNetworkSense 0.5.41 built with zero warnings and zero errors; changed PowerShell scripts parsed under PowerShell 5.1."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "A4"
        ]
      },
      "id": "roadmap:20260730230706-move-durable-zdo-semantics-onto-the-canonical-se",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-30T23:07:06.773Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L305",
        "sha256": "bd2b4bbdc1ed0a274685318a1bd1a89f48bf953f06479415e129ab0b8be3cd2b"
      },
      "summary": "C4a gives the Valheim server and each client a stable opaque logical-peer identity independent of transport incarnation, then carries C3 mutation, interest, delivery, receipt, and ACK frames on the authenticated reliable Lumberjacks session. In the accepted unattended AM4 pair run, Gateway restart and fresh Valheim processes changed connection ids without changing logical peers; six mutations were accepted, two recipient queues drained to zero, and no HTTP fallback row appeared. This proves identity and semantic carriage only; ownership leases, gameplay action authority, world and zone synchronization, motion authority, cold join, Steam transport, fallback deletion, and P7 promotion remain. P7 was not changed.",
      "title": "Move durable ZDO semantics onto the canonical session",
      "updated_at": "2026-07-30T23:07:06.773Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260730230706-move-durable-zdo-semantics-onto-the-canonical-se"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T01:04:20.559Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/NATIVE-NETWORK-LANDSCAPE-2026-07-30.md",
          "fieldlab/plan-native-network-final-cutover.md",
          "fieldlab/runs/native-valheim/native-20260730-c4b-tenth/ownership-lease-cutover-summary.json"
        ],
        "id": "20260731010420-prove-logical-peer-ownership-leases-and-authorit",
        "impact": "C4 now moves one real pickup per physical client through server-issued Lumberjacks leases on the canonical session. A forced socket loss reclaimed the first lease, wrong and expired epochs were rejected before mutation, and selected native owner, candidate, destroy, and inventory-pickup paths were suppressed. OMEN and i5 each received exactly one authoritative Raspberry, acknowledged completion, resumed in a fresh Valheim process, and stopped unattended. This is the selected AM4 ownership boundary only; world and zone synchronization, general method breadth, motion authority, cold join, Steam transport, fallback deletion, and P7 promotion remain.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "M4b",
          "M7",
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Prove logical-peer ownership leases and authoritative pickup",
        "verification": [
          "The retained ownership-lease-cutover-summary.json passed every client, server, runtime-gate, journal cleanup, exact inventory delta, renderer, reconnect, and composition check.",
          "Gateway verified image completed all 580 checks during the live cell; ComfyNetworkSense 0.5.42 built with zero warnings and zero errors; changed PowerShell scripts parsed under PowerShell 5.1."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "M4b",
          "M7",
          "A4"
        ]
      },
      "id": "roadmap:20260731010420-prove-logical-peer-ownership-leases-and-authorit",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T01:04:20.559Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L306",
        "sha256": "bbcd57cbc37673214887f45fc25e983c716b5195be591a96a352e7c05995eef7"
      },
      "summary": "C4 now moves one real pickup per physical client through server-issued Lumberjacks leases on the canonical session. A forced socket loss reclaimed the first lease, wrong and expired epochs were rejected before mutation, and selected native owner, candidate, destroy, and inventory-pickup paths were suppressed. OMEN and i5 each received exactly one authoritative Raspberry, acknowledged completion, resumed in a fresh Valheim process, and stopped unattended. This is the selected AM4 ownership boundary only; world and zone synchronization, general method breadth, motion authority, cold join, Steam transport, fallback deletion, and P7 promotion remain.",
      "title": "Prove logical-peer ownership leases and authoritative pickup",
      "updated_at": "2026-07-31T01:04:20.559Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731010420-prove-logical-peer-ownership-leases-and-authorit"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T02:20:59.604Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/NATIVE-NETWORK-LANDSCAPE-2026-07-30.md",
          "fieldlab/plan-native-network-final-cutover.md",
          "fieldlab/runs/native-valheim/native-20260730-c5-final/c5-boundary-summary.json"
        ],
        "id": "20260731022059-prove-lumberjacks-world-bootstrap-and-resumable-",
        "impact": "C5 moves the selected world descriptor and run-tagged zone-membership boundary onto the canonical Lumberjacks session. In the accepted unattended AM4 pair run, both physical GPU clients entered with native world fields blank, replayed an interrupted three-object snapshot idempotently, completed exactly once, unloaded to zero stale objects, and spawned nothing when membership was withheld; all selected native membership candidates were suppressed. Wrong protocol and world-generation descriptors stopped before scene entry. This is the selected AM4 boundary only; general-prefab breadth, motion authority, Steam-free cold join, native-zero composition, fallback deletion, and P7 promotion remain. The mandatory C5 replan advances to binary motion-authority proof without tuning.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "M4b",
          "M7",
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Prove Lumberjacks world bootstrap and resumable zone membership",
        "verification": [
          "The retained c5-boundary-summary.json records the artifact hashes, both renderers, descriptor substitution, snapshot replay, ACK gating, typed release, native suppression, and both pre-scene fault cells.",
          "ComfyNetworkSense 0.5.44 built with zero warnings and zero errors; the Gateway verified image built successfully; all changed PowerShell scripts parsed under PowerShell 5.1."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "M4b",
          "M7",
          "A4"
        ]
      },
      "id": "roadmap:20260731022059-prove-lumberjacks-world-bootstrap-and-resumable-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T02:20:59.604Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L307",
        "sha256": "ded4174895b71205c81628d58af97719c6fde0d95dbb4d60908a7fb3a6eb594e"
      },
      "summary": "C5 moves the selected world descriptor and run-tagged zone-membership boundary onto the canonical Lumberjacks session. In the accepted unattended AM4 pair run, both physical GPU clients entered with native world fields blank, replayed an interrupted three-object snapshot idempotently, completed exactly once, unloaded to zero stale objects, and spawned nothing when membership was withheld; all selected native membership candidates were suppressed. Wrong protocol and world-generation descriptors stopped before scene entry. This is the selected AM4 boundary only; general-prefab breadth, motion authority, Steam-free cold join, native-zero composition, fallback deletion, and P7 promotion remain. The mandatory C5 replan advances to binary motion-authority proof without tuning.",
      "title": "Prove Lumberjacks world bootstrap and resumable zone membership",
      "updated_at": "2026-07-31T02:20:59.604Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731022059-prove-lumberjacks-world-bootstrap-and-resumable-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T03:15:43.847Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/NATIVE-NETWORK-LANDSCAPE-2026-07-30.md",
          "fieldlab/plan-native-network-final-cutover.md",
          "fieldlab/runs/native-valheim/native-20260730-c6-eighth/c6-boundary-summary.json"
        ],
        "id": "20260731031543-prove-selected-lumberjacks-motion-authority-on-a",
        "impact": "C6 now makes authenticated numbered Lumberjacks motion the selected two-player remote transform source on the AM4 development lane. Both physical GPU clients applied motion in both directions while selected native writers were suppressed; an exact 20-frame gap held without native correction and recovered through reliable resync. This is binary authority evidence only. Steam-free cold join, general breadth, native-zero composition, tuning, P7 promotion, and fallback deletion remain.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Prove selected Lumberjacks motion authority on AM4",
        "verification": [
          "Both physical clients completed rendezvous, bidirectional drive/observe, exact gap, reliable resync, fresh-process resume, and unattended stop in native-20260730-c6-eighth.",
          "ComfyNetworkSense 0.5.45 built with zero warnings and zero errors; the Gateway verified image built and all 580 existing checks passed; changed PowerShell scripts parsed under PowerShell 5.1."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M3",
          "M4a",
          "A4"
        ]
      },
      "id": "roadmap:20260731031543-prove-selected-lumberjacks-motion-authority-on-a",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T03:15:43.847Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L308",
        "sha256": "dae4f972995e65624124f0b07bf0f3ee17ce41042b8c22932696ce2afaba22ed"
      },
      "summary": "C6 now makes authenticated numbered Lumberjacks motion the selected two-player remote transform source on the AM4 development lane. Both physical GPU clients applied motion in both directions while selected native writers were suppressed; an exact 20-frame gap held without native correction and recovered through reliable resync. This is binary authority evidence only. Steam-free cold join, general breadth, native-zero composition, tuning, P7 promotion, and fallback deletion remain.",
      "title": "Prove selected Lumberjacks motion authority on AM4",
      "updated_at": "2026-07-31T03:15:43.847Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731031543-prove-selected-lumberjacks-motion-authority-on-a"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T05:10:26.216Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731051026-wire-the-c7-native-socket-quarantine-falsifier-i",
        "impact": "The 60-second logical-peer hold is buildable and opt-in; live proof remains gated on a reachable Lumberjacks gateway.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Wire the C7 native socket-quarantine falsifier into the mod, client manifest, and OMEN/i5 harness",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731051026-wire-the-c7-native-socket-quarantine-falsifier-i",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T05:10:26.216Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L309",
        "sha256": "0947e04c29e425c844b8805f90c2ca9b6c8cb92c56d282b5b45519d8dfb36b6f"
      },
      "summary": "The 60-second logical-peer hold is buildable and opt-in; live proof remains gated on a reachable Lumberjacks gateway.",
      "title": "Wire the C7 native socket-quarantine falsifier into the mod, client manifest, and OMEN/i5 harness",
      "updated_at": "2026-07-31T05:10:26.216Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731051026-wire-the-c7-native-socket-quarantine-falsifier-i"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T05:27:10.093Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731052710-gate-c7-connection-status-virtualization-until-s",
        "impact": "Native character selection and world entry retain their real pre-quarantine state instead of entering respawn with an uninitialized player profile.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Gate C7 connection-status virtualization until socket quarantine actually starts",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731052710-gate-c7-connection-status-virtualization-until-s",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T05:27:10.093Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L310",
        "sha256": "30ccff45f900c231171ce81d14bf9cf34561f0499fbf8463172b7e3c839e44db"
      },
      "summary": "Native character selection and world entry retain their real pre-quarantine state instead of entering respawn with an uninitialized player profile.",
      "title": "Gate C7 connection-status virtualization until socket quarantine actually starts",
      "updated_at": "2026-07-31T05:27:10.093Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731052710-gate-c7-connection-status-virtualization-until-s"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T05:39:14.921Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731053914-retain-the-passing-two-client-c7-native-socket-q",
        "impact": "OMEN and i5 each held a live scene for 60 seconds with the selected ZSteamSocket disconnected, zero native funnel delta, and no native fallback; C7 remains open for Steam-free cold join.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Retain the passing two-client C7 native socket-quarantine falsifier",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731053914-retain-the-passing-two-client-c7-native-socket-q",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-31T05:39:14.921Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L311",
        "sha256": "9ec16c3e28464f0674e429d894d534a0045bcbffa84b9406cb28a8fef7dccb16"
      },
      "summary": "OMEN and i5 each held a live scene for 60 seconds with the selected ZSteamSocket disconnected, zero native funnel delta, and no native fallback; C7 remains open for Steam-free cold join.",
      "title": "Retain the passing two-client C7 native socket-quarantine falsifier",
      "updated_at": "2026-07-31T05:39:14.921Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731053914-retain-the-passing-two-client-c7-native-socket-q"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T06:24:54.854Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/scripts/Write-LogicalPeerCutoverSummary.ps1"
        ],
        "id": "20260731062454-implement-the-steam-free-logical-peer-cold-join-",
        "impact": "Authenticated Gateway peer announcements now construct Valheim bookkeeping peers without native sockets or serialized ZRpc packages. The physical-client lane omits +connect, requires a coherent C2a-C6 gate set, retains logical-peer evidence, and rejects partial server activation. Live OMEN/i5 cold-join and negative-cell proof remain pending; C7 is not complete.",
        "kind": "implementation",
        "milestones": [
          "M1",
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Implement the Steam-free logical-peer cold-join boundary and exact proof harness",
        "verification": [
          "ComfyNetworkSense Release build completed with zero warnings and zero errors.",
          "The Gateway verified image completed all 586 tests, including logical peer bind, resume reannouncement, and typed CharacterID forwarding."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1",
          "M7"
        ]
      },
      "id": "roadmap:20260731062454-implement-the-steam-free-logical-peer-cold-join-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T06:24:54.854Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L312",
        "sha256": "8bc5df698ae4765dc643404293f443fe30b0d54cbb25c4b240884d9d280ecde6"
      },
      "summary": "Authenticated Gateway peer announcements now construct Valheim bookkeeping peers without native sockets or serialized ZRpc packages. The physical-client lane omits +connect, requires a coherent C2a-C6 gate set, retains logical-peer evidence, and rejects partial server activation. Live OMEN/i5 cold-join and negative-cell proof remain pending; C7 is not complete.",
      "title": "Implement the Steam-free logical-peer cold-join boundary and exact proof harness",
      "updated_at": "2026-07-31T06:24:54.854Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731062454-implement-the-steam-free-logical-peer-cold-join-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T06:37:42.669Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731063742-hold-steam-free-clients-in-connecting-state-unti",
        "impact": "Prevents Game.FixedUpdate from logging out before the Gateway supplies the logical server and world descriptor; no native socket or handshake is created.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Hold Steam-free clients in connecting state until logical peer bootstrap",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731063742-hold-steam-free-clients-in-connecting-state-unti",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T06:37:42.669Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L313",
        "sha256": "da55ceb2814cbe8bf1b313f751f11a3e57bcc42348b8f4a33f3690e027557f5f"
      },
      "summary": "Prevents Game.FixedUpdate from logging out before the Gateway supplies the logical server and world descriptor; no native socket or handshake is created.",
      "title": "Hold Steam-free clients in connecting state until logical peer bootstrap",
      "updated_at": "2026-07-31T06:37:42.669Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731063742-hold-steam-free-clients-in-connecting-state-unti"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T06:50:42.510Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731065042-treat-absent-server-motion-telemetry-as-expected",
        "impact": "The collector now preflights the optional motion file and emits an explicit not-emitted receipt instead of failing a Steam-free join run that contains no motion actions.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Treat absent server motion telemetry as expected in the wait-only C7 cold-join proof",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731065042-treat-absent-server-motion-telemetry-as-expected",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T06:50:42.510Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L314",
        "sha256": "83204c9d9e87b89ef50316b29eebf1d6cdea9d16026467fb79d239370f0bda68"
      },
      "summary": "The collector now preflights the optional motion file and emits an explicit not-emitted receipt instead of failing a Steam-free join run that contains no motion actions.",
      "title": "Treat absent server motion telemetry as expected in the wait-only C7 cold-join proof",
      "updated_at": "2026-07-31T06:50:42.510Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731065042-treat-absent-server-motion-telemetry-as-expected"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T06:57:59.898Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731065759-make-native-poison-mandatory-for-every-steam-fre",
        "impact": "C7 now arms the native-use blocker on initial launch and fresh-process resume, and its reducer rejects an otherwise clean zero-use run when either client ledger was not poison-enabled.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make native poison mandatory for every Steam-free cold-join process",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731065759-make-native-poison-mandatory-for-every-steam-fre",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T06:57:59.898Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L315",
        "sha256": "4c6944ebea5e118f52d7abbf823291d30c43665cb68b3022673840be4ab47f4d"
      },
      "summary": "C7 now arms the native-use blocker on initial launch and fresh-process resume, and its reducer rejects an otherwise clean zero-use run when either client ledger was not poison-enabled.",
      "title": "Make native poison mandatory for every Steam-free cold-join process",
      "updated_at": "2026-07-31T06:57:59.898Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731065759-make-native-poison-mandatory-for-every-steam-fre"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T07:08:18.829Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731070818-add-exact-c7-fail-closed-admission-and-descripto",
        "impact": "The physical OMEN lane now proves invalid enrollment, unavailable Gateway, incompatible release, and wrong protocol each stop without joining or native fallback under poison. Explicit invalid enrollment claims also fail closed instead of inheriting private-plane authority. Live four-cell execution remains pending.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add exact C7 fail-closed admission and descriptor cells",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731070818-add-exact-c7-fail-closed-admission-and-descripto",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T07:08:18.829Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L316",
        "sha256": "071ab9add94977dfa4160355c5a02ef35d53f94d02a627c80f76a90b26d8df16"
      },
      "summary": "The physical OMEN lane now proves invalid enrollment, unavailable Gateway, incompatible release, and wrong protocol each stop without joining or native fallback under poison. Explicit invalid enrollment claims also fail closed instead of inheriting private-plane authority. Live four-cell execution remains pending.",
      "title": "Add exact C7 fail-closed admission and descriptor cells",
      "updated_at": "2026-07-31T07:08:18.829Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731070818-add-exact-c7-fail-closed-admission-and-descripto"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T07:13:23.643Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731071323-scope-invalid-enrollment-strictness-to-the-expli",
        "impact": "The local Gateway retains its established private-plane development fallback when no production enrollment store is mounted, while the bounded C7 query still proves an invalid explicit credential is denied; negative-run cleanup receipts now serialize reliably.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Scope invalid-enrollment strictness to the explicit C7 negative cell",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731071323-scope-invalid-enrollment-strictness-to-the-expli",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T07:13:23.643Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L317",
        "sha256": "ad11ee191ed1d75f9037c371e53d7bd15ae0b859394fea536dac28dc50fb71d7"
      },
      "summary": "The local Gateway retains its established private-plane development fallback when no production enrollment store is mounted, while the bounded C7 query still proves an invalid explicit credential is denied; negative-run cleanup receipts now serialize reliably.",
      "title": "Scope invalid-enrollment strictness to the explicit C7 negative cell",
      "updated_at": "2026-07-31T07:13:23.643Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731071323-scope-invalid-enrollment-strictness-to-the-expli"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T07:32:56.821Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731073256-accepted-steam-free-cold-join-and-completed-the-",
        "impact": "OMEN and i5 cold-joined twice with client native use zero; four negative cells failed closed. C8 is now ordered as candidate closure and coverage audit, first full fault composition, then an independent repeat with save-integrity comparison.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Accepted Steam-free cold join and completed the mandatory C7 replan",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731073256-accepted-steam-free-cold-join-and-completed-the-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-31T07:32:56.821Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L318",
        "sha256": "cdd4141f64b2e3b7755a9375b4aa08c3b86b0afd01368b1eee875373452e1e98"
      },
      "summary": "OMEN and i5 cold-joined twice with client native use zero; four negative cells failed closed. C8 is now ordered as candidate closure and coverage audit, first full fault composition, then an independent repeat with save-integrity comparison.",
      "title": "Accepted Steam-free cold join and completed the mandatory C7 replan",
      "updated_at": "2026-07-31T07:32:56.821Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731073256-accepted-steam-free-cold-join-and-completed-the-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T07:50:14.887Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731075014-build-the-c8-native-zero-composition-gate",
        "impact": "C8 now machine-checks all required actions and faults, arms native poison on AM4 and both clients, compares world-save fingerprints, proves a distinct logical-peer ownership contender is rejected, excludes disconnected listen-shell no-ops from the remote-native denominator, and emits one terminal descriptor failure receipt.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Build the C8 native-zero composition gate",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731075014-build-the-c8-native-zero-composition-gate",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T07:50:14.887Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L319",
        "sha256": "3f595d1e4ff970ddac3e591fc42a696efedd10ba22217f7a6bf91c6cb8bd0e5b"
      },
      "summary": "C8 now machine-checks all required actions and faults, arms native poison on AM4 and both clients, compares world-save fingerprints, proves a distinct logical-peer ownership contender is rejected, excludes disconnected listen-shell no-ops from the remote-native denominator, and emits one terminal descriptor failure receipt.",
      "title": "Build the C8 native-zero composition gate",
      "updated_at": "2026-07-31T07:50:14.887Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731075014-build-the-c8-native-zero-composition-gate"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T12:20:13.729Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731122013-native-two-client-cutover-reached-full-compositi",
        "impact": "C0-C7 and focused C8 gates remain accepted; rerun a clean full C8 before C9, with lifecycle-safe Player protection retained as a hard invariant.",
        "kind": "documentation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Native two-client cutover reached full composition; reject full24 after reconnect Player safety loss and ship continuous godmode re-arm",
        "verification": []
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731122013-native-two-client-cutover-reached-full-compositi",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-31T12:20:13.729Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L320",
        "sha256": "5c68d4a3ad2b8428ca5a4df1a31899788421f58836e1f1be11e7e5278436b198"
      },
      "summary": "C0-C7 and focused C8 gates remain accepted; rerun a clean full C8 before C9, with lifecycle-safe Player protection retained as a hard invariant.",
      "title": "Native two-client cutover reached full composition; reject full24 after reconnect Player safety loss and ship continuous godmode re-arm",
      "updated_at": "2026-07-31T12:20:13.729Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731122013-native-two-client-cutover-reached-full-compositi"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T13:11:50.186Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731131150-harden-i5-lane-probe-and-deploy-scripts-against-",
        "impact": "C8 full-composition preflight no longer dies on ssh stderr chatter; lane health and delivery are decided only by explicit checks, exit codes, and SHA256 verification",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Harden i5 lane probe and deploy scripts against new OpenSSH post-quantum stderr warnings that aborted C8 preflight under the orchestrator's fail-closed error mode",
        "verification": [
          "Test-I5Link.ps1 and a scratch Deploy-ToI5.ps1 rerun in-process under ErrorActionPreference=Stop; exit 0 and SHA-verified delivery; the following full25 attempt passed i5 preflight and all three deploys"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731131150-harden-i5-lane-probe-and-deploy-scripts-against-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T13:11:50.186Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L321",
        "sha256": "718915f3b17fec68b62d021b7d418a2eca1e0f8e28b6352e5c33f0e500e438b6"
      },
      "summary": "C8 full-composition preflight no longer dies on ssh stderr chatter; lane health and delivery are decided only by explicit checks, exit codes, and SHA256 verification",
      "title": "Harden i5 lane probe and deploy scripts against new OpenSSH post-quantum stderr warnings that aborted C8 preflight under the orchestrator's fail-closed error mode",
      "updated_at": "2026-07-31T13:11:50.186Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731131150-harden-i5-lane-probe-and-deploy-scripts-against-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T13:32:53.008Z",
        "author": "Claude",
        "evidence": [
          "Lumberjacks/scripts/roadmap.mjs",
          "Lumberjacks/scripts/roadmap.test.mjs",
          "db3248c"
        ],
        "id": "20260731133253-make-the-roadmap-staged-gate-survive-the-hook-en",
        "impact": "The pre-commit gate rejected correctly-staged commits from any git worktree: git exports GIT_DIR pointing at .git/worktrees/<name>, which is outside the work tree, so git stopped discovering, treated the cwd as the top of the tree, and returned an empty --show-prefix. The gate then hunted for a staged docs/roadmap/commit-notes.jsonl that git had just reported as Lumberjacks/docs/roadmap/commit-notes.jsonl. roadmap.mjs now drops the inherited GIT_DIR/GIT_WORK_TREE for every git call it makes, restoring discovery from repoRoot and fixing the same latent defect in the repoRoot-relative pathspec below it; GIT_INDEX_FILE is deliberately kept because during a hook it names the index being committed.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Make the roadmap staged gate survive the hook environment so worktree commits stop needing --no-verify",
        "verification": [
          "node --test scripts/roadmap.test.mjs — three new tests run the real staged check over a real index in each shape git can produce: linked worktree with hook GIT_DIR, main checkout with no GIT_DIR and a relative index, and a standalone checkout where the package is the repo root",
          "Reverting the fix fails the worktree test with the exact production message, every non-merge commit must stage an appended docs/roadmap/commit-notes.jsonl record, while the main-checkout test keeps passing",
          "This commit was made from a git worktree with the hook enabled and no --no-verify"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260731133253-make-the-roadmap-staged-gate-survive-the-hook-en",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T13:32:53.008Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L322",
        "sha256": "d436f7c4675c4e7927320a01df4d3582aea376d84ac790fdebb60143bc94879c"
      },
      "summary": "The pre-commit gate rejected correctly-staged commits from any git worktree: git exports GIT_DIR pointing at .git/worktrees/<name>, which is outside the work tree, so git stopped discovering, treated the cwd as the top of the tree, and returned an empty --show-prefix. The gate then hunted for a staged docs/roadmap/commit-notes.jsonl that git had just reported as Lumberjacks/docs/roadmap/commit-notes.jsonl. roadmap.mjs now drops the inherited GIT_DIR/GIT_WORK_TREE for every git call it makes, restoring discovery from repoRoot and fixing the same latent defect in the repoRoot-relative pathspec below it; GIT_INDEX_FILE is deliberately kept because during a hook it names the index being committed.",
      "title": "Make the roadmap staged gate survive the hook environment so worktree commits stop needing --no-verify",
      "updated_at": "2026-07-31T13:32:53.008Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731133253-make-the-roadmap-staged-gate-survive-the-hook-en"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T13:33:25.478Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731133325-refactored-hot-paths-in-comfynetworksense-for-ze",
        "impact": "Substantially reduced GC pressure in Unity network context during dense telemetry and ZDO chunking.",
        "kind": "implementation",
        "milestones": [
          "M0"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Refactored hot paths in ComfyNetworkSense for zero-allocation (using ReadOnlySpan and Utf8JsonReader) and catalog arrays.",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M0"
        ]
      },
      "id": "roadmap:20260731133325-refactored-hot-paths-in-comfynetworksense-for-ze",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T13:33:25.478Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L323",
        "sha256": "e4fe2437ffbb03b9f376276c35223cdd9cb7ba12bde9514dbdb3535a4ac217dd"
      },
      "summary": "Substantially reduced GC pressure in Unity network context during dense telemetry and ZDO chunking.",
      "title": "Refactored hot paths in ComfyNetworkSense for zero-allocation (using ReadOnlySpan and Utf8JsonReader) and catalog arrays.",
      "updated_at": "2026-07-31T13:33:25.478Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731133325-refactored-hot-paths-in-comfynetworksense-for-ze"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T13:43:35.973Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731134335-retain-full25-full26-failure-evidence-three-orch",
        "impact": "full26 proved the Gateway-restart boundary and holder_mismatch contention on the patched build with native-zero intact end to end; the remaining defect is scoped to client interest re-declaration after Gateway reincarnation, fixed next",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Retain full25/full26 failure evidence: three orchestration walls (ssh post-quantum stderr, WaitSeconds range mismatch, RunId single-use dedup refusal) plus the post-reincarnation AoI interest starvation that stops ownership pickup",
        "verification": [
          "run receipts force-added per the ignored-runs convention; both clients re-verified on pinned SHA E6634AF7 after restoring OMEN's build-hijacked plugins DLL"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731134335-retain-full25-full26-failure-evidence-three-orch",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-31T13:43:35.973Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L324",
        "sha256": "6b44452409b1669440194f5c4b6d88c9fae08f86e3a9b364cea7aa5e188bf508"
      },
      "summary": "full26 proved the Gateway-restart boundary and holder_mismatch contention on the patched build with native-zero intact end to end; the remaining defect is scoped to client interest re-declaration after Gateway reincarnation, fixed next",
      "title": "Retain full25/full26 failure evidence: three orchestration walls (ssh post-quantum stderr, WaitSeconds range mismatch, RunId single-use dedup refusal) plus the post-reincarnation AoI interest starvation that stops ownership pickup",
      "updated_at": "2026-07-31T13:43:35.973Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731134335-retain-full25-full26-failure-evidence-three-orch"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T13:50:52.903Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731135052-harden-the-zero-allocation-refactor-strict-share",
        "impact": "chunk-size garbage now fails loudly instead of silently truncating evidence streams; the mod sheds the undeployable System.Text.Json dependency; hot-path parser changes are provable in seconds instead of full composition runs",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Harden the zero-allocation refactor: strict shared hex parsing, dependency-free telemetry extraction, guarded plugin auto-copy, and a host-run golden test net over the wire parsers",
        "verification": [
          "dotnet build Release 0 warnings; 102/102 golden tests green on host net8.0; live plugins DLL hash unchanged after a build, proving the CopyAssembly guard"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731135052-harden-the-zero-allocation-refactor-strict-share",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T13:50:52.903Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L325",
        "sha256": "85ab3565c0374bc261cb1e17362e8db7a5f6e06868f52ade367d7c6f5cd82c73"
      },
      "summary": "chunk-size garbage now fails loudly instead of silently truncating evidence streams; the mod sheds the undeployable System.Text.Json dependency; hot-path parser changes are provable in seconds instead of full composition runs",
      "title": "Harden the zero-allocation refactor: strict shared hex parsing, dependency-free telemetry extraction, guarded plugin auto-copy, and a host-run golden test net over the wire parsers",
      "updated_at": "2026-07-31T13:50:52.903Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731135052-harden-the-zero-allocation-refactor-strict-share"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T14:16:49.988Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731141649-re-declare-zdo-interest-when-the-gateway-session",
        "impact": "closes the full26 await_target starvation class; live-proven in full28: reincarnation_interest_rearm_requested at 14:06:12.005, interest re-registered and a 1647-object snapshot redelivered 218ms after the restarted Gateway came back",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Re-declare ZDO interest when the Gateway session reincarnates: the client now clears its registered-interest latch on reincarnation so AoI delivery resumes without a zone change",
        "verification": [
          "receipt chain in the retained full28 run bundle; build 90104C9A deployed SHA-verified to both clients with the System.Memory closure"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731141649-re-declare-zdo-interest-when-the-gateway-session",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T14:16:49.988Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L326",
        "sha256": "90279d7faed294a2d7d4425abf52847ef277bfac7dd5b040b62f5a08e1b7b3b3"
      },
      "summary": "closes the full26 await_target starvation class; live-proven in full28: reincarnation_interest_rearm_requested at 14:06:12.005, interest re-registered and a 1647-object snapshot redelivered 218ms after the restarted Gateway came back",
      "title": "Re-declare ZDO interest when the Gateway session reincarnates: the client now clears its registered-interest latch on reincarnation so AoI delivery resumes without a zone change",
      "updated_at": "2026-07-31T14:16:49.988Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731141649-re-declare-zdo-interest-when-the-gateway-session"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T14:17:49.728Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731141749-retain-full28-evidence-the-reincarnation-interes",
        "impact": "the full26 starvation class is closed by receipts; the remaining defect is orchestrator sequencing (restart on first mutation_posted instead of the correlated drive_complete), fixed next alongside the i5 queue gating",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Retain full28 evidence: the reincarnation interest re-arm fires and redelivers a 1647-object snapshot in 218ms, while the run itself fell to the orchestrator restart trigger racing OMEN mid-journal-drive",
        "verification": [
          "receipts under 500KB force-added per convention; the 76MB omen journal stream stays on disk in the run bundle for gate hashing"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731141749-retain-full28-evidence-the-reincarnation-interes",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-31T14:17:49.728Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L327",
        "sha256": "5d5b915a9819331b6620d6a50e0d0532c3bd68f13aa388f7b57775012dc36b18"
      },
      "summary": "the full26 starvation class is closed by receipts; the remaining defect is orchestrator sequencing (restart on first mutation_posted instead of the correlated drive_complete), fixed next alongside the i5 queue gating",
      "title": "Retain full28 evidence: the reincarnation interest re-arm fires and redelivers a 1647-object snapshot in 218ms, while the run itself fell to the orchestrator restart trigger racing OMEN mid-journal-drive",
      "updated_at": "2026-07-31T14:17:49.728Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731141749-retain-full28-evidence-the-reincarnation-interes"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T14:19:09.961Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731141909-align-the-native-client-s-waitseconds-ceiling-wi",
        "impact": "The C8 orchestrator can now honour its own -WaitSeconds 1800 contract end to end; long composition runs no longer abort at the i5 queue-smoke step after remote state is armed, and the queued run-pending leg re-binds the same widened ceiling",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Align the native client's -WaitSeconds ceiling with the orchestrator's advertised 1800s maximum",
        "verification": [
          "tests/test_powershell_param_contracts.py asserts every forwarded ValidateRange is a subset of its callee's; red against the old 1200 ceiling with the observed message, green after; -HoldSeconds 0..120 confirmed a subset of the client's 0..300; suite 9 passed 2 skipped"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731141909-align-the-native-client-s-waitseconds-ceiling-wi",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T14:19:09.961Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L328",
        "sha256": "d7019510ed893e4aca0c3341f78a6571129986475b4e6eacf518213ea6b9d9a8"
      },
      "summary": "The C8 orchestrator can now honour its own -WaitSeconds 1800 contract end to end; long composition runs no longer abort at the i5 queue-smoke step after remote state is armed, and the queued run-pending leg re-binds the same widened ceiling",
      "title": "Align the native client's -WaitSeconds ceiling with the orchestrator's advertised 1800s maximum",
      "updated_at": "2026-07-31T14:19:09.961Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731141909-align-the-native-client-s-waitseconds-ceiling-wi"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T14:21:45.884Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731142145-harden-the-c8-orchestrator-restart-proof-fires-o",
        "impact": "closes the full28 restart-vs-drive race, the focused-gate stale-task misread, the burned-RunId class, and the orphaned-client class in one pass; focused two-client gates become first-class runs",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Harden the C8 orchestrator: restart proof fires only on the correlated drive_complete, the i5 leg queues for every concurrent-harness run, RunId reuse is refused before arming, and abort cleanup sweeps late-spawning clients",
        "verification": [
          "PowerShell parser 0 errors; param-contract gate green; each defect is receipted in the retained full25/restartgate1/full27/full28 bundles"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731142145-harden-the-c8-orchestrator-restart-proof-fires-o",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T14:21:45.884Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L329",
        "sha256": "f61daf06f5003d9b20e12e9683da052536765ba424bb336fb5f0cd3733dad0c8"
      },
      "summary": "closes the full28 restart-vs-drive race, the focused-gate stale-task misread, the burned-RunId class, and the orphaned-client class in one pass; focused two-client gates become first-class runs",
      "title": "Harden the C8 orchestrator: restart proof fires only on the correlated drive_complete, the i5 leg queues for every concurrent-harness run, RunId reuse is refused before arming, and abort cleanup sweeps late-spawning clients",
      "updated_at": "2026-07-31T14:21:45.884Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731142145-harden-the-c8-orchestrator-restart-proof-fires-o"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T14:23:58.207Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731142358-runid-preflight-pattern-goes-quote-free-powershe",
        "impact": "the preflight failed closed before arming, so full29's namespace stayed clean and the RunId remains usable; validated against am4 with full28 counting 23 receipts and full29 zero",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "RunId preflight pattern goes quote-free: PowerShell 5.1 does not escape embedded double quotes on native command lines, so the remote grep uses dot-wildcards for the JSON quotes",
        "verification": [
          "manual ssh probes on both patterns; parse clean"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731142358-runid-preflight-pattern-goes-quote-free-powershe",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T14:23:58.207Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L330",
        "sha256": "f70c5794503f6432c6c23d406154d46ebab66957ec60726fef098f1eaab704c7"
      },
      "summary": "the preflight failed closed before arming, so full29's namespace stayed clean and the RunId remains usable; validated against am4 with full28 counting 23 receipts and full29 zero",
      "title": "RunId preflight pattern goes quote-free: PowerShell 5.1 does not escape embedded double quotes on native command lines, so the remote grep uses dot-wildcards for the JSON quotes",
      "updated_at": "2026-07-31T14:23:58.207Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731142358-runid-preflight-pattern-goes-quote-free-powershe"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T14:26:47.137Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731142647-complete-the-c8-breadth-audit-extractor-v2-surfa",
        "impact": "the C10 fallback-deletion entry criteria gain a concrete queue: 29 P1 admissions on the proven routed target-ZDO pattern, three component-family verification gates (vehicles, containers, AI handoff), 9 admin paths deferred behind the poison tripwire; resolves the RPC Admission Gaps register entry",
        "kind": "documentation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Complete the C8 breadth audit: extractor v2 surfaces the 120 ZNetView instance RPCs v1 missed, and every one of 160 RPCs plus 122 components is classified against the replacement lanes",
        "verification": [
          "extractor v2 deterministic with zero unresolved registrations against assembly sha 3b26c851; machine draft reviewed row-by-row with six corrections recorded in the audit doc"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731142647-complete-the-c8-breadth-audit-extractor-v2-surfa",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-31T14:26:47.137Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L331",
        "sha256": "a688f3252a1010c742b60e7c203ec44bd6af99de682c33c81710a29b6fcb81db"
      },
      "summary": "the C10 fallback-deletion entry criteria gain a concrete queue: 29 P1 admissions on the proven routed target-ZDO pattern, three component-family verification gates (vehicles, containers, AI handoff), 9 admin paths deferred behind the poison tripwire; resolves the RPC Admission Gaps register entry",
      "title": "Complete the C8 breadth audit: extractor v2 surfaces the 120 ZNetView instance RPCs v1 missed, and every one of 160 RPCs plus 122 components is classified against the replacement lanes",
      "updated_at": "2026-07-31T14:26:47.137Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731142647-complete-the-c8-breadth-audit-extractor-v2-surfa"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T14:36:37.944Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731143637-retain-full29-the-hardened-sequencing-held-drive",
        "impact": "the boundary chain is now proven through drive, restart, reconnect, and re-arm on two runs; the remaining defect reproduces only under a synchronized thundering-herd reconnect, and the lock-ordering audit is running before any further burn",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Retain full29: the hardened sequencing held (drive completed before the restart fired) and the interest re-arm fired again, but OMEN froze totally at the instant all three peers reconnected within 20ms - a timing race under investigation as a lock-order deadlock",
        "verification": [
          "zero log lines from any thread after 14:26:44.94 with no crash event and no shutdown ceremony; gateway shows all three sessions established at 14:26:44.93-44.97; same build survived the staggered reconnect in full28"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731143637-retain-full29-the-hardened-sequencing-held-drive",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-31T14:36:37.944Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L332",
        "sha256": "d3ee0658a27358101f38041276ff61a564cf6f27599381b522a5935c3897947c"
      },
      "summary": "the boundary chain is now proven through drive, restart, reconnect, and re-arm on two runs; the remaining defect reproduces only under a synchronized thundering-herd reconnect, and the lock-ordering audit is running before any further burn",
      "title": "Retain full29: the hardened sequencing held (drive completed before the restart fired) and the interest re-arm fired again, but OMEN froze totally at the instant all three peers reconnected within 20ms - a timing race under investigation as a lock-order deadlock",
      "updated_at": "2026-07-31T14:36:37.944Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731143637-retain-full29-the-hardened-sequencing-held-drive"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T14:49:11.771Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731144911-break-the-session-runner-s-ab-ba-deadlock-the-ou",
        "impact": "closes the full29 total-freeze class: main thread held gate wanting outboundGate while the worker held outboundGate wanting gate, and every gate-guarded getter froze across threads the moment a herd reconnect lined them up; the lock graph is now acyclic",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Break the session runner's AB-BA deadlock: the outbound-queue critical section no longer acquires the session gate, with a lock-free sequence counter and a pre-lock connection-id snapshot",
        "verification": [
          "lock-ordering audit verified the cycle and the fix shape; Release build 0 warnings; 102/102 golden tests; SHA 327C499B deployed verified to both clients; log-under-lock hygiene filed as a follow-up chip"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731144911-break-the-session-runner-s-ab-ba-deadlock-the-ou",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T14:49:11.771Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L333",
        "sha256": "77ee16bab9307fa8a051bb7f427330cd970cf7ba33a3ac07c01c68b419c6debc"
      },
      "summary": "closes the full29 total-freeze class: main thread held gate wanting outboundGate while the worker held outboundGate wanting gate, and every gate-guarded getter froze across threads the moment a herd reconnect lined them up; the lock graph is now acyclic",
      "title": "Break the session runner's AB-BA deadlock: the outbound-queue critical section no longer acquires the session gate, with a lock-free sequence counter and a pre-lock connection-id snapshot",
      "updated_at": "2026-07-31T14:49:11.771Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731144911-break-the-session-runner-s-ab-ba-deadlock-the-ou"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T14:56:02.828Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731145602-full30-omen-completes-all-49-composition-actions",
        "impact": "the ownership starvation class that consumed full26 through full29 is closed by receipts on the deadlock-free build; one boundary remains - i5's zone_membership_resume starved on stale post-reincarnation epoch state while OMEN's ordering dodged it - and the focused trace is running",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "full30: OMEN completes all 49 composition actions for the first time in program history, and the post-reincarnation ownership boundary passes on both clients - contention resolves in one second and the authoritative pickup lands with 131 native ownership calls suppressed",
        "verification": [
          "OMEN scenario_complete all_actions_completed at 14:53:35 including portal roundtrips and the disconnect-relaunch cycle; i5 receipts green through ownership pickup, zone_cross, then world_zone_probe_deadline applied=1 replayed=1 complete_count=0"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731145602-full30-omen-completes-all-49-composition-actions",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-31T14:56:02.828Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L334",
        "sha256": "12a0cd549828019b171f3347c192d689a36165c145c06dbc4f5fbf1f5719a01b"
      },
      "summary": "the ownership starvation class that consumed full26 through full29 is closed by receipts on the deadlock-free build; one boundary remains - i5's zone_membership_resume starved on stale post-reincarnation epoch state while OMEN's ordering dodged it - and the focused trace is running",
      "title": "full30: OMEN completes all 49 composition actions for the first time in program history, and the post-reincarnation ownership boundary passes on both clients - contention resolves in one second and the authoritative pickup lands with 131 native ownership calls suppressed",
      "updated_at": "2026-07-31T14:56:02.828Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731145602-full30-omen-completes-all-49-composition-actions"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T15:04:05.855Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731150405-re-arm-the-world-descriptor-cache-on-gateway-rei",
        "impact": "closes the last open composition boundary - full30's i5 zone_membership_resume starvation - by restoring the readiness-ladder barrier instead of racing the server's descriptor republish; sibling of the proven ZDO interest re-arm",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Re-arm the world-descriptor cache on Gateway reincarnation: the client drops its once-cached descriptor so zone actions wait for one confirmed against the new incarnation",
        "verification": [
          "code trace verified the cache is set once and the re-request gate never re-arms; Release build 0 warnings; 102/102 golden tests; SHA 0B69588B deployed verified to both clients"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731150405-re-arm-the-world-descriptor-cache-on-gateway-rei",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T15:04:05.855Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L335",
        "sha256": "dc6795a59316ecb428b4bb003f337d899420a9bac60e246b7a871eb20b2d79ca"
      },
      "summary": "closes the last open composition boundary - full30's i5 zone_membership_resume starvation - by restoring the readiness-ladder barrier instead of racing the server's descriptor republish; sibling of the proven ZDO interest re-arm",
      "title": "Re-arm the world-descriptor cache on Gateway reincarnation: the client drops its once-cached descriptor so zone actions wait for one confirmed against the new incarnation",
      "updated_at": "2026-07-31T15:04:05.855Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731150405-re-arm-the-world-descriptor-cache-on-gateway-rei"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T15:10:59.962Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731151059-close-the-log-under-lock-hazard-filed-alongside-",
        "impact": "closes candidate #2 from the 2026-07-31 lock-ordering audit (candidate #1, the outbound-gate AB-BA cycle, closed separately in 2b59e3e/327C499B): if the shared BepInEx log sink ever stalls, the main thread no longer wedges holding _gate, so every _gate-guarded getter (WebSocketConnected, UdpReady, State, ConnectionId, LogicalPeerId, ResumeEpoch) stays live across threads instead of freezing with it",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Close the log-under-lock hazard filed alongside the AB-BA fix: WriteReceipt now returns the formatted line instead of calling LogInfo itself, and all four _gate-holding call sites (BeginDirectPulseProbe, BeginProbe, EvaluateProbeDeadline, EvaluateDirectProbeDeadline) defer the LogInfo call until after _gate releases",
        "verification": [
          "Release build 0 warnings, 0 errors",
          "102/102 golden tests green; the Unity-free harness links WireParsers/BoundedRawHttp/etc but not this UnityEngine-dependent file by design, so this is a regression gate on adjacent code, not direct coverage of the fix"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731151059-close-the-log-under-lock-hazard-filed-alongside-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T15:10:59.962Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L336",
        "sha256": "5486dfcd4cf1df8379a50d123e3b11b98434d46f75fc0faad0d4c3c21722b839"
      },
      "summary": "closes candidate #2 from the 2026-07-31 lock-ordering audit (candidate #1, the outbound-gate AB-BA cycle, closed separately in 2b59e3e/327C499B): if the shared BepInEx log sink ever stalls, the main thread no longer wedges holding _gate, so every _gate-guarded getter (WebSocketConnected, UdpReady, State, ConnectionId, LogicalPeerId, ResumeEpoch) stays live across threads instead of freezing with it",
      "title": "Close the log-under-lock hazard filed alongside the AB-BA fix: WriteReceipt now returns the formatted line instead of calling LogInfo itself, and all four _gate-holding call sites (BeginDirectPulseProbe, BeginProbe, EvaluateProbeDeadline, EvaluateDirectProbeDeadline) defer the LogInfo call until after _gate releases",
      "updated_at": "2026-07-31T15:10:59.962Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731151059-close-the-log-under-lock-hazard-filed-alongside-"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T15:13:39.247Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731151339-full31-confirms-the-descriptor-re-arm-i5-s-zone-",
        "impact": "ownership passed again on both clients; the remaining failure is a zone-sampling race on the enter payload - i5 sent its post-cross zone and completed, OMEN sent its pre-cross zone and saw zero chunks; trace in flight",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "full31 confirms the descriptor re-arm (i5's zone resume passes; OMEN re-requests and accepts a fresh descriptor in one second) and isolates the last defect: the membership enter can carry the pre-teleport zone when zone_cross and zone_resume land in the same second",
        "verification": [
          "server published snapshots for both recipients instantly; OMEN session alive with journal acks while zero zone chunks arrived; receipts retained"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731151339-full31-confirms-the-descriptor-re-arm-i5-s-zone-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-31T15:13:39.247Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L337",
        "sha256": "c7fe6e780ae7273b97948748d0024613063e9476701d13e3e9c4981bf96e6d8f"
      },
      "summary": "ownership passed again on both clients; the remaining failure is a zone-sampling race on the enter payload - i5 sent its post-cross zone and completed, OMEN sent its pre-cross zone and saw zero chunks; trace in flight",
      "title": "full31 confirms the descriptor re-arm (i5's zone resume passes; OMEN re-requests and accepts a fresh descriptor in one second) and isolates the last defect: the membership enter can carry the pre-teleport zone when zone_cross and zone_resume land in the same second",
      "updated_at": "2026-07-31T15:13:39.247Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731151339-full31-confirms-the-descriptor-re-arm-i5-s-zone-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T15:22:22.834Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731152222-settle-barrier-for-zone-cross-the-action-complet",
        "impact": "closes the full31 zone-sampling race - the raw position write could be reverted by the character's per-tick processing, and the membership enter carried the pre-cross zone; the completion receipt now reports the observed settled zone, in the codebase's own settle-then-confirm idiom",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Settle barrier for zone_cross: the action completes only when a fresh tick-entry read reports the new zone, so the move has survived a full engine tick before any dependent action samples it",
        "verification": [
          "code trace verified the sampling site and the revert mechanism; Release build 0 warnings; 102/102 golden tests; SHA 363F3E15 deployed verified to both clients"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731152222-settle-barrier-for-zone-cross-the-action-complet",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T15:22:22.834Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L338",
        "sha256": "4ffc4cea908e112c385481a73eed0b3055c5aec77035e25d340ce4dbbfd4904f"
      },
      "summary": "closes the full31 zone-sampling race - the raw position write could be reverted by the character's per-tick processing, and the membership enter carried the pre-cross zone; the completion receipt now reports the observed settled zone, in the codebase's own settle-then-confirm idiom",
      "title": "Settle barrier for zone_cross: the action completes only when a fresh tick-entry read reports the new zone, so the move has survived a full engine tick before any dependent action samples it",
      "updated_at": "2026-07-31T15:22:22.834Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731152222-settle-barrier-for-zone-cross-the-action-complet"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T15:28:57.601Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731152857-portal-roundtrip-waits-bounded-for-far-portal-de",
        "impact": "full32 failed 2s into a 22s deadline while the linked portal ZDO was in flight after a relocation; the selection now retries each tick with a throttled progress receipt, and malformed portal state still fails immediately",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Portal roundtrip waits bounded for far-portal dependency delivery instead of failing on capacity timing - the retro's transient-pressure rule applied to the last fail-fast in the composition path",
        "verification": [
          "Release build 0 warnings; 102/102 golden tests; SHA 6A00DB9F deployed verified to both clients; full32 receipts retained"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731152857-portal-roundtrip-waits-bounded-for-far-portal-de",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T15:28:57.601Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L339",
        "sha256": "66e0caa168a21d3ed0236d29746b9c632f215d6b6aebde1114e1f03e212eaf59"
      },
      "summary": "full32 failed 2s into a 22s deadline while the linked portal ZDO was in flight after a relocation; the selection now retries each tick with a throttled progress receipt, and malformed portal state still fails immediately",
      "title": "Portal roundtrip waits bounded for far-portal dependency delivery instead of failing on capacity timing - the retro's transient-pressure rule applied to the last fail-fast in the composition path",
      "updated_at": "2026-07-31T15:28:57.601Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731152857-portal-roundtrip-waits-bounded-for-far-portal-de"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T15:33:48.830Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731153348-abort-cleanup-drains-the-i5-scheduled-task-befor",
        "impact": "full33's queue was correctly refused while full32's stopped-but-draining task still reported Running; the finally now polls task state up to 90s after the stop",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Abort cleanup drains the i5 scheduled task before the orchestrator exits, so a successor run can never collide with a predecessor's wait-loop tail",
        "verification": [
          "PowerShell parser 0 errors; param-contract gate green; the collision and refusal are receipted in the retained full33 stderr"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731153348-abort-cleanup-drains-the-i5-scheduled-task-befor",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T15:33:48.830Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L340",
        "sha256": "d41ddfa1ca1f31b285e4a9e4c81a4df5f3cf143bb3194ccc0be32339b03908df"
      },
      "summary": "full33's queue was correctly refused while full32's stopped-but-draining task still reported Running; the finally now polls task state up to 90s after the stop",
      "title": "Abort cleanup drains the i5 scheduled task before the orchestrator exits, so a successor run can never collide with a predecessor's wait-loop tail",
      "updated_at": "2026-07-31T15:33:48.830Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731153348-abort-cleanup-drains-the-i5-scheduled-task-befor"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T15:39:19.556Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731153919-teleport-readiness-receipts-name-the-missing-obj",
        "impact": "the next occurrence of the initial-load readiness tail self-identifies in the retained receipts instead of costing a diagnosis run; ties into the C9-adjacent initial-load measurement the retro already scheduled",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Teleport readiness receipts name the missing objects (uid and prefab, up to five) when a handful hold area_ready false - full34's initial-load tail sat at missing=1 of 1245 for ten stable seconds with no way to say which object",
        "verification": [
          "Release build 0 warnings; 102/102 golden tests; SHA ED5C598D deployed verified to both clients; full34 receipts retained"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731153919-teleport-readiness-receipts-name-the-missing-obj",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T15:39:19.556Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L341",
        "sha256": "03482569bef6e9827f2f48cef7e813e417b637b16af24b4744066cade9430d7c"
      },
      "summary": "the next occurrence of the initial-load readiness tail self-identifies in the retained receipts instead of costing a diagnosis run; ties into the C9-adjacent initial-load measurement the retro already scheduled",
      "title": "Teleport readiness receipts name the missing objects (uid and prefab, up to five) when a handful hold area_ready false - full34's initial-load tail sat at missing=1 of 1245 for ten stable seconds with no way to say which object",
      "updated_at": "2026-07-31T15:39:19.556Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731153919-teleport-readiness-receipts-name-the-missing-obj"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T15:43:38.002Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731154338-full34-full35-readiness-failures-root-caused-by-",
        "impact": "the acceptance pair is blocked on substrate hygiene, not machinery: completing runs clean up after themselves, aborted runs do not; the remediation is a run-tagged residue cleanup verb on the server plus abort-path invocation, and the current world needs a one-time sweep",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "full34/full35 readiness failures root-caused by receipts: zone 35,-1 grew from a stable 1245 objects to 1790 across the aborted full32/full33 - aborted runs leak their synthetic journal-drive objects, and the spawn zone's initial load can no longer converge inside deadlines",
        "verification": [
          "sector_objects receipts across the retained run bundles: full26=1241, full28=1246, full29=1245, full30=1246, full31=1245, full34=1790; full35 bootstrap could not reach area_ready at spawn"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731154338-full34-full35-readiness-failures-root-caused-by-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-31T15:43:38.002Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L342",
        "sha256": "d653ddf5f9dd72975bd8426a2093c4976c45b952959bf9ada10821ab17d29643"
      },
      "summary": "the acceptance pair is blocked on substrate hygiene, not machinery: completing runs clean up after themselves, aborted runs do not; the remediation is a run-tagged residue cleanup verb on the server plus abort-path invocation, and the current world needs a one-time sweep",
      "title": "full34/full35 readiness failures root-caused by receipts: zone 35,-1 grew from a stable 1245 objects to 1790 across the aborted full32/full33 - aborted runs leak their synthetic journal-drive objects, and the spawn zone's initial load can no longer converge inside deadlines",
      "updated_at": "2026-07-31T15:43:38.002Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731154338-full34-full35-readiness-failures-root-caused-by-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T22:38:59.009Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260731223859-retain-the-day-s-scenario-manifests-full27-throu",
        "impact": "scenario inputs referenced by every retained run bundle are tracked; OMEN's installed state matches main; i5 deploy is the one pending-by-actor item alongside the world residue sweep",
        "kind": "documentation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Retain the day's scenario manifests full27 through full35 plus restartgate1; OMEN synced to the merged build carrying every fix of the day plus the chip session's log-under-lock hygiene; the i5 went offline mid-deploy and takes the merged DLL on return",
        "verification": [
          "merged tree builds 0 warnings, 102/102 golden tests; OMEN deploy hash-verified 933C1259; i5 lane reported offline per doctrine, no retry"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731223859-retain-the-day-s-scenario-manifests-full27-throu",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-07-31T22:38:59.009Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L343",
        "sha256": "983178e09d9fb5797cefd07beac72b4f7b3d8141fffd2b97ad1a677904c97703"
      },
      "summary": "scenario inputs referenced by every retained run bundle are tracked; OMEN's installed state matches main; i5 deploy is the one pending-by-actor item alongside the world residue sweep",
      "title": "Retain the day's scenario manifests full27 through full35 plus restartgate1; OMEN synced to the merged build carrying every fix of the day plus the chip session's log-under-lock hygiene; the i5 went offline mid-deploy and takes the merged DLL on return",
      "updated_at": "2026-07-31T22:38:59.009Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731223859-retain-the-day-s-scenario-manifests-full27-throu"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T23:18:13.752Z",
        "author": "Codex",
        "evidence": [
          "leak receipts in note 20260731154338"
        ],
        "id": "20260731231813-the-cutoverresiduecleanup-runtime-control-verb-d",
        "impact": "Aborted runs can no longer starve spawn-zone bootstrap by accumulating drive residue (zone 35,-1 grew 1245 to 1790 across aborted full32/full33); this unblocks the one-time world sweep and the C8 acceptance pair full36+full37.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The cutoverResidueCleanup runtime-control verb destroys leaked synthetic cutover objects (C3/C5 probes and run-tagged ownership items), and the scenario orchestrator now invokes it unconditionally from its cleanup path with a per-run receipt.",
        "verification": [
          "mod builds with 0 warnings",
          "102/102 golden tests pass"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731231813-the-cutoverresiduecleanup-runtime-control-verb-d",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T23:18:13.752Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L344",
        "sha256": "3038704d17752d7a26b07f975c403b1c2f6351bc19277ebd78b7c409c84e683a"
      },
      "summary": "Aborted runs can no longer starve spawn-zone bootstrap by accumulating drive residue (zone 35,-1 grew 1245 to 1790 across aborted full32/full33); this unblocks the one-time world sweep and the C8 acceptance pair full36+full37.",
      "title": "The cutoverResidueCleanup runtime-control verb destroys leaked synthetic cutover objects (C3/C5 probes and run-tagged ownership items), and the scenario orchestrator now invokes it unconditionally from its cleanup path with a per-run receipt.",
      "updated_at": "2026-07-31T23:18:13.752Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731231813-the-cutoverresiduecleanup-runtime-control-verb-d"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T23:23:44.220Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/c8-native-zero-composition/residue-sweep-20260731.json"
        ],
        "id": "20260731232344-the-0-5-45-build-carrying-the-residue-cleanup-ve",
        "impact": "Zone 35,-1 is back at its ~1245 baseline (1236 before, 1234 after; the restart cleared the non-persistent probe residue and the verb destroyed the 5 persistent run-tagged ownership items). The C8 acceptance pair full36+full37 is unblocked on a single frozen build.",
        "kind": "deployment",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The 0.5.45 build carrying the residue-cleanup verb is live on all three machines - AM4 server restarted onto it, OMEN and i5 plugins hash-verified against the same DLL - and the one-time world sweep ran clean.",
        "verification": [
          "sweep receipt sweep-20260731-zone35: scanned=9155599 matched=5 destroyed=5",
          "i5 deploy verified 1/1 sha256; OMEN and AM4 md5 d0dfc9a6 identical"
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731232344-the-0-5-45-build-carrying-the-residue-cleanup-ve",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-07-31T23:23:44.220Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L345",
        "sha256": "72b3f9091553f7771024f16cd9026aa9080f64f045305f4f175edf54f69f382c"
      },
      "summary": "Zone 35,-1 is back at its ~1245 baseline (1236 before, 1234 after; the restart cleared the non-persistent probe residue and the verb destroyed the 5 persistent run-tagged ownership items). The C8 acceptance pair full36+full37 is unblocked on a single frozen build.",
      "title": "The 0.5.45 build carrying the residue-cleanup verb is live on all three machines - AM4 server restarted onto it, OMEN and i5 plugins hash-verified against the same DLL - and the one-time world sweep ran clean.",
      "updated_at": "2026-07-31T23:23:44.220Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731232344-the-0-5-45-build-carrying-the-residue-cleanup-ve"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-07-31T23:45:08.219Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/runs/native-valheim/native-20260731-c8-diag1"
        ],
        "id": "20260731234508-wall-class-11-root-caused-by-receipts-the-canoni",
        "impact": "The diagnosis instrumentation (TerrainComp awake identity log, named missing_objects with owners in bootstrap receipts, server-side terrain-compiler dedup in the cleanup verb) turned a spawn flake into a named object, owner, and contract gap in two runs. Immediate unblock: discard the stale journal WAL after any server restart; durable fix (session-scoped epoch invalidating the bank) goes to the post-C8 replan.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Wall class 11 root-caused by receipts: the canonical zone bank keys on the world-stable epoch while ZDO ids are server-session-scoped, so a server restart makes the Gateway replay phantom pre-restart objects - the client materializes a duplicate terrain compiler and vanilla's per-frame removal livelocks IsAreaReady, which is what actually failed full34/full35/full36 (the drive-object leak was real but coincidental).",
        "verification": [
          "diag1 receipts: two _TerrainCompiler ZDOs uid 1:2906630/1:2906632 alternating 291/290 removals in zone 34,0",
          "server dedup receipt sweep-20260731-terrain-dedup: zero duplicate compilers in 9155594 ZDOs - the collision is client-side",
          "102/102 golden tests; build 0 warnings"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731234508-wall-class-11-root-caused-by-receipts-the-canoni",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-07-31T23:45:08.219Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L346",
        "sha256": "cb873a28cae4ba92310278f58399f772e23271461d67597b669bb57b0a7566c1"
      },
      "summary": "The diagnosis instrumentation (TerrainComp awake identity log, named missing_objects with owners in bootstrap receipts, server-side terrain-compiler dedup in the cleanup verb) turned a spawn flake into a named object, owner, and contract gap in two runs. Immediate unblock: discard the stale journal WAL after any server restart; durable fix (session-scoped epoch invalidating the bank) goes to the post-C8 replan.",
      "title": "Wall class 11 root-caused by receipts: the canonical zone bank keys on the world-stable epoch while ZDO ids are server-session-scoped, so a server restart makes the Gateway replay phantom pre-restart objects - the client materializes a duplicate terrain compiler and vanilla's per-frame removal livelocks IsAreaReady, which is what actually failed full34/full35/full36 (the drive-object leak was real but coincidental).",
      "updated_at": "2026-07-31T23:45:08.219Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731234508-wall-class-11-root-caused-by-receipts-the-canoni"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-07-31T23:55:57.392Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/runs/native-valheim/native-20260731-c8-full37"
        ],
        "id": "20260731235557-the-zdo-journal-observe-verdict-now-counts-a-rec",
        "impact": "full37's only failure: after the post-restart WAL rebuild, the re-banked world delivers every object delta-first, so all snapshots land superseded and the old snapshot>=1 predicate deadlined a healthy observe. The canonical path had delivered the drive snapshot; the verdict could not see it. Wall class 12, and the acceptance pair is clear to rerun.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The zdo-journal observe verdict now counts a receipt-required snapshot that arrives as an idempotent duplicate (superseded at current revision) as delivery proof, receipted as receipt_snapshot_arrivals.",
        "verification": [
          "i5 full37 receipts: probe_failed zdo_journal_deadline snapshot=0 with superseded=4096 incoming==current",
          "102/102 golden tests; build 0 warnings"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260731235557-the-zdo-journal-observe-verdict-now-counts-a-rec",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-07-31T23:55:57.392Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L347",
        "sha256": "9f9c769824f3fbbbdf257444325666ac5de8e83e0f455edb85c918ce62bd787f"
      },
      "summary": "full37's only failure: after the post-restart WAL rebuild, the re-banked world delivers every object delta-first, so all snapshots land superseded and the old snapshot>=1 predicate deadlined a healthy observe. The canonical path had delivered the drive snapshot; the verdict could not see it. Wall class 12, and the acceptance pair is clear to rerun.",
      "title": "The zdo-journal observe verdict now counts a receipt-required snapshot that arrives as an idempotent duplicate (superseded at current revision) as delivery proof, receipted as receipt_snapshot_arrivals.",
      "updated_at": "2026-07-31T23:55:57.392Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260731235557-the-zdo-journal-observe-verdict-now-counts-a-rec"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-01T00:06:59.704Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/runs/native-valheim/native-20260731-c8-full38"
        ],
        "id": "20260801000659-the-zdo-journal-drive-now-actually-enqueues-its-",
        "impact": "The observe verdict historically passed on Gateway bank warmth (interest-snapshot replay of already-banked areas), which the wall-11 cold-bank rule made structurally unsatisfiable - full38 receipted snapshot=0 receipt_snapshot_arrivals=0 while faults arrived. The drive protocol is now deterministic under cold or warm banks; walls 12a/12b closed together.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The zdo-journal drive now actually enqueues its valid receipt-required full-body delivery (it was constructed but never sent), the fault clones are de-flagged so negative controls cannot satisfy the check, and the client counts a validated receipt-required arrival on any branch - applied, superseded, or stale-rejected.",
        "verification": [
          "receipt_required assignment audited: single setter, drive-only",
          "Gateway kind assignment read from source: mutations ride kind=delta, kind=snapshot exists only in RegisterInterest replay",
          "102/102 golden tests; build 0 warnings"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801000659-the-zdo-journal-drive-now-actually-enqueues-its-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-01T00:06:59.704Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L348",
        "sha256": "f35a01146115c1b40e15720eb3c7eed9216225560e6143b276fb3c301ca260d3"
      },
      "summary": "The observe verdict historically passed on Gateway bank warmth (interest-snapshot replay of already-banked areas), which the wall-11 cold-bank rule made structurally unsatisfiable - full38 receipted snapshot=0 receipt_snapshot_arrivals=0 while faults arrived. The drive protocol is now deterministic under cold or warm banks; walls 12a/12b closed together.",
      "title": "The zdo-journal drive now actually enqueues its valid receipt-required full-body delivery (it was constructed but never sent), the fault clones are de-flagged so negative controls cannot satisfy the check, and the client counts a validated receipt-required arrival on any branch - applied, superseded, or stale-rejected.",
      "updated_at": "2026-08-01T00:06:59.704Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801000659-the-zdo-journal-drive-now-actually-enqueues-its-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-01T00:33:37.948Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/runs/native-valheim/native-20260731-c8-full40"
        ],
        "id": "20260801003337-ownership-lease-frames-now-always-enqueue-on-the",
        "impact": "Wall class 14, receipted end to end: full40's server session events show ownership_frame_queue_rejected at queue_depth=256 with sequences 877 to 2639 in three seconds while the grant tried to enqueue. One queue is kept so reliable-sequence ordering is untouched; overshoot is bounded by the probes' own attempt budgets. Same class explains full39's contender seeing lease_missing.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Ownership lease frames now always enqueue on the canonical session - the 256-frame outbound cap is a bulk-data cap, not a control-plane cap - closing the priority inversion where a post-resume interest re-publish flood rejected the lease reissue grant at queue_depth=256 and starved the holder probe to its deadline.",
        "verification": [
          "server session receipt: ownership_frame_queue_rejected seq=2639 queue_depth=256",
          "102/102 golden tests; build 0 warnings"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801003337-ownership-lease-frames-now-always-enqueue-on-the",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-01T00:33:37.948Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L349",
        "sha256": "a3ecc7fdbbc7966cc60943a57aef2f5c13ebfbdfe40ca21d6fcc849beefe749e"
      },
      "summary": "Wall class 14, receipted end to end: full40's server session events show ownership_frame_queue_rejected at queue_depth=256 with sequences 877 to 2639 in three seconds while the grant tried to enqueue. One queue is kept so reliable-sequence ordering is untouched; overshoot is bounded by the probes' own attempt budgets. Same class explains full39's contender seeing lease_missing.",
      "title": "Ownership lease frames now always enqueue on the canonical session - the 256-frame outbound cap is a bulk-data cap, not a control-plane cap - closing the priority inversion where a post-resume interest re-publish flood rejected the lease reissue grant at queue_depth=256 and starved the holder probe to its deadline.",
      "updated_at": "2026-08-01T00:33:37.948Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801003337-ownership-lease-frames-now-always-enqueue-on-the"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-01T00:46:00.201Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/runs/native-valheim/native-20260731-c8-full41"
        ],
        "id": "20260801004600-a-local-teleport-now-announces-itself-on-the-rel",
        "impact": "Wall class 15: full41's mover teleported to the safe origin mid-observation and the observer's fail-closed implausible-target guard correctly refused the 87m correction forever (applied=0, failures=795, resync_applied=0). The guard stays strict; legitimate jumps get a legal reliable channel. This also de-races the composition's cross-client ordering: observers re-anchor whenever the mover teleports, not only when scheduling luck put the teleport first.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "A local teleport now announces itself on the reliable motion-resync lane (reason local_teleport, degenerate one-frame gap fields): the mover detects its own >30m jump between queued frames and publishes the resync, the Gateway accepts the second reason, and observers re-anchor through the existing ApplyReliableResync path.",
        "verification": [
          "full41 receipts: target_rejected target_error_mm=87058 stable; i5 safe-origin completed 00:38:08 after OMEN drive began 00:38:02",
          "102/102 golden tests; mod and gateway images build clean"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801004600-a-local-teleport-now-announces-itself-on-the-rel",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-01T00:46:00.201Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L350",
        "sha256": "b669d5be508ec99f82d072f1831d3fe92a2ca85afbc5e2d825b53966f4d5fb24"
      },
      "summary": "Wall class 15: full41's mover teleported to the safe origin mid-observation and the observer's fail-closed implausible-target guard correctly refused the 87m correction forever (applied=0, failures=795, resync_applied=0). The guard stays strict; legitimate jumps get a legal reliable channel. This also de-races the composition's cross-client ordering: observers re-anchor whenever the mover teleports, not only when scheduling luck put the teleport first.",
      "title": "A local teleport now announces itself on the reliable motion-resync lane (reason local_teleport, degenerate one-frame gap fields): the mover detects its own >30m jump between queued frames and publishes the resync, the Gateway accepts the second reason, and observers re-anchor through the existing ApplyReliableResync path.",
      "updated_at": "2026-08-01T00:46:00.201Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801004600-a-local-teleport-now-announces-itself-on-the-rel"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T01:18:47.414Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/docs/runbook-native-cutover-scenario.md preconditions"
        ],
        "id": "20260801011847-wall-class-13-root-caused-from-a-live-hang-dump-",
        "impact": "The intermittent whole-client freeze (full39, full42) was environmental, not netcode: any stray click into the console window - trivially possible on a streamed desktop - froze the client at the next log burst. Disk logging carries all evidence, so nothing is lost. The stall watchdog plus procdump turned one recurrence into the answer.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Wall class 13 root-caused from a live hang dump: the client freeze is the Windows QuickEdit console selection blocking the BepInEx console WriteFile on Unity's main thread - one thread in NtWriteFile, 316 in ordinary waits, no lock cycle. The BepInEx console is now disabled on both physical clients and the constraint is in the scenario runbook.",
        "verification": [
          "hang dump valheim-hang-20260731-175212: MainValheimThread blocked in KERNELBASE!WriteFile via mono icall",
          "BepInEx.cfg Logging.Console Enabled=false verified on OMEN and i5"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801011847-wall-class-13-root-caused-from-a-live-hang-dump-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-01T01:18:47.414Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L351",
        "sha256": "48db9a7fc3a472b73d36c5c13fb0baddcb4683e9bdb15d9d7ca92e5978684565"
      },
      "summary": "The intermittent whole-client freeze (full39, full42) was environmental, not netcode: any stray click into the console window - trivially possible on a streamed desktop - froze the client at the next log burst. Disk logging carries all evidence, so nothing is lost. The stall watchdog plus procdump turned one recurrence into the answer.",
      "title": "Wall class 13 root-caused from a live hang dump: the client freeze is the Windows QuickEdit console selection blocking the BepInEx console WriteFile on Unity's main thread - one thread in NtWriteFile, 316 in ordinary waits, no lock cycle. The BepInEx console is now disabled on both physical clients and the constraint is in the scenario runbook.",
      "updated_at": "2026-08-01T01:18:47.414Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801011847-wall-class-13-root-caused-from-a-live-hang-dump-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-01T01:25:39.402Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/runs/native-valheim/native-20260731-c8-full43"
        ],
        "id": "20260801012539-the-c8-portal-roundtrip-deadline-is-40-seconds-t",
        "impact": "A calibration miss, not a boundary defect: full43's receipts show the return zone converging 1753 missing to 0 in four seconds and the action failing at the finish line. The budget stays bounded at two vanilla worst-case legs plus margin.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The c8 portal-roundtrip deadline is 40 seconds: the old 22s budget covered both legs, the outbound consumed ~16s, and full43's return leg deadlined 0.2s after its area went ready - vanilla needs FindFloor plus teleport-timer ticks after readiness, up to 2s+15s per leg by decompiled contract.",
        "verification": [
          "full43 receipts: area_ready=True at 01:22:05.79, deadline_exceeded at 01:22:05.99",
          "Player.UpdateTeleport decompiled: 2s minimum, FindFloor gate, 15s distant fallback per leg"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801012539-the-c8-portal-roundtrip-deadline-is-40-seconds-t",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-01T01:25:39.402Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L352",
        "sha256": "92102015b090491c8317512366962bb46e825adf50c612bf75f6db456fd188f7"
      },
      "summary": "A calibration miss, not a boundary defect: full43's receipts show the return zone converging 1753 missing to 0 in four seconds and the action failing at the finish line. The budget stays bounded at two vanilla worst-case legs plus margin.",
      "title": "The c8 portal-roundtrip deadline is 40 seconds: the old 22s budget covered both legs, the outbound consumed ~16s, and full43's return leg deadlined 0.2s after its area went ready - vanilla needs FindFloor plus teleport-timer ticks after readiness, up to 2s+15s per leg by decompiled contract.",
      "updated_at": "2026-08-01T01:25:39.402Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801012539-the-c8-portal-roundtrip-deadline-is-40-seconds-t"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T01:36:44.033Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/runs/native-valheim/native-20260731-c8-full44",
          "fieldlab/runs/native-valheim/native-20260731-c8-full45"
        ],
        "id": "20260801013644-c8-is-complete-the-acceptance-pair-full44-and-fu",
        "impact": "Native replacement is proven complete on AM4 for the selected surface; the tuning lab (C9) may now open. The retained pair plus tonight's six receipted wall-class closures are the evidence base; the mandatory post-C8 replan lands next.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "C8 is complete: the acceptance pair full44 and full45 ran the full 49-action native-zero composition twice from clean client launches on one frozen build with unconditional client and server poison - composition passed, save integrity passed, coverage 20/20, zero failed checks, both runs.",
        "verification": [
          "full44: composition=passed integrity=passed coverage=passed failed_checks=none",
          "full45: composition=passed integrity=passed coverage=passed failed_checks=none",
          "residue receipts destroyed=0 both runs - steady-state hygiene"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801013644-c8-is-complete-the-acceptance-pair-full44-and-fu",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-01T01:36:44.033Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L353",
        "sha256": "fcca4c9f9e991bfaf56e4b47d428c6f4dd9fc5d7ebbd1643ccf36c35b27a702b"
      },
      "summary": "Native replacement is proven complete on AM4 for the selected surface; the tuning lab (C9) may now open. The retained pair plus tonight's six receipted wall-class closures are the evidence base; the mandatory post-C8 replan lands next.",
      "title": "C8 is complete: the acceptance pair full44 and full45 ran the full 49-action native-zero composition twice from clean client launches on one frozen build with unconditional client and server poison - composition passed, save integrity passed, coverage 20/20, zero failed checks, both runs.",
      "updated_at": "2026-08-01T01:36:44.033Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801013644-c8-is-complete-the-acceptance-pair-full44-and-fu"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T01:39:45.550Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/c8-native-zero-composition/README.md",
          "fieldlab/plan-native-network-final-cutover.md post-C8 replan"
        ],
        "id": "20260801013945-the-mandatory-post-c8-replan-is-in-the-master-pl",
        "impact": "The campaign's forward path is fully written: 2-6 focused days remain (C9 1-3, C10 1-3) plus two bounded P7 world reloads. Nothing in C0-C8 architecture reopens without new evidence.",
        "kind": "documentation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The mandatory post-C8 replan is in the master plan (C9 rendered motion next, then C10a admissions plus the session-scoped epoch fix, then C10b P7 promotion and close), the C8 evidence directory carries the pair's README and gate-summary with what it does and does not prove, the status table marks C8 complete, and the landscape records the composition while keeping breadth rows honest at Partial.",
        "verification": [
          "plan status table C8 row names full44+full45",
          "evidence README states the unverified set explicitly"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801013945-the-mandatory-post-c8-replan-is-in-the-master-pl",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-01T01:39:45.550Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L354",
        "sha256": "bbb301e447e389ecef41daab00ffaa59c20a3bc88343c5a96d40aa10e9c0f2be"
      },
      "summary": "The campaign's forward path is fully written: 2-6 focused days remain (C9 1-3, C10 1-3) plus two bounded P7 world reloads. Nothing in C0-C8 architecture reopens without new evidence.",
      "title": "The mandatory post-C8 replan is in the master plan (C9 rendered motion next, then C10a admissions plus the session-scoped epoch fix, then C10b P7 promotion and close), the C8 evidence directory carries the pair's README and gate-summary with what it does and does not prove, the status table marks C8 complete, and the landscape records the composition while keeping breadth rows honest at Partial.",
      "updated_at": "2026-08-01T01:39:45.550Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801013945-the-mandatory-post-c8-replan-is-in-the-master-pl"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T01:45:26.442Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/retro/SESSION-RETRO-2026-07-31.md",
          "fieldlab/docs/adr/0016-banked-state-must-carry-session-identity.md"
        ],
        "id": "20260801014526-session-retro-2026-07-31-and-adr-0016-are-writte",
        "impact": "The retro series has no gap and the campaign's biggest architectural finding has one durable home; five of last session's six lessons graded acted-on tonight.",
        "kind": "documentation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Session retro 2026-07-31 and ADR 0016 are written: the retro carries the six-wall night seat by seat with seven durable lessons, and the ADR fixes the contract that banked state must carry the identity scope of what it banks - the session-scoped epoch is a named C10a precondition with the WAL-wipe rule interim.",
        "verification": [
          "SESSION-RETRO-2026-07-31.md follows the house sections including follow-through and provenance",
          "ADR index carries 0016"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801014526-session-retro-2026-07-31-and-adr-0016-are-writte",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-01T01:45:26.442Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L355",
        "sha256": "018e816e2ae1a3460af1f50b1ff6c1424df5adc009e3c2dfaf0e7fffb28c0576"
      },
      "summary": "The retro series has no gap and the campaign's biggest architectural finding has one durable home; five of last session's six lessons graded acted-on tonight.",
      "title": "Session retro 2026-07-31 and ADR 0016 are written: the retro carries the six-wall night seat by seat with seven durable lessons, and the ADR fixes the contract that banked state must carry the identity scope of what it banks - the session-scoped epoch is a named C10a precondition with the WAL-wipe rule interim.",
      "updated_at": "2026-08-01T01:45:26.442Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801014526-session-retro-2026-07-31-and-adr-0016-are-writte"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T04:50:57.239Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260801045057-c9-motion-quality-lands-its-machine-half-from-th",
        "impact": "C9's acceptance is now half receipted and half honestly open: the rendered clip and the subjective verdict are still outstanding, i5 frame timing is labelled unmeasured rather than clean, and a reproducible 1.87s once-per-session stall in LumberjacksMotionRunner.Update is recorded as unresolved rather than guessed at.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "C9 motion quality lands its machine half from the retained C8 acceptance pair with no new run: zero native fallback, every hard correction attributed once peer actions are considered, divergence transient at 0.501s worst, recovery bounded at 10.866s inside deliberate interruptions, and no apply-attributable frame hitch on OMEN under magnitude attribution. The capture lane for the outstanding observer clip is built and proven on both machines.",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801045057-c9-motion-quality-lands-its-machine-half-from-th",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-01T04:50:57.239Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L356",
        "sha256": "7bf1c07b088b3fb9a46a7e621fb9919a9b8409f8b24a6f3b447b1727fe09ee93"
      },
      "summary": "C9's acceptance is now half receipted and half honestly open: the rendered clip and the subjective verdict are still outstanding, i5 frame timing is labelled unmeasured rather than clean, and a reproducible 1.87s once-per-session stall in LumberjacksMotionRunner.Update is recorded as unresolved rather than guessed at.",
      "title": "C9 motion quality lands its machine half from the retained C8 acceptance pair with no new run: zero native fallback, every hard correction attributed once peer actions are considered, divergence transient at 0.501s worst, recovery bounded at 10.866s inside deliberate interruptions, and no apply-attributable frame hitch on OMEN under magnitude attribution. The capture lane for the outstanding observer clip is built and proven on both machines.",
      "updated_at": "2026-08-01T04:50:57.239Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801045057-c9-motion-quality-lands-its-machine-half-from-th"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T05:37:04.853Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260801053704-the-i5-s-perf-receipts-were-lifted-off-the-lapto",
        "impact": "Two discriminators now constrain the open stall: it binds to ZNet initialisation, and its duration tracks machine class (OMEN 1.86-1.88s, i5 2.24-2.46s) rather than staying fixed, which favours CPU-bound one-shot work over a network timeout. Threshold-lowering is also ruled out as a probe because the motion runner carries no nested instrumented sections.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The i5's perf receipts were lifted off the laptop and the C9 motion-quality evidence now measures frame timing on BOTH clients, closing the unmeasured gap. The once-per-session motion runner stall reproduces 8/8 across both machines and sharpens into a named pattern: it opens on the first Update after ZNET START, records zero frame hitches inside a multi-second main-thread section, and precedes Starting respawn by 4.8-7.1s.",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801053704-the-i5-s-perf-receipts-were-lifted-off-the-lapto",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-01T05:37:04.853Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L357",
        "sha256": "fa65de18de42c5f51a134e78f5f6d5793defe0db5df79f51f75eeabb8609f9ef"
      },
      "summary": "Two discriminators now constrain the open stall: it binds to ZNet initialisation, and its duration tracks machine class (OMEN 1.86-1.88s, i5 2.24-2.46s) rather than staying fixed, which favours CPU-bound one-shot work over a network timeout. Threshold-lowering is also ruled out as a probe because the motion runner carries no nested instrumented sections.",
      "title": "The i5's perf receipts were lifted off the laptop and the C9 motion-quality evidence now measures frame timing on BOTH clients, closing the unmeasured gap. The once-per-session motion runner stall reproduces 8/8 across both machines and sharpens into a named pattern: it opens on the first Update after ZNET START, records zero frame hitches inside a multi-second main-thread section, and precedes Starting respawn by 4.8-7.1s.",
      "updated_at": "2026-08-01T05:37:04.853Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801053704-the-i5-s-perf-receipts-were-lifted-off-the-lapto"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T06:13:19.432Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260801061319-the-once-per-session-cold-join-stall-is-root-cau",
        "impact": "Two earlier claims in the C9 evidence are corrected rather than left standing: the cost was misattributed to LumberjacksMotionRunner because one perf section wraps eight runners and names only the last, and the reported missing frame hitch was a reading error - both row types stamp at completion, and reconstructed backwards the section and the respawn frame start together in all eight occurrences at 26-28 percent of that frame. The misnamed section is recorded as an unfixed observability defect because the build is frozen.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The once-per-session cold-join stall is root-caused and was NOT a motion defect: it is Valheim's own WorldGenerator.Initialize river/lake pregeneration, called synchronously from LogicalPeerCutoverRunner.ConstructPeer, and vanilla ZNet.RPC_PeerInfo does the same thing at the same point - so the Steam-free cold join pays vanilla's join cost rather than adding one. Corroborated 8/8 against an independent receipt clock.",
        "verification": []
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801061319-the-once-per-session-cold-join-stall-is-root-cau",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-01T06:13:19.432Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L358",
        "sha256": "0b919253fc26176d9aa4bafef00310aa1a40f4b812839e16d19573d2ff7479b0"
      },
      "summary": "Two earlier claims in the C9 evidence are corrected rather than left standing: the cost was misattributed to LumberjacksMotionRunner because one perf section wraps eight runners and names only the last, and the reported missing frame hitch was a reading error - both row types stamp at completion, and reconstructed backwards the section and the respawn frame start together in all eight occurrences at 26-28 percent of that frame. The misnamed section is recorded as an unfixed observability defect because the build is frozen.",
      "title": "The once-per-session cold-join stall is root-caused and was NOT a motion defect: it is Valheim's own WorldGenerator.Initialize river/lake pregeneration, called synchronously from LogicalPeerCutoverRunner.ConstructPeer, and vanilla ZNet.RPC_PeerInfo does the same thing at the same point - so the Steam-free cold join pays vanilla's join cost rather than adding one. Corroborated 8/8 against an independent receipt clock.",
      "updated_at": "2026-08-01T06:13:19.432Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801061319-the-once-per-session-cold-join-stall-is-root-cau"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T06:30:42.810Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260801063042-landed-the-pre-c10a-vehicles-mounts-research-sev",
        "impact": "A committed document is corrected rather than left standing: NETCODE-OWNERSHIP-MAP.md's headline that ZDO ownership is 100 percent server-authoritative through a single funnel is falsified by five verified client-side SetOwner sites (Ship, Sadle, Vagon, ArmorStand, ItemStand); its narrower ReleaseNearbyZDOS claim survives. OwnershipPinRunner was designed against that thesis and its selector has never been evaluated against a funnel it cannot see.",
        "kind": "planning",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Landed the pre-C10a vehicles/mounts research: seven source lenses over decompiled vanilla plus three adversarial critics, with the 16 blocking/serious corrections placed ahead of the body because several falsify claims the body tags as verified. The central finding is that ships separate control from simulation authority while mounts fuse them, so the audit's single vehicles-mounts family is really two.",
        "verification": []
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801063042-landed-the-pre-c10a-vehicles-mounts-research-sev",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-08-01T06:30:42.810Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L359",
        "sha256": "fa98d17ee250e40eb3dfd0783143508dd54970b06466583027a94f241d6a8117"
      },
      "summary": "A committed document is corrected rather than left standing: NETCODE-OWNERSHIP-MAP.md's headline that ZDO ownership is 100 percent server-authoritative through a single funnel is falsified by five verified client-side SetOwner sites (Ship, Sadle, Vagon, ArmorStand, ItemStand); its narrower ReleaseNearbyZDOS claim survives. OwnershipPinRunner was designed against that thesis and its selector has never been evaluated against a funnel it cannot see.",
      "title": "Landed the pre-C10a vehicles/mounts research: seven source lenses over decompiled vanilla plus three adversarial critics, with the 16 blocking/serious corrections placed ahead of the body because several falsify claims the body tags as verified. The central finding is that ships separate control from simulation authority while mounts fuse them, so the audit's single vehicles-mounts family is really two.",
      "updated_at": "2026-08-01T06:30:42.810Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801063042-landed-the-pre-c10a-vehicles-mounts-research-sev"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-01T06:42:40.277Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260801064240-split-the-eight-runner-perf-section-in-comfynetw",
        "impact": "Closes the observability defect that sent the first pass of the C9 stall analysis at the wrong component and put a vanilla worldgen cost into evidence as a motion defect. Source-only: the C9 build freeze holds and the deployed artifact is still mod SHA-256 765090d1 from c0db122, so the new labels first appear in the build C10a cuts. Because a section row is written only above PerfSectionWarnThresholdMs (25ms default), splitting changes which rows appear - the culprit runner is now named instead of hidden, and same-named LumberjacksMotionRunner rows are not comparable across the label change.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Split the eight-runner perf section in ComfyNetworkSense.Update into one named Measure() section per runner, inside an honestly named ComfyNetworkSense.CutoverRunners.Update roll-up. The old single section was named after only the last runner it wrapped, so every over-threshold row in perf-sections.jsonl charged seven other runners' cost to LumberjacksMotionRunner.",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801064240-split-the-eight-runner-perf-section-in-comfynetw",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-01T06:42:40.277Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L360",
        "sha256": "dc9048aa2f98f38a5969aba1f016458d13f8acc1a325c4521d420278a5f01608"
      },
      "summary": "Closes the observability defect that sent the first pass of the C9 stall analysis at the wrong component and put a vanilla worldgen cost into evidence as a motion defect. Source-only: the C9 build freeze holds and the deployed artifact is still mod SHA-256 765090d1 from c0db122, so the new labels first appear in the build C10a cuts. Because a section row is written only above PerfSectionWarnThresholdMs (25ms default), splitting changes which rows appear - the culprit runner is now named instead of hidden, and same-named LumberjacksMotionRunner rows are not comparable across the label change.",
      "title": "Split the eight-runner perf section in ComfyNetworkSense.Update into one named Measure() section per runner, inside an honestly named ComfyNetworkSense.CutoverRunners.Update roll-up. The old single section was named after only the last runner it wrapped, so every over-threshold row in perf-sections.jsonl charged seven other runners' cost to LumberjacksMotionRunner.",
      "updated_at": "2026-08-01T06:42:40.277Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801064240-split-the-eight-runner-perf-section-in-comfynetw"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T07:33:48.467Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260801073348-carried-the-2026-08-01-vehicles-mounts-research-",
        "impact": "Three corrections now sit where a C10a planner reads them: vehicles/mounts is two gates with opposite shapes (ships separate control from simulation authority, mounts fuse them), the lab cannot spawn a boat or cart or tame a Lox and has no board verb so those cells need new mod code plus world seeding before they can run at all, and the ownership exposure is live but misattributed. OwnershipPinRunner was deleted on 2026-07-21 in 66f7069; its successor OwnershipLeaseCutoverRunner patches ZDO.SetOwner globally but gates the body on ReleaseScopeDepth, raised only inside ReleaseNearbyZDOS, so the same blind spot was inherited and the five client-side SetOwner sites still pass through untouched.",
        "kind": "documentation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Carried the 2026-08-01 vehicles/mounts research corrections into the plan's own limits block, where C10a is actually costed, and traced the flagged ownership exposure to live code. The research had corrected NETCODE-OWNERSHIP-MAP.md but left the plan repeating the falsified framing.",
        "verification": []
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801073348-carried-the-2026-08-01-vehicles-mounts-research-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-01T07:33:48.467Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L361",
        "sha256": "f2bb07f55e1b7be1dc16c214a538bb97d673e5b69a655ebe5450060f90c6e4d9"
      },
      "summary": "Three corrections now sit where a C10a planner reads them: vehicles/mounts is two gates with opposite shapes (ships separate control from simulation authority, mounts fuse them), the lab cannot spawn a boat or cart or tame a Lox and has no board verb so those cells need new mod code plus world seeding before they can run at all, and the ownership exposure is live but misattributed. OwnershipPinRunner was deleted on 2026-07-21 in 66f7069; its successor OwnershipLeaseCutoverRunner patches ZDO.SetOwner globally but gates the body on ReleaseScopeDepth, raised only inside ReleaseNearbyZDOS, so the same blind spot was inherited and the five client-side SetOwner sites still pass through untouched.",
      "title": "Carried the 2026-08-01 vehicles/mounts research corrections into the plan's own limits block, where C10a is actually costed, and traced the flagged ownership exposure to live code. The research had corrected NETCODE-OWNERSHIP-MAP.md but left the plan repeating the falsified framing.",
      "updated_at": "2026-08-01T07:33:48.467Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801073348-carried-the-2026-08-01-vehicles-mounts-research-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T07:35:28.351Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260801073528-committed-the-nine-c8-wall-hunt-scenario-files-t",
        "impact": "The main checkout's git status is clean for the first time since the wall-hunt, so a future agent no longer has to work out whether nine unexplained files matter. Honest limit recorded with them: all fourteen wall-hunt scenarios plus diag1 share one identical action body and differ only in run_id, created_utc and expires_utc, so their value is a run-id ledger rather than distinct experiment designs. The retained acceptance pair full44/full45 carries a different body, which means the composition changed between the wall-hunt and acceptance. All of them carry a one-hour expires_utc and are historical records, not directly replayable.",
        "kind": "documentation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Committed the nine C8 wall-hunt scenario files that the overnight run left untracked (full36-full43 plus diag1), closing the holes in a series whose neighbours full30-full35 were already tracked. The 07-31 retro names these runs one by one as the walls they exposed, so the run ids now resolve to artifacts in the repo instead of to nothing.",
        "verification": []
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801073528-committed-the-nine-c8-wall-hunt-scenario-files-t",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-01T07:35:28.351Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L362",
        "sha256": "842f691c6dcf1807ca83868d823621a04802fbacae5e28732a41b125ead1233c"
      },
      "summary": "The main checkout's git status is clean for the first time since the wall-hunt, so a future agent no longer has to work out whether nine unexplained files matter. Honest limit recorded with them: all fourteen wall-hunt scenarios plus diag1 share one identical action body and differ only in run_id, created_utc and expires_utc, so their value is a run-id ledger rather than distinct experiment designs. The retained acceptance pair full44/full45 carries a different body, which means the composition changed between the wall-hunt and acceptance. All of them carry a one-hour expires_utc and are historical records, not directly replayable.",
      "title": "Committed the nine C8 wall-hunt scenario files that the overnight run left untracked (full36-full43 plus diag1), closing the holes in a series whose neighbours full30-full35 were already tracked. The 07-31 retro names these runs one by one as the walls they exposed, so the run ids now resolve to artifacts in the repo instead of to nothing.",
      "updated_at": "2026-08-01T07:35:28.351Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801073528-committed-the-nine-c8-wall-hunt-scenario-files-t"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-01T08:16:12.522Z",
        "author": "Claude",
        "evidence": [
          "network/mcp/etc/start-comfy-gateway.cmd",
          "network/mcp/requirements.txt",
          "network/mcp/tests/test_distribution_independence.py",
          "docs/audit/2026-08-01-hearth-boundary-audit.md"
        ],
        "id": "20260801081612-make-the-project-owned-mcp-independently-reprodu",
        "impact": "network/mcp is Baseline's own localhost mod-dev gateway, but its launcher carried a second interpreter rung pointing at a private operator virtual environment, so a component documented as project-owned silently preferred one machine. That rung is removed: the launcher now resolves COMFY_GATEWAY_PYTHON when explicitly set and otherwise plain python on PATH, with no machine-specific fallback. Dependencies are declared once in network/mcp/requirements.txt, and both the contributor setup in the README and the Docker image install from that same declaration, so a local environment and a built image resolve identical versions. The mod and MCP test instructions now run under the active project environment. This is an architectural correction about coupling, not a prohibition on naming: HEARTH and Mechnet remain valid terminology for development provenance and for drawing the product boundary, and what the new checks reject is concrete private environment configuration reaching into the distributable surface.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "baseline",
        "schema_version": 1,
        "summary": "Make the project-owned MCP independently reproducible",
        "verification": [
          "Gateway starts and answers healthz both from PATH-resolved python with no environment variable set and from an explicitly supplied interpreter.",
          "New distribution-independence test scans only the distributable MCP and workbench-tool surface, leaving internal evidence and provenance untouched; proven to fail when the original launcher rung is reintroduced, then restored green.",
          "Zip privacy scanner gains narrowly scoped private-configuration rules, drops its own hardcoded machine path, and now proves in its clean fixture that bare provenance naming and unrelated loopback endpoints stay legal.",
          "Full set green after integrating the inbound-direction boundary clause: 10 MCP tests, 28 roadmap tests, 19 workbench tests, 14 scanner rules, both generator checks current, telemetry-starter zip built CLEAN through the mandatory gate.",
          "Append-only history was not modified: the existing journal and the generated community roadmap page are byte-for-byte unchanged, and the new note validator is wired into note authoring only."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260801081612-make-the-project-owned-mcp-independently-reprodu",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-01T08:16:12.522Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L363",
        "sha256": "427adbbc3e5092a917bf6d40253e0305b4ee5b880557a604f639d8563f843dd8"
      },
      "summary": "network/mcp is Baseline's own localhost mod-dev gateway, but its launcher carried a second interpreter rung pointing at a private operator virtual environment, so a component documented as project-owned silently preferred one machine. That rung is removed: the launcher now resolves COMFY_GATEWAY_PYTHON when explicitly set and otherwise plain python on PATH, with no machine-specific fallback. Dependencies are declared once in network/mcp/requirements.txt, and both the contributor setup in the README and the Docker image install from that same declaration, so a local environment and a built image resolve identical versions. The mod and MCP test instructions now run under the active project environment. This is an architectural correction about coupling, not a prohibition on naming: HEARTH and Mechnet remain valid terminology for development provenance and for drawing the product boundary, and what the new checks reject is concrete private environment configuration reaching into the distributable surface.",
      "title": "Make the project-owned MCP independently reproducible",
      "updated_at": "2026-08-01T08:16:12.522Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801081612-make-the-project-owned-mcp-independently-reprodu"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-01T08:32:50.089Z",
        "author": "Codex",
        "evidence": [
          "Lumberjacks/scripts/workbench.mjs",
          "Lumberjacks/scripts/workbench.test.mjs",
          "cab0486"
        ],
        "id": "20260801083250-make-the-workbench-provenance-stamp-survive-the-",
        "impact": "provenance() built its git helper without scrubbing GIT_DIR/GIT_WORK_TREE, so from a linked worktree git stopped discovering the repository, treated Lumberjacks/ as the top of the work tree, and reported the committed provenance inputs as untracked. The mode flipped to preview and the pre-commit gate rejected a correctly-published page for any commit touching docs/workbench/ (worked around with --no-verify in cab0486). The generator now drops the inherited pointers exactly as roadmap.mjs already does.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make the workbench provenance stamp survive the hook environment",
        "verification": [
          "node --test scripts/workbench.test.mjs: 20/20, including a new linked-worktree test that renders and checks under the GIT_DIR git exports for a hook; the test was confirmed red against the unfixed generator."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260801083250-make-the-workbench-provenance-stamp-survive-the-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-01T08:32:50.089Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L364",
        "sha256": "8dc781e7f802e4de4799499e073d7cb1fb187a963ce27a2eee2eeb871bafd6aa"
      },
      "summary": "provenance() built its git helper without scrubbing GIT_DIR/GIT_WORK_TREE, so from a linked worktree git stopped discovering the repository, treated Lumberjacks/ as the top of the work tree, and reported the committed provenance inputs as untracked. The mode flipped to preview and the pre-commit gate rejected a correctly-published page for any commit touching docs/workbench/ (worked around with --no-verify in cab0486). The generator now drops the inherited pointers exactly as roadmap.mjs already does.",
      "title": "Make the workbench provenance stamp survive the hook environment",
      "updated_at": "2026-08-01T08:32:50.089Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801083250-make-the-workbench-provenance-stamp-survive-the-"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T08:33:24.466Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260801083324-land-the-git-dir-scrubbed-workbench-render",
        "impact": "The public workbench page now names its source commit again, published from a3c6aad, and a commit touching docs/workbench/ passes the pre-commit gate from a linked worktree without --no-verify.",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Land the GIT_DIR-scrubbed workbench render",
        "verification": [
          "workbench:check green on both phases; the pre-commit hook ran clean on a3c6aad from a linked worktree."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260801083324-land-the-git-dir-scrubbed-workbench-render",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-01T08:33:24.466Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L365",
        "sha256": "3ed5c18c2d9fd7279a637e6a47a823004e7a70b5e4387792f122b36cc1396eca"
      },
      "summary": "The public workbench page now names its source commit again, published from a3c6aad, and a commit touching docs/workbench/ passes the pre-commit gate from a linked worktree without --no-verify.",
      "title": "Land the GIT_DIR-scrubbed workbench render",
      "updated_at": "2026-08-01T08:33:24.466Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801083324-land-the-git-dir-scrubbed-workbench-render"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T09:12:56.168Z",
        "author": "Codex",
        "evidence": [
          "Lumberjacks/docs/roadmap/valheim-volunteer-roadmap.json,fieldlab/PINNED-networking-lane-2026-07.md,fieldlab/plan-native-network-final-cutover.md"
        ],
        "id": "20260801091256-correct-the-public-roadmap-the-networking-lane-i",
        "impact": "current_focus led with a 2026-07-28 PAUSED entry claiming the networking lane was on hard hold with no work scheduled, which the public roadmap page had been rendering faithfully for four days while slices C0-C8 landed. It now leads with the 2026-07-30 reopening and points at fieldlab/plan-native-network-final-cutover.md. The volunteer does_not_own line stopped citing the hold as the reason. This note is also the supersession marker the append-only journal lacked: the 2026-07-28 pin note stands as history and is not rewritten. Separately, 52 cp1252 round-trip mojibake sequences were repaired across the file, so the public page no longer renders corrupted glyphs.",
        "kind": "documentation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Correct the public roadmap: the networking lane is active, not on hard hold",
        "verification": [
          "roadmap:render + roadmap:check green; JSON re-parsed and structurally identical after the encoding repair; zero mojibake sequences remain in the rendered HTML"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260801091256-correct-the-public-roadmap-the-networking-lane-i",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-01T09:12:56.168Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L366",
        "sha256": "09e6ecbb32f927b82eacf0e1d55bc7a00d49736ac1081c32798382ef6fecf18b"
      },
      "summary": "current_focus led with a 2026-07-28 PAUSED entry claiming the networking lane was on hard hold with no work scheduled, which the public roadmap page had been rendering faithfully for four days while slices C0-C8 landed. It now leads with the 2026-07-30 reopening and points at fieldlab/plan-native-network-final-cutover.md. The volunteer does_not_own line stopped citing the hold as the reason. This note is also the supersession marker the append-only journal lacked: the 2026-07-28 pin note stands as history and is not rewritten. Separately, 52 cp1252 round-trip mojibake sequences were repaired across the file, so the public page no longer renders corrupted glyphs.",
      "title": "Correct the public roadmap: the networking lane is active, not on hard hold",
      "updated_at": "2026-08-01T09:12:56.168Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801091256-correct-the-public-roadmap-the-networking-lane-i"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-01T09:20:38.247Z",
        "author": "Codex",
        "evidence": [
          "HANDOFF-2026-07-29.md,fieldlab/docs/adr/0014-boot-must-converge-or-say-so.md"
        ],
        "id": "20260801092038-stop-the-public-roadmap-claiming-p7-is-live-whil",
        "impact": "Four current_focus entries used present-tense CURRENT/ACTIVE/LIVE language about P7 - 'remain on admitted release', 'remains live on P7', 'armed permanently on P7', 'serves the local Companion surfaces' - while the VM has been terminated since 2026-07-29T23:04 PT. They now read as LAST DEPLOYED CONFIG or ARMED IN CONFIG, DORMANT, each naming the stopped state. The Companion-surfaces entry was not merely stale but named the wrong host: that surface moved to AM4 and no longer depends on P7 at all. Same defect class as the hard-hold correction earlier today: present-tense prose in current_focus with no expiry, re-rendered under a fresh updated_at that vouches for it.",
        "kind": "documentation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Stop the public roadmap claiming P7 is live while the VM is stopped",
        "verification": [
          "P7 terminated state confirmed at HANDOFF-2026-07-29.md:65-68; AM4 migration at HANDOFF-2026-07-29.md:78-79; ADR-0014 confirms boot fixes remain unverified against the VM; roadmap:test and roadmap:check green"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260801092038-stop-the-public-roadmap-claiming-p7-is-live-whil",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-01T09:20:38.247Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L367",
        "sha256": "b62b16d32572600d040b001035283eeea078e07ac55547a43a6c921c1b8c15f2"
      },
      "summary": "Four current_focus entries used present-tense CURRENT/ACTIVE/LIVE language about P7 - 'remain on admitted release', 'remains live on P7', 'armed permanently on P7', 'serves the local Companion surfaces' - while the VM has been terminated since 2026-07-29T23:04 PT. They now read as LAST DEPLOYED CONFIG or ARMED IN CONFIG, DORMANT, each naming the stopped state. The Companion-surfaces entry was not merely stale but named the wrong host: that surface moved to AM4 and no longer depends on P7 at all. Same defect class as the hard-hold correction earlier today: present-tense prose in current_focus with no expiry, re-rendered under a fresh updated_at that vouches for it.",
      "title": "Stop the public roadmap claiming P7 is live while the VM is stopped",
      "updated_at": "2026-08-01T09:20:38.247Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801092038-stop-the-public-roadmap-claiming-p7-is-live-whil"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-01T09:31:56.678Z",
        "author": "Codex",
        "evidence": [
          "Lumberjacks/scripts/roadmap.mjs,Lumberjacks/scripts/roadmap.test.mjs,tools/wave0/Test-Wave0RoadmapFreshness.ps1"
        ],
        "id": "20260801093156-make-current-focus-structurally-incapable-of-hid",
        "impact": "current_focus was a bare string array that produced two false public claims in one day while every check stayed green. Entries are now objects with a present-tense-only status enum (active, deployed_config, dormant), an as_of date recording when the line was last checked against reality, and an optional milestone reference. Completed work and future gates now FAIL validation with a message naming the milestone field that owns them, so a fact cannot live in two places. roadmap:check goes red once the newest as_of is over 14 days old. Decomposed 9 entries to 5, dropping four already fully stated by M0 exit_evidence or by the M2/M3/M4a and M6 dependency edges, and moved the one orphan fact into M0. The section heading was also wrong and is now Where things stand rather than Next actions.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make current_focus structurally incapable of hiding a stale claim",
        "verification": [
          "roadmap:test 41/41 with 13 new guards, each negative case mutating the live fixture and asserting its specific message; roadmap:check green; Test-Wave0RoadmapFreshness.ps1 updated to project .text and its m30/r26 assertions re-verified"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260801093156-make-current-focus-structurally-incapable-of-hid",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-01T09:31:56.678Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L368",
        "sha256": "2632cba6c19dfd52ef47f2c48dabe6553a1b0724385a15eb0efc20cf2aa70d3c"
      },
      "summary": "current_focus was a bare string array that produced two false public claims in one day while every check stayed green. Entries are now objects with a present-tense-only status enum (active, deployed_config, dormant), an as_of date recording when the line was last checked against reality, and an optional milestone reference. Completed work and future gates now FAIL validation with a message naming the milestone field that owns them, so a fact cannot live in two places. roadmap:check goes red once the newest as_of is over 14 days old. Decomposed 9 entries to 5, dropping four already fully stated by M0 exit_evidence or by the M2/M3/M4a and M6 dependency edges, and moved the one orphan fact into M0. The section heading was also wrong and is now Where things stand rather than Next actions.",
      "title": "Make current_focus structurally incapable of hiding a stale claim",
      "updated_at": "2026-08-01T09:31:56.678Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801093156-make-current-focus-structurally-incapable-of-hid"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-08-01T09:42:13.990Z",
        "author": "Codex",
        "evidence": [
          "docs/decisions/pd-4-evidence-standard.md,Lumberjacks/scripts/roadmap.mjs,Lumberjacks/scripts/roadmap.test.mjs"
        ],
        "id": "20260801094213-adopt-pd-4-evidence-paths-over-binary-guards-and",
        "impact": "Written down as docs/decisions/pd-4-evidence-standard.md so any agent on any machine can be pointed at one place instead of reconstructing the standard from whichever comment it read first. The falsifiable-guard rule is scoped to published surfaces with a stable contract; discovery work states an evidence path instead - the claim, what would prove it, the gate that upgrades it, and how to inspect further. Applied immediately to the current_focus freshness gate added earlier today: it kept the hard fail, because this field renders publicly, but every entry now carries verify_by and the failure enumerates those routes rather than blocking mute. verify_by paths are existence-checked, which caught a wrong ADR filename within a minute of the guard existing.",
        "kind": "decision",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Adopt PD-4: evidence paths over binary guards, and give every public claim its check route",
        "verification": [
          "roadmap:test 46/46 including a guard asserting the staleness message hands over the route; roadmap:check green; existence check scoped to a positively-identified monorepo root so it cannot fire on a partial checkout"
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260801094213-adopt-pd-4-evidence-paths-over-binary-guards-and",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-08-01T09:42:13.990Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L369",
        "sha256": "851e1de8a89a81fcccf428eed2e0c914a30b163f10443d03fa523da860f07c94"
      },
      "summary": "Written down as docs/decisions/pd-4-evidence-standard.md so any agent on any machine can be pointed at one place instead of reconstructing the standard from whichever comment it read first. The falsifiable-guard rule is scoped to published surfaces with a stable contract; discovery work states an evidence path instead - the claim, what would prove it, the gate that upgrades it, and how to inspect further. Applied immediately to the current_focus freshness gate added earlier today: it kept the hard fail, because this field renders publicly, but every entry now carries verify_by and the failure enumerates those routes rather than blocking mute. verify_by paths are existence-checked, which caught a wrong ADR filename within a minute of the guard existing.",
      "title": "Adopt PD-4: evidence paths over binary guards, and give every public claim its check route",
      "updated_at": "2026-08-01T09:42:13.990Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801094213-adopt-pd-4-evidence-paths-over-binary-guards-and"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-01T23:21:29.212Z",
        "author": "Codex",
        "evidence": [
          "plans/workbench-v1-implementation-receipt.md",
          "plans/workbench-v1-verification-matrix.md",
          "docs/decisions/pd-5-local-workbench-ownership-appliance.md",
          "docs/decisions/pd-6-development-mcp-lifecycle.md"
        ],
        "id": "20260801232129-build-the-local-first-workbench-ownership-applia",
        "impact": "The turnkey Companion now provides claimed installation ownership, Standard and Advanced views, profile-gated local tooling, durable jobs and receipts, public-safe support export, and a bounded rendered-client acceptance lane. Default and Production exclude development MCP; Dev and Lab use identity-attested loopback port 8721. The optional mod side channel is disabled by default, and the legacy shared listener is retired without coupling this project to HEARTH.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Build the local-first Workbench ownership appliance and provenance boundary",
        "verification": [
          "Workbench UI, API, profile, runner-ownership, support-export, and privacy contracts passed.",
          "Gateway tests passed 11/11; the .NET solution passed 589 tests; Workbench and roadmap generators passed 29 and 46 tests.",
          "The bootstrap verifier passed 22 required files and the complete package passed the privacy scan."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260801232129-build-the-local-first-workbench-ownership-applia",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-01T23:21:29.212Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L370",
        "sha256": "f18c78f8ec4646aff6b002a3b04735253d377e4d1b866f5b2f74a117935abd51"
      },
      "summary": "The turnkey Companion now provides claimed installation ownership, Standard and Advanced views, profile-gated local tooling, durable jobs and receipts, public-safe support export, and a bounded rendered-client acceptance lane. Default and Production exclude development MCP; Dev and Lab use identity-attested loopback port 8721. The optional mod side channel is disabled by default, and the legacy shared listener is retired without coupling this project to HEARTH.",
      "title": "Build the local-first Workbench ownership appliance and provenance boundary",
      "updated_at": "2026-08-01T23:21:29.212Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801232129-build-the-local-first-workbench-ownership-applia"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-01T23:54:13.287Z",
        "author": "Codex",
        "evidence": [
          "Workbench runs workbench-20260801-233515-4b06aa9f and workbench-20260801-234514-9e402c53 isolated the missing character authorization"
        ],
        "id": "20260801235413-restore-standalone-c6-character-authorization-at",
        "impact": "Rendered C6 no longer depends on the later Steam-free logical-peer composition: native clients bind their current player ZDO generation with the authenticated peer UID before the first motion frame, while mismatched identities fail closed and C7 can still publish a later generation.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Restore standalone C6 character authorization at the reliable peer-binding edge",
        "verification": [
          "Game.Gateway ValheimLogicalPeerRouterTests 5/5; ComfyNetworkSense Release build 0 warnings/errors"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260801235413-restore-standalone-c6-character-authorization-at",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-01T23:54:13.287Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L371",
        "sha256": "7d52af0f811de984c38e23aad52b102b1ab910ba2750d28019e1c69b056a0979"
      },
      "summary": "Rendered C6 no longer depends on the later Steam-free logical-peer composition: native clients bind their current player ZDO generation with the authenticated peer UID before the first motion frame, while mismatched identities fail closed and C7 can still publish a later generation.",
      "title": "Restore standalone C6 character authorization at the reliable peer-binding edge",
      "updated_at": "2026-08-01T23:54:13.287Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260801235413-restore-standalone-c6-character-authorization-at"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T00:19:21.204Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/scripts/Invoke-NativeValheimCutoverScenario.ps1"
        ],
        "id": "20260802001921-aligned-clean-c6-collection-with-the-client-only",
        "impact": "A fresh AM4 no longer needs an impossible dedicated-server motion event file; both OMEN and i5 receipts remain authoritative and required.",
        "kind": "implementation",
        "milestones": [
          "M7",
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Aligned clean C6 collection with the client-only motion evidence boundary.",
        "verification": [
          "workbench-20260802-000554-c0ab921b completed every OMEN and i5 C6 action before the stale server-file collector check."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7",
          "A7"
        ]
      },
      "id": "roadmap:20260802001921-aligned-clean-c6-collection-with-the-client-only",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T00:19:21.204Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L372",
        "sha256": "f5301b7a03a9fa78c38f0c1f9af99f7176ea28beb5b1c79532b9738ae6095a8d"
      },
      "summary": "A fresh AM4 no longer needs an impossible dedicated-server motion event file; both OMEN and i5 receipts remain authoritative and required.",
      "title": "Aligned clean C6 collection with the client-only motion evidence boundary.",
      "updated_at": "2026-08-02T00:19:21.204Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802001921-aligned-clean-c6-collection-with-the-client-only"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T01:13:18.888Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802011318-add-hash-verified-local-lab-modpack-feed",
        "impact": "Workbench Lab now selects the local Docker Gateway by default, and an immutable local publisher stages the existing release-pointer contract in the persistent Gateway volume without GCP access or Valheim writes. Compose, publisher dry-run, public package authorization, and 32 focused middleware tests passed.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add hash-verified local Lab modpack feed",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260802011318-add-hash-verified-local-lab-modpack-feed",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T01:13:18.888Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L373",
        "sha256": "e54cccb405d6376dc7da06eef58bc1075d48a7a03dde44d8488af0eafbb4c621"
      },
      "summary": "Workbench Lab now selects the local Docker Gateway by default, and an immutable local publisher stages the existing release-pointer contract in the persistent Gateway volume without GCP access or Valheim writes. Compose, publisher dry-run, public package authorization, and 32 focused middleware tests passed.",
      "title": "Add hash-verified local Lab modpack feed",
      "updated_at": "2026-08-02T01:13:18.888Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802011318-add-hash-verified-local-lab-modpack-feed"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T01:20:03.146Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802012003-project-configured-gateway-identity-in-workbench",
        "impact": "The Workbench Gateway node now derives local, P7, or configured-remote placement from the selected origin, and the separate P7 node is excluded unless P7 is actually configured. The Companion container build and topology contract syntax passed.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Project configured Gateway identity in Workbench topology",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260802012003-project-configured-gateway-identity-in-workbench",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T01:20:03.146Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L374",
        "sha256": "2b76c086e1aa6c975316f24c3f3e7b3f2921cbc3ab3de2481898d7079b954d93"
      },
      "summary": "The Workbench Gateway node now derives local, P7, or configured-remote placement from the selected origin, and the separate P7 node is excluded unless P7 is actually configured. The Companion container build and topology contract syntax passed.",
      "title": "Project configured Gateway identity in Workbench topology",
      "updated_at": "2026-08-02T01:20:03.146Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802012003-project-configured-gateway-identity-in-workbench"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T01:25:22.053Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802012522-add-in-product-newcomer-orientation-path",
        "impact": "Standard mode now guides a first visitor from topology through a read-only inspection, durable evidence, and safe recovery boundaries. The no-coaching desktop/mobile protocol is documented for the remaining human usability gate, and the Companion image build passed.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add in-product newcomer orientation path",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260802012522-add-in-product-newcomer-orientation-path",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T01:25:22.053Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L375",
        "sha256": "2a2be5ab76dbd6c91867b2df72239bb4233c146b579f56afe58280afade39b1a"
      },
      "summary": "Standard mode now guides a first visitor from topology through a read-only inspection, durable evidence, and safe recovery boundaries. The no-coaching desktop/mobile protocol is documented for the remaining human usability gate, and the Companion image build passed.",
      "title": "Add in-product newcomer orientation path",
      "updated_at": "2026-08-02T01:25:22.053Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802012522-add-in-product-newcomer-orientation-path"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T01:31:36.243Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802013136-add-byte-level-modpack-preflight",
        "impact": "A local verifier now compares every Valheim payload entry by SHA-256, rejects path escapes, duplicate or out-of-scope entries and personalized credential config, and can require a zero-byte-difference install drill. Isolated exact, changed, credential, and boundary fixtures passed.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add byte-level modpack preflight",
        "verification": []
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260802013136-add-byte-level-modpack-preflight",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T01:31:36.243Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L376",
        "sha256": "b65ee0d4484273a9c1e46d41b75f054ef3152cbc4108bdbaac164a370219db1b"
      },
      "summary": "A local verifier now compares every Valheim payload entry by SHA-256, rejects path escapes, duplicate or out-of-scope entries and personalized credential config, and can require a zero-byte-difference install drill. Isolated exact, changed, credential, and boundary fixtures passed.",
      "title": "Add byte-level modpack preflight",
      "updated_at": "2026-08-02T01:31:36.243Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802013136-add-byte-level-modpack-preflight"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T01:47:50.448Z",
        "author": "Codex",
        "evidence": [
          "src/Game.Companion/Program.cs",
          "tests/Game.Companion.Tests/ModpackInstallerTests.cs"
        ],
        "id": "20260802014750-make-workbench-mod-updates-reversibly-safe",
        "impact": "The Companion now rejects the complete package before writing any game file, serializes install and rollback requests, applies each file atomically, restores applied bytes when installation or state recording fails, removes files introduced by the candidate on rollback, and restores the prior installed-release identity. Legacy backup records remain readable. The live m32 candidate remains operator-gated; this commit changes no Valheim files.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make Workbench mod updates reversibly safe",
        "verification": [
          "11 focused Companion installer tests and all 604 solution tests passed in the .NET 9 SDK container."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260802014750-make-workbench-mod-updates-reversibly-safe",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T01:47:50.448Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L377",
        "sha256": "3c68c92b885f9cb2c406c6d743f2fc3f8d53c1da073a51c9bf3b73a782952ad7"
      },
      "summary": "The Companion now rejects the complete package before writing any game file, serializes install and rollback requests, applies each file atomically, restores applied bytes when installation or state recording fails, removes files introduced by the candidate on rollback, and restores the prior installed-release identity. Legacy backup records remain readable. The live m32 candidate remains operator-gated; this commit changes no Valheim files.",
      "title": "Make Workbench mod updates reversibly safe",
      "updated_at": "2026-08-02T01:47:50.448Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802014750-make-workbench-mod-updates-reversibly-safe"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-02T02:12:46.212Z",
        "author": "Codex",
        "evidence": [
          "tools/modpack/Invoke-LocalWorkbenchModRollbackDrill.ps1",
          "tools/companion/Test-WorkbenchRunnerOwnership.ps1"
        ],
        "id": "20260802021246-prove-and-productize-the-reversible-workbench-up",
        "impact": "The admitted m32 package completed one explicitly approved local install-to-rollback cycle through Workbench jobs: all 30 payload entries matched before, during, and after; the prior m31 installed record returned byte-for-byte; and no game process or updater residue remained. A checked-in verifier now reproduces that evidence sequence, refuses mutation without an explicit approval switch, and the host runner independently blocks install or rollback while Windows Valheim is running.",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Prove and productize the reversible Workbench update drill",
        "verification": [
          "Install job job-20260802-015909355-13073d0c and rollback job job-20260802-015911118-89a57d29 succeeded without recovery fallback.",
          "Runner ownership fixture proved both the harmless valheim.exe negative control and the mutating-operation dispatch gate."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260802021246-prove-and-productize-the-reversible-workbench-up",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-02T02:12:46.212Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L378",
        "sha256": "f719ad551154d9f308bbe46b9143c381cfa55e65b5b3e5eb30edfb82c6a5d1f4"
      },
      "summary": "The admitted m32 package completed one explicitly approved local install-to-rollback cycle through Workbench jobs: all 30 payload entries matched before, during, and after; the prior m31 installed record returned byte-for-byte; and no game process or updater residue remained. A checked-in verifier now reproduces that evidence sequence, refuses mutation without an explicit approval switch, and the host runner independently blocks install or rollback while Windows Valheim is running.",
      "title": "Prove and productize the reversible Workbench update drill",
      "updated_at": "2026-08-02T02:12:46.212Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802021246-prove-and-productize-the-reversible-workbench-up"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T02:22:01.999Z",
        "author": "Codex",
        "evidence": [
          "src/Game.Companion/Program.cs",
          "src/Game.Companion/WorkbenchKernel.cs",
          "tools/companion/Test-WorkbenchRunnerOwnership.ps1"
        ],
        "id": "20260802022201-fail-closed-on-legacy-rollback-and-empty-capture",
        "impact": "A hands-on Workbench test drive exposed two honest-state gaps: a second rollback could reapply a schema-0 backup whose prior release was unknowable, and a transport capture with no peers still rendered as a successful job. Legacy rollback is now unavailable in the API and UI and refused by the compatibility endpoint; only schema-1 reversible transactions can roll back. No-peer and incomplete-telemetry captures now complete as failed evidence jobs with specific reasons instead of green success.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Fail closed on legacy rollback and empty captures",
        "verification": [
          "12 Companion tests passed, including legacy byte/state preservation and dynamic rollback eligibility.",
          "The runner fixture passed host-process dispatch and no-peer capture negative controls; the full solution passed 605 tests."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260802022201-fail-closed-on-legacy-rollback-and-empty-capture",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T02:22:01.999Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L379",
        "sha256": "34e5ea2de44926984e4b74da35c72bdd11ad2852798cd3b1dce291229a0c7f51"
      },
      "summary": "A hands-on Workbench test drive exposed two honest-state gaps: a second rollback could reapply a schema-0 backup whose prior release was unknowable, and a transport capture with no peers still rendered as a successful job. Legacy rollback is now unavailable in the API and UI and refused by the compatibility endpoint; only schema-1 reversible transactions can roll back. No-peer and incomplete-telemetry captures now complete as failed evidence jobs with specific reasons instead of green success.",
      "title": "Fail closed on legacy rollback and empty captures",
      "updated_at": "2026-08-02T02:22:01.999Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802022201-fail-closed-on-legacy-rollback-and-empty-capture"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T02:25:18.343Z",
        "author": "Codex",
        "evidence": [
          "src/Game.Companion/CompanionPage.cs",
          "tools/companion/Test-WorkbenchUiContract.ps1"
        ],
        "id": "20260802022518-gate-rollback-on-the-legacy-companion-page",
        "impact": "The compatibility page now follows the same reversible-transaction rule as Workbench: schema-0 installed records leave rollback disabled with a plain explanation, so an older surface cannot invite an operation the API will refuse.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Gate rollback on the legacy Companion page",
        "verification": [
          "Companion tests passed 12 of 12 and the UI contract now checks both Workbench and compatibility-page rollback guidance."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260802022518-gate-rollback-on-the-legacy-companion-page",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T02:25:18.343Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L380",
        "sha256": "7c7a193f7e1235a504460735f9659ce8aa1865da9206d933b9e5a1595e7b393e"
      },
      "summary": "The compatibility page now follows the same reversible-transaction rule as Workbench: schema-0 installed records leave rollback disabled with a plain explanation, so an older surface cannot invite an operation the API will refuse.",
      "title": "Gate rollback on the legacy Companion page",
      "updated_at": "2026-08-02T02:25:18.343Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802022518-gate-rollback-on-the-legacy-companion-page"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T05:59:12.401Z",
        "author": "Codex",
        "evidence": [
          "plans/workbench-v1-implementation-receipt.md",
          "docs/decisions/pd-7-lab-runtime-provenance-and-session-boundary.md",
          "docs/audit/2026-08-02-workbench-lab-runtime-provenance.md"
        ],
        "id": "20260802055912-harden-lab-provenance-and-bounded-stall-forensic",
        "impact": "PD-7 now records the canonical Baseline Lab source and session boundary. Rendered Workbench preflight refuses the retained legacy state bridge before launching clients, while per-node Gateway routing, durable failed-run restoration, and worker-watchdog evidence make the next single diagnostic C6 bounded and attributable. The machine-wide HEARTH gateway remains independent from the profile-gated Workbench Dev MCP.",
        "kind": "implementation",
        "milestones": [
          "M7",
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Harden Lab provenance and bounded stall forensics",
        "verification": [
          "The strict provenance preflight failed closed before source, i5, scenario, or client actions and left both clients stopped.",
          "Workbench runner ownership, compose-profile and MCP identity contracts passed; the focused solution build passed 605 tests."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7",
          "A7"
        ]
      },
      "id": "roadmap:20260802055912-harden-lab-provenance-and-bounded-stall-forensic",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T05:59:12.401Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L381",
        "sha256": "8496e8e9401a7484bb5ff4d0f6eb58dfa27a3229338050ce7ff92e751950e2a8"
      },
      "summary": "PD-7 now records the canonical Baseline Lab source and session boundary. Rendered Workbench preflight refuses the retained legacy state bridge before launching clients, while per-node Gateway routing, durable failed-run restoration, and worker-watchdog evidence make the next single diagnostic C6 bounded and attributable. The machine-wide HEARTH gateway remains independent from the profile-gated Workbench Dev MCP.",
      "title": "Harden Lab provenance and bounded stall forensics",
      "updated_at": "2026-08-02T05:59:12.401Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802055912-harden-lab-provenance-and-bounded-stall-forensic"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T06:36:25.560Z",
        "author": "Codex",
        "evidence": [
          "docs/decisions/pd-7-lab-runtime-provenance-and-session-boundary.md",
          "docs/audit/2026-08-02-workbench-lab-runtime-provenance.md",
          "plans/workbench-v1-verification-matrix.md"
        ],
        "id": "20260802063625-migrate-the-local-lab-state-into-baseline-owners",
        "impact": "A fail-closed migration command now requires fresh zero-peer Gateway telemetry and an idle world backup, preserves the retained source as rollback, verifies the stopped server inventory and critical world hashes, and recreates the active server with only Baseline Compose and state mounts. The strict rendered provenance gate now reports baseline_migrated. HEARTH remains independent from the Workbench Dev MCP.",
        "kind": "implementation",
        "milestones": [
          "M7",
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Migrate the local Lab state into Baseline ownership",
        "verification": [
          "The stopped source and target matched at 2,561 files and 57,551,976,393 bytes plus four critical world hashes.",
          "Strict Lab provenance and post-start zero-peer readiness passed after recreation."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7",
          "A7"
        ]
      },
      "id": "roadmap:20260802063625-migrate-the-local-lab-state-into-baseline-owners",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T06:36:25.560Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L382",
        "sha256": "61f53023eb44f72800054f6ffe08272cc71111c5b54c39ab66fe7e9ccf364dca"
      },
      "summary": "A fail-closed migration command now requires fresh zero-peer Gateway telemetry and an idle world backup, preserves the retained source as rollback, verifies the stopped server inventory and critical world hashes, and recreates the active server with only Baseline Compose and state mounts. The strict rendered provenance gate now reports baseline_migrated. HEARTH remains independent from the Workbench Dev MCP.",
      "title": "Migrate the local Lab state into Baseline ownership",
      "updated_at": "2026-08-02T06:36:25.560Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802063625-migrate-the-local-lab-state-into-baseline-owners"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T07:09:43.238Z",
        "author": "Codex",
        "evidence": [
          "plans/workbench-v1-implementation-receipt.md",
          "docs/audit/2026-08-02-workbench-lab-runtime-provenance.md"
        ],
        "id": "20260802070943-disposition-the-clean-c6-watchdog-run-and-guard-",
        "impact": "The admitted watchdog run passed ordinary canonical motion in both directions and showed OMEN completing gap drive, rejecting the persistent-stall hypothesis for that run. It failed because i5 applied the correlated resync before its observe-gap baseline began. C6 now reuses the bounded C8 observer-alignment step and fails locally before remote mutation when that order or correlation is absent. No second physical run was attempted; validation remains explicit follow-up.",
        "kind": "implementation",
        "milestones": [
          "M7",
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Disposition the clean C6 watchdog run and guard gap-observer ordering",
        "verification": [
          "Workbench job job-20260802-065514705-b159b3fb retained clean source identity, both client bundles, watchdog rows, exact config restores, server disarm, and post-run zero-peer quiescence.",
          "Generated C6 24-action coverage passed; a fixture with the alignment action removed failed the three alignment checks; C8 49-action coverage remained green."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7",
          "A7"
        ]
      },
      "id": "roadmap:20260802070943-disposition-the-clean-c6-watchdog-run-and-guard-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T07:09:43.238Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L383",
        "sha256": "fe01848f2d61bcf035965ac89e017d823f0b5e915b0dc31b03c50965934e2b48"
      },
      "summary": "The admitted watchdog run passed ordinary canonical motion in both directions and showed OMEN completing gap drive, rejecting the persistent-stall hypothesis for that run. It failed because i5 applied the correlated resync before its observe-gap baseline began. C6 now reuses the bounded C8 observer-alignment step and fails locally before remote mutation when that order or correlation is absent. No second physical run was attempted; validation remains explicit follow-up.",
      "title": "Disposition the clean C6 watchdog run and guard gap-observer ordering",
      "updated_at": "2026-08-02T07:09:43.238Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802070943-disposition-the-clean-c6-watchdog-run-and-guard-"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-02T07:35:23.303Z",
        "author": "Codex",
        "evidence": [
          "plans/workbench-v1-implementation-receipt.md",
          "docs/audit/2026-08-02-workbench-lab-runtime-provenance.md"
        ],
        "id": "20260802073523-physically-validate-corrected-c6-gap-ordering",
        "impact": "One separately authorized Workbench run completed all 24 C6 actions on both rendered clients. The i5 observer opened before OMEN gap drive and recorded the held gap plus reliable resync; cleanup returned both clients and the Baseline Lab to their safe at-rest posture. Only the unfamiliar-user usability gate remains for WB-1.",
        "kind": "verification",
        "milestones": [
          "M7",
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Physically validate corrected C6 gap ordering",
        "verification": [
          "Workbench job job-20260802-072520719-74b07483 reached rendered_role_reversal_complete; run workbench-20260802-072523-74b07483 recorded both scenario terminals, holds=1 gaps=1 resync_applied=1, exact config restoration, server disarm, zero residue, and post-run zero-peer quiescence."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7",
          "A7"
        ]
      },
      "id": "roadmap:20260802073523-physically-validate-corrected-c6-gap-ordering",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-02T07:35:23.303Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L384",
        "sha256": "d75abf7071c4dd6eb0216ee461161a34d916ec381f8ae9eb817c15a0dc5384e0"
      },
      "summary": "One separately authorized Workbench run completed all 24 C6 actions on both rendered clients. The i5 observer opened before OMEN gap drive and recorded the held gap plus reliable resync; cleanup returned both clients and the Baseline Lab to their safe at-rest posture. Only the unfamiliar-user usability gate remains for WB-1.",
      "title": "Physically validate corrected C6 gap ordering",
      "updated_at": "2026-08-02T07:35:23.303Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802073523-physically-validate-corrected-c6-gap-ordering"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T09:25:38.592Z",
        "author": "Codex",
        "evidence": [
          "plans/workbench-v1-verification-matrix.md",
          "fieldlab/docs/adr/0016-banked-state-must-carry-session-identity.md",
          "plans/workbench-appliance-convergence.md"
        ],
        "id": "20260802092538-restore-workbench-live-operator-value-and-implem",
        "impact": "Workbench Home now exposes fresh server, player, activity, cutover, motion, and journal-epoch truth with one next action. Gateway banks retain valid state across a Gateway-only restart and invalidate stale ZDO state when the dedicated-server session changes. C9 remains next; C10a paired release and runtime proof plus admissions remain explicit.",
        "kind": "implementation",
        "milestones": [
          "A7",
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Restore Workbench live operator value and implement session-scoped zone-bank epochs",
        "verification": [
          "The image-producing Docker target passed 612 tests; the Valheim-linked mod build passed with zero warnings and errors; Workbench UI, API, and Baseline MCP identity tools passed; restart and replay tests cover stale bank invalidation."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7",
          "M7"
        ]
      },
      "id": "roadmap:20260802092538-restore-workbench-live-operator-value-and-implem",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T09:25:38.592Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L385",
        "sha256": "be33c4f0cd6d91ae1d6fa6259bdc7e45bf8d415d4f7bec1896f71948853e47e9"
      },
      "summary": "Workbench Home now exposes fresh server, player, activity, cutover, motion, and journal-epoch truth with one next action. Gateway banks retain valid state across a Gateway-only restart and invalidate stale ZDO state when the dedicated-server session changes. C9 remains next; C10a paired release and runtime proof plus admissions remain explicit.",
      "title": "Restore Workbench live operator value and implement session-scoped zone-bank epochs",
      "updated_at": "2026-08-02T09:25:38.592Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802092538-restore-workbench-live-operator-value-and-implem"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T10:47:06.461Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/c8-native-zero-composition/recovery5-session-epoch-gate.json",
          "fieldlab/runs/native-valheim/native-20260802-cutover-recovery5/c8-composition-summary.json"
        ],
        "id": "20260802104706-close-the-physical-native-zero-runtime-and-serve",
        "impact": "OMEN and i5 completed all 49 actions against AM4 on fresh rendered Valheim processes with zero selected native use or poison trips. A real dedicated-server restart changed the session-scoped world epoch, same-session Gateway replay retained 1,632 objects, and a valid old-session mutation failed closed. The ownership probe now waits for the refreshed descriptor after Gateway restart, the manifest generator cannot exceed deployed motion bounds, and the interim WAL-discard rule is retired.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Close the physical native-zero runtime and server-session epoch gate",
        "verification": [
          "Recovery5 passed 20/20 coverage, composition, ownership contention, Gateway restart/replay, clean rejoin, and save integrity",
          "AM4, OMEN, and i5 ran identical mod SHA-256 8ac344592a6f6bd341dfbcc117a2b1a5d6eec67e580eaed29df187bdde5abe85",
          "Old epoch mutation returned HTTP 409 world_epoch_not_active with zero durable-object or WAL change",
          "ComfyNetworkSense built with zero warnings/errors; 102 mod tests and 11 project-MCP tests passed"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802104706-close-the-physical-native-zero-runtime-and-serve",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T10:47:06.461Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L386",
        "sha256": "69c23aa62c251128f1f5576c24584a4d96087f8c8ed992bc09c4a916fd4313c2"
      },
      "summary": "OMEN and i5 completed all 49 actions against AM4 on fresh rendered Valheim processes with zero selected native use or poison trips. A real dedicated-server restart changed the session-scoped world epoch, same-session Gateway replay retained 1,632 objects, and a valid old-session mutation failed closed. The ownership probe now waits for the refreshed descriptor after Gateway restart, the manifest generator cannot exceed deployed motion bounds, and the interim WAL-discard rule is retired.",
      "title": "Close the physical native-zero runtime and server-session epoch gate",
      "updated_at": "2026-08-02T10:47:06.461Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802104706-close-the-physical-native-zero-runtime-and-serve"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T12:53:21.328Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802125321-close-c9-with-foreground-verified-two-client-ren",
        "impact": "The native-zero cutover now has a retained reviewable OMEN/i5 motion artifact in both directions, bounded reliable recovery from injected loss, and fail-closed foreground/framing evidence; Workbench remains outside the cutover path and C10 is the only remaining slice",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Close C9 with foreground-verified two-client rendered motion evidence and harden each harness boundary exposed by rejected captures",
        "verification": [
          "Physical run native-20260802-c9-motion6: both rendered clients scenario_complete plus one fresh-process resume, native_total=0, poison_trips=0, ordinary observer failures=0, injected 20-frame loss recovered in 0.895 s",
          "Canonical Docker mod build succeeded with 0 warnings and 0 errors at SHA-256 a658af8bb39ac619cbf967dc9fa007745d042088c4ffaa500b119012c9085d55; focused ComfyNetworkSense suite passed 102/102",
          "Foreground receipts verify the exact Valheim HWND on both machines; retained 20.067 s 2560x720 clip SHA-256 b419d17995cde00146a32c2a4ea9e5c7937458ff13c473c114292db68a3b2dee; final lab quiescence passed at zero peers and players"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802125321-close-c9-with-foreground-verified-two-client-ren",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T12:53:21.328Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L387",
        "sha256": "df7e082108a1aa1e9145d505aa64bb6b97dda323090b30fe67591b085d5fc637"
      },
      "summary": "The native-zero cutover now has a retained reviewable OMEN/i5 motion artifact in both directions, bounded reliable recovery from injected loss, and fail-closed foreground/framing evidence; Workbench remains outside the cutover path and C10 is the only remaining slice",
      "title": "Close C9 with foreground-verified two-client rendered motion evidence and harden each harness boundary exposed by rejected captures",
      "updated_at": "2026-08-02T12:53:21.328Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802125321-close-c9-with-foreground-verified-two-client-ren"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T13:27:11.665Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/plan-native-network-final-cutover.md",
          "fieldlab/NATIVE-NETWORK-LANDSCAPE-2026-07-30.md",
          "tools/synthetic-baseline-extractor/synthetic_baseline_v2.json"
        ],
        "id": "20260802132711-admit-all-p1-routed-rpcs-through-one-byte-exact-",
        "impact": "The mod and Gateway now compile one admission source for all 33 P1 methods, validate exact Valheim payload layouts and target shapes, and make unadmitted outbound routes visible to the poison ledger. The roadmap also corrects C9 to machine/artifact complete with Derek's subjective verdict still pending; paired-release AM4 exercise and component-family gates remain.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Admit all P1 routed RPCs through one byte-exact release contract",
        "verification": [
          "ComfyNetworkSense Release build completed with zero warnings and zero errors; focused tests passed 107 of 107.",
          "The canonical Lumberjacks Docker verify target passed 614 of 614 tests, including 221 Gateway forwarding and rejection tests."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802132711-admit-all-p1-routed-rpcs-through-one-byte-exact-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T13:27:11.665Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L388",
        "sha256": "b517f8affc8eedb1524ab624fe3a30d3f34844ac7388988f03009eeb207839f1"
      },
      "summary": "The mod and Gateway now compile one admission source for all 33 P1 methods, validate exact Valheim payload layouts and target shapes, and make unadmitted outbound routes visible to the poison ledger. The roadmap also corrects C9 to machine/artifact complete with Derek's subjective verdict still pending; paired-release AM4 exercise and component-family gates remain.",
      "title": "Admit all P1 routed RPCs through one byte-exact release contract",
      "updated_at": "2026-08-02T13:27:11.665Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802132711-admit-all-p1-routed-rpcs-through-one-byte-exact-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T13:29:33.410Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/plan-native-network-final-cutover.md"
        ],
        "id": "20260802132933-stamp-the-c10a-paired-local-candidate-before-art",
        "impact": "ComfyNetworkSense now names immutable candidate m7-c10a-20260802-r1. The stamp is committed before the paired mod and Gateway build so both artifacts can carry one release identity and reproducible commit provenance; this does not promote or change P7.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Stamp the C10a paired local candidate before artifact build",
        "verification": [
          "The release id matches the enforced m7 label/date/revision format and was unused in source and local Docker tags before the cut."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802132933-stamp-the-c10a-paired-local-candidate-before-art",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T13:29:33.410Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L389",
        "sha256": "c52c7e8dbebe9fabafeae5ff79a0f0dbc48061465711315df18b1f0fe57c9a76"
      },
      "summary": "ComfyNetworkSense now names immutable candidate m7-c10a-20260802-r1. The stamp is committed before the paired mod and Gateway build so both artifacts can carry one release identity and reproducible commit provenance; this does not promote or change P7.",
      "title": "Stamp the C10a paired local candidate before artifact build",
      "updated_at": "2026-08-02T13:29:33.410Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802132933-stamp-the-c10a-paired-local-candidate-before-art"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T14:01:00.039Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/c10a-r1-outbound-falsifier/README.md",
          "fieldlab/runs/native-valheim/native-20260802-c10a-r1/c7-logical-peer-summary.json"
        ],
        "id": "20260802140100-close-the-outbound-routed-rpc-fallback-exposed-b",
        "impact": "The first paired candidate is retained as failed evidence: both clients completed all 49 actions, but the new outbound seam found ten poison trips per client plus server-side unadmitted sends. The r2 contract now routes the observed normal-play and mod RPCs, explicitly consumes replacement-owned journal, descriptor, and logical-session methods, and rejects superseded Gateway injection. P7 remains untouched and physical r2 proof is still required.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Close the outbound routed-RPC fallback exposed by the r1 physical falsifier",
        "verification": [
          "ComfyNetworkSense focused tests pass 107/107 and its Release build has zero warnings/errors.",
          "The canonical Docker verify target passes 614/614, including 221 Gateway tests."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802140100-close-the-outbound-routed-rpc-fallback-exposed-b",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T14:01:00.039Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L390",
        "sha256": "f4ca7c365504ff8862fcdb7c8e4541136ca620fb4624d5966ad8f3532c2d94ac"
      },
      "summary": "The first paired candidate is retained as failed evidence: both clients completed all 49 actions, but the new outbound seam found ten poison trips per client plus server-side unadmitted sends. The r2 contract now routes the observed normal-play and mod RPCs, explicitly consumes replacement-owned journal, descriptor, and logical-session methods, and rejects superseded Gateway injection. P7 remains untouched and physical r2 proof is still required.",
      "title": "Close the outbound routed-RPC fallback exposed by the r1 physical falsifier",
      "updated_at": "2026-08-02T14:01:00.039Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802140100-close-the-outbound-routed-rpc-fallback-exposed-b"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T14:25:20.053Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802142520-make-c10a-zone-replay-deterministic-and-admit-ob",
        "impact": "r2 is retained as failed physical evidence: a cumulative ACK crossed the deliberately held i5 zone chunk before socket abort, so Gateway could not replay it. The client now installs an ACK barrier on receipt and defers later cumulative acknowledgements until the held sequence replays; RPC_HealthChanged and RPC_UpdateMaterial are exact shared-contract P2 instance routes. Workbench remains frozen and P7 is untouched.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make C10a zone replay deterministic and admit observed P2 object updates",
        "verification": [
          "112/112 focused mod tests; 615/615 containerized repository tests including exact P2 Gateway forwarding; ComfyNetworkSense Release build succeeded with zero warnings and zero errors; r2 cleanup disarmed all runtime controls and stopped both clients"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802142520-make-c10a-zone-replay-deterministic-and-admit-ob",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T14:25:20.053Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L391",
        "sha256": "906242bb31862313202956499c8354cc2f27d3e72c7310c5e164f97bc3e27325"
      },
      "summary": "r2 is retained as failed physical evidence: a cumulative ACK crossed the deliberately held i5 zone chunk before socket abort, so Gateway could not replay it. The client now installs an ACK barrier on receipt and defers later cumulative acknowledgements until the held sequence replays; RPC_HealthChanged and RPC_UpdateMaterial are exact shared-contract P2 instance routes. Workbench remains frozen and P7 is untouched.",
      "title": "Make C10a zone replay deterministic and admit observed P2 object updates",
      "updated_at": "2026-08-02T14:25:20.053Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802142520-make-c10a-zone-replay-deterministic-and-admit-ob"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T14:55:03.954Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802145503-fail-closed-and-reconnect-when-a-native-client-w",
        "impact": "The r3 physical falsifier proved i5 could remain receive-live while its unsupervised outbound queue stopped draining. Every client WebSocket send now has a five-second guard that records frame context, aborts the half-open socket, and enters reliable resume; r3 evidence is retained and P7 remains untouched.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Fail closed and reconnect when a native client WebSocket sender stalls",
        "verification": [
          "117/117 focused mod tests; zero-warning Release mod build; 615/615 canonical .NET 9 container tests; native-20260802-c10a-r3 cleanup stopped both clients, disarmed all controls, and destroyed three tagged probes."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802145503-fail-closed-and-reconnect-when-a-native-client-w",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T14:55:03.954Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L392",
        "sha256": "33dbae0b2a72b03ced3cc7bc6fd4b935c05d520cc38e99cbdf210d029d75b4d8"
      },
      "summary": "The r3 physical falsifier proved i5 could remain receive-live while its unsupervised outbound queue stopped draining. Every client WebSocket send now has a five-second guard that records frame context, aborts the half-open socket, and enters reliable resume; r3 evidence is retained and P7 remains untouched.",
      "title": "Fail closed and reconnect when a native client WebSocket sender stalls",
      "updated_at": "2026-08-02T14:55:03.954Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802145503-fail-closed-and-reconnect-when-a-native-client-w"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-02T15:15:47.620Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802151547-accept-r4-paired-native-cutover-candidate-on-the",
        "impact": "The exact r4 mod and Gateway pair passed all 49 actions on real OMEN and i5 clients with client/server native totals and poison trips zero; forced zone resume, Gateway replay, save integrity, and cleanup passed. Four explicit verification items and four component-family gates still precede P7 and fallback deletion.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Accept r4 paired native-cutover candidate on the physical AM4 lane",
        "verification": [
          "fieldlab/evidence/c10a-r4-physical-acceptance/acceptance-summary.json",
          "fieldlab/runs/releases/m7-c10a-20260802-r4/manifest.json",
          "native-20260802-c10a-r4"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802151547-accept-r4-paired-native-cutover-candidate-on-the",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-02T15:15:47.620Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L393",
        "sha256": "4a647e6fdc4226a927565f404c1cbc5e2f088c501ede35eea5d7ee63b24fc5d9"
      },
      "summary": "The exact r4 mod and Gateway pair passed all 49 actions on real OMEN and i5 clients with client/server native totals and poison trips zero; forced zone resume, Gateway replay, save integrity, and cleanup passed. Four explicit verification items and four component-family gates still precede P7 and fallback deletion.",
      "title": "Accept r4 paired native-cutover candidate on the physical AM4 lane",
      "updated_at": "2026-08-02T15:15:47.620Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802151547-accept-r4-paired-native-cutover-candidate-on-the"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-02T15:23:57.968Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802152357-close-rpc-setconnection-as-a-portal-cache-owned-",
        "impact": "The pinned call graph and accepted r4 runtime prove the server portal cache supersedes the only vanilla outbound caller. AM4 hash-joined 4,472 pairs, both real clients traversed the same pair forward and reverse under poison, and OMEN/i5/server recorded zero method rows and zero native use. The method stays unadmitted so a regression fails closed; three VERIFY items remain.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Close RPC_SetConnection as a portal-cache-owned poison tripwire",
        "verification": [
          "fieldlab/evidence/c10a-rpc-setconnection-verification/verification-summary.json",
          "dotnet test ComfyNetworkSense.Tests: 118/118"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802152357-close-rpc-setconnection-as-a-portal-cache-owned-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-02T15:23:57.968Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L394",
        "sha256": "a803ce593b8a0fbf87e823c1b142e536448972b94a154fb8ff076d254e0fbeae"
      },
      "summary": "The pinned call graph and accepted r4 runtime prove the server portal cache supersedes the only vanilla outbound caller. AM4 hash-joined 4,472 pairs, both real clients traversed the same pair forward and reverse under poison, and OMEN/i5/server recorded zero method rows and zero native use. The method stays unadmitted so a regression fails closed; three VERIFY items remain.",
      "title": "Close RPC_SetConnection as a portal-cache-owned poison tripwire",
      "updated_at": "2026-08-02T15:23:57.968Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802152357-close-rpc-setconnection-as-a-portal-cache-owned-"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-02T15:29:44.636Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802152944-close-rpc-teleportplayer-as-deferred-admin-recal",
        "impact": "Pinned call-site tracing isolates the global RPC to Terminal's cheat-only admin recall command; normal portal travel uses admitted instance RPC_TeleportTo. Exact r4 physical traversal produced zero method rows, native use, or poison trips, and the exact payload remains deliberately unadmitted as a fail-closed regression guard.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Close RPC_TeleportPlayer as deferred admin recall",
        "verification": [
          "fieldlab/evidence/c10a-rpc-teleportplayer-verification/verification-summary.json",
          "dotnet test ComfyNetworkSense.Tests: 119/119"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802152944-close-rpc-teleportplayer-as-deferred-admin-recal",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-02T15:29:44.636Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L395",
        "sha256": "b86a7112e1d70649e5607a5bbb94a07ec208dd2ff236f89250c4ac3d948a1719"
      },
      "summary": "Pinned call-site tracing isolates the global RPC to Terminal's cheat-only admin recall command; normal portal travel uses admitted instance RPC_TeleportTo. Exact r4 physical traversal produced zero method rows, native use, or poison trips, and the exact payload remains deliberately unadmitted as a fail-closed regression guard.",
      "title": "Close RPC_TeleportPlayer as deferred admin recall",
      "updated_at": "2026-08-02T15:29:44.636Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802152944-close-rpc-teleportplayer-as-deferred-admin-recal"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T15:47:04.864Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802154704-build-exact-usestamina-p3-lane-and-physical-prob",
        "impact": "Pinned call-graph review found legitimate cross-owner harpoon and fishing paths. Candidate m7-c10a-20260802-r5 now routes the exact Single payload through the shared contract and requires an owning-client before/requested/after stamina receipt; physical OMEN+i5 proof remains open and P7 is untouched.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Build exact UseStamina P3 lane and physical probe",
        "verification": [
          "119/119 focused mod tests",
          "616/616 canonical .NET 9 tests",
          "ComfyNetworkSense Release build: 0 warnings, 0 errors",
          "c10a-stamina 16-action manifest generated"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802154704-build-exact-usestamina-p3-lane-and-physical-prob",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T15:47:04.864Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L396",
        "sha256": "c2cf88265b2fcd08b7e1e4721cc3da995b3d90eda3bd45c68326d07f9aec8c6f"
      },
      "summary": "Pinned call-graph review found legitimate cross-owner harpoon and fishing paths. Candidate m7-c10a-20260802-r5 now routes the exact Single payload through the shared contract and requires an owning-client before/requested/after stamina receipt; physical OMEN+i5 proof remains open and P7 is untouched.",
      "title": "Build exact UseStamina P3 lane and physical probe",
      "updated_at": "2026-08-02T15:47:04.864Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802154704-build-exact-usestamina-p3-lane-and-physical-prob"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T15:54:06.708Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802155406-arm-native-poison-in-focused-physical-client-gat",
        "impact": "The OMEN+i5 harness can now enable the existing native-use poison independently of the full C8 composition. The focused UseStamina run will therefore fail closed on client fallback as well as server fallback; no runtime was changed and P7 is untouched.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Arm native poison in focused physical client gates",
        "verification": [
          "PowerShell parser: Invoke-NativeValheimClient.ps1",
          "PowerShell parser: Invoke-NativeValheimCutoverScenario.ps1",
          "c10a-stamina manifest generation: 16 actions"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802155406-arm-native-poison-in-focused-physical-client-gat",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T15:54:06.708Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L397",
        "sha256": "9052d1b5f6a06540e00cb9e7a1e8fab44d9c721de7d4f1499135dbe5e6a35d26"
      },
      "summary": "The OMEN+i5 harness can now enable the existing native-use poison independently of the full C8 composition. The focused UseStamina run will therefore fail closed on client fallback as well as server fallback; no runtime was changed and P7 is untouched.",
      "title": "Arm native poison in focused physical client gates",
      "updated_at": "2026-08-02T15:54:06.708Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802155406-arm-native-poison-in-focused-physical-client-gat"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T16:13:41.401Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/c10a-r5-stamina-falsifier/falsifier-summary.json"
        ],
        "id": "20260802161341-reject-aliased-player-targets-after-the-r5-stami",
        "impact": "The native-zero r5 run proved OMEN-to-i5 stamina delivery but rejected the reverse direction because an unfiltered Player scan chose an aliased ZDO. r6 requires target ZDO user identity to equal its current owner, selects the nearest live match, and gives focused breadth gates one native-zero composition switch. The receiver remains fail-closed; P7 is untouched.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Reject aliased player targets after the r5 stamina falsifier",
        "verification": [
          "122/122 focused mod tests",
          "ComfyNetworkSense Release build: 0 warnings, 0 errors",
          "Both r5 physical attempts cleaned up all clients and AM4 controls"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802161341-reject-aliased-player-targets-after-the-r5-stami",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T16:13:41.401Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L398",
        "sha256": "6e95fb0f8e39baae69e4d735ab9495f655069832f49ff6817b7074dd574f460c"
      },
      "summary": "The native-zero r5 run proved OMEN-to-i5 stamina delivery but rejected the reverse direction because an unfiltered Player scan chose an aliased ZDO. r6 requires target ZDO user identity to equal its current owner, selects the nearest live match, and gives focused breadth gates one native-zero composition switch. The receiver remains fail-closed; P7 is untouched.",
      "title": "Reject aliased player targets after the r5 stamina falsifier",
      "updated_at": "2026-08-02T16:13:41.401Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802161341-reject-aliased-player-targets-after-the-r5-stami"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-02T16:39:40.939Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/c10a-usestamina-verification/verification-summary.json"
        ],
        "id": "20260802163940-accept-physical-usestamina-p3-gate",
        "impact": "Exact paired r6 passed both real OMEN+i5 cross-owner stamina directions with live owner-matching targets, exact receiver debits, correlated sender receipts, native totals and poison trips zero, one fresh-process resume each, and clean disarm/config/residue cleanup. One vehicle-control VERIFY plus four physical family gates remain; P7, Workbench, and the separate MCP lane are untouched.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Accept physical UseStamina P3 gate",
        "verification": [
          "122/122 focused mod tests and 616/616 canonical .NET 9 tests on the r6 source commit",
          "native-20260802-c10a-stamina-r6-sync1 completed 18 actions with both physical debit receipts and native-zero composition",
          "OMEN and i5 configs matched their pre-run backups; both games stopped; i5 task Ready; residue matched=0 destroyed=0"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802163940-accept-physical-usestamina-p3-gate",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-02T16:39:40.939Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L399",
        "sha256": "50157a05af76997235cadaa253ad1b82c6b7e6c574daabd5ef0ba765e1feead3"
      },
      "summary": "Exact paired r6 passed both real OMEN+i5 cross-owner stamina directions with live owner-matching targets, exact receiver debits, correlated sender receipts, native totals and poison trips zero, one fresh-process resume each, and clean disarm/config/residue cleanup. One vehicle-control VERIFY plus four physical family gates remain; P7, Workbench, and the separate MCP lane are untouched.",
      "title": "Accept physical UseStamina P3 gate",
      "updated_at": "2026-08-02T16:39:40.939Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802163940-accept-physical-usestamina-p3-gate"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-02T16:49:54.662Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/c10a-vehicle-control-verification/verification-summary.json"
        ],
        "id": "20260802164954-split-the-vehicle-control-contract-by-registrant",
        "impact": "Fresh extractor reproduction closed the shared-hash verification: ship and saddle control require separate typed contracts, remain outside the generic routed lane, and keep poison as the fallback guard while the four physical breadth gates continue.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Split the vehicle-control contract by registrant semantics",
        "verification": [
          "ComfyNetworkSense focused suite passed 123/123 including VehicleControlCollision_RequiresTypedShipAndSaddleContracts.",
          "Extractor reproduced 19 routed, 21 direct, 120 instance RPCs, 122 components, and zero unresolved registrations from the pinned assembly."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802164954-split-the-vehicle-control-contract-by-registrant",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-02T16:49:54.662Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L400",
        "sha256": "13c6400f6f49e3045d24f320b582d553b1e26a6b90e150ea019be76b8e8974c5"
      },
      "summary": "Fresh extractor reproduction closed the shared-hash verification: ship and saddle control require separate typed contracts, remain outside the generic routed lane, and keep poison as the fallback guard while the four physical breadth gates continue.",
      "title": "Split the vehicle-control contract by registrant semantics",
      "updated_at": "2026-08-02T16:49:54.662Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802164954-split-the-vehicle-control-contract-by-registrant"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T18:41:21.200Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/c10a-ship-physical-acceptance/verification-summary.json"
        ],
        "id": "20260802184121-close-the-c10a-physical-ship-cutover-on-am4",
        "impact": "Typed ship control, authenticated owner handoff, and canonical server snapshot fan-out now replace the selected native ship path in both helm and physics-owner directions; mount, container/station, and AI/creature remain local gates.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Close the C10a physical ship cutover on AM4",
        "verification": [
          "Exact r15 completed 34 actions and 12/12 choreography checks on real OMEN and i5 clients with native totals and poison trips zero.",
          "The exact DLL rebuilt to the physical-run SHA with zero warnings; 138 mod tests and 620 clean no-cache repository tests passed."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802184121-close-the-c10a-physical-ship-cutover-on-am4",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T18:41:21.200Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L401",
        "sha256": "38b61944c6373528cbc8bcd000c2ee9922b39539e9364156fc3dcb0053b65870"
      },
      "summary": "Typed ship control, authenticated owner handoff, and canonical server snapshot fan-out now replace the selected native ship path in both helm and physics-owner directions; mount, container/station, and AI/creature remain local gates.",
      "title": "Close the C10a physical ship cutover on AM4",
      "updated_at": "2026-08-02T18:41:21.200Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802184121-close-the-c10a-physical-ship-cutover-on-am4"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-02T22:35:17.470Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260802223517-accept-selected-saddle-canary-and-repair-atomic-",
        "impact": "Exact r27 physically accepted two-client saddle control, ownership, reconnect reclaim, rider attachment, stale fencing, and native-zero on OMEN+i5+AM4. Its exact ship rerun exposed a stale helm user; r28 now releases canonical helm state before owner transfer and reconfirmed both ship directions. Workbench remains frozen; container/station is next.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Accept selected saddle canary and repair atomic ship handoff",
        "verification": [
          "Mount r27 reducer 18/18; ship r28 reducer 19/19; mod tests 140/140; exact AM4 artifacts and physical receipts retained; P7, Workbench, and HEARTH untouched."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260802223517-accept-selected-saddle-canary-and-repair-atomic-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-02T22:35:17.470Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L402",
        "sha256": "6752d9db6623f3eeda802123ed014c67f81c0e8d2ace63631d35ff19e396003b"
      },
      "summary": "Exact r27 physically accepted two-client saddle control, ownership, reconnect reclaim, rider attachment, stale fencing, and native-zero on OMEN+i5+AM4. Its exact ship rerun exposed a stale helm user; r28 now releases canonical helm state before owner transfer and reconfirmed both ship directions. Workbench remains frozen; container/station is next.",
      "title": "Accept selected saddle canary and repair atomic ship handoff",
      "updated_at": "2026-08-02T22:35:17.470Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260802223517-accept-selected-saddle-canary-and-repair-atomic-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T00:22:07.472Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/c10a-container-physical-acceptance/verification-summary.json"
        ],
        "id": "20260803002207-accept-the-selected-two-client-container-transac",
        "impact": "An actual wood chest now holds two physical peers at one canonical revision, commits exactly one item, rejects the stale contender, replays duplicates, and reconstructs empty state in both fresh processes without native networking. AI/creature is the next named physical gate; Workbench remains frozen and P7 untouched.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Accept the selected two-client container transaction cutover",
        "verification": [
          "ComfyNetworkSense 164/164; forced net48 Rebuild zero warnings; Docker solution Verify 625/625 on the r34 source cache; native-20260802-c10a-container-r34-1 passed 19/19 with exact DLL and Gateway hashes, native-zero, and one-container cleanup."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803002207-accept-the-selected-two-client-container-transac",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T00:22:07.472Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L403",
        "sha256": "736cf514dc8d9b630ca2132dddaefefe62f1180fdc55246b82e4c4f5186923a7"
      },
      "summary": "An actual wood chest now holds two physical peers at one canonical revision, commits exactly one item, rejects the stale contender, replays duplicates, and reconstructs empty state in both fresh processes without native networking. AI/creature is the next named physical gate; Workbench remains frozen and P7 untouched.",
      "title": "Accept the selected two-client container transaction cutover",
      "updated_at": "2026-08-03T00:22:07.472Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803002207-accept-the-selected-two-client-container-transac"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-03T01:10:18.903Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/c10a-creature-physical-acceptance/verification-summary.json"
        ],
        "id": "20260803011018-accept-selected-autonomous-creature-authority-on",
        "impact": "Exact r36 closes the actual tamed Lox MonsterAI ownership, transfer, loss, and reclaim canary without weakening native-zero or motion bounds. The next functional gate is arbitrary untagged vehicle/mount handling plus third-recipient AoI/relevance; Workbench, HEARTH, and P7 remain untouched.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Accept selected autonomous creature authority on OMEN, i5, and AM4",
        "verification": [
          "Release m7-c10a-20260802-r36; DLL f5fafbe2beda387d48191993813201250ad3306f759c9f18a418ffb1056bfad2; Gateway image sha256:6a79a70e358320fa6ef84cd11cee5b556e0b9b23f9b5a027655db03e3beafc8f; physical run native-20260802-c10a-creature-r36-1 passed 19/19 reducer checks, 175/175 unit tests, native-zero on OMEN/i5/AM4, and exact one-Lox cleanup."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803011018-accept-selected-autonomous-creature-authority-on",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-03T01:10:18.903Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L404",
        "sha256": "9fa805859405a48f9645a07ffa1f5557b39107f0bde1bbee79bdee0e3c3e3edd"
      },
      "summary": "Exact r36 closes the actual tamed Lox MonsterAI ownership, transfer, loss, and reclaim canary without weakening native-zero or motion bounds. The next functional gate is arbitrary untagged vehicle/mount handling plus third-recipient AoI/relevance; Workbench, HEARTH, and P7 remain untouched.",
      "title": "Accept selected autonomous creature authority on OMEN, i5, and AM4",
      "updated_at": "2026-08-03T01:10:18.903Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803011018-accept-selected-autonomous-creature-authority-on"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T02:50:04.077Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/experiments/m7/m7-e04-vehicle-relevance/experiment.md",
          "fieldlab/evidence/c10a-station-breadth-review/verification-summary.json"
        ],
        "id": "20260803025004-prepare-the-r39-untagged-vehicle-relevance-candi",
        "impact": "General vehicle and mount snapshots now use independent direct recipient relevance, adopt ordinary untagged saddled mounts, publish correctly from a dedicated-server owner, and fail fast on cross-machine release mismatch; station admission breadth is closed while the exact physical r39 run remains pending.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Prepare the r39 untagged vehicle relevance candidate",
        "verification": [
          "ComfyNetworkSense tests passed 182 of 182 and the Release build completed with zero warnings or errors.",
          "M7-E04 produced repeatable normalized three-recipient relevance receipts; the 41-action physical manifest passed its fail-closed coverage check."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803025004-prepare-the-r39-untagged-vehicle-relevance-candi",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T02:50:04.077Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L405",
        "sha256": "a4930a67c2e49a51178862cb95d227a1222c069eb859e2222cbab708cc768515"
      },
      "summary": "General vehicle and mount snapshots now use independent direct recipient relevance, adopt ordinary untagged saddled mounts, publish correctly from a dedicated-server owner, and fail fast on cross-machine release mismatch; station admission breadth is closed while the exact physical r39 run remains pending.",
      "title": "Prepare the r39 untagged vehicle relevance candidate",
      "updated_at": "2026-08-03T02:50:04.077Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803025004-prepare-the-r39-untagged-vehicle-relevance-candi"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T03:11:56.274Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/scenarios/native-20260802-c10a-relevance-r39-1.json",
          "fieldlab/scenarios/native-20260802-c10a-relevance-r39-1.coverage.json"
        ],
        "id": "20260803031156-repair-the-r39-server-owner-physical-falsifier",
        "impact": "The r40 candidate makes wait-only saddle discovery non-creating, derives untagged authority from the actual ZDO, publishes canonical snapshots from a server-owned ZDO without a scene instance, and preserves complete OMEN failure evidence. r39 remains a named two-client functional falsifier; P7, Workbench, and HEARTH remain untouched.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Repair the r39 server-owner physical falsifier",
        "verification": [
          "The exact r39 DLL reached joined gameplay on AM4, OMEN, and i5 and isolated zero snapshot advancement after dedicated-server handoff plus the earlier waiter creation race.",
          "ComfyNetworkSense passed 182 of 182 tests, built Release with zero warnings or errors, the 41-action manifest passed all 15 coverage checks, and the canonical Docker verify target passed."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803031156-repair-the-r39-server-owner-physical-falsifier",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T03:11:56.274Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L406",
        "sha256": "5b517f655e83a8eb825d9952bd7ba8d10a03dd757f953f1c61b91db172d87b1c"
      },
      "summary": "The r40 candidate makes wait-only saddle discovery non-creating, derives untagged authority from the actual ZDO, publishes canonical snapshots from a server-owned ZDO without a scene instance, and preserves complete OMEN failure evidence. r39 remains a named two-client functional falsifier; P7, Workbench, and HEARTH remain untouched.",
      "title": "Repair the r39 server-owner physical falsifier",
      "updated_at": "2026-08-03T03:11:56.274Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803031156-repair-the-r39-server-owner-physical-falsifier"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T03:27:04.537Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/scenarios/native-20260802-c10a-relevance-r40-1.json",
          "fieldlab/scenarios/native-20260802-c10a-relevance-r40-1.coverage.json"
        ],
        "id": "20260803032704-fence-the-r40-native-saddle-owner-revocation",
        "impact": "The exact r40 two-client run proved untagged discovery and ZDO-only publication, then isolated Valheim's two-second ReleaseNearbyZDOS sweep revoking the canonical server owner after two snapshots. r41 adds the saddle authority map to the existing scoped ZDO.SetOwner guard, logs the suppression, repairs any surviving drift, and makes the physical reducer require that event. P7, Workbench, and HEARTH remain untouched.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Fence the r40 native saddle-owner revocation",
        "verification": [
          "r40 reached exact epoch 6 with both clients receiving server-owner snapshots, then failed at snapshot_advance=2; all prior drive/observe, stale fencing, native-zero, hash identity, and exact untagged cleanup checks passed.",
          "ComfyNetworkSense passed 186 of 186 tests and built Release with zero warnings or errors; the updated reducer correctly fails the retained r40 evidence on the new native-sweep fence check."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803032704-fence-the-r40-native-saddle-owner-revocation",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T03:27:04.537Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L407",
        "sha256": "9728a9bd71fd9a9f24e6810471c62195da00fcc32bfb3f14234b8ba874f38271"
      },
      "summary": "The exact r40 two-client run proved untagged discovery and ZDO-only publication, then isolated Valheim's two-second ReleaseNearbyZDOS sweep revoking the canonical server owner after two snapshots. r41 adds the saddle authority map to the existing scoped ZDO.SetOwner guard, logs the suppression, repairs any surviving drift, and makes the physical reducer require that event. P7, Workbench, and HEARTH remain untouched.",
      "title": "Fence the r40 native saddle-owner revocation",
      "updated_at": "2026-08-03T03:27:04.537Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803032704-fence-the-r40-native-saddle-owner-revocation"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-03T03:43:37.259Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/c10a-vehicle-relevance-physical-acceptance/verification-summary.json",
          "fieldlab/scenarios/native-20260802-c10a-relevance-r41-1.json"
        ],
        "id": "20260803034337-accept-the-r41-untagged-vehicle-relevance-gate",
        "impact": "Exact r41 passed the last local C10a functional gate; C10b P7 promotion and final fallback deletion remain.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Accept the r41 untagged vehicle relevance gate",
        "verification": [
          "Both rendered clients completed all 41 actions, both drive/observe directions, one fresh-process resume, epochs 1-6, server-owner publication, i5 relevance leave/re-entry, native-zero, and exact cleanup.",
          "The corrected reducer passes r41 27/27 and still rejects retained r40; all four physically attempted ReleaseNearbyZDOS owner reassignments were suppressed."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803034337-accept-the-r41-untagged-vehicle-relevance-gate",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-03T03:43:37.259Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L408",
        "sha256": "cec268df74d41a1697a1a3a0a0f351d32b8a73f5211c62751a1b496772a01b51"
      },
      "summary": "Exact r41 passed the last local C10a functional gate; C10b P7 promotion and final fallback deletion remain.",
      "title": "Accept the r41 untagged vehicle relevance gate",
      "updated_at": "2026-08-03T03:43:37.259Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803034337-accept-the-r41-untagged-vehicle-relevance-gate"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T04:05:49.219Z",
        "author": "Codex",
        "evidence": [
          "tools/p7/Invoke-P7BootDeterminism.ps1",
          "tools/p7/Invoke-C10bPairPromotion.ps1",
          "tools/p7/Invoke-C10bCandidateProof.ps1",
          "fieldlab/plan-native-network-final-cutover.md"
        ],
        "id": "20260803040549-make-the-c10b-physical-harness-p7-capable",
        "impact": "The pair proof now selects one remote server and Gateway topology, verifies predeployed bytes before client launch, produces a boot-bound determinism receipt, and promotes the frozen pair as one rollback unit while preserving AM4 defaults; P7 remains terminated and unchanged.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make the C10b physical harness P7-capable",
        "verification": [
          "PowerShell parses all changed scripts; the retained recovery5 C8 reducer still passes; boot preflight reports ready while the candidate wrapper proves the exact local r41 pair and restored i5 lane, then fails closed as not_ready while P7 is terminated.",
          "Boot execution requires an explicit mutation switch, rejects unsafe save/disk/boot state, injects a real first-start systemd failure, and binds its acceptance to the current instance and boot; frozen pair promotion restores both artifacts on any failure."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803040549-make-the-c10b-physical-harness-p7-capable",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T04:05:49.219Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L409",
        "sha256": "658b7233fd58b61ad2a1323513a997248d9739af4773cc035bdad227b6863a8b"
      },
      "summary": "The pair proof now selects one remote server and Gateway topology, verifies predeployed bytes before client launch, produces a boot-bound determinism receipt, and promotes the frozen pair as one rollback unit while preserving AM4 defaults; P7 remains terminated and unchanged.",
      "title": "Make the C10b physical harness P7-capable",
      "updated_at": "2026-08-03T04:05:49.219Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803040549-make-the-c10b-physical-harness-p7-capable"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T04:55:21.113Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260803045521-make-coupled-release-cuts-prove-final-artifact-s",
        "impact": "The canonical coupled cutter now derives the active checkout reliably, force-rebuilds the mod, and requires the source-plus-DLL candidate/final fallback boundary before any Gateway image build. This closes the stale incremental artifact path exposed by r28; P7 remains terminated and untouched.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make coupled release cuts prove final artifact semantics",
        "verification": [
          "PowerShell parsing passed; default-final and explicit-candidate dry runs passed from the repo and an unrelated working directory without mutating source; r41 passes candidate mode and is correctly rejected by final mode while all retained native-ledger guards remain present."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803045521-make-coupled-release-cuts-prove-final-artifact-s",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T04:55:21.113Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L410",
        "sha256": "b38800818b432e32661ba9ee3511ca81d66d8b86a504c4bae9ded54a57d867c0"
      },
      "summary": "The canonical coupled cutter now derives the active checkout reliably, force-rebuilds the mod, and requires the source-plus-DLL candidate/final fallback boundary before any Gateway image build. This closes the stale incremental artifact path exposed by r28; P7 remains terminated and untouched.",
      "title": "Make coupled release cuts prove final artifact semantics",
      "updated_at": "2026-08-03T04:55:21.113Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803045521-make-coupled-release-cuts-prove-final-artifact-s"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T05:24:19.632Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/plan-native-network-final-cutover.md",
          "tools/p7/Invoke-C10bCandidateProof.ps1"
        ],
        "id": "20260803052419-enforce-c10b-candidate-and-final-proof-stages",
        "impact": "The physical harness, pair promotion, and P7 proof now distinguish retained candidate controls from the no-fallback final artifact; final runs cannot arm or emit migration controls while permanent evidence and Steam-free join controls remain. The i5 lane is restored; P7 remains terminated and unchanged.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Enforce C10b candidate and final proof stages",
        "verification": [
          "Local and remote i5 request previews emitted eight candidate migration fields and zero final fields; the runtime plan emitted nine candidate migration settings and zero final settings.",
          "Candidate, final, and legacy reducers passed positive fixtures and rejected a final lifecycle that emitted migration fields; candidate promotion dry-run passed and final promotion refused r41 before mutation.",
          "The read-only C10b preflight reports the local pair, artifact boundary, and i5 lane ready, then remains not_ready because P7 is terminated and lacks an accepted boot receipt."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803052419-enforce-c10b-candidate-and-final-proof-stages",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T05:24:19.632Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L411",
        "sha256": "9a2169c9181d404c8f8a3056710da072dfc07982dde442b12891064b5ab8846f"
      },
      "summary": "The physical harness, pair promotion, and P7 proof now distinguish retained candidate controls from the no-fallback final artifact; final runs cannot arm or emit migration controls while permanent evidence and Steam-free join controls remain. The i5 lane is restored; P7 remains terminated and unchanged.",
      "title": "Enforce C10b candidate and final proof stages",
      "updated_at": "2026-08-03T05:24:19.632Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803052419-enforce-c10b-candidate-and-final-proof-stages"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T05:36:30.691Z",
        "author": "Codex",
        "evidence": [
          "tools/p7/Test-C10bArtifactFallbackBoundary.ps1",
          "fieldlab/plan-native-network-final-cutover.md"
        ],
        "id": "20260803053630-require-permanent-native-replacement-semantics-i",
        "impact": "The C10b final artifact gate now refuses a marker-free build that deletes or disables replacement behavior. It retains the ledger, mapped patches, permanent request controls, and every replacement runner family, and requires explicit final source semantics for poison, cold join, direct control, routed RPC, journal, ownership, world and zone, motion, logical peers, ships, saddles, creatures, and containers. P7 remains terminated and unchanged.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Require permanent native-replacement semantics in the final gate",
        "verification": [
          "Exact r41 still passes candidate mode with all 28 retained guard and replacement markers; candidate pair promotion dry-run and the read-only P7 preflight remain green through the local pair and i5 lane.",
          "Final mode rejects r41 on all 35 migration markers and the 20 permanent-behavior conversions not yet performed; final pair promotion refuses before any external mutation."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803053630-require-permanent-native-replacement-semantics-i",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T05:36:30.691Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L412",
        "sha256": "71d5d2d2e00b8c9b0095b7f883656b1de0bb2044447b11d7bf41dd5999b588fc"
      },
      "summary": "The C10b final artifact gate now refuses a marker-free build that deletes or disables replacement behavior. It retains the ledger, mapped patches, permanent request controls, and every replacement runner family, and requires explicit final source semantics for poison, cold join, direct control, routed RPC, journal, ownership, world and zone, motion, logical peers, ships, saddles, creatures, and containers. P7 remains terminated and unchanged.",
      "title": "Require permanent native-replacement semantics in the final gate",
      "updated_at": "2026-08-03T05:36:30.691Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803053630-require-permanent-native-replacement-semantics-i"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T08:21:50.347Z",
        "author": "Codex",
        "evidence": [
          "tools/p7/Invoke-P7BootDeterminism.ps1"
        ],
        "id": "20260803082150-make-the-p7-boot-receipt-directory-fail-safe",
        "impact": "The boot-determinism runner now creates its local receipt directory before the first preserved-incident evidence write, preventing a local filesystem error from stranding a newly started P7 in the guarded running state. No remote unit or artifact was changed by this correction.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make the P7 boot receipt directory fail-safe",
        "verification": [
          "PowerShell parsing passed; the failed first attempt was returned to TERMINATED without applying the boot fix, and the next run will use the committed receipt-path guard."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803082150-make-the-p7-boot-receipt-directory-fail-safe",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T08:21:50.347Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L413",
        "sha256": "afe2fe35baa9f0fd53a0cd4fbc349c4558510d368a309d3f2371436053027965"
      },
      "summary": "The boot-determinism runner now creates its local receipt directory before the first preserved-incident evidence write, preventing a local filesystem error from stranding a newly started P7 in the guarded running state. No remote unit or artifact was changed by this correction.",
      "title": "Make the P7 boot receipt directory fail-safe",
      "updated_at": "2026-08-03T08:21:50.347Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803082150-make-the-p7-boot-receipt-directory-fail-safe"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T08:24:47.551Z",
        "author": "Codex",
        "evidence": [
          "tools/p7/Invoke-P7BootDeterminism.ps1"
        ],
        "id": "20260803082447-verify-the-p7-runtime-mask-by-its-systemd-link",
        "impact": "The boot-determinism guard now verifies the actual runtime mask symlink to /dev/null instead of trusting systemctl is-enabled, which reports enabled for this Debian unit even while the runtime mask is present. This closes the second local false refusal; P7 was returned to TERMINATED without installing the permanent boot fix.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Verify the P7 runtime mask by its systemd link",
        "verification": [
          "The remote failed attempt showed /run/systemd/system/comfy-lumberjacks-p7.service -> /dev/null while systemctl is-enabled reported enabled; the VM was stopped again and is ready for the corrected run."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803082447-verify-the-p7-runtime-mask-by-its-systemd-link",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T08:24:47.551Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L414",
        "sha256": "b8ba96461de42bd971e52e7336b58213dc3a515d333a618379017b77b7b2ab51"
      },
      "summary": "The boot-determinism guard now verifies the actual runtime mask symlink to /dev/null instead of trusting systemctl is-enabled, which reports enabled for this Debian unit even while the runtime mask is present. This closes the second local false refusal; P7 was returned to TERMINATED without installing the permanent boot fix.",
      "title": "Verify the P7 runtime mask by its systemd link",
      "updated_at": "2026-08-03T08:24:47.551Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803082447-verify-the-p7-runtime-mask-by-its-systemd-link"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T08:49:37.852Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260803084937-pass-the-p7-environment-file-explicitly-to-every",
        "impact": "Prevents boot-loop interpolation drift where dbschema exists in the deployed compose but systemd cannot resolve required release variables",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Pass the P7 environment file explicitly to every Compose unit invocation",
        "verification": [
          "systemd-analyze verify passes; P7 boot receipt rerun"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803084937-pass-the-p7-environment-file-explicitly-to-every",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T08:49:37.852Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L415",
        "sha256": "d53914d02e085fa0edb82206424f9a73b86d6595575806202007ee33b31ef639"
      },
      "summary": "Prevents boot-loop interpolation drift where dbschema exists in the deployed compose but systemd cannot resolve required release variables",
      "title": "Pass the P7 environment file explicitly to every Compose unit invocation",
      "updated_at": "2026-08-03T08:49:37.852Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803084937-pass-the-p7-environment-file-explicitly-to-every"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T09:08:57.775Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260803090857-treat-an-absent-first-run-runtime-receipt-ledger",
        "impact": "Allows the P7 candidate harness to launch a genuinely fresh run while still failing closed on unreadable or previously used server evidence",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Treat an absent first-run runtime receipt ledger as unused",
        "verification": [
          "Fresh P7 candidate proof proceeds past RunId preflight; existing receipt matches still refuse"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803090857-treat-an-absent-first-run-runtime-receipt-ledger",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T09:08:57.775Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L416",
        "sha256": "4d0b9cedf98abe3f6a49e72c4dc558c8c93a4c182c96235cafaac187999685cc"
      },
      "summary": "Allows the P7 candidate harness to launch a genuinely fresh run while still failing closed on unreadable or previously used server evidence",
      "title": "Treat an absent first-run runtime receipt ledger as unused",
      "updated_at": "2026-08-03T09:08:57.775Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803090857-treat-an-absent-first-run-runtime-receipt-ledger"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T09:09:50.193Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260803090950-keep-the-fresh-runtime-receipt-probe-valid-shell",
        "impact": "Avoids prepending sudo to a compound if probe, allowing the first P7 candidate run to pass single-use preflight without weakening unreadable-ledger refusal",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Keep the fresh runtime receipt probe valid shell",
        "verification": [
          "Fresh candidate proof reaches client launch; reused receipt matches still refuse"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803090950-keep-the-fresh-runtime-receipt-probe-valid-shell",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T09:09:50.193Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L417",
        "sha256": "6616276c0c82b2c24b9f2655c310157aa23041130807e03aaeb72343a9181283"
      },
      "summary": "Avoids prepending sudo to a compound if probe, allowing the first P7 candidate run to pass single-use preflight without weakening unreadable-ledger refusal",
      "title": "Keep the fresh runtime receipt probe valid shell",
      "updated_at": "2026-08-03T09:09:50.193Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803090950-keep-the-fresh-runtime-receipt-probe-valid-shell"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T09:15:46.820Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260803091546-accept-the-current-valheim-world-count-load-line",
        "impact": "Keeps the candidate save-integrity gate grounded on the live Loading <n> zdos evidence while retaining compatibility with older ZDOS heartbeat lines",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Accept the current Valheim world-count load line in save fingerprints",
        "verification": [
          "P7 candidate fingerprint passes from the current load block; structural counts and world files remain required"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803091546-accept-the-current-valheim-world-count-load-line",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T09:15:46.820Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L418",
        "sha256": "0347bf16b6cf11ecf7ad81d7dcd7891708df5174d373584bb502888b3b26cc16"
      },
      "summary": "Keeps the candidate save-integrity gate grounded on the live Loading <n> zdos evidence while retaining compatibility with older ZDOS heartbeat lines",
      "title": "Accept the current Valheim world-count load line in save fingerprints",
      "updated_at": "2026-08-03T09:15:46.820Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803091546-accept-the-current-valheim-world-count-load-line"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T09:16:51.689Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260803091651-collect-current-valheim-load-counts-before-finge",
        "impact": "Ensures the save-integrity probe retains the live Loading zdos line instead of filtering it out before validation",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Collect current Valheim load counts before fingerprint parsing",
        "verification": [
          "P7 candidate fingerprint sees zdos, portals, spawner, target, and location counts from one load block"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803091651-collect-current-valheim-load-counts-before-finge",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T09:16:51.689Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L419",
        "sha256": "7aba211c8905f61a9864481dd888fd66a87fbd17f354f9efbecaedd82a5d5235"
      },
      "summary": "Ensures the save-integrity probe retains the live Loading zdos line instead of filtering it out before validation",
      "title": "Collect current Valheim load counts before fingerprint parsing",
      "updated_at": "2026-08-03T09:16:51.689Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803091651-collect-current-valheim-load-counts-before-finge"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T09:23:31.322Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260803092331-keep-runtime-control-cleanup-immune-to-benign-ia",
        "impact": "Prevents a successful remote runtime receipt from being converted into a local failure by gcloud's Windows stdin teardown warning",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Keep runtime-control cleanup immune to benign IAP warnings",
        "verification": [
          "P7 candidate runtime-control receipts parse and cleanup returns without NativeCommandError"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803092331-keep-runtime-control-cleanup-immune-to-benign-ia",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T09:23:31.322Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L420",
        "sha256": "f7c1590f5aabaaed0c6a58404305e01f1c09b0ce7affa28fa7b8da8bacffedf3"
      },
      "summary": "Prevents a successful remote runtime receipt from being converted into a local failure by gcloud's Windows stdin teardown warning",
      "title": "Keep runtime-control cleanup immune to benign IAP warnings",
      "updated_at": "2026-08-03T09:23:31.322Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803092331-keep-runtime-control-cleanup-immune-to-benign-ia"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T09:32:17.222Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260803093217-route-remote-gateway-journal-assertions-over-the",
        "impact": "Keeps public player endpoints credentialed while letting the physical harness inspect and reset its own journal through P7 loopback",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Route remote Gateway journal assertions over the private P7 plane",
        "verification": [
          "Candidate C3 restart proof uses private loopback status/reset and completes without public 401"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803093217-route-remote-gateway-journal-assertions-over-the",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T09:32:17.222Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L421",
        "sha256": "66a3220c7c42984507942caa5d63448073dc33dce4e02f2c5b865d2b5679d26f"
      },
      "summary": "Keeps public player endpoints credentialed while letting the physical harness inspect and reset its own journal through P7 loopback",
      "title": "Route remote Gateway journal assertions over the private P7 plane",
      "updated_at": "2026-08-03T09:32:17.222Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803093217-route-remote-gateway-journal-assertions-over-the"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-03T09:41:15.289Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260803094115-separate-p7-c3-journal-persistence-from-redirect",
        "impact": "Gateway restart replay now has an explicit durable journal path in the P7 compose contract, so C3 proof can validate real rehydration.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Separate P7 C3 journal persistence from redirect queue WAL",
        "verification": [
          "Compose inspection confirms VALHEIM_ZDO_JOURNAL_PATH is mounted under the P7 persistent zdo-queue volume."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260803094115-separate-p7-c3-journal-persistence-from-redirect",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-03T09:41:15.289Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L422",
        "sha256": "2e17bcbe36bb4b73d9c216b3372226d30db25464d980558de2b83c49b62a7e1f"
      },
      "summary": "Gateway restart replay now has an explicit durable journal path in the P7 compose contract, so C3 proof can validate real rehydration.",
      "title": "Separate P7 C3 journal persistence from redirect queue WAL",
      "updated_at": "2026-08-03T09:41:15.289Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260803094115-separate-p7-c3-journal-persistence-from-redirect"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-04T03:35:42.138Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260804033542-record-p7-c10b-cutover-findings-and-stopped-vm-s",
        "impact": "Preserves the exact boot, persistence, and physical-client evidence while clearly separating the proven C3 replay from the still-unproven full cutover.",
        "kind": "documentation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Record P7 C10b cutover findings and stopped-VM state",
        "verification": [
          "fieldlab/evidence/p7-c10b-20260803-findings.md; P7 Compute Engine status verified TERMINATED."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260804033542-record-p7-c10b-cutover-findings-and-stopped-vm-s",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-04T03:35:42.138Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L423",
        "sha256": "cf50cc67c6e8656047a9a5688cf7b20b0322bf6b3743cf61d719ecb74acb68c1"
      },
      "summary": "Preserves the exact boot, persistence, and physical-client evidence while clearly separating the proven C3 replay from the still-unproven full cutover.",
      "title": "Record P7 C10b cutover findings and stopped-VM state",
      "updated_at": "2026-08-04T03:35:42.138Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260804033542-record-p7-c10b-cutover-findings-and-stopped-vm-s"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-05T09:40:17.310Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260805094017-calibrate-c8-gateway-restart-resume-deadline-for",
        "impact": "The 20s budget absorbed ~8s of IAP SSH restart latency plus Caddy-mediated death detection on P7; 3 of 4 P7 attempts deadlined while local runs pass in 5-12s. 45s keeps the recovery assertion while fitting the remote rig path; the deployed r41 mod accepts deadlines to 300s so the promoted pair is untouched.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Calibrate C8 gateway-restart-resume deadline for remote P7 topology",
        "verification": [
          "candidate11 passed the step in 22.8s on P7 with both clients; local bound semantics unchanged"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260805094017-calibrate-c8-gateway-restart-resume-deadline-for",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-05T09:40:17.310Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L424",
        "sha256": "7582948c85db6a6093c45c1eb3964f1a6587037540db354ed223a4d89fd61290"
      },
      "summary": "The 20s budget absorbed ~8s of IAP SSH restart latency plus Caddy-mediated death detection on P7; 3 of 4 P7 attempts deadlined while local runs pass in 5-12s. 45s keeps the recovery assertion while fitting the remote rig path; the deployed r41 mod accepts deadlines to 300s so the promoted pair is untouched.",
      "title": "Calibrate C8 gateway-restart-resume deadline for remote P7 topology",
      "updated_at": "2026-08-05T09:40:17.310Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260805094017-calibrate-c8-gateway-restart-resume-deadline-for"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-05T10:03:19.178Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260805100319-plan-the-gateway-session-plane-fixes-blocking-th",
        "impact": "Five prioritized fixes with receipts: resume-evict for zombie sessions, gateway-side stalled-session abort, paced journal redelivery with control-frame priority, owner-liveness for recipient partitions, and declarative cutover mode. Candidates 8/9/10/11 plus the 08-05 outage all trace to these.",
        "kind": "documentation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Plan the Gateway session-plane fixes blocking the P7 cutover",
        "verification": [
          "fieldlab/evidence/p7-gateway-session-plane-fix-plan-20260805.md; each defect cites run receipts or Cloud Logging entries"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260805100319-plan-the-gateway-session-plane-fixes-blocking-th",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-05T10:03:19.178Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L425",
        "sha256": "d1a6667726956e6f22e4e54a3eced582f386065884e05e699782fbb79ae3101a"
      },
      "summary": "Five prioritized fixes with receipts: resume-evict for zombie sessions, gateway-side stalled-session abort, paced journal redelivery with control-frame priority, owner-liveness for recipient partitions, and declarative cutover mode. Candidates 8/9/10/11 plus the 08-05 outage all trace to these.",
      "title": "Plan the Gateway session-plane fixes blocking the P7 cutover",
      "updated_at": "2026-08-05T10:03:19.178Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260805100319-plan-the-gateway-session-plane-fixes-blocking-th"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-05T10:30:18.012Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260805103018-record-the-enrollment-lane-alpha-gate-and-08-05-",
        "impact": "The candidate proof exercises the harness journal lane while alpha testers run the enrollment consumer lane, which the new stack has never exercised on P7; a mod-zip-to-visible-world proof is now the alpha gate. Also: unconsumed-window WAL hit 1GB and needs a growth bound; human motion baseline on WAN vanilla sync is smooth; P7 left in native play mode with the armed config backed up.",
        "kind": "documentation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Record the enrollment-lane alpha gate and 08-05 human-session findings",
        "verification": [
          "fieldlab/evidence/p7-gateway-session-plane-fix-plan-20260805.md addendum; cutover telemetry showed active_consumers 0 with 4421 pending; VM verified TERMINATED"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260805103018-record-the-enrollment-lane-alpha-gate-and-08-05-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-05T10:30:18.012Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L426",
        "sha256": "49cf392392747aa44f350c9e3a56621f8cffb999948a5649e74fd1997fb4a780"
      },
      "summary": "The candidate proof exercises the harness journal lane while alpha testers run the enrollment consumer lane, which the new stack has never exercised on P7; a mod-zip-to-visible-world proof is now the alpha gate. Also: unconsumed-window WAL hit 1GB and needs a growth bound; human motion baseline on WAN vanilla sync is smooth; P7 left in native play mode with the armed config backed up.",
      "title": "Record the enrollment-lane alpha gate and 08-05 human-session findings",
      "updated_at": "2026-08-05T10:30:18.012Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260805103018-record-the-enrollment-lane-alpha-gate-and-08-05-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-05T10:38:27.984Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260805103827-session-retro-08-05-adr-0017-proof-lane-fidelity",
        "impact": "Retires two failed failure theories with receipts, records the three-delivery-lanes finding as ADR 0017 (acceptance proofs must exercise the lane users ship on), grades prior lessons, and queues the r42 cut, alpha-gate ratification, and redirect-restore decisions in the register.",
        "kind": "documentation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Session retro 08-05, ADR 0017 proof-lane fidelity, and the open r42/alpha-gate decisions",
        "verification": [
          "fieldlab/retro/SESSION-RETRO-2026-08-05.md; fieldlab/docs/adr/0017-prove-the-lane-users-ship-on.md; fieldlab/DECISIONS-PENDING.md"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260805103827-session-retro-08-05-adr-0017-proof-lane-fidelity",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-05T10:38:27.984Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L427",
        "sha256": "bdd22b60469ed01a3e8065985aa03462b2f5a2a16d2c888277c871f5f84d43d1"
      },
      "summary": "Retires two failed failure theories with receipts, records the three-delivery-lanes finding as ADR 0017 (acceptance proofs must exercise the lane users ship on), grades prior lessons, and queues the r42 cut, alpha-gate ratification, and redirect-restore decisions in the register.",
      "title": "Session retro 08-05, ADR 0017 proof-lane fidelity, and the open r42/alpha-gate decisions",
      "updated_at": "2026-08-05T10:38:27.984Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260805103827-session-retro-08-05-adr-0017-proof-lane-fidelity"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-05T11:04:40.329Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260805110440-r42-gateway-session-plane-fix-cut-per-the-2026-0",
        "impact": "Resume now evicts a live zombie session and carries reliable state (ends the candidate-8/9 reconnect storm); a 10s stalled-session abort mirrors the mod send guard; post-restart journal redelivery is capped at 64 in-flight bulk frames; motion resync degrades per recipient instead of throwing into the publisher loop; window completeness only counts partitions with live consumers and WAL-replayed partitions are provisional with a 60s TTL (ends the heartbeat-409 starvation); redirect pending is bounded per partition with shed-and-log plus WAL auto-compact; /live/valheim-cutover reports effective mode and the last admission verdict; the mod abandons a refused resume after 3 attempts with backoff and reincarnates, logs effective cutover mode at boot at Warning, and gains a harness-only apply throttle to reproduce the redelivery wedge on AM4 before GCP spend.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "r42 Gateway session-plane fix cut per the 2026-08-05 plan",
        "verification": [
          "Gateway 242/242 tests in the sdk:9.0 container incl. new SessionPlaneRecoveryTests; mod 190/190 on host dotnet incl. new ResumeReattachPolicyTests; net48 plugin builds with the PluginOutputPath guard"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260805110440-r42-gateway-session-plane-fix-cut-per-the-2026-0",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-05T11:04:40.329Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L428",
        "sha256": "530885f4e50fbcd5499792562d6521c53a61b149bfa9619626238291249c93e8"
      },
      "summary": "Resume now evicts a live zombie session and carries reliable state (ends the candidate-8/9 reconnect storm); a 10s stalled-session abort mirrors the mod send guard; post-restart journal redelivery is capped at 64 in-flight bulk frames; motion resync degrades per recipient instead of throwing into the publisher loop; window completeness only counts partitions with live consumers and WAL-replayed partitions are provisional with a 60s TTL (ends the heartbeat-409 starvation); redirect pending is bounded per partition with shed-and-log plus WAL auto-compact; /live/valheim-cutover reports effective mode and the last admission verdict; the mod abandons a refused resume after 3 attempts with backoff and reincarnates, logs effective cutover mode at boot at Warning, and gains a harness-only apply throttle to reproduce the redelivery wedge on AM4 before GCP spend.",
      "title": "r42 Gateway session-plane fix cut per the 2026-08-05 plan",
      "updated_at": "2026-08-05T11:04:40.329Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260805110440-r42-gateway-session-plane-fix-cut-per-the-2026-0"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T03:32:36.262Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807033236-qb-1-re-scoped-and-executed-adr-0018-decides-the",
        "impact": "The stale catalog framing (point bridge_consumer.py at a folder) hid a design call: the live mod deliberately produces no evidence envelope, so ADR 0018 declines re-materializing screenshots/trace and keeps the thin record. tools/quest-bridge/ lands the port (EventLog quest_completed row -> thin submission -> review record -> guild-command export, deterministic ids, review state preserved across refetches); the producer now forwards the quest's public-safe name in the EventLog payload; the workbench catalog entry and one-pager now describe the decided shape, and QB-1 narrows to the live proof. Archive copies stay byte-exact except the consumer README path fix, recorded in PROVENANCE.md.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "QB-1 re-scoped and executed: ADR 0018 decides the quest proof is the durable EventLog row, and the bridge back half is ported to that contract",
        "verification": [
          "tests/test_quest_bridge.py 6/6 on host python; mod 190/190 on host dotnet after the quest_name payload change; fieldlab/docs/adr/0018-quest-proof-is-the-eventlog-row.md"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807033236-qb-1-re-scoped-and-executed-adr-0018-decides-the",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T03:32:36.262Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L429",
        "sha256": "69e17826af78b3decbf476fbc7f1990c2b5b98941ade4f24d96d1e9aa7b98ef4"
      },
      "summary": "The stale catalog framing (point bridge_consumer.py at a folder) hid a design call: the live mod deliberately produces no evidence envelope, so ADR 0018 declines re-materializing screenshots/trace and keeps the thin record. tools/quest-bridge/ lands the port (EventLog quest_completed row -> thin submission -> review record -> guild-command export, deterministic ids, review state preserved across refetches); the producer now forwards the quest's public-safe name in the EventLog payload; the workbench catalog entry and one-pager now describe the decided shape, and QB-1 narrows to the live proof. Archive copies stay byte-exact except the consumer README path fix, recorded in PROVENANCE.md.",
      "title": "QB-1 re-scoped and executed: ADR 0018 decides the quest proof is the durable EventLog row, and the bridge back half is ported to that contract",
      "updated_at": "2026-08-07T03:32:36.262Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807033236-qb-1-re-scoped-and-executed-adr-0018-decides-the"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T07:09:44.536Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807070944-terrain-only-regression-plan-phases-0-3-diagnosi",
        "impact": "The 08-05 outage class now has receipts (Phase 0 census incl. the surprise at-rest client credentials), pinned admission semantics (409-by-design + late-attach flip, 2 new tests, 244/244 green), a client harness that can ride the enrollment-consumer lane (-EnrollmentId/-ClientAccessKey, byte-exact restore), a host-path-aware ZDO queue reset script rehearsed locally, and a read-only mode-coherence preflight that fails loud on the L-2026-08-05-4 three-place divergence (verified: 4 real mismatches caught today).",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Terrain-only regression plan phases 0-3: diagnosis confirmed against the 08-05 retro, recovery-path admission tests, enrollment-lane harness params, WAL reset + mode-coherence tooling",
        "verification": [
          "Game.Gateway.Tests 244/244 in sdk:9.0 container; all four scripts parse clean under PS 5.1; Reset-LumberjacksZdoQueue -Target local archived the 5.3MB dev journal with gateway stopped; Test-CutoverModeCoherence exit 1 on lumberjacks-primary (4 named mismatches) and exit 0 on native"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260807070944-terrain-only-regression-plan-phases-0-3-diagnosi",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T07:09:44.536Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L430",
        "sha256": "7f87a1a0212adaacb579fb51957e7adddd8635f6c950dc3bace0a627d66bc9c2"
      },
      "summary": "The 08-05 outage class now has receipts (Phase 0 census incl. the surprise at-rest client credentials), pinned admission semantics (409-by-design + late-attach flip, 2 new tests, 244/244 green), a client harness that can ride the enrollment-consumer lane (-EnrollmentId/-ClientAccessKey, byte-exact restore), a host-path-aware ZDO queue reset script rehearsed locally, and a read-only mode-coherence preflight that fails loud on the L-2026-08-05-4 three-place divergence (verified: 4 real mismatches caught today).",
      "title": "Terrain-only regression plan phases 0-3: diagnosis confirmed against the 08-05 retro, recovery-path admission tests, enrollment-lane harness params, WAL reset + mode-coherence tooling",
      "updated_at": "2026-08-07T07:09:44.536Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807070944-terrain-only-regression-plan-phases-0-3-diagnosi"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T08:02:16.532Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807080216-quest-lab-scaffold-a-separate-client-only-mod-th",
        "impact": "Quest authors currently guess, and the guess fails silently: the loader still accepts trigger.event=hit with target=tree_or_bush while the evaluator matches kill only, so a bush quest yields no error and no event. Increment 0 enumerated the surface from assembly_valheim.dll (91 seams, 8 categories, exactly 1 usable by a quest today). This lands increment 1's scaffold: ComfyQuestLab, deliberately separate from ComfyNetworkSense because it hooks far more of the game and draws an overlay, neither of which belongs in the mod that runs against the live server. The quest contract is linked source rather than copied, so a quest behaves identically in both. Harvest is wired end to end as the worked example, using the three seams the retired ComfyControlSurface hooked - which is why punching a bush used to fire a quest and no longer does.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab scaffold: a separate client-only mod that shows which game seams a quest can actually fire on",
        "verification": [
          "dotnet build -c Release on host dotnet 8 with both PluginOutputPath copy guards shut: succeeded, 0 warnings, 34816-byte DLL; live BepInEx/plugins confirmed untouched. Linked contract types verified present in the compiled output. Not loaded in game yet - no runtime verification claimed."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807080216-quest-lab-scaffold-a-separate-client-only-mod-th",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T08:02:16.532Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L431",
        "sha256": "4ea439c24c9f5a2c37582a2d09715863bb03e4d57b52578ae41255c013431f57"
      },
      "summary": "Quest authors currently guess, and the guess fails silently: the loader still accepts trigger.event=hit with target=tree_or_bush while the evaluator matches kill only, so a bush quest yields no error and no event. Increment 0 enumerated the surface from assembly_valheim.dll (91 seams, 8 categories, exactly 1 usable by a quest today). This lands increment 1's scaffold: ComfyQuestLab, deliberately separate from ComfyNetworkSense because it hooks far more of the game and draws an overlay, neither of which belongs in the mod that runs against the live server. The quest contract is linked source rather than copied, so a quest behaves identically in both. Harvest is wired end to end as the worked example, using the three seams the retired ComfyControlSurface hooked - which is why punching a bush used to fire a quest and no longer does.",
      "title": "Quest Lab scaffold: a separate client-only mod that shows which game seams a quest can actually fire on",
      "updated_at": "2026-08-07T08:02:16.532Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807080216-quest-lab-scaffold-a-separate-client-only-mod-th"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-07T08:05:23.617Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807080523-wedge-repro-ladder-complete-on-the-local-loop-ca",
        "impact": "The DECISIONS-PENDING precondition for spending the r42 cut is met with receipts both directions: r41 refills a throttled client to the 224-frame headroom with a 171-second starvation window after a gateway restart; the r42 build caps the refill at 61 frames with delivery progress one second after restart, and its /live/valheim-cutover admission surface is confirmed live. The harness gained the zdoJournalApplyThrottleMs fault-injection param to make this drill repeatable.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Wedge repro ladder complete on the local loop: candidate-8/11 redelivery wedge reproduces on the promoted r41 gateway and not on an r42 build, under identical throttle fault injection",
        "verification": [
          "Receipts in fieldlab/runs/native-valheim/native-20260807-wedge1c-r41-omen and native-20260807-wedge2-r42-omen; drill driven end-to-end by runtime-control receipts (arm/disarm) and the client harness; server disarmed back to at-rest after the runs"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260807080523-wedge-repro-ladder-complete-on-the-local-loop-ca",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-07T08:05:23.617Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L432",
        "sha256": "bed78a33d06da9ffe1939af679b9887be3e154b215bd1a547452205725c91fa9"
      },
      "summary": "The DECISIONS-PENDING precondition for spending the r42 cut is met with receipts both directions: r41 refills a throttled client to the 224-frame headroom with a 171-second starvation window after a gateway restart; the r42 build caps the refill at 61 frames with delivery progress one second after restart, and its /live/valheim-cutover admission surface is confirmed live. The harness gained the zdoJournalApplyThrottleMs fault-injection param to make this drill repeatable.",
      "title": "Wedge repro ladder complete on the local loop: candidate-8/11 redelivery wedge reproduces on the promoted r41 gateway and not on an r42 build, under identical throttle fault injection",
      "updated_at": "2026-08-07T08:05:23.617Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807080523-wedge-repro-ladder-complete-on-the-local-loop-ca"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T08:13:42.377Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807081342-quest-lab-four-of-eight-hook-categories-wired-pl",
        "impact": "Harmony resolves AccessTools.Method at runtime, so a wrong argument list does not fail the build - it returns null and the patch silently never applies, which is the same class of silent failure the lab exists to expose. Two tools close that: generate_seam_catalog.py projects the atlas into a compiled-in lookup so a patch names its seam and the catalog answers category and usability (no hand-copied verdicts to rot), and check_lab_patches.py verifies every TryPatch target against the atlas headless. Categories wired: harvest, combat, inventory, progression - 17 seams. Inventory.AddItem is deliberately not hooked: seven overloads and it fires on every internal shuffle.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab: four of eight hook categories wired, plus the two tools that keep the mod and the atlas from drifting",
        "verification": [
          "dotnet build -c Release, 0 warnings, both PluginOutputPath guards shut and live plugins folder untouched. check_lab_patches.py: 17/17 targets resolve against the atlas. Guard proven non-decorative against the real atlas - it rejects wrong arg lists, missing parameters, typo'd method names, and overloads that do not exist, while accepting one of AddItem's seven. NOT verified in game: no hook has been observed firing."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807081342-quest-lab-four-of-eight-hook-categories-wired-pl",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T08:13:42.377Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L433",
        "sha256": "ac92a8caab0268f1f9a3f6f5413d6f1844d68c5f8ddf6670820f0c028ea0e9e0"
      },
      "summary": "Harmony resolves AccessTools.Method at runtime, so a wrong argument list does not fail the build - it returns null and the patch silently never applies, which is the same class of silent failure the lab exists to expose. Two tools close that: generate_seam_catalog.py projects the atlas into a compiled-in lookup so a patch names its seam and the catalog answers category and usability (no hand-copied verdicts to rot), and check_lab_patches.py verifies every TryPatch target against the atlas headless. Categories wired: harvest, combat, inventory, progression - 17 seams. Inventory.AddItem is deliberately not hooked: seven overloads and it fires on every internal shuffle.",
      "title": "Quest Lab: four of eight hook categories wired, plus the two tools that keep the mod and the atlas from drifting",
      "updated_at": "2026-08-07T08:13:42.377Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807081342-quest-lab-four-of-eight-hook-categories-wired-pl"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T08:14:59.811Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807081459-cut-the-r42-coupled-pair-m7-c10b-20260807-r42-ca",
        "impact": "D2 decided: the session-plane fixes ship as a coupled pair. The wedge-ladder receipts justified the spend; the cut invalidates the promoted r41 pair on promotion. Candidate stage retained deliberately - candidate 12 runs the harness lane and the proposed alpha posture is fallback-capable, so the no-fallback final cut waits for alpha traffic per the open posture decision.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Cut the r42 coupled pair m7-c10b-20260807-r42 (candidate stage): mod and gateway image verified to carry one release identity",
        "verification": [
          "New-ReleaseCut identity check read m7-c10b-20260807-r42 back out of both compiled artifacts; candidate fallback-boundary receipt passed with zero failed checks; all five images built and tagged"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260807081459-cut-the-r42-coupled-pair-m7-c10b-20260807-r42-ca",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T08:14:59.811Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L434",
        "sha256": "2ff593c3e618f7584390ef91019e24448456507e4f8cd9d4549d03bfe1a0b227"
      },
      "summary": "D2 decided: the session-plane fixes ship as a coupled pair. The wedge-ladder receipts justified the spend; the cut invalidates the promoted r41 pair on promotion. Candidate stage retained deliberately - candidate 12 runs the harness lane and the proposed alpha posture is fallback-capable, so the no-fallback final cut waits for alpha traffic per the open posture decision.",
      "title": "Cut the r42 coupled pair m7-c10b-20260807-r42 (candidate stage): mod and gateway image verified to carry one release identity",
      "updated_at": "2026-08-07T08:14:59.811Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807081459-cut-the-r42-coupled-pair-m7-c10b-20260807-r42-ca"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T08:28:46.877Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807082846-alpha-modpack-template-now-carries-a-sanitized-c",
        "impact": "New-AlphaModpack.ps1 shipped no config entry (correct for the Companion update lane, fatal for /join first-install: ModPackBuilder 503s on a template without the entry). Every published pack to date had this shape, which is a concrete reason the mod-zip-to-visible-world alpha gate could not pass. The builder now stages a sanitized template (credential pair blanked, consumer disarmed) and the full enrollment chain - invite, Steam OpenID, personalized pack with minted credential - is proven live against the r42 pair image on the local gateway. A lab compose overlay fixes the local public-URL fallback (4006 dead port) and moves the enrollment store onto the persistent volume.",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Alpha modpack template now carries a sanitized config entry - the /join personalization lane was structurally unsatisfiable without it",
        "verification": [
          "wary.fool enrolled via real Steam OpenID; personalized pack downloaded with matching enrollment id, 43-char key, window id and consumer armed; sanitized template verified credential-free inside the zip"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260807082846-alpha-modpack-template-now-carries-a-sanitized-c",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T08:28:46.877Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L435",
        "sha256": "e0614ae341e70412d61c4ad1eba32b8d4d99793321f5fb98e53413b067757331"
      },
      "summary": "New-AlphaModpack.ps1 shipped no config entry (correct for the Companion update lane, fatal for /join first-install: ModPackBuilder 503s on a template without the entry). Every published pack to date had this shape, which is a concrete reason the mod-zip-to-visible-world alpha gate could not pass. The builder now stages a sanitized template (credential pair blanked, consumer disarmed) and the full enrollment chain - invite, Steam OpenID, personalized pack with minted credential - is proven live against the r42 pair image on the local gateway. A lab compose overlay fixes the local public-URL fallback (4006 dead port) and moves the enrollment store onto the persistent volume.",
      "title": "Alpha modpack template now carries a sanitized config entry - the /join personalization lane was structurally unsatisfiable without it",
      "updated_at": "2026-08-07T08:28:46.877Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807082846-alpha-modpack-template-now-carries-a-sanitized-c"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T08:34:25.214Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807083425-quest-lab-all-eight-event-categories-wired-28-se",
        "impact": "Completes the observation surface. Building, crafting, world and social join the four already wired. Three findings a hand-written hook list would have got wrong: the craft seam is InventoryGui.DoCrafting, on the UI class rather than Player or CraftingStation, so anyone hunting Player.Craft concludes crafting is unhookable; ZoneSystem.SetGlobalKey is how Valheim records that a boss is dead, making it the nearest thing to a server-wide progression event and nothing has ever hooked it; and only its string overload is patched because the two enum overloads route into it, so hooking all three would triple-count. Social is the sleeper - a quest that completes on writing a sign needs nothing from combat, and community rituals look more like that than like killing things.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab: all eight event categories wired, 28 seams, every target verified against the atlas",
        "verification": [
          "dotnet build -c Release, 0 warnings, both PluginOutputPath guards shut and the live plugins folder untouched. check_lab_patches.py: 28/28 TryPatch targets resolve against the atlas. NOT verified in game: no hook has been observed firing, and the README, CHANGELOG and this note all say so."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807083425-quest-lab-all-eight-event-categories-wired-28-se",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T08:34:25.214Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L436",
        "sha256": "8a6e350f7e65f427a7d6ae14c0d233342eeaabb696688714295bb49458d4c3d4"
      },
      "summary": "Completes the observation surface. Building, crafting, world and social join the four already wired. Three findings a hand-written hook list would have got wrong: the craft seam is InventoryGui.DoCrafting, on the UI class rather than Player or CraftingStation, so anyone hunting Player.Craft concludes crafting is unhookable; ZoneSystem.SetGlobalKey is how Valheim records that a boss is dead, making it the nearest thing to a server-wide progression event and nothing has ever hooked it; and only its string overload is patched because the two enum overloads route into it, so hooking all three would triple-count. Social is the sleeper - a quest that completes on writing a sign needs nothing from combat, and community rituals look more like that than like killing things.",
      "title": "Quest Lab: all eight event categories wired, 28 seams, every target verified against the atlas",
      "updated_at": "2026-08-07T08:34:25.214Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807083425-quest-lab-all-eight-event-categories-wired-28-se"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T08:40:19.133Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807084019-quest-lab-journal-eight-generated-pages-that-joi",
        "impact": "The console shows what just happened; the journal explains what is possible. Each page carries what the category covers, an exercise, the trap that costs an hour, and the full seam list for that category with the ones this build hooks marked. That last mark is the point: the difference between what Valheim can do and what the lab will show you is invisible in a list of method names and it decides what someone chooses to build. Generated by generate_journal.py joining journal-pages.json (drafted prose) with the atlas (verified seams), so a page can never promise a seam the extractor does not see - the custom-fields confidence contract applied to a UI rather than a document. Selecting a page also enables that category in the console, because the next thing anyone does after reading punch a tree is punch a tree.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab journal: eight generated pages that join written prose to the extracted seam list",
        "verification": [
          "dotnet build -c Release, 0 warnings, both copy guards shut, live plugins folder untouched. Generator emits 8 pages, 78 seams listed, 28 marked hooked - the hooked set read from the patch sources rather than assumed. check_lab_patches.py still 28/28. NOT verified in game."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807084019-quest-lab-journal-eight-generated-pages-that-joi",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T08:40:19.133Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L437",
        "sha256": "5f8fd0c587050c1ae075f2ae79936a3745105e036ef5da9830a5627045c63584"
      },
      "summary": "The console shows what just happened; the journal explains what is possible. Each page carries what the category covers, an exercise, the trap that costs an hour, and the full seam list for that category with the ones this build hooks marked. That last mark is the point: the difference between what Valheim can do and what the lab will show you is invisible in a list of method names and it decides what someone chooses to build. Generated by generate_journal.py joining journal-pages.json (drafted prose) with the atlas (verified seams), so a page can never promise a seam the extractor does not see - the custom-fields confidence contract applied to a UI rather than a document. Selecting a page also enables that category in the console, because the next thing anyone does after reading punch a tree is punch a tree.",
      "title": "Quest Lab journal: eight generated pages that join written prose to the extracted seam list",
      "updated_at": "2026-08-07T08:40:19.133Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807084019-quest-lab-journal-eight-generated-pages-that-joi"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-07T08:48:57.295Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807084857-enrollment-consumer-lane-proven-on-the-r42-pair-",
        "impact": "The 08-05 failure-4 class (no enrolled consumer, terrain-only) closed on the local loop against the actual m7-c10b-20260807-r42 pair: active_consumers 1, applied 8 of 8, complete true, and the fail-closed triple shows an invalid key rejected 401 even from a private socket. The r42 empty-server admission carve-out and the scoped-prefab coverage refusal were both observed live and match the pinned unit semantics. The harness gained -AuthoritativeWindowId so an enrolled leg polls the window its enrollment was minted for. Remaining: the two-client leg and the ADR 0017 human gate on P7.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Enrollment-consumer lane proven on the r42 pair: minted credential attaches, drains, and fails closed on a bad key",
        "verification": [
          "Receipt in fieldlab/runs/native-valheim/native-20260807-rung3-cred-omen; telemetry counters and fail-closed HTTP codes recorded; client config restored byte-exact; AM4 left armed for the two-client leg with the cfg backup named in the receipt"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260807084857-enrollment-consumer-lane-proven-on-the-r42-pair-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-07T08:48:57.295Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L438",
        "sha256": "9d115098a5b5c46bfb897a2da170bea806097738bcb2a9e18dbeec9c665fd53d"
      },
      "summary": "The 08-05 failure-4 class (no enrolled consumer, terrain-only) closed on the local loop against the actual m7-c10b-20260807-r42 pair: active_consumers 1, applied 8 of 8, complete true, and the fail-closed triple shows an invalid key rejected 401 even from a private socket. The r42 empty-server admission carve-out and the scoped-prefab coverage refusal were both observed live and match the pinned unit semantics. The harness gained -AuthoritativeWindowId so an enrolled leg polls the window its enrollment was minted for. Remaining: the two-client leg and the ADR 0017 human gate on P7.",
      "title": "Enrollment-consumer lane proven on the r42 pair: minted credential attaches, drains, and fails closed on a bad key",
      "updated_at": "2026-08-07T08:48:57.295Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807084857-enrollment-consumer-lane-proven-on-the-r42-pair-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T08:54:35.925Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807085435-quest-lab-the-journal-becomes-a-spellbook-and-on",
        "impact": "Reframing from documentation to grimoire, on Derek's steer. Eight Elder Futhark runes, one per school of things the world answers to, and the same rune is both the spellbook tab and the live-view filter toggle - so learning the book teaches the console for free, because the mark is the same mark. Drawn procedurally from line segments rather than shipped as art: runes ARE line segments, so there is no atlas to keep in sync with a game update and no font that might lack the glyph, and the source stays readable as three lines of coordinates instead of a base64 blob. Meanings are apt rather than decorative - Jera is literally harvest, Fehu property, Othala the homestead, Tiwaz battle.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab: the journal becomes a spellbook, and one rune per school filters the live view",
        "verification": [
          "dotnet build -c Release, 0 warnings, both copy guards shut, live plugins folder untouched. check_lab_patches.py still 28/28. Runes rendered headless from the same segment table at both inspection size and the actual 18px display size before shipping: the first pass had Fehu and Ansuz as near-identical shapes, so Social moved to Mannaz. Legible beat faithful. NOT verified in game."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807085435-quest-lab-the-journal-becomes-a-spellbook-and-on",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T08:54:35.925Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L439",
        "sha256": "d916807d863d8c99be96a08e14be524dd8be4b52d4c6e1692e092e0cf814e71d"
      },
      "summary": "Reframing from documentation to grimoire, on Derek's steer. Eight Elder Futhark runes, one per school of things the world answers to, and the same rune is both the spellbook tab and the live-view filter toggle - so learning the book teaches the console for free, because the mark is the same mark. Drawn procedurally from line segments rather than shipped as art: runes ARE line segments, so there is no atlas to keep in sync with a game update and no font that might lack the glyph, and the source stays readable as three lines of coordinates instead of a base64 blob. Meanings are apt rather than decorative - Jera is literally harvest, Fehu property, Othala the homestead, Tiwaz battle.",
      "title": "Quest Lab: the journal becomes a spellbook, and one rune per school filters the live view",
      "updated_at": "2026-08-07T08:54:35.925Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807085435-quest-lab-the-journal-becomes-a-spellbook-and-on"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T09:02:51.421Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807090251-quest-lab-speaks-plainly-77-things-the-world-ans",
        "impact": "Derek's pedagogy: an arcane student handed a tome does not need to understand how a spell works in order to cast one, and a quest builder does not need to understand Harmony to build a quest. The tome was still listing raw method names, which is precisely the layer that should not be required. Every one of the 77 things the world answers to now has a plain name - striking a standing tree, feeding ore to a smelter, the world recording something as when a boss falls - and the live view uses the same words, so a row is recognisable without reading a method signature. The method name became the TRUE name, one toggle away, which is structurally accurate rather than cute: knowing a thing's true name is what gives you power over it, and here it is literally what you would write code against. Verdicts were rephrased to match - a quest can be bound to this, the world speaks but no quest is listening, nothing binds a quest to this yet.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab speaks plainly: 77 things the world answers to, named in words, with the method as the true name behind a toggle",
        "verification": [
          "dotnet build -c Release, 0 warnings, both copy guards shut, live plugins folder untouched. check_lab_patches.py still 28/28. Generator cross-check confirms all 77 atlas seams have a plain name and no name refers to a seam the extractor does not see - neither list can drift from the other. NOT verified in game."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807090251-quest-lab-speaks-plainly-77-things-the-world-ans",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T09:02:51.421Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L440",
        "sha256": "8292676573382099fc35947e1adef5c72eda922891f18aff154fda386e5fe6f9"
      },
      "summary": "Derek's pedagogy: an arcane student handed a tome does not need to understand how a spell works in order to cast one, and a quest builder does not need to understand Harmony to build a quest. The tome was still listing raw method names, which is precisely the layer that should not be required. Every one of the 77 things the world answers to now has a plain name - striking a standing tree, feeding ore to a smelter, the world recording something as when a boss falls - and the live view uses the same words, so a row is recognisable without reading a method signature. The method name became the TRUE name, one toggle away, which is structurally accurate rather than cute: knowing a thing's true name is what gives you power over it, and here it is literally what you would write code against. Verdicts were rephrased to match - a quest can be bound to this, the world speaks but no quest is listening, nothing binds a quest to this yet.",
      "title": "Quest Lab speaks plainly: 77 things the world answers to, named in words, with the method as the true name behind a toggle",
      "updated_at": "2026-08-07T09:02:51.421Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807090251-quest-lab-speaks-plainly-77-things-the-world-ans"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-07T09:04:34.600Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807090434-two-client-credentialed-lane-green-on-the-r42-pa",
        "impact": "Both lab clients rode the enrollment-consumer lane simultaneously with independently minted credentials: 3103 of 3103 acknowledged, 1255 applied, zero rejected, complete true over a bounded two-player window. One telemetry artifact flagged for candidate-12 acceptance: active_consumers read 1 with two live consumers, so the per-consumer identity in the heartbeat needs confirming before that counter gates a two-player criterion. Lab restored to native at-rest afterward.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Two-client credentialed lane green on the r42 pair: both Steam-enrolled consumers drained a live two-player window clean",
        "verification": [
          "Receipt in fieldlab/runs/native-valheim/native-20260807-rung3-twoclient; i5 consumer log shows independent applies; server restored from the named cfg backup and restarted"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260807090434-two-client-credentialed-lane-green-on-the-r42-pa",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-07T09:04:34.600Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L441",
        "sha256": "629bbd2204415386461437e0982659da9cba6419c60e0f81bf68202f212c0a42"
      },
      "summary": "Both lab clients rode the enrollment-consumer lane simultaneously with independently minted credentials: 3103 of 3103 acknowledged, 1255 applied, zero rejected, complete true over a bounded two-player window. One telemetry artifact flagged for candidate-12 acceptance: active_consumers read 1 with two live consumers, so the per-consumer identity in the heartbeat needs confirming before that counter gates a two-player criterion. Lab restored to native at-rest afterward.",
      "title": "Two-client credentialed lane green on the r42 pair: both Steam-enrolled consumers drained a live two-player window clean",
      "updated_at": "2026-08-07T09:04:34.600Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807090434-two-client-credentialed-lane-green-on-the-r42-pa"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-07T09:12:34.938Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807091234-quest-lab-gallery-a-laid-out-ground-the-tome-can",
        "impact": "Derek's call, and the right tradeoff: a bigger download that gives value two minutes after install beats a smaller one that needs an hour of hunting creatures and crafting a bow. The gallery is eight rune monuments on a 46 m ring, a practice station under each, and an armoury at the centre so nothing must be found or made. The runes are raised from logs, and the beam positions are cut from the SAME segment table that draws the 14-pixel glyph in the panel - one shape at two scales, so a monument cannot end up a different shape from the page it belongs to. Emitted as generated data rather than numbers embedded in code, so the preview renders exactly what will be built.",
        "kind": "planning",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab gallery: a laid-out ground the Tome can raise, with the rune monuments cut from the same table that draws the glyphs",
        "verification": [
          "Plan generated: 8 monuments, 89 beams, 8 armoury stands, and it compiles into the mod. Reconstructed every monument face-on FROM THE BEAM DATA ALONE and all eight runes remain legible after being cut into 2 m lengths - that was the real risk and it is closed. NOT verified: prefab names are the one thing here not read out of the assembly, and terrain is not addressed - Valheim ground is not flat and the gallery will need levelling or a platform. No piece has been placed in a game."
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807091234-quest-lab-gallery-a-laid-out-ground-the-tome-can",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-08-07T09:12:34.938Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L442",
        "sha256": "ed6c9d3a22b4036e8fd3ee3e12b287505d98e700bbc38c57036d5ff488c972c8"
      },
      "summary": "Derek's call, and the right tradeoff: a bigger download that gives value two minutes after install beats a smaller one that needs an hour of hunting creatures and crafting a bow. The gallery is eight rune monuments on a 46 m ring, a practice station under each, and an armoury at the centre so nothing must be found or made. The runes are raised from logs, and the beam positions are cut from the SAME segment table that draws the 14-pixel glyph in the panel - one shape at two scales, so a monument cannot end up a different shape from the page it belongs to. Emitted as generated data rather than numbers embedded in code, so the preview renders exactly what will be built.",
      "title": "Quest Lab gallery: a laid-out ground the Tome can raise, with the rune monuments cut from the same table that draws the glyphs",
      "updated_at": "2026-08-07T09:12:34.938Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807091234-quest-lab-gallery-a-laid-out-ground-the-tome-can"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-07T09:16:40.472Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807091640-human-confirmed-two-enrolled-players-mutually-vi",
        "impact": "The operator watched both screens: tugcorp and Durracktu co-located, each rendering and moving on the other's display, with Player ZDOs riding the enrollment-consumer redirect lane. Both the credential class and the delivery class of the 08-05 terrain-only outage are now closed on the rehearsal loop with human eyes, not just telemetry. The pinned ADR 0013 building-sharing case remains its own follow-up run.",
        "kind": "verification",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Human-confirmed: two enrolled players mutually visible and moving through the credentialed lane on the r42 pair",
        "verification": [
          "Operator confirmation recorded in fieldlab/runs/native-valheim/native-20260807-rung3-visual; counters at confirmation receipts 1161 acknowledged 1160 applied 549 rejected 0; lab restored to native at-rest"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260807091640-human-confirmed-two-enrolled-players-mutually-vi",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-07T09:16:40.472Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L443",
        "sha256": "f5d351f36ad574da90d460198cdb8bf55c775dd0a18b39d29668cb7c40d65df6"
      },
      "summary": "The operator watched both screens: tugcorp and Durracktu co-located, each rendering and moving on the other's display, with Player ZDOs riding the enrollment-consumer redirect lane. Both the credential class and the delivery class of the 08-05 terrain-only outage are now closed on the rehearsal loop with human eyes, not just telemetry. The pinned ADR 0013 building-sharing case remains its own follow-up run.",
      "title": "Human-confirmed: two enrolled players mutually visible and moving through the credentialed lane on the r42 pair",
      "updated_at": "2026-08-07T09:16:40.472Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807091640-human-confirmed-two-enrolled-players-mutually-vi"
    },
    {
      "audiences": [
        "creator",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-07T09:22:13.306Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807092213-quest-lab-gallery-stands-on-a-raised-platform-pl",
        "impact": "Derek's call. Valheim ground is not flat and 89 beams on a hillside reads as broken rather than impressive, so the gallery brings its own floor. Deliberately not a disc - a 38 m disc is roughly 1100 tiles of which most are never walked on, whereas a plaza with eight spokes and eight pads is 499 and looks like a ritual floor rather than a car park, with the shape itself telling a visitor where to walk. Ring tightened from 46 m to 38 m so the spokes stay short while leaving 30 m of arc between monuments. The builder picks one world height for the whole platform - highest ground under the footprint plus clearance - so the floor is level where the terrain is not.",
        "kind": "planning",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab gallery stands on a raised platform: plaza, eight spokes, eight pads",
        "verification": [
          "Plan regenerates to 8 monuments, 89 beams, 8 armoury stands, 499 floor tiles, and compiles into the mod. Geometry checked numerically rather than by eye: every one of the 8 stations and all 89 beam footings land within half a tile of a floor piece. First pass had the stations sitting just off the front edge of their pads, which the check caught and a smaller inset fixed. No piece has been placed in a game."
        ]
      },
      "facets": {
        "kind": "planning",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807092213-quest-lab-gallery-stands-on-a-raised-platform-pl",
      "kind": "roadmap-note",
      "primary_audiences": [
        "creator"
      ],
      "published_at": "2026-08-07T09:22:13.306Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L444",
        "sha256": "b5c0a55597223683df873308e43a54985ab08ad7f676316506957d9ec0a8188b"
      },
      "summary": "Derek's call. Valheim ground is not flat and 89 beams on a hillside reads as broken rather than impressive, so the gallery brings its own floor. Deliberately not a disc - a 38 m disc is roughly 1100 tiles of which most are never walked on, whereas a plaza with eight spokes and eight pads is 499 and looks like a ritual floor rather than a car park, with the shape itself telling a visitor where to walk. Ring tightened from 46 m to 38 m so the spokes stay short while leaving 30 m of arc between monuments. The builder picks one world height for the whole platform - highest ground under the footprint plus clearance - so the floor is level where the terrain is not.",
      "title": "Quest Lab gallery stands on a raised platform: plaza, eight spokes, eight pads",
      "updated_at": "2026-08-07T09:22:13.306Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807092213-quest-lab-gallery-stands-on-a-raised-platform-pl"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T09:30:57.129Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807093057-am4-runs-lumberjacks-full-cutover-prefabs-is-now",
        "impact": "Posture inversion, permanent: server at lumberjacks-primary with full suppression, both clients running their personalized pack configs at rest (credentialed, consumer armed), gateway on the r42 pair image with a restart policy. Launching Valheim normally on either machine now plays on Lumberjacks with no harness or arming. Coherence preflight: zero failures, admission true. The ADR 0013 building-sharing question is now live in the next play session with the hot-reloadable fan-out as the fix-forward lever. Remaining for 100 percent: the same posture on P7 (promote r42, candidate 12, human alpha gate).",
        "kind": "implementation",
        "milestones": [
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "AM4 runs Lumberjacks: full cutover (prefabs *) is now the at-rest posture on the lab; native is the rollback, not the default",
        "verification": [
          "Test-CutoverModeCoherence coherent with zero failures; i5 config hash-verified via the deploy lane's new -ValheimConfig switch; server cfg and both client backups named in fieldlab/evidence/am4-full-cutover-posture-20260807.md"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M7"
        ]
      },
      "id": "roadmap:20260807093057-am4-runs-lumberjacks-full-cutover-prefabs-is-now",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T09:30:57.129Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L445",
        "sha256": "345181e287cddf60d2d7bb3bd1ba2d269690e8a9da3012526d76268c3e80b1dd"
      },
      "summary": "Posture inversion, permanent: server at lumberjacks-primary with full suppression, both clients running their personalized pack configs at rest (credentialed, consumer armed), gateway on the r42 pair image with a restart policy. Launching Valheim normally on either machine now plays on Lumberjacks with no harness or arming. Coherence preflight: zero failures, admission true. The ADR 0013 building-sharing question is now live in the next play session with the hot-reloadable fan-out as the fix-forward lever. Remaining for 100 percent: the same posture on P7 (promote r42, candidate 12, human alpha gate).",
      "title": "AM4 runs Lumberjacks: full cutover (prefabs *) is now the at-rest posture on the lab; native is the rollback, not the default",
      "updated_at": "2026-08-07T09:30:57.129Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807093057-am4-runs-lumberjacks-full-cutover-prefabs-is-now"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T09:32:41.734Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807093241-quest-lab-gallery-builder-and-the-mod-installed-",
        "impact": "The one part of the Tome that changes a world rather than witnessing it, so it moves only when a person types a command: questlab_gallery check | build | clear, plus questlab_prefabs to search what a game build actually has. check resolves every prefab the plan names and places nothing, because prefab names are the one thing here not read out of the assembly and 600 pieces is the wrong place to discover a typo. Support wear is disabled on everything placed - a platform standing clear of the ground has nothing holding it up as far as the game is concerned and would begin collapsing within minutes. Build is a coroutine at twelve pieces a frame, and a manifest of placed ZDOIDs is written so clear works across sessions.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab gallery builder, and the mod installed to the OMEN client for its first run",
        "verification": [
          "dotnet build -c Release, 0 warnings, then installed to the client with ComfyCopyToPlugins after confirming Valheim was not running. Compiling against the real assembly caught two API errors that would have been runtime failures: ZNetScene.FindInstance returns a ZNetView rather than a GameObject, and ItemStand.SetVisualItem does not exist as a method at all - the extractor shows it is a registered RPC. Rather than guess an RPC signature from outside a running game, the armoury now also places each item as a real ItemDrop beside its stand, so a bare stand is a cosmetic loss instead of a student with no axe. NOT verified in game: nothing has been placed and no hook has been seen firing."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807093241-quest-lab-gallery-builder-and-the-mod-installed-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T09:32:41.734Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L446",
        "sha256": "73a7b6000fcb4b9f01142c1df175d479964793c6b4a20a8422a01fc83a00275d"
      },
      "summary": "The one part of the Tome that changes a world rather than witnessing it, so it moves only when a person types a command: questlab_gallery check | build | clear, plus questlab_prefabs to search what a game build actually has. check resolves every prefab the plan names and places nothing, because prefab names are the one thing here not read out of the assembly and 600 pieces is the wrong place to discover a typo. Support wear is disabled on everything placed - a platform standing clear of the ground has nothing holding it up as far as the game is concerned and would begin collapsing within minutes. Build is a coroutine at twelve pieces a frame, and a manifest of placed ZDOIDs is written so clear works across sessions.",
      "title": "Quest Lab gallery builder, and the mod installed to the OMEN client for its first run",
      "updated_at": "2026-08-07T09:32:41.734Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807093241-quest-lab-gallery-builder-and-the-mod-installed-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T10:13:55.562Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807101355-quest-lab-gallery-pieces-carry-a-zdo-mark-and-cl",
        "impact": "questlab_gallery clear destroyed two arbitrary world objects and the local player, ending the session. Root cause: the build manifest stores raw ZDOIDs, which are session-scoped, so after a reload the recorded ids resolve to unrelated objects. Every gallery piece now writes a comfyQuestLabGallery mark into its own ZDO (same mechanism as the portal pairing tag) and clear skips anything without it, reporting the count it left alone. Also fixed: the ground portal was sampled with GetSolidHeight after the floor was placed, so it landed on the deck beside its partner instead of on the ground - it is now sampled before the first tile. And WearNTear.m_noSupportWear is a TunableField, not a ZdoField, so it did not survive ZNetScene rebuilding pieces on zone reload and the platform collapsed; a WearNTear.Awake postfix re-applies it from the ZDO mark.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest lab gallery: pieces carry a ZDO mark, and clear will not destroy anything unmarked",
        "verification": [
          "Builds Release with 0 warnings; ZDO.Set(key,string) and ZDO.GetString(key,default) are compile-verified against assembly_valheim. NOT verified in game: no build, clear, portal, or standing platform has been observed since the change."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807101355-quest-lab-gallery-pieces-carry-a-zdo-mark-and-cl",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T10:13:55.562Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L447",
        "sha256": "fce4ef6e64a6f5fc4345a9005cab2f4ea281428bd180008e24be3485fe20958f"
      },
      "summary": "questlab_gallery clear destroyed two arbitrary world objects and the local player, ending the session. Root cause: the build manifest stores raw ZDOIDs, which are session-scoped, so after a reload the recorded ids resolve to unrelated objects. Every gallery piece now writes a comfyQuestLabGallery mark into its own ZDO (same mechanism as the portal pairing tag) and clear skips anything without it, reporting the count it left alone. Also fixed: the ground portal was sampled with GetSolidHeight after the floor was placed, so it landed on the deck beside its partner instead of on the ground - it is now sampled before the first tile. And WearNTear.m_noSupportWear is a TunableField, not a ZdoField, so it did not survive ZNetScene rebuilding pieces on zone reload and the platform collapsed; a WearNTear.Awake postfix re-applies it from the ZDO mark.",
      "title": "Quest lab gallery: pieces carry a ZDO mark, and clear will not destroy anything unmarked",
      "updated_at": "2026-08-07T10:13:55.562Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807101355-quest-lab-gallery-pieces-carry-a-zdo-mark-and-cl"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T10:30:19.490Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807103019-wearntear-no-wear-flags-are-opt-ins-false-is-off",
        "impact": "The raised gallery kept decaying after both no-wear flags were set true, and got more consistent about it once a WearNTear.Awake postfix started re-applying them. Reading the shipped assembly with Mono.Cecil settled it: in WearNTear.UpdateWear the support check sits behind brfalse on m_noSupportWear and the rain damage behind brfalse on m_noRoofWear, so each damage path is reached ONLY when its flag is true. The fields are opt-ins wearing a name that reads like an opt-out. Both are now set false at placement and in the Awake postfix. The annotation layer that misled this (annotations-piece.json and wearntear-field-dictionary.md, both saying Disables) is corrected to say ENABLES and to name the branch.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "WearNTear no-wear flags are opt-ins: false is off, and the atlas annotation said the opposite",
        "verification": [
          "Read from assembly_valheim.dll via Mono.Cecil: UpdateWear reads m_noRoofWear and m_noSupportWear, and the brfalse targets skip the damage blocks when false. Builds Release with 0 warnings. NOT verified in game: no gallery has been observed standing since the change."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807103019-wearntear-no-wear-flags-are-opt-ins-false-is-off",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T10:30:19.490Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L448",
        "sha256": "6af29306e7cee7905ff03eabf28dea0a9d03c02f223e2988429c90e26f09809e"
      },
      "summary": "The raised gallery kept decaying after both no-wear flags were set true, and got more consistent about it once a WearNTear.Awake postfix started re-applying them. Reading the shipped assembly with Mono.Cecil settled it: in WearNTear.UpdateWear the support check sits behind brfalse on m_noSupportWear and the rain damage behind brfalse on m_noRoofWear, so each damage path is reached ONLY when its flag is true. The fields are opt-ins wearing a name that reads like an opt-out. Both are now set false at placement and in the Awake postfix. The annotation layer that misled this (annotations-piece.json and wearntear-field-dictionary.md, both saying Disables) is corrected to say ENABLES and to name the branch.",
      "title": "WearNTear no-wear flags are opt-ins: false is off, and the atlas annotation said the opposite",
      "updated_at": "2026-08-07T10:30:19.490Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807103019-wearntear-no-wear-flags-are-opt-ins-false-is-off"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T10:39:21.269Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807103921-component-packets-gains-field-ask-what-a-flag-ac",
        "impact": "The atlas annotation for WearNTear.m_noSupportWear said Disables when the field is an opt-in, and three rounds of a collapsing gallery went by before anyone read the branch. The extractor already walked IL for ZDO keys, so the capability was there and unexposed. New mode: dotnet run -- <dll> --field <Type>.<field> prints every read of the field and, where the read is branched on, the block of IL that branch skips, then states which polarity runs it. The README Confidence labeling section now records that a drafted description can be confidently and unmarkedly backwards, and that a negated boolean name is a coin flip the description cannot settle. Also resolved a standing question: the mod reports 27/27 seams while check_lab_patches.py counts 28 targets - Player.UseStamina is gated behind LabConfig.ObserveStamina, off by default, so both numbers are right and answer different questions.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "component-packets gains --field: ask what a flag actually gates instead of trusting its description",
        "verification": [
          "Ran against the shipped assembly for m_noSupportWear, m_noRoofWear and m_supports: reproduces the UpdateWear support-damage block behind brfalse, finds both read sites on m_supports, and reports polarity per read. Seam count traced to ProgressionPatches.cs:33."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807103921-component-packets-gains-field-ask-what-a-flag-ac",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T10:39:21.269Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L449",
        "sha256": "39a1efcf12ebf9b6c399a6c084e7b4e7b54a255179a6597861fa4763a977cee5"
      },
      "summary": "The atlas annotation for WearNTear.m_noSupportWear said Disables when the field is an opt-in, and three rounds of a collapsing gallery went by before anyone read the branch. The extractor already walked IL for ZDO keys, so the capability was there and unexposed. New mode: dotnet run -- <dll> --field <Type>.<field> prints every read of the field and, where the read is branched on, the block of IL that branch skips, then states which polarity runs it. The README Confidence labeling section now records that a drafted description can be confidently and unmarkedly backwards, and that a negated boolean name is a coin flip the description cannot settle. Also resolved a standing question: the mod reports 27/27 seams while check_lab_patches.py counts 28 targets - Player.UseStamina is gated behind LabConfig.ObserveStamina, off by default, so both numbers are right and answer different questions.",
      "title": "component-packets gains --field: ask what a flag actually gates instead of trusting its description",
      "updated_at": "2026-08-07T10:39:21.269Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807103921-component-packets-gains-field-ask-what-a-flag-ac"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-07T10:45:38.194Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807104538-the-quest-lab-gallery-stands-in-game-builds-port",
        "impact": "First in-game verification of the gallery end to end, human-confirmed by Derek on 2026-08-07. The platform builds (620 pieces, floor 35 m up), the ground-to-plaza portal pair connects and carries a player, and the structure no longer falls apart. That closes the three defects found this session: the inverted no-wear flags, the ground portal sampled against solid height after the floor existed, and clear trusting session-scoped ZDOIDs. The mod README and CHANGELOG previously said nothing had been verified in game; both now separate what is proven from what is not, because leaving a stale not-verified label on proven work is the same calibration failure as the reverse.",
        "kind": "verification",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The quest lab gallery stands in game: builds, portals connect, and it stops decaying",
        "verification": [
          "Human-confirmed in game by Derek: gallery built, portals used, platform still standing rather than decaying. Still NOT verified: no hook has been observed firing, which is the lab's actual purpose; item stands remain bare because SetVisualItem is a registered RPC, not a callable method."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807104538-the-quest-lab-gallery-stands-in-game-builds-port",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-07T10:45:38.194Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L450",
        "sha256": "3b7f77078d6bece8c5b1230c9a5d8ae06b39c62fc8856e97a55e6b50098a1b5a"
      },
      "summary": "First in-game verification of the gallery end to end, human-confirmed by Derek on 2026-08-07. The platform builds (620 pieces, floor 35 m up), the ground-to-plaza portal pair connects and carries a player, and the structure no longer falls apart. That closes the three defects found this session: the inverted no-wear flags, the ground portal sampled against solid height after the floor existed, and clear trusting session-scoped ZDOIDs. The mod README and CHANGELOG previously said nothing had been verified in game; both now separate what is proven from what is not, because leaving a stale not-verified label on proven work is the same calibration failure as the reverse.",
      "title": "The quest lab gallery stands in game: builds, portals connect, and it stops decaying",
      "updated_at": "2026-08-07T10:45:38.194Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807104538-the-quest-lab-gallery-stands-in-game-builds-port"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-07T10:51:14.484Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807105114-first-hook-observed-firing-in-game-the-live-view",
        "impact": "The quest lab has demonstrated its actual claim for the first time. Striking a beech produced a live-view entry reading: striking a standing tree / Beech1 (tree) skill Unarmed / -> nothing binds a quest to this yet. That single line exercises the whole stack at once - the harvest seam patched and firing, the plain name resolved from the spellbook table, the target resolved to a prefab, the skill, the ring buffer holding and counting, and the verdict line that is the reason the lab exists. A quest builder reading it learns both that the game can see the hit and that no quest can be bound to it, which is the argument the project was built to make. Human-confirmed by Derek on 2026-08-07 with a screenshot. README and CHANGELOG updated the same day they had claimed no hook had ever been observed.",
        "kind": "verification",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "First hook observed firing in game: the live view reports a harvest seam and its verdict",
        "verification": [
          "Human-confirmed in game by Derek, screenshot: four harvest events at 03:50:01-03:50:03, panel showing 20 held / 20 seen, all eight category filters present. Still NOT verified: only the harvest category has been witnessed firing; the other seven are patched but unobserved. Item stands remain bare because SetVisualItem is a registered RPC rather than a callable method."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807105114-first-hook-observed-firing-in-game-the-live-view",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-07T10:51:14.484Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L451",
        "sha256": "36e3025df86213359177c43f979b6ff113bb418460efcba264099a79ab1d43fb"
      },
      "summary": "The quest lab has demonstrated its actual claim for the first time. Striking a beech produced a live-view entry reading: striking a standing tree / Beech1 (tree) skill Unarmed / -> nothing binds a quest to this yet. That single line exercises the whole stack at once - the harvest seam patched and firing, the plain name resolved from the spellbook table, the target resolved to a prefab, the skill, the ring buffer holding and counting, and the verdict line that is the reason the lab exists. A quest builder reading it learns both that the game can see the hit and that no quest can be bound to it, which is the argument the project was built to make. Human-confirmed by Derek on 2026-08-07 with a screenshot. README and CHANGELOG updated the same day they had claimed no hook had ever been observed.",
      "title": "First hook observed firing in game: the live view reports a harvest seam and its verdict",
      "updated_at": "2026-08-07T10:51:14.484Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807105114-first-hook-observed-firing-in-game-the-live-view"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T10:52:03.139Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807105203-the-lab-can-read-a-planbuild-blueprint-parser-la",
        "impact": "First step of the blueprint-import lane (toward building Fallingwater from the HABS drawings). BlueprintFile.cs parses the community .blueprint format Unity-free - headers, bare sections like #Description whose text runs to the next # line, snap-point and terrain sections counted and deliberately ignored, semicolon piece lines with optional scale. Non-unit scale is rejected per piece rather than silently built unscaled. The golden fixtures are verbatim copies of PlanBuild's checked-in test blueprints, not our own generator's output, so format drift between the projects fails in a 40 ms test run instead of in a half-placed building. Nothing in the parser throws: a community download with three bad lines builds the other two thousand pieces and itemizes the damage.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The lab can read a PlanBuild blueprint: parser landed, pinned to PlanBuild's own fixtures",
        "verification": [
          "13 new xunit tests green in ComfyNetworkSense.Tests (203/203 total); ComfyQuestLab builds clean net48 with the linked file. Not yet verified: nothing consumes the parser in game - the builder is the next commit."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807105203-the-lab-can-read-a-planbuild-blueprint-parser-la",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T10:52:03.139Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L452",
        "sha256": "43b1bdf8278a2d6bcae5884141290e0b10179bc8d5842aae067e8e15b56f4e35"
      },
      "summary": "First step of the blueprint-import lane (toward building Fallingwater from the HABS drawings). BlueprintFile.cs parses the community .blueprint format Unity-free - headers, bare sections like #Description whose text runs to the next # line, snap-point and terrain sections counted and deliberately ignored, semicolon piece lines with optional scale. Non-unit scale is rejected per piece rather than silently built unscaled. The golden fixtures are verbatim copies of PlanBuild's checked-in test blueprints, not our own generator's output, so format drift between the projects fails in a 40 ms test run instead of in a half-placed building. Nothing in the parser throws: a community download with three bad lines builds the other two thousand pieces and itemizes the damage.",
      "title": "The lab can read a PlanBuild blueprint: parser landed, pinned to PlanBuild's own fixtures",
      "updated_at": "2026-08-07T10:52:03.139Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807105203-the-lab-can-read-a-planbuild-blueprint-parser-la"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T10:56:44.964Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807105644-questlab-prefabs-dump-the-runtime-prefab-catalog",
        "impact": "The component atlas reads the assembly, and the assembly cannot say which prefabs carry which components - component-packets README has named a runtime ZNetScene dump as the missing artifact since it was written. questlab_prefabs dump now writes it: every prefab with its stable hash, ZNetView presence, piece category, WearNTear presence, snap-point local positions, and approximate mesh bounds, as JSON in the mod config dir. Snap points are the piece's own statement of its footprint (wood_floor says +/-1 on both axes), which is how the offline blueprint generator learns the grid without a tape measure. Needed assembly_utils referenced for GetStableHashCode; the game Version type is not public, so the version label is read by reflection and degrades to unknown rather than costing the dump.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "questlab_prefabs dump: the runtime prefab catalog the atlas could never provide",
        "verification": [
          "Mod builds clean net48, 0 warnings. NOT yet run in game: the dump is a client-side command, so the committed JSON artifact lands with the first in-game session of the blueprint lane."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807105644-questlab-prefabs-dump-the-runtime-prefab-catalog",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T10:56:44.964Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L453",
        "sha256": "36dbf28b59231971dc54c7831607b393b8c2a6ab1d895023e854533dcf3b7f13"
      },
      "summary": "The component atlas reads the assembly, and the assembly cannot say which prefabs carry which components - component-packets README has named a runtime ZNetScene dump as the missing artifact since it was written. questlab_prefabs dump now writes it: every prefab with its stable hash, ZNetView presence, piece category, WearNTear presence, snap-point local positions, and approximate mesh bounds, as JSON in the mod config dir. Snap points are the piece's own statement of its footprint (wood_floor says +/-1 on both axes), which is how the offline blueprint generator learns the grid without a tape measure. Needed assembly_utils referenced for GetStableHashCode; the game Version type is not public, so the version label is read by reflection and degrades to unknown rather than costing the dump.",
      "title": "questlab_prefabs dump: the runtime prefab catalog the atlas could never provide",
      "updated_at": "2026-08-07T10:56:44.964Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807105644-questlab-prefabs-dump-the-runtime-prefab-catalog"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T11:00:23.620Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807110023-questlab-blueprint-a-blueprint-file-at-your-feet",
        "impact": "The second world-changing lane. list/check/build/clear over PlanBuild .blueprint files dropped into the mod config dir - no DLL rebuild between a community blueprint and the world. Build refuses past a failed check, places at the player's feet with ONE ground sample (a house keeps its own levels; the gallery's highest-ground scan would hoist the building by its tallest bump), batches per frame via new config blueprintPiecesPerFrame, and writes the blueprint's name into each piece's own ZDO. Clear is the fix the gallery documented wanting: a mark-sweep over the loaded ZDO table (the FieldRefAccess pattern CutoverResidueSweeper proved), so a restart costs nothing - no manifest at all. The WearNTear keep-standing postfix now keys off LabMarks.IsLabBuilt covering both lanes; that one line is load-bearing, since Fallingwater's terraces are cantilevers by design. Gallery code untouched beyond that line.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "questlab_blueprint: a .blueprint file at your feet, and a clear that survives restarts",
        "verification": [
          "Mod builds clean, 203/203 host tests green. NOT verified in game yet: first build is the Fallingwater session, where the zone-boundary walk proves the keep-standing generalization and a client restart proves the mark-sweep clear."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807110023-questlab-blueprint-a-blueprint-file-at-your-feet",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T11:00:23.620Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L454",
        "sha256": "67dd6173b2adb15ed53623bef8e4b487b5577b70a354af8908888de9c4fcb947"
      },
      "summary": "The second world-changing lane. list/check/build/clear over PlanBuild .blueprint files dropped into the mod config dir - no DLL rebuild between a community blueprint and the world. Build refuses past a failed check, places at the player's feet with ONE ground sample (a house keeps its own levels; the gallery's highest-ground scan would hoist the building by its tallest bump), batches per frame via new config blueprintPiecesPerFrame, and writes the blueprint's name into each piece's own ZDO. Clear is the fix the gallery documented wanting: a mark-sweep over the loaded ZDO table (the FieldRefAccess pattern CutoverResidueSweeper proved), so a restart costs nothing - no manifest at all. The WearNTear keep-standing postfix now keys off LabMarks.IsLabBuilt covering both lanes; that one line is load-bearing, since Fallingwater's terraces are cantilevers by design. Gallery code untouched beyond that line.",
      "title": "questlab_blueprint: a .blueprint file at your feet, and a clear that survives restarts",
      "updated_at": "2026-08-07T11:00:23.620Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807110023-questlab-blueprint-a-blueprint-file-at-your-feet"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T11:06:03.751Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807110603-fallingwater-as-parametric-massing-a-671-piece-b",
        "impact": "tools/blueprints/ lands the offline half of the blueprint lane: blueprint_lib.py emits and parses the PlanBuild format (so future blueprints and their tests come free), and generate_fallingwater.py models the house as the things that make it read - three stacked cantilevered trays (30x18, 22x12, 10x8 m from the Library of Congress HABS PA-1690 sheets, public domain), a vertical stone core, 1 m parapet bands with 2 m continuous glazing above on the south and east faces, darkwood trim as the Cherokee-red line. 671 pieces across 8 masses, every mass a function of one parameter object so post-build tuning is constant-editing. The generator has no snapping and no collision, so its grid discipline is the defense against z-fighting: the test suite makes duplicate-pose a failure, pins the 10-field no-scale line form, the closed palette, the footprint, and that the checked-in blueprint matches a fresh generation byte for byte.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Fallingwater as parametric massing: a 671-piece blueprint from the HABS survey",
        "verification": [
          "9 tests in tests/test_fallingwater_blueprint.py: 8 green, 1 self-skips until the prefab dump artifact lands from the first in-game session. Palette names remain guesses until questlab_blueprint check confirms them in game."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807110603-fallingwater-as-parametric-massing-a-671-piece-b",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T11:06:03.751Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L455",
        "sha256": "9d37bc2a873c8358e90ad52972c448f3efa1346bc7cbb2546c530295f846948e"
      },
      "summary": "tools/blueprints/ lands the offline half of the blueprint lane: blueprint_lib.py emits and parses the PlanBuild format (so future blueprints and their tests come free), and generate_fallingwater.py models the house as the things that make it read - three stacked cantilevered trays (30x18, 22x12, 10x8 m from the Library of Congress HABS PA-1690 sheets, public domain), a vertical stone core, 1 m parapet bands with 2 m continuous glazing above on the south and east faces, darkwood trim as the Cherokee-red line. 671 pieces across 8 masses, every mass a function of one parameter object so post-build tuning is constant-editing. The generator has no snapping and no collision, so its grid discipline is the defense against z-fighting: the test suite makes duplicate-pose a failure, pins the 10-field no-scale line form, the closed palette, the footprint, and that the checked-in blueprint matches a fresh generation byte for byte.",
      "title": "Fallingwater as parametric massing: a 671-piece blueprint from the HABS survey",
      "updated_at": "2026-08-07T11:06:03.751Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807110603-fallingwater-as-parametric-massing-a-671-piece-b"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T11:13:33.109Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807111333-the-monuments-read-as-runes-beams-measured-off-t",
        "impact": "Three fixes from one in-game look, all human-confirmed. (1) Beam orientation was an assumption - that a wood beam runs along its local Z - and 89 beams standing end-on to the glyphs they drew looked like the dots in a connect-the-dots book. The builder now measures the prefab's mesh, picks the longest local axis, swings that onto each stroke via FromToRotation, and corrects for a pivot that is not at the mesh centre. It reports what it measured so the next person can check instead of trusting. (2) Each monument carries a coloured lamp, one per school. Valheim has no field for this: LightFlicker and LightLod only modulate and cull an existing light, and only EnvMan.m_dirLight, MenuScene.m_dirLight and ShieldGenerator.m_coloredLights hold a Light at all. So the lamp is a UnityEngine.Light the lab hangs itself - client-side, unsaved, and re-hung from a ZDO mark on every zone reload, the same shape of answer the wear flags needed. Intensity, range and on/off are config; colour is per school. (3) Clear now sweeps by mark rather than by manifest. The manifest only ever described the most recent build because every build empties it first, so a second gallery orphaned the first beyond reach and pieces accumulated to 1527 while clear reported zero. WearNTear.GetAllInstances enumerates every loaded piece, so the sweep finds every lab-marked gallery in any session. It only sees loaded zones and now says so. Blueprint pieces are deliberately excluded - the sweep asks IsGalleryPiece, not IsLabBuilt.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The monuments read as runes: beams measured off the prefab, and a coloured lamp per school",
        "verification": [
          "Human-confirmed in game by Derek with screenshots: the monuments now read as their glyphs and are lit, and a clear brought the world from 1527 pieces down to 738. Builds Release with 0 warnings alongside the concurrent blueprint lane. WearNTear.GetAllInstances is compile-verified against assembly_valheim. NOT verified: whether the measured axis is correct or merely closer - the measurement line it prints has not been read back yet."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807111333-the-monuments-read-as-runes-beams-measured-off-t",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T11:13:33.109Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L456",
        "sha256": "ce4b68beb5e0009c3a35eecacd0749612dec0abb359b0057acf0e5efc099a793"
      },
      "summary": "Three fixes from one in-game look, all human-confirmed. (1) Beam orientation was an assumption - that a wood beam runs along its local Z - and 89 beams standing end-on to the glyphs they drew looked like the dots in a connect-the-dots book. The builder now measures the prefab's mesh, picks the longest local axis, swings that onto each stroke via FromToRotation, and corrects for a pivot that is not at the mesh centre. It reports what it measured so the next person can check instead of trusting. (2) Each monument carries a coloured lamp, one per school. Valheim has no field for this: LightFlicker and LightLod only modulate and cull an existing light, and only EnvMan.m_dirLight, MenuScene.m_dirLight and ShieldGenerator.m_coloredLights hold a Light at all. So the lamp is a UnityEngine.Light the lab hangs itself - client-side, unsaved, and re-hung from a ZDO mark on every zone reload, the same shape of answer the wear flags needed. Intensity, range and on/off are config; colour is per school. (3) Clear now sweeps by mark rather than by manifest. The manifest only ever described the most recent build because every build empties it first, so a second gallery orphaned the first beyond reach and pieces accumulated to 1527 while clear reported zero. WearNTear.GetAllInstances enumerates every loaded piece, so the sweep finds every lab-marked gallery in any session. It only sees loaded zones and now says so. Blueprint pieces are deliberately excluded - the sweep asks IsGalleryPiece, not IsLabBuilt.",
      "title": "The monuments read as runes: beams measured off the prefab, and a coloured lamp per school",
      "updated_at": "2026-08-07T11:13:33.109Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807111333-the-monuments-read-as-runes-beams-measured-off-t"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-07T11:27:19.999Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807112719-the-prefab-dump-paid-for-itself-before-the-first",
        "impact": "Derek ran questlab_prefabs dump in game: 3458 prefabs, game 0.221.12, committed as tools/component-packets/samples/prefab-dump.json - the artifact the component-packets README has named missing since it was written. All six Fallingwater palette names resolved on the first try, and the snap-point data immediately falsified the generator's placement assumption: stone_floor_2x2 and both stone walls carry snaps at y -0.5..+0.5 (center pivot) while crystal_wall_1x1 carries them at 0..1 (bottom pivot). As authored, every stone course would have stood half a metre low with glass floating above it. The generator now carries a measured LIFT table per palette entry, the blueprint is regenerated, and the last self-skipping test runs for real: 9/9 green including palette-against-dump.",
        "kind": "verification",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The prefab dump paid for itself before the first build: stone pieces pivot at center, not bottom",
        "verification": [
          "python -m unittest tests.test_fallingwater_blueprint: 9/9, no skips. Corrected blueprint redeployed to the client. Remaining in-game: check, build, zone walk, clear, restart-clear."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807112719-the-prefab-dump-paid-for-itself-before-the-first",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-07T11:27:19.999Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L457",
        "sha256": "9b389837171dad4d681bf21606280f53ac5c4ba0f214801b33f0656a958c9b97"
      },
      "summary": "Derek ran questlab_prefabs dump in game: 3458 prefabs, game 0.221.12, committed as tools/component-packets/samples/prefab-dump.json - the artifact the component-packets README has named missing since it was written. All six Fallingwater palette names resolved on the first try, and the snap-point data immediately falsified the generator's placement assumption: stone_floor_2x2 and both stone walls carry snaps at y -0.5..+0.5 (center pivot) while crystal_wall_1x1 carries them at 0..1 (bottom pivot). As authored, every stone course would have stood half a metre low with glass floating above it. The generator now carries a measured LIFT table per palette entry, the blueprint is regenerated, and the last self-skipping test runs for real: 9/9 green including palette-against-dump.",
      "title": "The prefab dump paid for itself before the first build: stone pieces pivot at center, not bottom",
      "updated_at": "2026-08-07T11:27:19.999Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807112719-the-prefab-dump-paid-for-itself-before-the-first"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T11:35:51.146Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807113551-sky-mode-a-blueprint-overhead-doors-bound-by-nam",
        "impact": "questlab_blueprint build <name> sky borrows the gallery's raised-platform move and generalizes it: the build rides 40 m above whatever the crosshair was aimed at when the command ran (camera-forward raycast, sampled before anything exists to hit), a ground portal stands at that aim point facing the operator, and an arrival pad with the sky-side portal hangs off the build's west edge - outside the footprint, because a generic blueprint offers no square metre that is provably empty and the pad is provably empty because we made it. The pair binds on tag bp <blueprint-name>, so every sky build auto-connects its own doors and two builds never cross-wire. Pad height rides on the dump's pivot facts (wood_floor's pivot IS its walking surface). Doors and pad carry the blueprint mark, so clear takes down the whole installation including the ground-side door. Needed UnityEngine.PhysicsModule referenced for the raycast.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Sky mode: a blueprint overhead, doors bound by name to where the operator aimed",
        "verification": [
          "Mod builds clean, 203/203 host tests green, DLL and blueprint deployed to the lab client. In-game proof pending: aim, build fallingwater sky, take the door up, clear from the ground."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807113551-sky-mode-a-blueprint-overhead-doors-bound-by-nam",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T11:35:51.146Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L458",
        "sha256": "4137e6dbd66282be111416322ba431f2ae0f65c11b8abadfecf27c099665a9e7"
      },
      "summary": "questlab_blueprint build <name> sky borrows the gallery's raised-platform move and generalizes it: the build rides 40 m above whatever the crosshair was aimed at when the command ran (camera-forward raycast, sampled before anything exists to hit), a ground portal stands at that aim point facing the operator, and an arrival pad with the sky-side portal hangs off the build's west edge - outside the footprint, because a generic blueprint offers no square metre that is provably empty and the pad is provably empty because we made it. The pair binds on tag bp <blueprint-name>, so every sky build auto-connects its own doors and two builds never cross-wire. Pad height rides on the dump's pivot facts (wood_floor's pivot IS its walking surface). Doors and pad carry the blueprint mark, so clear takes down the whole installation including the ground-side door. Needed UnityEngine.PhysicsModule referenced for the raycast.",
      "title": "Sky mode: a blueprint overhead, doors bound by name to where the operator aimed",
      "updated_at": "2026-08-07T11:35:51.146Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807113551-sky-mode-a-blueprint-overhead-doors-bound-by-nam"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T12:32:04.808Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807123204-marble-halls-signs-and-a-floating-stage-per-rune",
        "impact": "The gallery is rebuilt in stone and black marble against a questlab_prefabs dump, with the generator failing loudly on any palette name the game build lacks and checking that anything laid on the 2m grid really spans 2m by its own snap points. Eight halls of blackmarble_2x2x1, open air, with a sign at each mouth carrying Unity rich-text into the piece's own ZDO text field - school name in its colour, what is staged there, and whether a quest can bind (only Combat can). Each rune now stands on its own 16x8m stage past the hall end with 4m of open air between, backed by a 16x16m backdrop of blackmarble_floor_large slabs stood on edge, which stops a chest or hearth from ever occluding the glyph and gives the light something black to land on. Pivots are measured, not assumed: snap-point minima showed the marble pieces pivot at their centre where wood_floor pivoted at its top face, which had buried every wall a metre and silently raised the walking surface. School colours now live once in the generator and are carried into the plan, so the rune lamp and the sign heading cannot drift. Lamps are tunable live via questlab_runelight without a rebuild.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Marble halls, signs, and a floating stage per rune - all built against a validated prefab palette",
        "verification": [
          "Human-confirmed in game by Derek across several iterations: halls stand, signs placed, backdrop panels stood vertical and catching rune light, clear keeps up at ~2100 pieces. Palette checked against 3458 prefabs. Builds Release 0 warnings alongside the concurrent blueprint lane. NOT verified: whether the 4m stage gap reads as intended, and default lamp values are still 40/6 while Derek's dialled-in look against the new backdrop is nearer 3/11."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807123204-marble-halls-signs-and-a-floating-stage-per-rune",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T12:32:04.808Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L459",
        "sha256": "101360318216d1a1beedabd7bf42bb90d3314a6c71f168e503eb55e0d08fe9dd"
      },
      "summary": "The gallery is rebuilt in stone and black marble against a questlab_prefabs dump, with the generator failing loudly on any palette name the game build lacks and checking that anything laid on the 2m grid really spans 2m by its own snap points. Eight halls of blackmarble_2x2x1, open air, with a sign at each mouth carrying Unity rich-text into the piece's own ZDO text field - school name in its colour, what is staged there, and whether a quest can bind (only Combat can). Each rune now stands on its own 16x8m stage past the hall end with 4m of open air between, backed by a 16x16m backdrop of blackmarble_floor_large slabs stood on edge, which stops a chest or hearth from ever occluding the glyph and gives the light something black to land on. Pivots are measured, not assumed: snap-point minima showed the marble pieces pivot at their centre where wood_floor pivoted at its top face, which had buried every wall a metre and silently raised the walking surface. School colours now live once in the generator and are carried into the plan, so the rune lamp and the sign heading cannot drift. Lamps are tunable live via questlab_runelight without a rebuild.",
      "title": "Marble halls, signs, and a floating stage per rune - all built against a validated prefab palette",
      "updated_at": "2026-08-07T12:32:04.808Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807123204-marble-halls-signs-and-a-floating-stage-per-rune"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T12:46:00.194Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807124600-rune-lamp-defaults-become-3-11-the-value-dialled",
        "impact": "A fresh gallery came up at 40/6, which was correct only while the runes stood against open sky: a wide reach lit the mist between viewer and glyph, so the fix then was bright and tight. With each rune now backed by a black marble panel there is nothing left to out-shine - the backdrop supplies the contrast and the lamp only has to wash it, so 40/6 blows out and a softer, wider 3/11 reads better. Defaults updated and the reasoning recorded at the binding, because the pair is a property of what the rune is seen against rather than of the lamp; changing the backdrop should be expected to need a retune.",
        "kind": "implementation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Rune lamp defaults become 3/11, the value dialled in against the marble backdrop",
        "verification": [
          "Human-confirmed in game by Derek, who arrived at 3/11 by live tuning with questlab_runelight against the built backdrop. Builds Release with 0 warnings and is installed to the client. NOT verified: a fresh build from these defaults has not been raised yet - the value was reached by retuning an existing gallery."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807124600-rune-lamp-defaults-become-3-11-the-value-dialled",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T12:46:00.194Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L460",
        "sha256": "ff95ee3e2a635f256bb3ad5ef1aedc0d62b8ac24808006529bd233206320b69c"
      },
      "summary": "A fresh gallery came up at 40/6, which was correct only while the runes stood against open sky: a wide reach lit the mist between viewer and glyph, so the fix then was bright and tight. With each rune now backed by a black marble panel there is nothing left to out-shine - the backdrop supplies the contrast and the lamp only has to wash it, so 40/6 blows out and a softer, wider 3/11 reads better. Defaults updated and the reasoning recorded at the binding, because the pair is a property of what the rune is seen against rather than of the lamp; changing the backdrop should be expected to need a retune.",
      "title": "Rune lamp defaults become 3/11, the value dialled in against the marble backdrop",
      "updated_at": "2026-08-07T12:46:00.194Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807124600-rune-lamp-defaults-become-3-11-the-value-dialled"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T13:53:13.799Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807135313-turnkey-quest-lab-packaging-and-unified-tool-sui",
        "impact": "Creators have a turnkey DLL/script package to safely learn quest hooks locally, and all gateway surfaces (roadmap, workbench, quest lab, quest picker, steward) now share a unified navigation header.",
        "kind": "implementation",
        "milestones": [
          "M1"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Turnkey quest lab packaging and unified tool suite navigation",
        "verification": [
          "Generated HTML visually verified; all tests pass."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M1"
        ]
      },
      "id": "roadmap:20260807135313-turnkey-quest-lab-packaging-and-unified-tool-sui",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T13:53:13.799Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L461",
        "sha256": "5cd8f6bbb70ca86a0547c83210ded67d55e4c94073d67bcb3a992793860c2ad5"
      },
      "summary": "Creators have a turnkey DLL/script package to safely learn quest hooks locally, and all gateway surfaces (roadmap, workbench, quest lab, quest picker, steward) now share a unified navigation header.",
      "title": "Turnkey quest lab packaging and unified tool suite navigation",
      "updated_at": "2026-08-07T13:53:13.799Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807135313-turnkey-quest-lab-packaging-and-unified-tool-sui"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-07T14:11:09.757Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807141109-lab-setup-exists-stop-the-mod-s-own-docs-saying-",
        "impact": "The README and CHANGELOG both still claimed lab_setup was not here yet, while ComfyQuestLab.cs registers it as a console command that raises the practice gallery and points at the tome. Found while fact-checking a strategy document written by another agent, which listed turnkey lab_setup packaging as complete - the doc was right and the repo was under-claiming. Stale docs are the same failure in either direction: a README that undersells a shipped command costs a newcomer the one instruction they needed. Also noted for follow-up and NOT changed here: the ontology document says 7 Schools of Magic where every source in the repo says 8, probably from misreading the in-game roster line about seven of the eight categories not being wired; and the README's no download claim now contradicts workbench.json, which describes downloading a zip - that contradiction is unresolved and someone should settle which is true.",
        "kind": "documentation",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "lab_setup exists: stop the mod's own docs saying it does not",
        "verification": [
          "Read ComfyQuestLab.cs where the lab_setup Terminal.ConsoleCommand is registered and confirmed it starts the gallery build coroutine. Grep across the repo for lab_setup showed the two stale claims plus the workbench.json entry that already assumed it worked. NOT verified: whether a packaged download exists, which is why that claim was dropped rather than rewritten."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807141109-lab-setup-exists-stop-the-mod-s-own-docs-saying-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-07T14:11:09.757Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L462",
        "sha256": "361a8637749efd013d89bdf03ae6c7ad1429cf06a27ad5a54115f29ca69c960f"
      },
      "summary": "The README and CHANGELOG both still claimed lab_setup was not here yet, while ComfyQuestLab.cs registers it as a console command that raises the practice gallery and points at the tome. Found while fact-checking a strategy document written by another agent, which listed turnkey lab_setup packaging as complete - the doc was right and the repo was under-claiming. Stale docs are the same failure in either direction: a README that undersells a shipped command costs a newcomer the one instruction they needed. Also noted for follow-up and NOT changed here: the ontology document says 7 Schools of Magic where every source in the repo says 8, probably from misreading the in-game roster line about seven of the eight categories not being wired; and the README's no download claim now contradicts workbench.json, which describes downloading a zip - that contradiction is unresolved and someone should settle which is true.",
      "title": "lab_setup exists: stop the mod's own docs saying it does not",
      "updated_at": "2026-08-07T14:11:09.757Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807141109-lab-setup-exists-stop-the-mod-s-own-docs-saying-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T14:59:26.051Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807145926-quest-lab-gains-a-unity-free-quest-core-per-file",
        "impact": "The lab could show what the game says but never loaded, validated, or evaluated a quest definition. LabQuestSet/LabQuestAdvisor/LabQuestSeed activate the already-linked ComfyNetworkSense contract (TrackedQuest, QuestViewLoader, QuestTriggerEvaluator) so a quest authored in the lab behaves identically in the shipping mod. Armed state is probed by echoing a quest's own filters back at a throwaway QuestTriggerEvaluator rather than by a mirror predicate, so it cannot drift from the contract. Quest files are whole quest-view.json documents, copyable byte-for-byte to comfy-network-sense/quest-view.json.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab gains a Unity-free quest core: per-file parse isolation, an armed verdict derived by dry-firing the real evaluator, and a starter seed that teaches the hit-vs-kill trap",
        "verification": [
          "dotnet test ComfyNetworkSense.Tests: 231 passed, 28 of them new (LabQuestSetTests, LabQuestSeedTests)",
          "The seed round-trips through QuestViewLoader.Parse and yields exactly one armed quest (neck_romancer, kill) and one that silently cannot fire (punchwood, hit) - the assertion goes red if either contract moves",
          "dotnet build ComfyQuestLab -c Release: 0 warnings, 0 errors against net48"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260807145926-quest-lab-gains-a-unity-free-quest-core-per-file",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T14:59:26.051Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L463",
        "sha256": "ec367a6a57c1a169fd0695bf4ee53840667406e25f2169a84468b0fcfe3ec633"
      },
      "summary": "The lab could show what the game says but never loaded, validated, or evaluated a quest definition. LabQuestSet/LabQuestAdvisor/LabQuestSeed activate the already-linked ComfyNetworkSense contract (TrackedQuest, QuestViewLoader, QuestTriggerEvaluator) so a quest authored in the lab behaves identically in the shipping mod. Armed state is probed by echoing a quest's own filters back at a throwaway QuestTriggerEvaluator rather than by a mirror predicate, so it cannot drift from the contract. Quest files are whole quest-view.json documents, copyable byte-for-byte to comfy-network-sense/quest-view.json.",
      "title": "Quest Lab gains a Unity-free quest core: per-file parse isolation, an armed verdict derived by dry-firing the real evaluator, and a starter seed that teaches the hit-vs-kill trap",
      "updated_at": "2026-08-07T14:59:26.051Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807145926-quest-lab-gains-a-unity-free-quest-core-per-file"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T15:06:53.484Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807150653-lab-reload-lands-the-quest-lane-is-wired-end-to-",
        "impact": "LabQuestEngine + LabKillWatch connect the quest core to the game: hits are recorded at damage time and consumed at Character.OnDeath, because OnDeath carries no HitData and IsDead() is still false in a damage postfix. A third panel tab holds the roster, per-quest armed reasons, cooldowns, fire counts and advisories, plus the last kill the matcher was actually given. lab_setup seeds a starter quest file into an empty folder only. FIXED: CombatPatches.Describe returned the GameObject name while promising the evaluator matched against exactly that -- the shipping mod passes m_name, so Greydwarf_Elite against $enemy_greydwarfbrute shared nothing and such a quest could never fire, with no error anywhere. The console now shows both names when they disagree.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "lab_reload lands: the quest lane is wired end to end, and a false promise in the lab's own console is fixed",
        "verification": [
          "dotnet test ComfyNetworkSense.Tests: 231 passed, 0 failed",
          "dotnet build ComfyQuestLab -c Release: 0 warnings, 0 errors",
          "PENDING in-game: seed on first lab_setup, a Neck kill firing neck_romancer, lab_reload diffing an edit, per-file error isolation, and the Greydwarf_Elite advisory"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260807150653-lab-reload-lands-the-quest-lane-is-wired-end-to-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T15:06:53.484Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L464",
        "sha256": "987d81393af86d06b408286ca7632ec5227f90bce174fed4c116cabb05c6ac4b"
      },
      "summary": "LabQuestEngine + LabKillWatch connect the quest core to the game: hits are recorded at damage time and consumed at Character.OnDeath, because OnDeath carries no HitData and IsDead() is still false in a damage postfix. A third panel tab holds the roster, per-quest armed reasons, cooldowns, fire counts and advisories, plus the last kill the matcher was actually given. lab_setup seeds a starter quest file into an empty folder only. FIXED: CombatPatches.Describe returned the GameObject name while promising the evaluator matched against exactly that -- the shipping mod passes m_name, so Greydwarf_Elite against $enemy_greydwarfbrute shared nothing and such a quest could never fire, with no error anywhere. The console now shows both names when they disagree.",
      "title": "lab_reload lands: the quest lane is wired end to end, and a false promise in the lab's own console is fixed",
      "updated_at": "2026-08-07T15:06:53.484Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807150653-lab-reload-lands-the-quest-lane-is-wired-end-to-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T15:14:12.445Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807151412-the-quest-lab-tome-finally-tells-you-how-to-inst",
        "impact": "The tome taught 8 schools and 78 spells and never once said where to get the mod, what BepInEx is, or that lab_setup exists -- a reader who wanted to try it had nowhere to go. Added a Start here block: download link, install, F5 lab_setup vs F6 panel, edit-and-lab_reload, plus the honest note that all eight schools are hooked and exactly one can have a quest bound to it. Two render defects fixed: the what/try fields are line-WRAPPED prose joined with a comma, producing a garbled pseudo-list; and the per-school watch field -- the trap sentence, the most valuable paragraph on each page -- was in journal-pages.json and in the in-game spellbook but silently dropped from the web. QuestLabViewEndpoints now mirrors WorkbenchViewEndpoints: LUMBERJACKS_QUESTLAB_HTML override, mtime cache, X-QuestLab-Sha256, degrading in steps; Publish-WorkbenchAssets carries questlab.html with the same remote SHA-256 verification.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The Quest Lab tome finally tells you how to install the mod, stops garbling its own prose, and can be published without a Gateway image",
        "verification": [
          "Gateway builds clean in mcr.microsoft.com/dotnet/sdk:9.0 (host SDK 8 cannot target net9)",
          "npm run workbench:test: 29 passed",
          "Regenerated questlab.html: onboarding present, 8 Worth knowing sections, prose rejoined as sentences, no U+FFFD, no BOM, LF endings",
          "PENDING: the lj-workbench container needs LUMBERJACKS_QUESTLAB_HTML added and a one-time recreate before tome edits ship by file copy rather than by image"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260807151412-the-quest-lab-tome-finally-tells-you-how-to-inst",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T15:14:12.445Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L465",
        "sha256": "a6045f5ab5371f0f531c00cae6386b03b03dd73e9a980d01388512503d9d90a2"
      },
      "summary": "The tome taught 8 schools and 78 spells and never once said where to get the mod, what BepInEx is, or that lab_setup exists -- a reader who wanted to try it had nowhere to go. Added a Start here block: download link, install, F5 lab_setup vs F6 panel, edit-and-lab_reload, plus the honest note that all eight schools are hooked and exactly one can have a quest bound to it. Two render defects fixed: the what/try fields are line-WRAPPED prose joined with a comma, producing a garbled pseudo-list; and the per-school watch field -- the trap sentence, the most valuable paragraph on each page -- was in journal-pages.json and in the in-game spellbook but silently dropped from the web. QuestLabViewEndpoints now mirrors WorkbenchViewEndpoints: LUMBERJACKS_QUESTLAB_HTML override, mtime cache, X-QuestLab-Sha256, degrading in steps; Publish-WorkbenchAssets carries questlab.html with the same remote SHA-256 verification.",
      "title": "The Quest Lab tome finally tells you how to install the mod, stops garbling its own prose, and can be published without a Gateway image",
      "updated_at": "2026-08-07T15:14:12.445Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807151412-the-quest-lab-tome-finally-tells-you-how-to-inst"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T15:19:23.868Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807151923-extract-docker-image-mcp-gateway-and-lab-toolset",
        "impact": "Formalizes contract boundaries, API schemas, and container builds in isolate, decoupling baseline from direct in-tree image builds.",
        "kind": "decision",
        "milestones": [
          "A5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Extract Docker image, MCP gateway, and lab toolset into isolated repository (isolate)",
        "verification": [
          "python unittest passed 11 tests; PD-8 and api-contract.json documented."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "A5"
        ]
      },
      "id": "roadmap:20260807151923-extract-docker-image-mcp-gateway-and-lab-toolset",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-08-07T15:19:23.868Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L466",
        "sha256": "8815b55c30aa69e83458e8a12310e82497cc1f962c6f350e05825e4ea8fa7911"
      },
      "summary": "Formalizes contract boundaries, API schemas, and container builds in isolate, decoupling baseline from direct in-tree image builds.",
      "title": "Extract Docker image, MCP gateway, and lab toolset into isolated repository (isolate)",
      "updated_at": "2026-08-07T15:19:23.868Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807151923-extract-docker-image-mcp-gateway-and-lab-toolset"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-07T15:23:15.089Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260807152315-correct-the-quest-lab-docs-to-match-the-build-8-",
        "impact": "The turnkey vision draft sat untracked at the repo root describing three friction removers as though all three shipped. lab_reload did not exist at all (it does now); the failure-boundary story credited LabEventRing, which is a buffer that prints nothing; and lab_export conflicts with fieldlab ADR-0018, which replaced outbox payloads with a durable EventLog row -- the bridge consumer explicitly rejects schema-1 outbox payloads. It also said 7 Schools of Magic, omitting World, while every source in the repo says 8, and placed diagnostics in an F5 overlay when F5 is Valheim's console and F6 is the lab panel. Rewritten as docs/quest-lab-turnkey-vision.md with a status column per friction remover and the honest gap named: the quest lane is proven by unit tests against the real contract and has never been run inside Valheim. START-HERE gained a ComfyQuestLab row and the full AM4 route list, and now flags that /questpicker and /steward appear in every nav bar with no route in this repo's Gateway source. 7-tools drift fixed in START-HERE and HANDOFF-2026-07-29.",
        "kind": "documentation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Correct the Quest Lab docs to match the build: 8 schools not 7, lab_export deferred with its reason, and the F5/F6 distinction that catches everyone",
        "verification": [
          "docs/ had zero mentions of the quest lab before this; it now has a vision doc, a START-HERE row, and a workbench one-pager",
          "fieldlab ADR-0018 path confirmed to exist before citing it (two ADR-0018s exist under different numbering roots; the fieldlab one is the quest-proof decision)"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260807152315-correct-the-quest-lab-docs-to-match-the-build-8-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-07T15:23:15.089Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L467",
        "sha256": "cadf22d8f06fc7a1124b308fcd044cf6703fcd7155542d93b96846bbe2804f30"
      },
      "summary": "The turnkey vision draft sat untracked at the repo root describing three friction removers as though all three shipped. lab_reload did not exist at all (it does now); the failure-boundary story credited LabEventRing, which is a buffer that prints nothing; and lab_export conflicts with fieldlab ADR-0018, which replaced outbox payloads with a durable EventLog row -- the bridge consumer explicitly rejects schema-1 outbox payloads. It also said 7 Schools of Magic, omitting World, while every source in the repo says 8, and placed diagnostics in an F5 overlay when F5 is Valheim's console and F6 is the lab panel. Rewritten as docs/quest-lab-turnkey-vision.md with a status column per friction remover and the honest gap named: the quest lane is proven by unit tests against the real contract and has never been run inside Valheim. START-HERE gained a ComfyQuestLab row and the full AM4 route list, and now flags that /questpicker and /steward appear in every nav bar with no route in this repo's Gateway source. 7-tools drift fixed in START-HERE and HANDOFF-2026-07-29.",
      "title": "Correct the Quest Lab docs to match the build: 8 schools not 7, lab_export deferred with its reason, and the F5/F6 distinction that catches everyone",
      "updated_at": "2026-08-07T15:23:15.089Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807152315-correct-the-quest-lab-docs-to-match-the-build-8-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-07T16:00:03.122Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/isolate-boundary-verification-20260807.json"
        ],
        "id": "20260807160003-make-the-pd-8-isolate-boundary-assert-something-",
        "impact": "The isolate extraction was a copy, and three of its own guards could not fail. Its compose file was byte-identical to baseline's including name: comfy-valheim-lab -- the LIVE lab project -- and with AUTONOMOUS_ROOT unset the world mounts rendered as blank-rooted absolute paths while docker compose still exited 0, so the documented launch command would have adopted the running server and recreated it against an empty world. gateway_identity() hardcoded project=baseline and source_root is /workspace in any container built from this Dockerfile, so /identity, the endpoint PD-8 names as THE contract boundary, could not distinguish the two repositories. contracts/api-contract.json declared fields the endpoints do not return and named 8721, a host publish belonging to baseline's companion container, as the protocol default. Fixed: project now comes from COMFY_MCP_PROJECT defaulting to baseline, the isolate stack runs as its own isolate-lab project with defaults resolving inside its own tree, and the contract is enforced in both directions. Test-WorkbenchMcpIdentity.ps1 gained -ExpectedProject.",
        "kind": "implementation",
        "milestones": [
          "A4",
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make the PD-8 isolate boundary assert something: /identity can name which repository answered, and the API contract file is now enforced by a test",
        "verification": [
          "OMEN 2026-08-07. Baseline suite 18 green, isolate 19 green (was 11 with 2 failures). The new contract guard was mutation-tested three ways -- dropping a declared field, declaring a phantom field, and reverting the wrong default port -- and turned the suite red each time, with the file restored byte-identical after. The re-scoped privacy scan was proven non-vacuous by planting a leak and detecting it. Negative control: the identity gate pointed at 8721 fails on 'project' FIRST, a mismatch that could not have fired before this change. Real probe: verdict passed on 8722 with project=isolate and real git provenance. The live comfy-valheim-lab server was untouched throughout -- container id and StartedAt unchanged. Multi-peer motion remains BLOCKED and unattempted: i5 is offline (TCP timeout)."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4",
          "A7"
        ]
      },
      "id": "roadmap:20260807160003-make-the-pd-8-isolate-boundary-assert-something-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-07T16:00:03.122Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L468",
        "sha256": "529ba4e7c2259f8a53a0b1b4a715c1144e62499b5346aa478adb3160870ceda1"
      },
      "summary": "The isolate extraction was a copy, and three of its own guards could not fail. Its compose file was byte-identical to baseline's including name: comfy-valheim-lab -- the LIVE lab project -- and with AUTONOMOUS_ROOT unset the world mounts rendered as blank-rooted absolute paths while docker compose still exited 0, so the documented launch command would have adopted the running server and recreated it against an empty world. gateway_identity() hardcoded project=baseline and source_root is /workspace in any container built from this Dockerfile, so /identity, the endpoint PD-8 names as THE contract boundary, could not distinguish the two repositories. contracts/api-contract.json declared fields the endpoints do not return and named 8721, a host publish belonging to baseline's companion container, as the protocol default. Fixed: project now comes from COMFY_MCP_PROJECT defaulting to baseline, the isolate stack runs as its own isolate-lab project with defaults resolving inside its own tree, and the contract is enforced in both directions. Test-WorkbenchMcpIdentity.ps1 gained -ExpectedProject.",
      "title": "Make the PD-8 isolate boundary assert something: /identity can name which repository answered, and the API contract file is now enforced by a test",
      "updated_at": "2026-08-07T16:00:03.122Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260807160003-make-the-pd-8-isolate-boundary-assert-something-"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T02:09:21.207Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/isolate-boundary-verification-20260807.json"
        ],
        "id": "20260808020921-i5-is-back-but-the-two-client-test-is-still-bloc",
        "impact": "The i5 lane came back up and Test-I5Link passes cleanly, so the blocker recorded this morning is superseded. It did not clear, it moved. Wave 0 readiness returns blocked_by_failed_preflight: both OMEN and i5 sit on m32-watchdog-20260802-r1 while the local gateway admits m7-c10b-20260807-r42, and Valheim is not running on either box. Aligning the installs then hit a real defect. The Companion refused with HTTP 400 package_personalized_config_forbidden on BepInEx/config/djcdevelopment.valheim.comfynetworksense.cfg. The guard is correct and was not forced: the Gateway keeps only a credential hash after install, so overwriting that file would destroy the client's only copy of its raw access key. Root cause is that two halves of the same codebase disagree about which artifact the headless lane gets. Game.Companion/Program.cs:842 fetches /api/v0/valheim/modpack/package, which SteamEnrollmentEndpoints.cs:76 serves as the unmodified template, while the config-stripping build ModPackBuilder.BuildConfigPreservingUpdatePack is only reachable via /join/update/steam-callback behind a Steam OpenID browser login that Install-I5LatestModpack.ps1 deliberately avoids. The headless update lane and the stripping builder never meet.",
        "kind": "verification",
        "milestones": [
          "M4b",
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "i5 is back but the two-client test is still blocked: release m7-c10b-20260807-r42 cannot be installed by the headless Companion update lane",
        "verification": [
          "Independently verified rather than taken from the error message. The downloaded package hashed to c5ee672f26dedad7e20e7063c38235fe34dd8d1b3d8bcae9e24bc86ab959821b at 1085425 bytes, matching the manifest exactly, and does contain the config entry. Comparing stored templates in artifacts/modpacks shows m31-motionphase-20260724-r1, m32-workbench-20260802-r1 and m32-watchdog-20260802-r1 are each 33 entries with NO personalized config entry, while m7-c10b-20260807-r42 is 33 entries WITH it: today's cut swapped one file and that is what the guard refuses. OMEN was left unchanged, confirmed by Companion status still reporting m32-watchdog-20260802-r1 installed 2026-08-02T06:40:57Z, because the guard fails before the first target byte is written. i5 was not attempted, since the same package and guard would only reproduce the failure. Also noted: Test-Wave0Readiness.ps1 defaults to the stopped P7 VM and dies on a timeout unless given -GatewayUrl http://127.0.0.1:4000."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M4b",
          "A7"
        ]
      },
      "id": "roadmap:20260808020921-i5-is-back-but-the-two-client-test-is-still-bloc",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-08T02:09:21.207Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L469",
        "sha256": "7fea64316e38fb4e3a6e037cc7c8d99c1b2609b731e0b4419e23506ee8a9596d"
      },
      "summary": "The i5 lane came back up and Test-I5Link passes cleanly, so the blocker recorded this morning is superseded. It did not clear, it moved. Wave 0 readiness returns blocked_by_failed_preflight: both OMEN and i5 sit on m32-watchdog-20260802-r1 while the local gateway admits m7-c10b-20260807-r42, and Valheim is not running on either box. Aligning the installs then hit a real defect. The Companion refused with HTTP 400 package_personalized_config_forbidden on BepInEx/config/djcdevelopment.valheim.comfynetworksense.cfg. The guard is correct and was not forced: the Gateway keeps only a credential hash after install, so overwriting that file would destroy the client's only copy of its raw access key. Root cause is that two halves of the same codebase disagree about which artifact the headless lane gets. Game.Companion/Program.cs:842 fetches /api/v0/valheim/modpack/package, which SteamEnrollmentEndpoints.cs:76 serves as the unmodified template, while the config-stripping build ModPackBuilder.BuildConfigPreservingUpdatePack is only reachable via /join/update/steam-callback behind a Steam OpenID browser login that Install-I5LatestModpack.ps1 deliberately avoids. The headless update lane and the stripping builder never meet.",
      "title": "i5 is back but the two-client test is still blocked: release m7-c10b-20260807-r42 cannot be installed by the headless Companion update lane",
      "updated_at": "2026-08-08T02:09:21.207Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808020921-i5-is-back-but-the-two-client-test-is-still-bloc"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T03:50:12.492Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/runs/motion-clips/native-20260802-c9-motion6/c9-motion-quality-side-by-side.receipt.json"
        ],
        "id": "20260808035012-reopen-c9-s-artifact-the-retained-motion-clip-sh",
        "impact": "The final-cutover plan recorded C9 as machine/artifact complete with only Derek's one-word smooth/rough/mixed verdict outstanding, and the remaining-cost table listed it as 1 operator verdict. That was wrong for six days. The retained side-by-side clip's own receipt records events 4 for the OMEN panel and events 5 for the i5 panel across two 20-second views -- near-static frames with a counter overlay rather than observable movement. Derek had already declined to call it on exactly that basis; the plan recorded the absence of a verdict as a pending reviewer action instead of an insufficient artifact, so every reader since has been told C9 was one word from done. Corrected the C9 execution-status row, the C9 acceptance and exit criteria, the 2026-08-02 checkpoint, the remaining-cost table, and the immediate-next-build paragraph. C9 is now blocked on producing an artifact that shows motion, or on a live two-client window, and the retained-boundary list no longer protects the artifact from being re-produced.",
        "kind": "documentation",
        "milestones": [
          "M4b"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Reopen C9's artifact: the retained motion clip shows no motion, so the plan's 'one operator verdict' was never the real remaining work",
        "verification": [
          "Read from the artifact's own receipt at fieldlab/runs/motion-clips/native-20260802-c9-motion6/c9-motion-quality-side-by-side.receipt.json, which reports panels.omen.events=4 duration=20.001s and panels.i5.events=5 duration=20.010s. No rerun performed and no machine claim altered: C9's machine evidence (zero holds, gaps, resyncs, native use or poison trips, and 0.895 s reliable-resync recovery from the injected 20-frame loss) stands unchanged. Only the artifact sufficiency claim and the derived remaining-work accounting were corrected. Acceptance criteria now require any replacement clip to state its per-panel motion event counts so this cannot recur silently."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M4b"
        ]
      },
      "id": "roadmap:20260808035012-reopen-c9-s-artifact-the-retained-motion-clip-sh",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-08T03:50:12.492Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L470",
        "sha256": "25c47568fad760f64eb20aac4bcb675784e0b5002326885b54c534fd51c5d1c7"
      },
      "summary": "The final-cutover plan recorded C9 as machine/artifact complete with only Derek's one-word smooth/rough/mixed verdict outstanding, and the remaining-cost table listed it as 1 operator verdict. That was wrong for six days. The retained side-by-side clip's own receipt records events 4 for the OMEN panel and events 5 for the i5 panel across two 20-second views -- near-static frames with a counter overlay rather than observable movement. Derek had already declined to call it on exactly that basis; the plan recorded the absence of a verdict as a pending reviewer action instead of an insufficient artifact, so every reader since has been told C9 was one word from done. Corrected the C9 execution-status row, the C9 acceptance and exit criteria, the 2026-08-02 checkpoint, the remaining-cost table, and the immediate-next-build paragraph. C9 is now blocked on producing an artifact that shows motion, or on a live two-client window, and the retained-boundary list no longer protects the artifact from being re-produced.",
      "title": "Reopen C9's artifact: the retained motion clip shows no motion, so the plan's 'one operator verdict' was never the real remaining work",
      "updated_at": "2026-08-08T03:50:12.492Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808035012-reopen-c9-s-artifact-the-retained-motion-clip-sh"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T04:03:12.366Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808040312-root-caused-the-am4-black-screen-under-zdoredire",
        "impact": "Explains why config permutation never isolated it and why the scoped redirect masked it; names a one-line Gateway fix plus two separate posture defects",
        "kind": "verification",
        "milestones": [
          "M4b",
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Root-caused the AM4 black screen under zdoRedirectPrefabs=* to the Gateway voiding refresh=true re-snapshots via the HasPending dedup guard",
        "verification": [
          "Journal-cutover receipts show snapshot_count 1230 -> 9 -> 1 -> 0 across the two-phase join, with zero delta_applied_typed for the run"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M4b",
          "A7"
        ]
      },
      "id": "roadmap:20260808040312-root-caused-the-am4-black-screen-under-zdoredire",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-08T04:03:12.366Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L471",
        "sha256": "bd740ceea850893b26ff9c07d2f640118383bc75cd2154d7b856b7d1ab73a52a"
      },
      "summary": "Explains why config permutation never isolated it and why the scoped redirect masked it; names a one-line Gateway fix plus two separate posture defects",
      "title": "Root-caused the AM4 black screen under zdoRedirectPrefabs=* to the Gateway voiding refresh=true re-snapshots via the HasPending dedup guard",
      "updated_at": "2026-08-08T04:03:12.366Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808040312-root-caused-the-am4-black-screen-under-zdoredire"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T04:38:29.364Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/evidence/am4-blackscreen-refresh-snapshot-20260808.md"
        ],
        "id": "20260808043829-fix-the-gateway-refresh-dedup-that-issued-each-r",
        "impact": "ValheimZdoJournalService.RegisterInterest honoured interest.Refresh and then immediately negated it: HasPending skipped every object already queued for that recipient. A refresh is precisely the case where the client has thrown its inbound queue away -- ZdoJournalCutoverRunner.ResetClientEpochState drains it on a ZNet teardown -- while the recipient id is the logical peer id and survives that teardown. So the Gateway deduped the re-snapshot against deliveries the client could never receive, and the world was issued once and never again. Latent since 2026-07-30 and masked until the server widened to zdoRedirectPrefabs=* on 08-07: under the earlier scoped redirect the world still arrived over the native ZDO path, so the lost lane snapshot cost a few mushrooms rather than everything. The fix drops the recipient's pending queue when Refresh is set, before re-snapshotting. Safe because _nextSequence is per-recipient and tracked separately from _pending, so re-enqueued deliveries take fresh higher sequences and cannot collide with acks for the discarded ones. Cut as Gateway-only image m7-c10b-20260808-r43 admitting the frozen mod m7-c10b-20260807-r42, so no client mod was invalidated.",
        "kind": "implementation",
        "milestones": [
          "M4b",
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Fix the Gateway refresh dedup that issued each recipient's world exactly once, and verify it with a live populated join on AM4",
        "verification": [
          "Three regression tests added and mutation-tested rather than merely run: with the one-line fix disabled, 2 of 3 fail (Expected 50 Actual 0 on the re-snapshot; re-snapshot reused sequence 1 where highest discarded was 10). The third passes either way by design, guarding against the fix widening into resend-everything. Full gateway suite 247 of 247 green. Live proof on AM4 with six cutover legs armed on both sides and zdoRedirectPrefabs=* -- the exact configuration that produced the black screen: canonical_delivery_progress reported banked=1024 inbound=962 delivery_seq=1024 where the broken run produced no delivery progress at all, and the client HUD moved from pieces 0 entities 0 zone 0:0 to pieces 667 zone 34:-1 with Black Forest terrain, runestones and vegetation rendered. Client log shows Starting music blackforest followed by TERRAIN_COMP awake across zones 34,-2 and 34,0. Not covered: two-client behaviour, since i5 was not joined for this run, so nothing here speaks to remote-player motion."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M4b",
          "M7"
        ]
      },
      "id": "roadmap:20260808043829-fix-the-gateway-refresh-dedup-that-issued-each-r",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T04:38:29.364Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L472",
        "sha256": "b3684be0edd5df0769fd6fb547fc6287e1dc77e7a06322132c423199acf4daa4"
      },
      "summary": "ValheimZdoJournalService.RegisterInterest honoured interest.Refresh and then immediately negated it: HasPending skipped every object already queued for that recipient. A refresh is precisely the case where the client has thrown its inbound queue away -- ZdoJournalCutoverRunner.ResetClientEpochState drains it on a ZNet teardown -- while the recipient id is the logical peer id and survives that teardown. So the Gateway deduped the re-snapshot against deliveries the client could never receive, and the world was issued once and never again. Latent since 2026-07-30 and masked until the server widened to zdoRedirectPrefabs=* on 08-07: under the earlier scoped redirect the world still arrived over the native ZDO path, so the lost lane snapshot cost a few mushrooms rather than everything. The fix drops the recipient's pending queue when Refresh is set, before re-snapshotting. Safe because _nextSequence is per-recipient and tracked separately from _pending, so re-enqueued deliveries take fresh higher sequences and cannot collide with acks for the discarded ones. Cut as Gateway-only image m7-c10b-20260808-r43 admitting the frozen mod m7-c10b-20260807-r42, so no client mod was invalidated.",
      "title": "Fix the Gateway refresh dedup that issued each recipient's world exactly once, and verify it with a live populated join on AM4",
      "updated_at": "2026-08-08T04:38:29.364Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808043829-fix-the-gateway-refresh-dedup-that-issued-each-r"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T05:01:29.409Z",
        "author": "Codex",
        "evidence": [
          "fieldlab/retro/SESSION-RETRO-2026-08-08.md"
        ],
        "id": "20260808050129-session-retro-2026-08-08-and-adr-0019-four-guard",
        "impact": "Retro for the isolate-boundary and AM4 black-screen session. The through-line is not the Gateway fix but that four independent guards had never been able to return a failure: an identity endpoint that hardcoded the value it was meant to discriminate, an API contract file no test read, a C9 acceptance criterion satisfied by a file existing, and a compose launch whose failure mode is exit 0 against blank-rooted world mounts. ADR 0019 turns that into a rule -- a guard is not accepted until it has been observed to fail, acceptance criteria state a property rather than an existence, contract files are read by a test or deleted, receipts carry negative controls, and commands whose failure mode is a zero exit get rendered before they are run. The retro is candid about operator error: a composition fired at a retained boundary the plan forbids, cutover legs disarmed to force a green join (a regression Derek had corrected an hour earlier), four gateway recomposes that silently downgraded a pinned release image, two false fix-did-not-work claims from measurement errors, and three attempts to extract a C9 verdict from an artifact Derek had already rejected.",
        "kind": "documentation",
        "milestones": [
          "M4b",
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Session retro 2026-08-08 and ADR 0019: four guards in this repo were structurally incapable of failing",
        "verification": [
          "Git range fe5b38fc..10323840, 7 commits, working tree clean. Role reads and candidate lessons drafted by gcp-gemini via HEARTH local_generate (1426 in / 1162 out, 23.4s), edit verdict minor-fixes -- factually faithful with no invented commits or numbers, rewritten for house voice and re-attributed per seat. All judgments, seat attributions, ADR wording and repo-coherent writes frontier. Last session's lessons audited for follow-through: L-2026-08-05-1 and -4 acted-on, -6 acted-on, -2 -3 -5 -7 pending, and -8 dropped-and-recurred which is what escalated into ADR 0019. Four memory files written and indexed; five open decisions appended to the fieldlab register."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "M4b",
          "A7"
        ]
      },
      "id": "roadmap:20260808050129-session-retro-2026-08-08-and-adr-0019-four-guard",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-08T05:01:29.409Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L473",
        "sha256": "64f9bdd8e14c1b2f2d227d726b1b53f6b8052a767cc05785c8e58a79772deb7f"
      },
      "summary": "Retro for the isolate-boundary and AM4 black-screen session. The through-line is not the Gateway fix but that four independent guards had never been able to return a failure: an identity endpoint that hardcoded the value it was meant to discriminate, an API contract file no test read, a C9 acceptance criterion satisfied by a file existing, and a compose launch whose failure mode is exit 0 against blank-rooted world mounts. ADR 0019 turns that into a rule -- a guard is not accepted until it has been observed to fail, acceptance criteria state a property rather than an existence, contract files are read by a test or deleted, receipts carry negative controls, and commands whose failure mode is a zero exit get rendered before they are run. The retro is candid about operator error: a composition fired at a retained boundary the plan forbids, cutover legs disarmed to force a green join (a regression Derek had corrected an hour earlier), four gateway recomposes that silently downgraded a pinned release image, two false fix-did-not-work claims from measurement errors, and three attempts to extract a C9 verdict from an artifact Derek had already rejected.",
      "title": "Session retro 2026-08-08 and ADR 0019: four guards in this repo were structurally incapable of failing",
      "updated_at": "2026-08-08T05:01:29.409Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808050129-session-retro-2026-08-08-and-adr-0019-four-guard"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T05:20:12.832Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808052012-turn-two-of-the-quest-lab-s-manual-in-game-check",
        "impact": "The creature-naming rule -- the load-bearing half of the 08-07 bug fix -- was pure string work living beside Character and HitData, so the only way to check it was to launch Valheim and kill something. Extracted to Core/LabCreatureNaming.cs, Unity-free and linked into ComfyNetworkSense.Tests; LabKillWatch and LabObserve.Clean now delegate to it so there is one home for the rule. The Greydwarf_Elite vs $enemy_greydwarfbrute case is a test rather than a ritual. Also tested LabQuestSeed.EnsureSeeded, whose never-overwrite guarantee protects a creator's authored quests from a re-run of lab_setup and had zero coverage -- including that the check is keyed on any *.json, so a renamed draft also suppresses the seed.",
        "kind": "verification",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Turn two of the Quest Lab's manual in-game checks into automated ones, and mutation-check that the regression test actually bites",
        "verification": [
          "241 tests pass, 10 new",
          "Mutation check: reverting Normalize to prefer the GameObject name (the original bug) fails 3 tests including TheEliteGreydwarfIsTheCaseThatUsedToLieAndItIsCaughtNow; file restored and suite re-verified green, 0 MUTANT markers left",
          "ComfyQuestLab builds clean on net48 after the extraction"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808052012-turn-two-of-the-quest-lab-s-manual-in-game-check",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-08T05:20:12.832Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L474",
        "sha256": "1a5bd335c457bcdc5bdf352cc0422de383fda11ecc78d3c48d40d306454ec9e0"
      },
      "summary": "The creature-naming rule -- the load-bearing half of the 08-07 bug fix -- was pure string work living beside Character and HitData, so the only way to check it was to launch Valheim and kill something. Extracted to Core/LabCreatureNaming.cs, Unity-free and linked into ComfyNetworkSense.Tests; LabKillWatch and LabObserve.Clean now delegate to it so there is one home for the rule. The Greydwarf_Elite vs $enemy_greydwarfbrute case is a test rather than a ritual. Also tested LabQuestSeed.EnsureSeeded, whose never-overwrite guarantee protects a creator's authored quests from a re-run of lab_setup and had zero coverage -- including that the check is keyed on any *.json, so a renamed draft also suppresses the seed.",
      "title": "Turn two of the Quest Lab's manual in-game checks into automated ones, and mutation-check that the regression test actually bites",
      "updated_at": "2026-08-08T05:20:12.832Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808052012-turn-two-of-the-quest-lab-s-manual-in-game-check"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T05:34:39.613Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808053439-lab-target-implement-the-respawn-the-gallery-pla",
        "impact": "Derek caught this in game. The seed quest targeted a Neck -- lifted from the test fixture because it was schema-valid -- so a creator's first act after raising an eight-monument practice ground was to walk away from it and find a shoreline. That cancels the gallery. Worse, the combat station is a single Instantiate: kill the one Greyling and the practice ground has nothing left to kill, so the edit-reload-retest loop died on its second iteration. LabGalleryPlan has declared Kind=spawner and a note reading 'respawned on demand' since it was generated, and nothing ever read either. Now: the seed targets Greyling with no weapon_skill filter so any kill fires it first try, lab_target [school] places a fresh station prefab facing the player wherever they are standing, and a test asserts the seed's target against the gallery plan rather than a hardcoded name.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "lab_target: implement the respawn the gallery plan has been promising, and point the starter quest at something the gallery actually stands up",
        "verification": [
          "243 tests pass, 2 new",
          "Mutation check: reverting the seed target to Neck fails TheArmedSeedQuestTargetsACreatureTheGalleryStandsUpForYou; restored and re-verified green",
          "PENDING in-game: lab_target placing a Greyling, and the seed quest firing on it"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808053439-lab-target-implement-the-respawn-the-gallery-pla",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T05:34:39.613Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L475",
        "sha256": "73504ce660d1aeeeca96d9a1a5c68d093ed1d92958cd1d0b13ad3079378fee97"
      },
      "summary": "Derek caught this in game. The seed quest targeted a Neck -- lifted from the test fixture because it was schema-valid -- so a creator's first act after raising an eight-monument practice ground was to walk away from it and find a shoreline. That cancels the gallery. Worse, the combat station is a single Instantiate: kill the one Greyling and the practice ground has nothing left to kill, so the edit-reload-retest loop died on its second iteration. LabGalleryPlan has declared Kind=spawner and a note reading 'respawned on demand' since it was generated, and nothing ever read either. Now: the seed targets Greyling with no weapon_skill filter so any kill fires it first try, lab_target [school] places a fresh station prefab facing the player wherever they are standing, and a test asserts the seed's target against the gallery plan rather than a hardcoded name.",
      "title": "lab_target: implement the respawn the gallery plan has been promising, and point the starter quest at something the gallery actually stands up",
      "updated_at": "2026-08-08T05:34:39.613Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808053439-lab-target-implement-the-respawn-the-gallery-pla"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T05:38:31.096Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808053831-lab-setup-no-longer-raises-a-second-gallery-thro",
        "impact": "lab_setup is the command we tell newcomers to start with, which makes it the one they are most likely to re-run -- and re-running it silently stacked another 620 pieces on the existing gallery. That is the same failure that once let the piece count reach 1527 before anyone noticed a clear reporting zero. LabGalleryBuilder.StandingPieceCount() sweeps the mark the way Clear does; lab_setup now leaves a standing gallery alone, says how many pieces it found, and points at questlab_gallery clear or lab_target instead. It only sees loaded zones, so a gallery across the map reads as zero -- wrong in the safe direction, offering to build rather than refusing to.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "lab_setup no longer raises a second gallery through the first",
        "verification": [
          "243 tests pass; ComfyQuestLab builds clean on net48",
          "DLL installed to the operator's BepInEx/plugins and hash-verified against the build output; starter.json written into comfy-quest-lab/quests and confirmed to parse with both seed quests",
          "PENDING in-game: a second lab_setup reporting the standing gallery instead of rebuilding"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808053831-lab-setup-no-longer-raises-a-second-gallery-thro",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T05:38:31.096Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L476",
        "sha256": "aa4572290f37739c13570c354dfc71080af5e2a502253e2e48596cf6cf477bf5"
      },
      "summary": "lab_setup is the command we tell newcomers to start with, which makes it the one they are most likely to re-run -- and re-running it silently stacked another 620 pieces on the existing gallery. That is the same failure that once let the piece count reach 1527 before anyone noticed a clear reporting zero. LabGalleryBuilder.StandingPieceCount() sweeps the mark the way Clear does; lab_setup now leaves a standing gallery alone, says how many pieces it found, and points at questlab_gallery clear or lab_target instead. It only sees loaded zones, so a gallery across the map reads as zero -- wrong in the safe direction, offering to build rather than refusing to.",
      "title": "lab_setup no longer raises a second gallery through the first",
      "updated_at": "2026-08-08T05:38:31.096Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808053831-lab-setup-no-longer-raises-a-second-gallery-thro"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T05:48:58.480Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808054858-combat-and-the-quest-lane-verified-in-a-live-val",
        "impact": "First in-game run of the quest lane. All four combat seams fired in one fight (OnDeath, Damage, RPC_Damage, Stagger), so combat joins harvest as witnessed. Startup logged '2 quests loaded (1 armed)' and the seeded quest completed twice on Greyling kills, with the Quests tab reporting fired-2-times and a live cooldown. The creature-naming fix showed correct: console printed $enemy_greyling with no prefab name beside it, because the token already contains Greyling. FOUND AND FIXED: the last-kill diagnostic read 'matched nothing' for a kill that matched fine but was on cooldown -- OnCreatureKilled returns empty for both cases -- which sends a creator to edit a target that was never wrong, the exact wrong-place-to-look failure the line exists to prevent. It now names the quest and the seconds remaining, deciding would-this-have-matched by dry-firing the real matcher.",
        "kind": "verification",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Combat and the quest lane verified in a live Valheim session; the run found a bug in the lab's own why-didnt-it-fire line",
        "verification": [
          "BepInEx log: '27/27 seams hooked, 2 quests loaded (1 armed)' then 'quest fired: First Blood' twice; no errors or warnings from ComfyQuestLab",
          "Quests tab screenshot: 2 loaded / 1 armed, First Blood armed with fired 2 times and re-arms in 22s, Punchwood dimmed carrying the verb explanation",
          "ComfyNetworkSense independently completed greyling_cull off the same kill from its own quest-view.json -- two mods, one linked contract, same verdict",
          "243 tests pass; DLL rebuilt and installed to the operator's plugins folder, hash-verified"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808054858-combat-and-the-quest-lane-verified-in-a-live-val",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-08T05:48:58.480Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L477",
        "sha256": "991362ec720a69fe7f1604d5c9816628ad0e5556ad59d178d6f2f607e316df43"
      },
      "summary": "First in-game run of the quest lane. All four combat seams fired in one fight (OnDeath, Damage, RPC_Damage, Stagger), so combat joins harvest as witnessed. Startup logged '2 quests loaded (1 armed)' and the seeded quest completed twice on Greyling kills, with the Quests tab reporting fired-2-times and a live cooldown. The creature-naming fix showed correct: console printed $enemy_greyling with no prefab name beside it, because the token already contains Greyling. FOUND AND FIXED: the last-kill diagnostic read 'matched nothing' for a kill that matched fine but was on cooldown -- OnCreatureKilled returns empty for both cases -- which sends a creator to edit a target that was never wrong, the exact wrong-place-to-look failure the line exists to prevent. It now names the quest and the seconds remaining, deciding would-this-have-matched by dry-firing the real matcher.",
      "title": "Combat and the quest lane verified in a live Valheim session; the run found a bug in the lab's own why-didnt-it-fire line",
      "updated_at": "2026-08-08T05:48:58.480Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808054858-combat-and-the-quest-lane-verified-in-a-live-val"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T06:09:29.960Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808060929-the-questlab-route-is-a-404-in-production-the-pu",
        "impact": "Chasing the container env var for the tome mount turned up three things. (1) /questlab returns 404 on the public origin: the running image is lumberjacks-gateway:m31-workbench-20260729-r2, pinned since 2026-08-01, and predates the route entirely -- so publishing questlab.html to the mount fixes nothing, and the earlier claim that this needed only an env var and a container recreate was wrong. It needs a Gateway image cut and promote. (2) The catalog's nav has been linking to that 404 since the questlab nav entry shipped; adding it to NAV_ROUTES today caught it, and because verify-live is Gate 4 the publish script now fails closed rather than shipping a page that links to a 404. (3) docker inspect shows lj-workbench carries no com.docker.compose.* labels, and no compose file exists in baseline, lumberjacks or isolate -- it was started by a bare docker run, so the only definition of a live public container was the container itself. Full spec captured in the Publish-WorkbenchAssets.ps1 header.",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The questlab route is a 404 in production, the publish lane is correctly blocked, and lj-workbench has no definition outside itself",
        "verification": [
          "curl against https://am4.tail8e749c.ts.net: questlab 404, workbench 200, health 200",
          "workbench-verify-live --pre-publish: 69 checks, 1 failed -- the questlab route -- proving the NAV_ROUTES addition catches a real live defect rather than being decoration",
          "docker inspect lj-workbench on homebase: no compose labels; image, entrypoint, ports, mount and all five env vars recorded in the script header"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260808060929-the-questlab-route-is-a-404-in-production-the-pu",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-08T06:09:29.960Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L478",
        "sha256": "1a65c93b71e66101dc8765973bf7922685c49a72c8f158fe031fd962d4b4eff7"
      },
      "summary": "Chasing the container env var for the tome mount turned up three things. (1) /questlab returns 404 on the public origin: the running image is lumberjacks-gateway:m31-workbench-20260729-r2, pinned since 2026-08-01, and predates the route entirely -- so publishing questlab.html to the mount fixes nothing, and the earlier claim that this needed only an env var and a container recreate was wrong. It needs a Gateway image cut and promote. (2) The catalog's nav has been linking to that 404 since the questlab nav entry shipped; adding it to NAV_ROUTES today caught it, and because verify-live is Gate 4 the publish script now fails closed rather than shipping a page that links to a 404. (3) docker inspect shows lj-workbench carries no com.docker.compose.* labels, and no compose file exists in baseline, lumberjacks or isolate -- it was started by a bare docker run, so the only definition of a live public container was the container itself. Full spec captured in the Publish-WorkbenchAssets.ps1 header.",
      "title": "The questlab route is a 404 in production, the publish lane is correctly blocked, and lj-workbench has no definition outside itself",
      "updated_at": "2026-08-08T06:09:29.960Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808060929-the-questlab-route-is-a-404-in-production-the-pu"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T06:17:27.725Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808061727-gateway-image-m31-questlab-20260808-r1-cut-and-r",
        "impact": "Cut a Gateway-only release (image m31-questlab-20260808-r1, still admitting the frozen mod m30-rolecontrol-20260723-r1) and rehearsed it locally rather than on the public origin. The route answered 200 where production 404s, X-QuestLab-Sha256 equalled the mounted file's digest -- proving it serves the mount and not the image copy -- and editing the mounted file changed the served digest with no restart, proving the mtime re-read. The onboarding, lab_target step and the hooked-vs-bound note all served. Two recreate traps recorded in the Publish-WorkbenchAssets header: the app reads a plain Urls config key that beats ASPNETCORE_URLS, and without it the host binds localhost inside the container -- status Up, Now listening in the log, no errors, and every request through the published port returns an empty reply. And the Postgres connection errors on startup are normal for this container, which carries no connection string and serves the static pages anyway. Promote-GatewayImage.ps1 cannot ship this: it targets comfy-p7 with a compose root, an environment file and a container name that do not exist on the AM4 host, and that VM is terminated. Delivery to lj-workbench has no tooling yet.",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Gateway image m31-questlab-20260808-r1 cut and rehearsed locally: the tome mount contract holds on a real image",
        "verification": [
          "New-GatewayReleaseCut: release identity confirmed from the shipped artifact -- image admits m30-rolecontrol-20260723-r1 read out of /app/Game.Gateway.dll, not bin/Release",
          "Local container on port 4100: health 200, questlab 200, workbench 200",
          "Mount precedence and hot re-read both proven by digest comparison before and after editing the mounted file; container and scratch mount removed afterwards"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260808061727-gateway-image-m31-questlab-20260808-r1-cut-and-r",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-08T06:17:27.725Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L479",
        "sha256": "cbd42c012ed9ca537bb75401cf358e9dfbb9cd211149fdb32a1b9d01bccf669a"
      },
      "summary": "Cut a Gateway-only release (image m31-questlab-20260808-r1, still admitting the frozen mod m30-rolecontrol-20260723-r1) and rehearsed it locally rather than on the public origin. The route answered 200 where production 404s, X-QuestLab-Sha256 equalled the mounted file's digest -- proving it serves the mount and not the image copy -- and editing the mounted file changed the served digest with no restart, proving the mtime re-read. The onboarding, lab_target step and the hooked-vs-bound note all served. Two recreate traps recorded in the Publish-WorkbenchAssets header: the app reads a plain Urls config key that beats ASPNETCORE_URLS, and without it the host binds localhost inside the container -- status Up, Now listening in the log, no errors, and every request through the published port returns an empty reply. And the Postgres connection errors on startup are normal for this container, which carries no connection string and serves the static pages anyway. Promote-GatewayImage.ps1 cannot ship this: it targets comfy-p7 with a compose root, an environment file and a container name that do not exist on the AM4 host, and that VM is terminated. Delivery to lj-workbench has no tooling yet.",
      "title": "Gateway image m31-questlab-20260808-r1 cut and rehearsed locally: the tome mount contract holds on a real image",
      "updated_at": "2026-08-08T06:17:27.725Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808061727-gateway-image-m31-questlab-20260808-r1-cut-and-r"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T06:26:52.904Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808062652-the-public-origin-gets-a-deploy-lane-in-isolate-",
        "impact": "Promote-GatewayImage.ps1 cannot serve the host that actually serves the public origin: it targets P7's compose root, environment file and container name, and that VM has been terminated since 2026-07-25. isolate now carries tools/am4/Deploy-GatewayImage.ps1, matching Deploy-NetworkSense.ps1 beside it -- BatchMode ssh, hash the artifact before and after transit, fail closed on mismatch, prove readiness against the real thing, emit a JSON receipt. It recreates rather than restarts because lj-workbench was started by a bare docker run with no compose labels and no compose file anywhere, so every field of that definition is now a parameter defaulted to the captured production value. Rollback reads the previous image tag before removing anything and restores it if /health, /workbench and /questlab do not all answer 200; when /questlab is required it also proves X-QuestLab-Sha256 equals the mounted file's digest, so a pass means the mount is genuinely what is served. Two traps encoded: the Gateway reads a plain Urls key that beats ASPNETCORE_URLS and without it binds localhost inside the container while looking healthy, and Postgres errors on startup are normal for this container so readiness is proven over HTTP.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The public origin gets a deploy lane, in isolate where PD-8 says deployment tooling belongs",
        "verification": [
          "Dry run against the live host: reads lj-workbench's current image as the rollback target and prints the exact run command without touching anything",
          "Parses clean under the PS 5.1 parser; pure ASCII and CRLF matching the sibling script, because an em dash in a double-quoted string is a parse error when 5.1 reads a BOM-less UTF-8 file as ANSI",
          "Landed in isolate at 351aa58; baseline's stale pointer to Promote-GatewayImage.ps1 corrected in both START-HERE and the publish script"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260808062652-the-public-origin-gets-a-deploy-lane-in-isolate-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T06:26:52.904Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L480",
        "sha256": "f316708557a39c926d5ba6d5d30ca4976c1d0052c692a5e49a856534a694df00"
      },
      "summary": "Promote-GatewayImage.ps1 cannot serve the host that actually serves the public origin: it targets P7's compose root, environment file and container name, and that VM has been terminated since 2026-07-25. isolate now carries tools/am4/Deploy-GatewayImage.ps1, matching Deploy-NetworkSense.ps1 beside it -- BatchMode ssh, hash the artifact before and after transit, fail closed on mismatch, prove readiness against the real thing, emit a JSON receipt. It recreates rather than restarts because lj-workbench was started by a bare docker run with no compose labels and no compose file anywhere, so every field of that definition is now a parameter defaulted to the captured production value. Rollback reads the previous image tag before removing anything and restores it if /health, /workbench and /questlab do not all answer 200; when /questlab is required it also proves X-QuestLab-Sha256 equals the mounted file's digest, so a pass means the mount is genuinely what is served. Two traps encoded: the Gateway reads a plain Urls key that beats ASPNETCORE_URLS and without it binds localhost inside the container while looking healthy, and Postgres errors on startup are normal for this container so readiness is proven over HTTP.",
      "title": "The public origin gets a deploy lane, in isolate where PD-8 says deployment tooling belongs",
      "updated_at": "2026-08-08T06:26:52.904Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808062652-the-public-origin-gets-a-deploy-lane-in-isolate-"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T06:35:49.436Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808063549-the-quest-lab-is-live-tome-download-and-all-and-",
        "impact": "Cut m31-questlab-20260808-r1, shipped it to AM4 with the new isolate deploy lane, recreated lj-workbench on it, and published. The download streams 74949 bytes at d49a20db and /questlab serves the real tome from the mount with X-QuestLab-Sha256 equal to the committed file. THE ACTUAL BLOCKER was neither the image nor the publish: Tailscale Funnel sends / to Caddy on 8190, and Caddy forwards a deliberate allowlist of paths to the Gateway, answering an honest 404 for everything else so that /ops/* is never funneled. The container answered /questlab correctly for twelve minutes while the origin still 404d. Adding /questlab to the @public matcher and reloading was the fix; the boundary was re-checked afterwards and still holds, /ops/* 403 and unmatched 404. That Caddyfile is host-only config carrying bcrypt credentials, so only the mechanism is documented, in START-HERE, in the publish script header, and in the deploy lane README where somebody adding a route will actually look. Also learned: questlab.html and workbench.html are not baked into the image at all -- both have always been served from the mount, and the fallback page is what /questlab served in the gap.",
        "kind": "deployment",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The Quest Lab is live: tome, download and all, and the last blocker was a Caddy allowlist nobody had written down",
        "verification": [
          "verify-live post-publish PASS: 82 checks, 0 failed, including quest-lab download streams, size, digest and X-Download-Sha256",
          "All ten public routes answer 200 through the funnel; /ops/anything still 403 and /nonsense still 404 after the allowlist change",
          "Served /questlab digest equals the committed questlab.html; Start here, lab_target and all eight Worth knowing sections present; no fallback markers",
          "Deploy receipt at captures/am4-gateway-deploy.json: archive hash verified remote-side before load, image digest matched local, rollback target recorded as m31-workbench-20260729-r2"
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260808063549-the-quest-lab-is-live-tome-download-and-all-and-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-08-08T06:35:49.436Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L481",
        "sha256": "c312d37bcf0e884e2fce3d006a9585fc9564a5aabe1f3ae73a3c52601f98c805"
      },
      "summary": "Cut m31-questlab-20260808-r1, shipped it to AM4 with the new isolate deploy lane, recreated lj-workbench on it, and published. The download streams 74949 bytes at d49a20db and /questlab serves the real tome from the mount with X-QuestLab-Sha256 equal to the committed file. THE ACTUAL BLOCKER was neither the image nor the publish: Tailscale Funnel sends / to Caddy on 8190, and Caddy forwards a deliberate allowlist of paths to the Gateway, answering an honest 404 for everything else so that /ops/* is never funneled. The container answered /questlab correctly for twelve minutes while the origin still 404d. Adding /questlab to the @public matcher and reloading was the fix; the boundary was re-checked afterwards and still holds, /ops/* 403 and unmatched 404. That Caddyfile is host-only config carrying bcrypt credentials, so only the mechanism is documented, in START-HERE, in the publish script header, and in the deploy lane README where somebody adding a route will actually look. Also learned: questlab.html and workbench.html are not baked into the image at all -- both have always been served from the mount, and the fallback page is what /questlab served in the gap.",
      "title": "The Quest Lab is live: tome, download and all, and the last blocker was a Caddy allowlist nobody had written down",
      "updated_at": "2026-08-08T06:35:49.436Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808063549-the-quest-lab-is-live-tome-download-and-all-and-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T10:12:16.837Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808101216-the-selfie-stick-goes-indoors-a-feature-scan-fin",
        "impact": "The gallery can show the builds the way their builders saw them - from the hall floor, the throne, the gatehouse - not only from a drone orbit",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The selfie stick goes indoors: a feature scan finds each build's rooms, seats, gates and windows, and an interior planner composes eye-level shots through sunrise, sunset, starry night and storm",
        "verification": [
          "Three pilot runs on clusters 439/71/407: 52/52 frames captured, 0 occluded, 0 skipped; seat lens offset fell from 17 m (inside a throne collider) to 1.8 m; frames reviewed by eye"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260808101216-the-selfie-stick-goes-indoors-a-feature-scan-fin",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T10:12:16.837Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L482",
        "sha256": "504f597bccc079568bd864ef251871c40de52bcf9546eb7e5bad8a78ce1990b8"
      },
      "summary": "The gallery can show the builds the way their builders saw them - from the hall floor, the throne, the gatehouse - not only from a drone orbit",
      "title": "The selfie stick goes indoors: a feature scan finds each build's rooms, seats, gates and windows, and an interior planner composes eye-level shots through sunrise, sunset, starry night and storm",
      "updated_at": "2026-08-08T10:12:16.837Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808101216-the-selfie-stick-goes-indoors-a-feature-scan-fin"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T11:20:46.168Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808112046-quest-lab-normalizes-the-91-row-atlas-into-an-ex",
        "impact": "The assembly atlas now has an enforced interpretation layer: 91 category rows normalize to 90 exact Valheim signatures and 77 method IDs, every method is explicitly classified, and 43 raw meanings collapse into 34 stable creator-safe event candidates with route, profile, actor boundary, and dedupe policy. The generated JSON manifest preserves overload identity and the dual-school Player.OnDeath row; the generated C# catalog keeps legacy method-ID lookups while exposing exact signatures. Existing runtime truth remains honest: 26 atlas integrations and two UI support hooks are reported separately, and only kill is called bindable until evaluator and witness work lands.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab normalizes the 91-row atlas into an exact creator-event capability contract",
        "verification": [
          "generate_seam_catalog.py --check: 91 rows / 90 signatures / 77 methods / 34 creator events; 8 capability tests pass including a mutation that removes Chat.OnNewChatMessage policy and turns the guard red; check_lab_patches.py: 26 atlas integrations and 2 support hooks resolve against 90 exact signatures; ComfyQuestLab Release build: 0 warnings, 0 errors; full repository unittest discovery reached 33 tests with only 3 pre-existing guest-package checks excluded by the intentionally running OMEN Valheim process, which was not disturbed"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808112046-quest-lab-normalizes-the-91-row-atlas-into-an-ex",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T11:20:46.168Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L483",
        "sha256": "d01220673ea5caba1584d73cf6d39964bfc8970639f4081e31b063dbd0f90dc8"
      },
      "summary": "The assembly atlas now has an enforced interpretation layer: 91 category rows normalize to 90 exact Valheim signatures and 77 method IDs, every method is explicitly classified, and 43 raw meanings collapse into 34 stable creator-safe event candidates with route, profile, actor boundary, and dedupe policy. The generated JSON manifest preserves overload identity and the dual-school Player.OnDeath row; the generated C# catalog keeps legacy method-ID lookups while exposing exact signatures. Existing runtime truth remains honest: 26 atlas integrations and two UI support hooks are reported separately, and only kill is called bindable until evaluator and witness work lands.",
      "title": "Quest Lab normalizes the 91-row atlas into an exact creator-event capability contract",
      "updated_at": "2026-08-08T11:20:46.168Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808112046-quest-lab-normalizes-the-91-row-atlas-into-an-ex"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T11:33:13.316Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808113313-the-shared-quest-contract-becomes-event-shaped-w",
        "impact": "ComfyNetworkSense and Quest Lab now source-link one Unity-free QuestEvent envelope, generated 34-event catalog, additive scalar trigger.where parser, and generic QuestTriggerEvaluator.OnEvent path. OnCreatureKilled remains a compatibility wrapper, kill behavior is unchanged, and the published hit verb is preserved as an alias spanning damage_dealt and resource_damaged. A caller-supplied action key deduplicates local/RPC or overload witnesses independently of per-quest cooldown, including cooldown zero. Unknown and diagnostic-only events cannot bind. The runtime still forwards only the witnessed kill lane; contract capability is documented separately from in-game proof.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The shared quest contract becomes event-shaped without breaking schema-1 kill and hit quests",
        "verification": [
          "ComfyNetworkSense.Tests Release: 258 passed, 0 failed, including one test per safe event, schema-1 fixture compatibility, scalar where rejection boundaries, broad hit alias behavior, and zero-cooldown duplicate suppression; ComfyNetworkSense Release build: 0 warnings, 0 errors; ComfyQuestLab Release build: 0 warnings, 0 errors; capability generator --check confirms 91 rows / 90 signatures / 77 methods / 34 creator events; patch checker confirms 26 atlas integrations plus 2 support hooks resolve"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808113313-the-shared-quest-contract-becomes-event-shaped-w",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T11:33:13.316Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L484",
        "sha256": "738c7a0882b4d1958f07024ae306c04a8bf24a056e48c7a76ea0ecd25cfc48c9"
      },
      "summary": "ComfyNetworkSense and Quest Lab now source-link one Unity-free QuestEvent envelope, generated 34-event catalog, additive scalar trigger.where parser, and generic QuestTriggerEvaluator.OnEvent path. OnCreatureKilled remains a compatibility wrapper, kill behavior is unchanged, and the published hit verb is preserved as an alias spanning damage_dealt and resource_damaged. A caller-supplied action key deduplicates local/RPC or overload witnesses independently of per-quest cooldown, including cooldown zero. Unknown and diagnostic-only events cannot bind. The runtime still forwards only the witnessed kill lane; contract capability is documented separately from in-game proof.",
      "title": "The shared quest contract becomes event-shaped without breaking schema-1 kill and hit quests",
      "updated_at": "2026-08-08T11:33:13.316Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808113313-the-shared-quest-contract-becomes-event-shaped-w"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T12:02:20.004Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808120220-quest-lab-routes-all-86-practical-atlas-signatur",
        "impact": "Every creator-safe Valheim witness now enters one canonical QuestEvent route shared with ComfyNetworkSense: 57 safe signatures normalize to 34 bindable events across all eight schools. Local/RPC and overload alternatives receive one tested action key before evaluation, including cooldown zero. The diagnostic profile exposes the other 29 practical witnesses without ever binding them; four query/cheat signatures remain explicitly disabled. The in-game spellbook, web tome, README, workbench card, and exact patch guard now distinguish integrated code from live witness evidence.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab routes all 86 practical atlas signatures through stable profile-gated events",
        "verification": [
          "ComfyNetworkSense.Tests Release: 274 passed, 0 failed; ComfyQuestLab and ComfyNetworkSense Release builds: 0 warnings, 0 errors; capability generator: 91 rows / 90 signatures / 77 methods / 34 creator events; patch guard: 57/57 creator-safe and 86/86 practical exact signatures, 4 intentionally disabled; capability pytest: 10 passed plus 10 subtests including missing-patch mutation; Workbench check and 29 generator tests pass"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808120220-quest-lab-routes-all-86-practical-atlas-signatur",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T12:02:20.004Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L485",
        "sha256": "5c4d09080b16e69587d3abdf862ac5021129e8eabe24c2e1817549d077d47065"
      },
      "summary": "Every creator-safe Valheim witness now enters one canonical QuestEvent route shared with ComfyNetworkSense: 57 safe signatures normalize to 34 bindable events across all eight schools. Local/RPC and overload alternatives receive one tested action key before evaluation, including cooldown zero. The diagnostic profile exposes the other 29 practical witnesses without ever binding them; four query/cheat signatures remain explicitly disabled. The in-game spellbook, web tome, README, workbench card, and exact patch guard now distinguish integrated code from live witness evidence.",
      "title": "Quest Lab routes all 86 practical atlas signatures through stable profile-gated events",
      "updated_at": "2026-08-08T12:02:20.004Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808120220-quest-lab-routes-all-86-practical-atlas-signatur"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T12:19:13.187Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808121913-quest-lab-gallery-v2-adds-generated-marble-profi",
        "impact": "Creators can choose classic, marble-wide, or marble-grand; build comparisons carry durable profile/build marks and can be identified, selectively cleared, or rebuilt without touching unmarked world objects.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab Gallery v2 adds generated marble profiles and safe comparison lifecycle",
        "verification": [
          "ComfyQuestLab Release build: 0 warnings/errors; 7 Gallery v2 Python drift tests; 274 shared .NET tests; generate_gallery.py --check reports 3 profiles and 3,458 known prefabs."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808121913-quest-lab-gallery-v2-adds-generated-marble-profi",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T12:19:13.187Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L486",
        "sha256": "01220ae876cf77a949f25cfa77d32e8951b23d60bd61ec0884c7b20f33e1142c"
      },
      "summary": "Creators can choose classic, marble-wide, or marble-grand; build comparisons carry durable profile/build marks and can be identified, selectively cleared, or rebuilt without touching unmarked world objects.",
      "title": "Quest Lab Gallery v2 adds generated marble profiles and safe comparison lifecycle",
      "updated_at": "2026-08-08T12:19:13.187Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808121913-quest-lab-gallery-v2-adds-generated-marble-profi"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T12:28:18.501Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808122818-make-discord-dispatches-authoritative-and-projec",
        "impact": "Baseline now offers eight combinable entry views for curious visitors, players, creators, community leads, operators, modders, developers, and contributors. Story sidecars, the Workbench catalog, the append-only roadmap, and Discord starter posts retain their native authority; a deterministic, source-hashed index accelerates role pages, exploration, RSS, and JSON Feed and can be discarded and rebuilt. The live Workbench exposes the same lens switchboard and links the separate dispatch forum without repurposing general conversation or support threads.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make Discord dispatches authoritative and project the public corpus through audience lenses",
        "verification": [
          "Corpus contract tests 5/5; Workbench tests 31/31; Workbench Discord self-test 95/95; dispatch contract self-test; live Discord plan converged to NOOP for #dispatches 1535624779418181703; desktop and responsive screenshots reviewed"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260808122818-make-discord-dispatches-authoritative-and-projec",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T12:28:18.501Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L487",
        "sha256": "a4e698a0a6dfd4619952853e2bea669fd3f731b0cdc42fc9e0caaa7f8a5d71b6"
      },
      "summary": "Baseline now offers eight combinable entry views for curious visitors, players, creators, community leads, operators, modders, developers, and contributors. Story sidecars, the Workbench catalog, the append-only roadmap, and Discord starter posts retain their native authority; a deterministic, source-hashed index accelerates role pages, exploration, RSS, and JSON Feed and can be discarded and rebuilt. The live Workbench exposes the same lens switchboard and links the separate dispatch forum without repurposing general conversation or support threads.",
      "title": "Make Discord dispatches authoritative and project the public corpus through audience lenses",
      "updated_at": "2026-08-08T12:28:18.501Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808122818-make-discord-dispatches-authoritative-and-projec"
    },
    {
      "audiences": [
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T12:29:23.991Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808122923-publish-the-audience-aware-workbench-from-commit",
        "impact": "The generated Workbench now carries a production provenance stamp for the committed audience vocabulary, catalog, and renderer instead of a preview stamp. The companion corpus projections were rebuilt after the deployment record, keeping the public index and roadmap adapter byte-current with their authoritative journal.",
        "kind": "deployment",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Publish the audience-aware Workbench from committed source inputs",
        "verification": [
          "workbench:check passes from clean provenance inputs; corpus --check passes after the deployment note; generated Workbench contains eight role lenses and the live #dispatches link"
        ]
      },
      "facets": {
        "kind": "deployment",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260808122923-publish-the-audience-aware-workbench-from-commit",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-08-08T12:29:23.991Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L488",
        "sha256": "3b5f187557a862754537c9cb75203bcc24ea9addc8647cfa18b84cddfd8813e7"
      },
      "summary": "The generated Workbench now carries a production provenance stamp for the committed audience vocabulary, catalog, and renderer instead of a preview stamp. The companion corpus projections were rebuilt after the deployment record, keeping the public index and roadmap adapter byte-current with their authoritative journal.",
      "title": "Publish the audience-aware Workbench from committed source inputs",
      "updated_at": "2026-08-08T12:29:23.991Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808122923-publish-the-audience-aware-workbench-from-commit"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T12:33:33.036Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808123333-interior-full-run-436-436-frames-over-25-builds-",
        "impact": "Curation is now measured instead of vibes: a depth veto catches camera-against-wall frames with zero keeper loss, and the notebook lets the operator move thresholds and watch winners reorder",
        "kind": "verification",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Interior full run: 436/436 frames over 25 builds, and the scoring bench grew instruments - depth-layer geometry (Depth Anything V2), a VLM judge lane, and a marimo curation notebook with frames inline in the dataframe",
        "verification": [
          "12 hand-labelled pilot frames: LAION 36/36 keeper-vs-dud pairs, depth veto fires on exactly the two geometric duds; full run 424 indexed frames, 527 depth-measured; judge measured compressing to a constant 8.0 and documented as such"
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260808123333-interior-full-run-436-436-frames-over-25-builds-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-08T12:33:33.036Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L489",
        "sha256": "ac7e1fc848912dce7f65f250b16da44cbbac74753c00a64c62d9947417243755"
      },
      "summary": "Curation is now measured instead of vibes: a depth veto catches camera-against-wall frames with zero keeper loss, and the notebook lets the operator move thresholds and watch winners reorder",
      "title": "Interior full run: 436/436 frames over 25 builds, and the scoring bench grew instruments - depth-layer geometry (Depth Anything V2), a VLM judge lane, and a marimo curation notebook with frames inline in the dataframe",
      "updated_at": "2026-08-08T12:33:33.036Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808123333-interior-full-run-436-436-frames-over-25-builds-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T12:46:38.006Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808124638-quest-lab-gains-bounded-self-service-suites-and-",
        "impact": "Creators can prepare, run, reset, report, and export all-school live evidence or an explicitly synthetic 34-event contract check; the i5 lane accepts only ten expiring allowlisted suite/gallery operations and no console or keystroke input.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab gains bounded self-service suites and i5 receipts",
        "verification": [
          "281 shared .NET tests; 47 Python repository tests; 57/57 safe and 86/86 practical patch coverage; ComfyQuestLab Release build 0 warnings/errors; privacy-clean local package sha256 09d5f2e19d9ca134df7132356007319e4bfbe27e3c0a7ea5fd9e98de9535c7bc."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808124638-quest-lab-gains-bounded-self-service-suites-and-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T12:46:38.006Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L490",
        "sha256": "def678963bfd533a06f2066cde567fb634c49ce91d8d4a2a4166e2b194dadc0a"
      },
      "summary": "Creators can prepare, run, reset, report, and export all-school live evidence or an explicitly synthetic 34-event contract check; the i5 lane accepts only ten expiring allowlisted suite/gallery operations and no console or keystroke input.",
      "title": "Quest Lab gains bounded self-service suites and i5 receipts",
      "updated_at": "2026-08-08T12:46:38.006Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808124638-quest-lab-gains-bounded-self-service-suites-and-"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T12:55:51.979Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808125551-part-2-of-the-selfie-stick-article-ships-standin",
        "impact": "The interior lane has a public story: five vantage recipes, the throne that threw the camera, four skies over one hall, and the instruments that curate without consenting on anyone's behalf",
        "kind": "documentation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Part 2 of the selfie-stick article ships: Standing where the builders stood - framing, perspective and judgement sharpening, linked from part 1",
        "verification": [
          "Page built self-contained (0.83 MB ascii), rendered and scrolled end to end locally; part 1 rebuilt with the part-2 link and an exterior-only curation guard; no coordinates or creator ids in either page"
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260808125551-part-2-of-the-selfie-stick-article-ships-standin",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-08T12:55:51.979Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L491",
        "sha256": "c73b9eb3c0834bfb769ff0879b3de54290a1f1b917ce26abbb3f5a5aadce3767"
      },
      "summary": "The interior lane has a public story: five vantage recipes, the throne that threw the camera, four skies over one hall, and the instruments that curate without consenting on anyone's behalf",
      "title": "Part 2 of the selfie-stick article ships: Standing where the builders stood - framing, perspective and judgement sharpening, linked from part 1",
      "updated_at": "2026-08-08T12:55:51.979Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808125551-part-2-of-the-selfie-stick-article-ships-standin"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T12:58:47.498Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808125847-quest-lab-cuts-an-identifiable-0-2-0-creator-pac",
        "impact": "The downloadable build now carries one version and release id through plugin, assembly and package manifests; its canonical BepInEx config has all section headers and every bound setting, and the bundled README gives exact install and update paths instead of requiring maintainer help.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab cuts an identifiable 0.2.0 creator package",
        "verification": [
          "10 package/i5 helper tests pass; ComfyQuestLab Release build has 0 warnings/errors and assembly version 0.2.0.0; privacy-clean zip reports questlab-v0.2.0-20260808-r1; i5 SHA verification matched DLL 7c023ac6e7a3 and config 88a9d5b35077."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808125847-quest-lab-cuts-an-identifiable-0-2-0-creator-pac",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T12:58:47.498Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L492",
        "sha256": "126758319f2ebef640421b1e16cc1b92ddf797266b931684002e1c5765b48e86"
      },
      "summary": "The downloadable build now carries one version and release id through plugin, assembly and package manifests; its canonical BepInEx config has all section headers and every bound setting, and the bundled README gives exact install and update paths instead of requiring maintainer help.",
      "title": "Quest Lab cuts an identifiable 0.2.0 creator package",
      "updated_at": "2026-08-08T12:58:47.498Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808125847-quest-lab-cuts-an-identifiable-0-2-0-creator-pac"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T13:07:48.660Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808130748-quest-lab-live-course-now-starts-from-zero-inven",
        "impact": "The all-schools batch stages Wood, Coal and Copper Ore at the player's feet and names the exact central tools and rune stations in every prompt, so a fresh creator can execute the eight-school witness run without prior inventory or Derek's directions.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab live course now starts from zero inventory",
        "verification": [
          "282 shared .NET tests pass; ComfyQuestLab Release build has 0 warnings/errors; privacy-clean r2 package built; i5 remotely rehashed the r2 DLL at a5144d273705 before Valheim start."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808130748-quest-lab-live-course-now-starts-from-zero-inven",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T13:07:48.660Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L493",
        "sha256": "7de889e938f7c1ac4431397bb8c942cb5845a0251417c256b0fe7cc5a1b47109"
      },
      "summary": "The all-schools batch stages Wood, Coal and Copper Ore at the player's feet and names the exact central tools and rune stations in every prompt, so a fresh creator can execute the eight-school witness run without prior inventory or Derek's directions.",
      "title": "Quest Lab live course now starts from zero inventory",
      "updated_at": "2026-08-08T13:07:48.660Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808130748-quest-lab-live-course-now-starts-from-zero-inven"
    },
    {
      "audiences": [
        "curious",
        "contributor",
        "developer"
      ],
      "data": {
        "at": "2026-08-08T13:20:52.039Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808132052-quest-lab-tome-teaches-the-expanded-creator-even",
        "impact": "The in-game spellbook and web Tome no longer repeat scaffold-era claims that only kills or combat can bind. All eight pages now distinguish stable canonical actions from diagnostic/query witnesses, name compatibility aliases and action coalescing where relevant, and regenerate from one authoritative prose source.",
        "kind": "documentation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab Tome teaches the expanded creator-event contract",
        "verification": [
          "Journal and web generators now support --check; both generated artifacts are current; 11 capability/tome drift tests pass and explicitly reject the retired scaffold claims."
        ]
      },
      "facets": {
        "kind": "documentation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808132052-quest-lab-tome-teaches-the-expanded-creator-even",
      "kind": "roadmap-note",
      "primary_audiences": [
        "curious"
      ],
      "published_at": "2026-08-08T13:20:52.039Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L494",
        "sha256": "8444957ab9b0b169898dc73c7c11bcec6f3a6caa32f4595d0625bd5c4df88616"
      },
      "summary": "The in-game spellbook and web Tome no longer repeat scaffold-era claims that only kills or combat can bind. All eight pages now distinguish stable canonical actions from diagnostic/query witnesses, name compatibility aliases and action coalescing where relevant, and regenerate from one authoritative prose source.",
      "title": "Quest Lab Tome teaches the expanded creator-event contract",
      "updated_at": "2026-08-08T13:20:52.039Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808132052-quest-lab-tome-teaches-the-expanded-creator-even"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T13:28:49.104Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808132849-the-gallery-learns-its-instruments-perspective-f",
        "impact": "The live gallery now carries the interior corpus and stops showing 87 whiteout duds by default, while the public index no longer serves builder coordinates or creator ids",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "The gallery learns its instruments: perspective facet (drone / eye level / seated), fog whiteouts measured and hidden behind a counted toggle, depth and judge readings in the lightbox, and a scripted deploy that scrubs coordinates before anything ships",
        "verification": [
          "Fog rule calibrated 10/10 whiteouts vs 0/7 bright controls with wide margin; local and live checks: 1772 of 1859 default view, facet counts drone 1435 / eye level 332 / seated 92, instruments render in lightbox, deployed index grep-verified free of top_creator_id"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260808132849-the-gallery-learns-its-instruments-perspective-f",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T13:28:49.104Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L495",
        "sha256": "d61dffbc4009ee8542ffc337ef1086580c7505e2960f944a1804031a45e857c6"
      },
      "summary": "The live gallery now carries the interior corpus and stops showing 87 whiteout duds by default, while the public index no longer serves builder coordinates or creator ids",
      "title": "The gallery learns its instruments: perspective facet (drone / eye level / seated), fog whiteouts measured and hidden behind a counted toggle, depth and judge readings in the lightbox, and a scripted deploy that scrubs coordinates before anything ships",
      "updated_at": "2026-08-08T13:28:49.104Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808132849-the-gallery-learns-its-instruments-perspective-f"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T14:18:46.223Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808141846-quest-lab-live-pass-closes-gallery-ownership-and",
        "impact": "The first complete OMEN all-schools run proved 8/8 events and quests with 47 coalesced witnesses and zero same-action doubles, then exposed two release blockers: clear counted unowned uninstantiated ZDO deletes that Valheim ignored, and prepare trusted a standing gallery whose Greyling had already been consumed. r4 claims only mark-validated ZDOs before deletion, refreshes Greyling and birch targets in the bounded prepare operation, pins every gallery receipt to plugin/release identity, and suppresses stale unrelated suite paths on gallery receipts.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab live pass closes gallery ownership and consumable target gaps",
        "verification": [
          "282 shared .NET tests; focused Gallery/release verifier tests; ComfyQuestLab Release build 0 warnings/errors; r4 OMEN lifecycle re-witness pending in the same live block."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808141846-quest-lab-live-pass-closes-gallery-ownership-and",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T14:18:46.223Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L496",
        "sha256": "32447f1716d5cadfd6f1e701474d34c3a670f494283da24af123e5057e9504f0"
      },
      "summary": "The first complete OMEN all-schools run proved 8/8 events and quests with 47 coalesced witnesses and zero same-action doubles, then exposed two release blockers: clear counted unowned uninstantiated ZDO deletes that Valheim ignored, and prepare trusted a standing gallery whose Greyling had already been consumed. r4 claims only mark-validated ZDOs before deletion, refreshes Greyling and birch targets in the bounded prepare operation, pins every gallery receipt to plugin/release identity, and suppresses stale unrelated suite paths on gallery receipts.",
      "title": "Quest Lab live pass closes gallery ownership and consumable target gaps",
      "updated_at": "2026-08-08T14:18:46.223Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808141846-quest-lab-live-pass-closes-gallery-ownership-and"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T14:49:57.704Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808144957-quest-lab-gallery-r5-adopts-the-grand-creator-co",
        "impact": "Derek's live side-by-side review selected marble-grand. The generated default now raises its solid-marble deck three metres over the highest sampled terrain, widens creators into the selected 10 m halls, and places one horizontal school-name header above each monumental glowing rune. Profile metadata, safe batch defaults, counts, previews, runtime reporting, and creator documentation all derive from the same plan.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab Gallery r5 adopts the grand creator court",
        "verification": [
          "ComfyQuestLab Release build: 0 warnings/errors; 282 shared .NET tests pass; 65 Python guards pass; generated plan check is current; OMEN exact-r5 visual and lifecycle receipt pass follows after deploy."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808144957-quest-lab-gallery-r5-adopts-the-grand-creator-co",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T14:49:57.704Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L497",
        "sha256": "ba7e3bf960c4230898a3cd4746cede68f20e434a591a3eeaee6b45e314d5a5ad"
      },
      "summary": "Derek's live side-by-side review selected marble-grand. The generated default now raises its solid-marble deck three metres over the highest sampled terrain, widens creators into the selected 10 m halls, and places one horizontal school-name header above each monumental glowing rune. Profile metadata, safe batch defaults, counts, previews, runtime reporting, and creator documentation all derive from the same plan.",
      "title": "Quest Lab Gallery r5 adopts the grand creator court",
      "updated_at": "2026-08-08T14:49:57.704Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808144957-quest-lab-gallery-r5-adopts-the-grand-creator-co"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T15:25:14.734Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808152514-quest-lab-r6-makes-the-gallery-labels-and-creato",
        "impact": "Derek's exact-r5 screenshots showed whole school names wrapping vertically on one-metre Valheim signs and the panel reading as a translucent non-interactive overlay. r6 generates each school name as a centred horizontal row of one-letter signs with one coloured light per word, while the panel gains explicit cursor/input ownership, a 97-percent opaque surface, larger type and default dimensions, a five-column event grid, visible Close control, and bounded drag resizing without adding Jotunn.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab r6 makes the gallery labels and creator panel readable",
        "verification": [
          "ComfyQuestLab Release build: 0 warnings/errors; 282 shared .NET tests pass; 71 Python guards pass, including new input lifecycle, contrast, grid, resize and generated-header checks; exact-r6 OMEN visual pass follows after SHA-verified deploy."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808152514-quest-lab-r6-makes-the-gallery-labels-and-creato",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T15:25:14.734Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L498",
        "sha256": "3f2667a1f42e1b4c8d150c94bd620072ba8377c58149d4ace507c83639e7cfb2"
      },
      "summary": "Derek's exact-r5 screenshots showed whole school names wrapping vertically on one-metre Valheim signs and the panel reading as a translucent non-interactive overlay. r6 generates each school name as a centred horizontal row of one-letter signs with one coloured light per word, while the panel gains explicit cursor/input ownership, a 97-percent opaque surface, larger type and default dimensions, a five-column event grid, visible Close control, and bounded drag resizing without adding Jotunn.",
      "title": "Quest Lab r6 makes the gallery labels and creator panel readable",
      "updated_at": "2026-08-08T15:25:14.734Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808152514-quest-lab-r6-makes-the-gallery-labels-and-creato"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T15:36:59.223Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808153659-quest-lab-r7-makes-gallery-sites-reusable",
        "impact": "Console clear, bounded batch clear, and rebuild now return a player standing on the selected raised Gallery to verified natural terrain at the same X/Z before deleting any marked object. A refused, incomplete, or unverifiable terrain handoff leaves the build standing, so creators can clear and rebuild repeatedly on one site without scouting new ground or remembering a portal exit.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab r7 makes Gallery sites reusable",
        "verification": [
          "ComfyQuestLab Release build: 0 warnings/errors; 282 shared .NET tests pass; 73 Python repository guards pass; generated Gallery profile check is current; exact-r7 OMEN lifecycle witness follows after SHA-verified deploy."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808153659-quest-lab-r7-makes-gallery-sites-reusable",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T15:36:59.223Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L499",
        "sha256": "934abc25f58b0acb68b5d1a1e2a9d17c0b53a41e540248aeb2acc1191f28b5a7"
      },
      "summary": "Console clear, bounded batch clear, and rebuild now return a player standing on the selected raised Gallery to verified natural terrain at the same X/Z before deleting any marked object. A refused, incomplete, or unverifiable terrain handoff leaves the build standing, so creators can clear and rebuild repeatedly on one site without scouting new ground or remembering a portal exit.",
      "title": "Quest Lab r7 makes Gallery sites reusable",
      "updated_at": "2026-08-08T15:36:59.223Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808153659-quest-lab-r7-makes-gallery-sites-reusable"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T16:19:10.220Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808161910-quest-lab-r8-compresses-the-creator-course-and-a",
        "impact": "Derek's 4K review is now encoded as a persistent 65-200% whole-panel zoom, while the selected marble-grand court keeps its 10 m halls, 3 m terrain clearance, monumental lit runes, and horizontal headers but cuts hub-to-station walks from 37 m to 9 m. lab_setup and all-schools preparation safely clear every marked old build before raising a fresh 1,349-object course with the birch, Greyling, sign, tools, arrows, food, building material, and smelter coal at point of use. Queued clear destroys receive a bounded settle check so request receipts cannot pass early.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab r8 compresses the creator course and adds resolution-independent panel zoom",
        "verification": [
          "282 source-shared .NET tests and 75 repository Python tests pass; ComfyQuestLab Release builds against the installed Valheim assembly with 0 warnings/errors.",
          "Atlas and patch guards confirm 91 rows / 90 signatures, 57/57 creator-safe and 86/86 practical runtime coverage; Gallery and Tome generators are current; 31 Workbench tests and both Workbench/Roadmap checks pass.",
          "Privacy-clean r8 package contains release id questlab-v0.2.0-20260808-r8, DLL SHA256 02f72efe35c77be2138c5db7b8133af4e3d0c55d885458de117ada54afea3e48; exact-r8 OMEN visual and suite receipts follow after SHA-verified deploy."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808161910-quest-lab-r8-compresses-the-creator-course-and-a",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T16:19:10.220Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L500",
        "sha256": "05f1c43a4c67174f58a7bf7a25378974f8617aab79a722a5072e4181f92f9ef8"
      },
      "summary": "Derek's 4K review is now encoded as a persistent 65-200% whole-panel zoom, while the selected marble-grand court keeps its 10 m halls, 3 m terrain clearance, monumental lit runes, and horizontal headers but cuts hub-to-station walks from 37 m to 9 m. lab_setup and all-schools preparation safely clear every marked old build before raising a fresh 1,349-object course with the birch, Greyling, sign, tools, arrows, food, building material, and smelter coal at point of use. Queued clear destroys receive a bounded settle check so request receipts cannot pass early.",
      "title": "Quest Lab r8 compresses the creator course and adds resolution-independent panel zoom",
      "updated_at": "2026-08-08T16:19:10.220Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808161910-quest-lab-r8-compresses-the-creator-course-and-a"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T16:32:35.389Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808163235-quest-lab-r9-anchors-rebuilds-to-terrain-after-t",
        "impact": "The exact-r8 OMEN reset proved that a zero marked-ZDO count can precede Unity collider retirement: the replacement deck stacked 18.1 m high and its ground portal caused a fatal fall. r9 samples terrain-only for the platform and return portal, refuses placement when terrain cannot be resolved, and gives retired GameObjects two quiescence frames before rebuilding so the reusable-site loop no longer trusts transient solids.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab r9 anchors rebuilds to terrain after the fatal r8 portal stack",
        "verification": [
          "Exact-r8 receipt cleared 3,668 marked objects and raised 1,349 before exposing the 18.1 m stack; 282 shared .NET tests and 76 repository Python tests pass; ComfyQuestLab Release build has 0 warnings/errors; atlas, patch, Gallery, Tome, and roadmap generators/checks are current; exact-r9 OMEN lifecycle and visual witness follows after SHA-verified deploy."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808163235-quest-lab-r9-anchors-rebuilds-to-terrain-after-t",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T16:32:35.389Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L501",
        "sha256": "826467ec98c7563562853952df35db97db18460d0abef2dfb462349e23ab7025"
      },
      "summary": "The exact-r8 OMEN reset proved that a zero marked-ZDO count can precede Unity collider retirement: the replacement deck stacked 18.1 m high and its ground portal caused a fatal fall. r9 samples terrain-only for the platform and return portal, refuses placement when terrain cannot be resolved, and gives retired GameObjects two quiescence frames before rebuilding so the reusable-site loop no longer trusts transient solids.",
      "title": "Quest Lab r9 anchors rebuilds to terrain after the fatal r8 portal stack",
      "updated_at": "2026-08-08T16:32:35.389Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808163235-quest-lab-r9-anchors-rebuilds-to-terrain-after-t"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T17:10:57.409Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808171057-quest-lab-r10-moves-the-creator-welcome-sequence",
        "impact": "Derek's exact-r9 review is now encoded as a reversible ground welcome camp before the ascent portal: a marked Birch and bronze axe, picnic table and benches with three foods mounted through Valheim's verified item-stand state, and a posted school-lit sign here prompt. The selected marble-grand deck rises 32 m above the highest sampled terrain to clear the measured Meadows canopy without deleting any unmarked world tree; generated artifacts report 1,353 owned objects.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab r10 moves the creator welcome sequence to ground and clears the canopy",
        "verification": [
          "282 source-shared .NET tests and 77 repository Python tests pass; ComfyQuestLab Release build succeeds against the installed Valheim assembly with 0 warnings/errors; atlas, patch, Gallery, journal, and Tome generators/checks are current; exact-r10 OMEN visual and suite receipts follow after SHA-verified deploy."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808171057-quest-lab-r10-moves-the-creator-welcome-sequence",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T17:10:57.409Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L502",
        "sha256": "28d603a54ea9262314576315ca1248a956e9597a391c03f3d968fe19c56d0435"
      },
      "summary": "Derek's exact-r9 review is now encoded as a reversible ground welcome camp before the ascent portal: a marked Birch and bronze axe, picnic table and benches with three foods mounted through Valheim's verified item-stand state, and a posted school-lit sign here prompt. The selected marble-grand deck rises 32 m above the highest sampled terrain to clear the measured Meadows canopy without deleting any unmarked world tree; generated artifacts report 1,353 owned objects.",
      "title": "Quest Lab r10 moves the creator welcome sequence to ground and clears the canopy",
      "updated_at": "2026-08-08T17:10:57.409Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808171057-quest-lab-r10-moves-the-creator-welcome-sequence"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T17:18:29.941Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808171829-quest-lab-keeps-release-dll-hashes-stable-across",
        "impact": "The direct-download plugin now disables SourceLink while retaining deterministic path mapping. SourceLink embedded the containing Git revision into the portable debug record and changed the PE checksum after unrelated commits, so exact live and package SHA receipts could diverge despite identical compiled source. A guard now preserves this release invariant.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab keeps release DLL hashes stable across documentation commits",
        "verification": [
          "Two clean Release rebuilds with different synthetic SourceRevisionId values produced the same 9ac0dcfe3043024f46ac182801426e5b22c97d76dc7b31cc6236c59d2565881a SHA256; both builds completed with 0 warnings/errors and all 78 repository Python tests pass."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808171829-quest-lab-keeps-release-dll-hashes-stable-across",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T17:18:29.941Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L503",
        "sha256": "7312cf12c509165c6f067e255f8c4cab82c03baedc8262ee64439085b9a94d86"
      },
      "summary": "The direct-download plugin now disables SourceLink while retaining deterministic path mapping. SourceLink embedded the containing Git revision into the portable debug record and changed the PE checksum after unrelated commits, so exact live and package SHA receipts could diverge despite identical compiled source. A guard now preserves this release invariant.",
      "title": "Quest Lab keeps release DLL hashes stable across documentation commits",
      "updated_at": "2026-08-08T17:18:29.941Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808171829-quest-lab-keeps-release-dll-hashes-stable-across"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T17:51:02.066Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808175102-quest-lab-r11-turns-course-labels-and-quest-stat",
        "impact": "Exact-r10 OMEN review now drives one batched correction: horizontal rune names sit as lit mid-spoke banners, sign and banner lamps wash their own faces instead of the marble floor, mounted food selects the first prefab with a real attach visual, and the Quests tab becomes a school-coloured expandable grid instead of repeated prose.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab r11 turns course labels and quest state into readable surfaces",
        "verification": [
          "25 focused Quest Lab Python checks pass; 281 unaffected shared-contract tests pass; ComfyQuestLab Release builds with zero warnings or errors and identical SHA256 under two SourceRevisionId values; all 91 atlas rows / 90 signatures, the 34-event catalog, three Gallery profiles, Workbench 31-test suite, and roadmap 46-test suite are current."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808175102-quest-lab-r11-turns-course-labels-and-quest-stat",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T17:51:02.066Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L504",
        "sha256": "dc167ae015a56f4d67705716905460e120cf7eab7069dc776b120907df273ced"
      },
      "summary": "Exact-r10 OMEN review now drives one batched correction: horizontal rune names sit as lit mid-spoke banners, sign and banner lamps wash their own faces instead of the marble floor, mounted food selects the first prefab with a real attach visual, and the Quests tab becomes a school-coloured expandable grid instead of repeated prose.",
      "title": "Quest Lab r11 turns course labels and quest state into readable surfaces",
      "updated_at": "2026-08-08T17:51:02.066Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808175102-quest-lab-r11-turns-course-labels-and-quest-stat"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T18:30:49.469Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808183049-quest-lab-r12-makes-every-dense-creator-surface-",
        "impact": "The panel now renders its authored cell detail in a persistent hover-help bar, freezes visible rows when paused, separates search clearing from log clearing, turns the Spellbook into a compact action/verdict grid, colors the latest evaluator outcome, remembers safe window geometry, and makes the zoom percentage a one-click 100-percent reset.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab r12 makes every dense creator surface self-explaining",
        "verification": [
          "ComfyQuestLab Release build succeeds with zero warnings or errors; 23 focused UX, package, and release-verifier tests plus all 75 repository Python guards pass; 281 unaffected shared-contract tests pass while concurrent bounded-history work owns the remaining allowlist assertion; Workbench 31-test and roadmap 46-test suites pass."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808183049-quest-lab-r12-makes-every-dense-creator-surface-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T18:30:49.469Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L505",
        "sha256": "651fb0e32548f6316d78d47f1a836db24a0b9a1f8c8cfefd4476093bcc0d11f1"
      },
      "summary": "The panel now renders its authored cell detail in a persistent hover-help bar, freezes visible rows when paused, separates search clearing from log clearing, turns the Spellbook into a compact action/verdict grid, colors the latest evaluator outcome, remembers safe window geometry, and makes the zoom percentage a one-click 100-percent reset.",
      "title": "Quest Lab r12 makes every dense creator surface self-explaining",
      "updated_at": "2026-08-08T18:30:49.469Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808183049-quest-lab-r12-makes-every-dense-creator-surface-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-08T19:45:34.400Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260808194534-quest-lab-r13-removes-trigger-transcription-and-",
        "impact": "Safe event cells in the live, Spellbook, and armed-quest grids now copy exact trigger.event IDs with visible confirmation; the Quests tab opens its fixed local folder or copies its path. All and Default presets recover school filters, selecting no schools finally shows no rows, and Pause freezes the retained moment while search and school filters remain usable over it.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Lab r13 removes trigger transcription and filter dead ends",
        "verification": [
          "ComfyQuestLab Release build succeeds with zero warnings or errors; 24 focused UX, package, and release-verifier checks plus all 76 repository Python guards pass; 281 unaffected shared-contract tests pass while concurrent bounded-history work owns the remaining allowlist assertion; Workbench 31-test and roadmap 46-test suites pass."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260808194534-quest-lab-r13-removes-trigger-transcription-and-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-08T19:45:34.400Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L506",
        "sha256": "63fe5a3f62b369cda16d2b1aa946e599ebaac457b18a07122cb7cc6a51a00243"
      },
      "summary": "Safe event cells in the live, Spellbook, and armed-quest grids now copy exact trigger.event IDs with visible confirmation; the Quests tab opens its fixed local folder or copies its path. All and Default presets recover school filters, selecting no schools finally shows no rows, and Pause freezes the retained moment while search and school filters remain usable over it.",
      "title": "Quest Lab r13 removes trigger transcription and filter dead ends",
      "updated_at": "2026-08-08T19:45:34.400Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260808194534-quest-lab-r13-removes-trigger-transcription-and-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T00:31:50.213Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809003150-polish-quest-lab-rune-banners-and-quest-detail-c",
        "impact": "Long-form school labels now retain readable emissive color in weather without multiplying realtime lights, and quest detail chevrons no longer conflict with panel zoom semantics.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Polish Quest Lab rune banners and quest detail controls",
        "verification": [
          "29 focused Python tests; ComfyQuestLab Release build with zero warnings/errors; exact clean full suite and live OMEN receipt pending"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809003150-polish-quest-lab-rune-banners-and-quest-detail-c",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T00:31:50.213Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L507",
        "sha256": "c54ad0450a57f4c10d7207677b2f3b035ee7f0c40456b2ccf50d3678f069f076"
      },
      "summary": "Long-form school labels now retain readable emissive color in weather without multiplying realtime lights, and quest detail chevrons no longer conflict with panel zoom semantics.",
      "title": "Polish Quest Lab rune banners and quest detail controls",
      "updated_at": "2026-08-09T00:31:50.213Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809003150-polish-quest-lab-rune-banners-and-quest-detail-c"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T02:18:20.166Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809021820-keep-the-quest-lab-social-prompt-off-the-marble-",
        "impact": "The editable sign now emits from its glyphs and removes the older point lamp, preserving interaction contrast without washing out the reflective hub floor.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Keep the Quest Lab Social prompt off the marble exposure",
        "verification": [
          "35 focused Python tests; ComfyQuestLab Release build with zero warnings/errors; exact clean full suite and OMEN visual receipt pending"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809021820-keep-the-quest-lab-social-prompt-off-the-marble-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T02:18:20.166Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L508",
        "sha256": "37c1a8096b6b88a2eaa4c321ced71f834b7c47de2ade66df616d790dc3a73d7f"
      },
      "summary": "The editable sign now emits from its glyphs and removes the older point lamp, preserving interaction contrast without washing out the reflective hub floor.",
      "title": "Keep the Quest Lab Social prompt off the marble exposure",
      "updated_at": "2026-08-09T02:18:20.166Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809021820-keep-the-quest-lab-social-prompt-off-the-marble-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T02:27:58.011Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809022758-make-the-quest-lab-social-no-light-rule-true-on-",
        "impact": "The text-only Social branch now precedes client-local lamp allocation, preventing a fresh process from recreating the marble-washing point light it was meant to remove.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make the Quest Lab Social no-light rule true on first load",
        "verification": [
          "23 focused Python tests; ComfyQuestLab Release build with zero warnings/errors; exact clean full suite and OMEN visual receipt pending"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809022758-make-the-quest-lab-social-no-light-rule-true-on-",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T02:27:58.011Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L509",
        "sha256": "8ab2740537f3d8eee46757f8d0d02b5d6d8c0048bd573c2aec16ff814d44d6d5"
      },
      "summary": "The text-only Social branch now precedes client-local lamp allocation, preventing a fresh process from recreating the marble-washing point light it was meant to remove.",
      "title": "Make the Quest Lab Social no-light rule true on first load",
      "updated_at": "2026-08-09T02:27:58.011Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809022758-make-the-quest-lab-social-no-light-rule-true-on-"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T05:44:14.637Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809054414-add-live-quest-lab-renderer-state-inspection",
        "impact": "Captures startup prefab materials and compares live instances so illumination, shared-material drift, property overrides, and child lights are diagnosed from Valheim's rendered state instead of placement assumptions.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add live Quest Lab renderer-state inspection",
        "verification": [
          "dotnet build network/mod/ComfyQuestLab/ComfyQuestLab.csproj -c Release --no-restore; python -m unittest tests.test_questlab_render_inspector"
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809054414-add-live-quest-lab-renderer-state-inspection",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T05:44:14.637Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L510",
        "sha256": "49ee5189ed376d5f69f528961b5537cda5b2416e470f826fda0d40a71268a93e"
      },
      "summary": "Captures startup prefab materials and compares live instances so illumination, shared-material drift, property overrides, and child lights are diagnosed from Valheim's rendered state instead of placement assumptions.",
      "title": "Add live Quest Lab renderer-state inspection",
      "updated_at": "2026-08-09T05:44:14.637Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809054414-add-live-quest-lab-renderer-state-inspection"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T07:31:18.876Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809073118-shelter-quest-lab-gallery-v2-below-the-snow-line",
        "impact": "The selected grand court returns to a 6 m deck and recoverably clears only natural trees under its measured crown boundary. It clones 550 black-marble floor cells into an 8 m roof, leaves rune stages open, hangs nine durable vanilla braziers, and exposes role, roof-coverage, and tree-ledger diagnostics for batch review.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Shelter Quest Lab Gallery v2 below the snow line",
        "verification": [
          "Gallery generator drift check passes for plan v7 and 3,458 known prefabs; 25 focused Gallery/release-verifier tests pass; ComfyQuestLab Release build succeeds with zero warnings or errors."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809073118-shelter-quest-lab-gallery-v2-below-the-snow-line",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T07:31:18.876Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L511",
        "sha256": "5a1c7567eb1a92368d0038c9abf602d59e2a72d3e18ef8088020b3e38fd07ffd"
      },
      "summary": "The selected grand court returns to a 6 m deck and recoverably clears only natural trees under its measured crown boundary. It clones 550 black-marble floor cells into an 8 m roof, leaves rune stages open, hangs nine durable vanilla braziers, and exposes role, roof-coverage, and tree-ledger diagnostics for batch review.",
      "title": "Shelter Quest Lab Gallery v2 below the snow line",
      "updated_at": "2026-08-09T07:31:18.876Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809073118-shelter-quest-lab-gallery-v2-below-the-snow-line"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T09:04:41.048Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809090441-raise-and-harden-quest-lab-s-sheltered-gallery",
        "impact": "Moves the selected canopy to 16 m, attaches all nine braziers by measured mesh bounds with a live under-slab audit, and makes recoverable tree pruning fail closed on a round-tripped count-and-digest ledger; an exact 43-tree r18 recovery ledger was reconstructed from before/after world snapshots.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Raise and harden Quest Lab's sheltered gallery",
        "verification": [
          "282/282 shared .NET tests; 93/93 Python tests with 2 environment skips; generator verified 3 profiles and 3458 prefabs; zero-warning/error Release build; deterministic DLL SHA256 9191e77fd28a6bf07ef815760103833dc194a0b6bcd5ead739913ee0b979ee3a; privacy-clean four-entry package SHA256 53a138b744562727d4b337adb352e56eac5ac70153f4f1961e63069f460c4460."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809090441-raise-and-harden-quest-lab-s-sheltered-gallery",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T09:04:41.048Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L512",
        "sha256": "1029a6ed0829d138ad437ca97b32170da173b1b6af8de1d0ee70c50b7899a1fa"
      },
      "summary": "Moves the selected canopy to 16 m, attaches all nine braziers by measured mesh bounds with a live under-slab audit, and makes recoverable tree pruning fail closed on a round-tripped count-and-digest ledger; an exact 43-tree r18 recovery ledger was reconstructed from before/after world snapshots.",
      "title": "Raise and harden Quest Lab's sheltered gallery",
      "updated_at": "2026-08-09T09:04:41.048Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809090441-raise-and-harden-quest-lab-s-sheltered-gallery"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T09:31:50.323Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809093150-make-quest-lab-tree-ledgers-readable-by-unity",
        "impact": "The first r19 OMEN identify receipt failed closed with 43 expected records but zero deserialized. Recovery DTOs now live at namespace scope and persist a plain record array, preserving the v1 JSON fields while removing the nested generic serializer ambiguity before any gallery clear.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make Quest Lab tree ledgers readable by Unity",
        "verification": [
          "Live r19 read-only receipt confirmed nine old brazier meshes above the roof and rejected the 43-tree ledger before mutation; 282/282 shared .NET tests; 93/93 Python tests with 2 environment skips; 19 focused Gallery tests; zero-warning/error deterministic Release DLL SHA256 7923b8dc97e1eb1046e0f260b09ee2dd50d27d98b58784dff6e4e48e12ed5f97; privacy-clean package SHA256 88fa0eaade4354afae46cabb7d68b10569f07ab6e4b3ce18fb266550305e5b0e."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809093150-make-quest-lab-tree-ledgers-readable-by-unity",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T09:31:50.323Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L513",
        "sha256": "ab0fc933184a8949defa615cec9440f6944eabd77e4b16fc737d38af1941f07b"
      },
      "summary": "The first r19 OMEN identify receipt failed closed with 43 expected records but zero deserialized. Recovery DTOs now live at namespace scope and persist a plain record array, preserving the v1 JSON fields while removing the nested generic serializer ambiguity before any gallery clear.",
      "title": "Make Quest Lab tree ledgers readable by Unity",
      "updated_at": "2026-08-09T09:31:50.323Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809093150-make-quest-lab-tree-ledgers-readable-by-unity"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T10:58:38.641Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809105838-replace-quest-lab-s-lossy-unity-ledger-serialize",
        "impact": "An isolated one-record r20 live probe proved Unity discarded every custom recovery-record collection. Quest Lab now uses an explicit data-contract JSON boundary already proven in the shipping mod, linked into the headless shared suite with 43-record and forensic-v1 parsing tests; the real recovery ledger was restored unchanged.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Replace Quest Lab's lossy Unity ledger serializer",
        "verification": [
          "r20 read-only OMEN probe expected 1 record and read 0 without world mutation; r21 serializer tests round-trip 43/43 records and parse the forensic v1 shape; 284/284 shared .NET tests; 93/93 Python tests with 2 environment skips; zero-warning/error deterministic DLL SHA256 5f8e3c3ac7946a05108d8f5aa56389df8a486e1f0eb331aae5832bbb50baa463; privacy-clean package SHA256 b8ba26ce3f9a1224fde3454559c36b045266113dd6d9a73ae653360d203d2eb2."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809105838-replace-quest-lab-s-lossy-unity-ledger-serialize",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T10:58:38.641Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L514",
        "sha256": "cf22980dcb02c8136b5573d3602710585b40a3ebf2893c0a45120c60b5e70000"
      },
      "summary": "An isolated one-record r20 live probe proved Unity discarded every custom recovery-record collection. Quest Lab now uses an explicit data-contract JSON boundary already proven in the shipping mod, linked into the headless shared suite with 43-record and forensic-v1 parsing tests; the real recovery ledger was restored unchanged.",
      "title": "Replace Quest Lab's lossy Unity ledger serializer",
      "updated_at": "2026-08-09T10:58:38.641Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809105838-replace-quest-lab-s-lossy-unity-ledger-serialize"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T12:25:01.680Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809122501-give-quest-lab-a-shared-creator-foundry-contract",
        "impact": "All 34 creator-safe events now publish honest target and filter metadata, and shared Unity-free primitives turn witnessed events into loader/evaluator-proven schema-1 drafts with structured exact-evaluator miss diagnostics. Existing quest files and matching behavior remain unchanged.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Give Quest Lab a shared Creator Foundry contract",
        "verification": [
          "Generator verifies 91 atlas rows, 90 signatures, 77 methods, and exact authoring coverage for 34 creator events; 293/293 shared .NET tests; 95 Python tests with 2 environment skips; ComfyQuestLab and ComfyNetworkSense Release builds each succeed with zero warnings or errors."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809122501-give-quest-lab-a-shared-creator-foundry-contract",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T12:25:01.680Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L515",
        "sha256": "874f7a651986662fe45c59ff98aa0b28a2c732a63088a8505f7c73bcd6c237e0"
      },
      "summary": "All 34 creator-safe events now publish honest target and filter metadata, and shared Unity-free primitives turn witnessed events into loader/evaluator-proven schema-1 drafts with structured exact-evaluator miss diagnostics. Existing quest files and matching behavior remain unchanged.",
      "title": "Give Quest Lab a shared Creator Foundry contract",
      "updated_at": "2026-08-09T12:25:01.680Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809122501-give-quest-lab-a-shared-creator-foundry-contract"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T12:30:30.200Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809123030-add-quest-lab-gallery-truth-evidence",
        "impact": "A bounded read-only Gallery pass now exports world/render bounds, honest roof and snow-risk classification, per-brazier roof clearance, fresh-prefab versus live render comparisons, and deterministic named camera views. OMEN and i5 can request and retrieve only this fixed-schema evidence without camera or world mutation, while final visual acceptance remains human.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add Quest Lab Gallery Truth evidence",
        "verification": [
          "ComfyQuestLab Release build succeeds with zero warnings/errors; 284/284 shared .NET tests pass; 103 Python tests pass with 2 environment skips; Gallery Truth verifier rejects structural failures and any claim that machine evidence replaces visible-snow judgment."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809123030-add-quest-lab-gallery-truth-evidence",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T12:30:30.200Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L516",
        "sha256": "5d940c822b8062b445e0ed7b657704015e19e30cf3e05d37139dd17edf1f734d"
      },
      "summary": "A bounded read-only Gallery pass now exports world/render bounds, honest roof and snow-risk classification, per-brazier roof clearance, fresh-prefab versus live render comparisons, and deterministic named camera views. OMEN and i5 can request and retrieve only this fixed-schema evidence without camera or world mutation, while final visual acceptance remains human.",
      "title": "Add Quest Lab Gallery Truth evidence",
      "updated_at": "2026-08-09T12:30:30.200Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809123030-add-quest-lab-gallery-truth-evidence"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T12:34:55.530Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809123455-add-bounded-quest-lab-build-by-example-capture",
        "impact": "Creators can export their own or Quest Lab-marked pieces inside an explicit local radius as a deterministic PlanBuild projection with hashed sign, item-stand, and light metadata, then inspect, diff, replay, and selectively clear it without asking Derek to transcribe a build.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add bounded Quest Lab build-by-example capture",
        "verification": [
          "293/293 shared .NET tests; 97/97 Python tests with 2 environment skips; ComfyQuestLab Docker Release build succeeds with zero warnings/errors against a read-only Valheim mount."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809123455-add-bounded-quest-lab-build-by-example-capture",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T12:34:55.530Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L517",
        "sha256": "52fbd36f9b1945d1035c1471c431e618680c0d62b838980d06bb67d79b396f22"
      },
      "summary": "Creators can export their own or Quest Lab-marked pieces inside an explicit local radius as a deterministic PlanBuild projection with hashed sign, item-stand, and light metadata, then inspect, diff, replay, and selectively clear it without asking Derek to transcribe a build.",
      "title": "Add bounded Quest Lab build-by-example capture",
      "updated_at": "2026-08-09T12:34:55.530Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809123455-add-bounded-quest-lab-build-by-example-capture"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T13:25:09.471Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809132509-add-accessible-quest-lab-demo-cockpit",
        "impact": "Creators get keyboard navigation, explicit input ownership, color-independent status cues, low-resolution layout recovery, and a real-state readiness tab that distinguishes runtime evidence from human visual acceptance.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add accessible Quest Lab demo cockpit",
        "verification": [
          "309/309 shared .NET tests; 134/134 Python tests with 2 environment skips; ComfyQuestLab Release build succeeds with zero warnings/errors."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809132509-add-accessible-quest-lab-demo-cockpit",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T13:25:09.471Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L518",
        "sha256": "c4308f779a38bec7d52eb94141f64ad75b326b71648100f5205ce1ea91a4dbee"
      },
      "summary": "Creators get keyboard navigation, explicit input ownership, color-independent status cues, low-resolution layout recovery, and a real-state readiness tab that distinguishes runtime evidence from human visual acceptance.",
      "title": "Add accessible Quest Lab demo cockpit",
      "updated_at": "2026-08-09T13:25:09.471Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809132509-add-accessible-quest-lab-demo-cockpit"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T13:33:23.604Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809133323-certify-and-publish-deterministic-quest-lab-crea",
        "impact": "Creators can run the shipping loader and evaluator against a local pack, earn only exact evidence-backed badges, publish reproducible public-safe artifacts with a generic getting-started guide, diagnose catalog or contract drift, and preview safe installation without Derek.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Certify and publish deterministic Quest Lab creator packs",
        "verification": [
          "Quest-pack contract host builds cleanly; focused certification, evidence, reproducibility, compatibility, install, and uninstall tests pass."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809133323-certify-and-publish-deterministic-quest-lab-crea",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T13:33:23.604Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L519",
        "sha256": "e1aeca37d25f390adf23c6b49f9a778fed1540d19dbd0d4ff8bff42d4b6e9f34"
      },
      "summary": "Creators can run the shipping loader and evaluator against a local pack, earn only exact evidence-backed badges, publish reproducible public-safe artifacts with a generic getting-started guide, diagnose catalog or contract drift, and preview safe installation without Derek.",
      "title": "Certify and publish deterministic Quest Lab creator packs",
      "updated_at": "2026-08-09T13:33:23.604Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809133323-certify-and-publish-deterministic-quest-lab-crea"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T13:37:28.678Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809133728-add-a-self-guided-quest-lab-scenario-cockpit",
        "impact": "Creators can browse every one of the 34 safe canonical events, copy or safely prepare an editable schema-1 quest with a deterministic manifest, rehearse it through the exact shared evaluator, and collect a receipt without Derek; the fixed OMEN/i5 mailbox gains only exact scenario suite IDs and no general execution surface.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add a self-guided Quest Lab scenario cockpit",
        "verification": [
          "305/305 shared .NET tests; 134/134 Python tests with 2 environment skips; ComfyQuestLab Release build succeeds with zero warnings/errors; 91-row atlas, 34-event catalog, journal, gallery, and web tome generators are current."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809133728-add-a-self-guided-quest-lab-scenario-cockpit",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T13:37:28.678Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L520",
        "sha256": "c3a0fd698bd22df9d240e3087c090da493b0bcd67edf49f66e0cadab3520c313"
      },
      "summary": "Creators can browse every one of the 34 safe canonical events, copy or safely prepare an editable schema-1 quest with a deterministic manifest, rehearse it through the exact shared evaluator, and collect a receipt without Derek; the fixed OMEN/i5 mailbox gains only exact scenario suite IDs and no general execution surface.",
      "title": "Add a self-guided Quest Lab scenario cockpit",
      "updated_at": "2026-08-09T13:37:28.678Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809133728-add-a-self-guided-quest-lab-scenario-cockpit"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T15:00:18.328Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809150018-add-privacy-safe-quest-lab-event-parsing-and-she",
        "impact": "Creators can turn one or many rotated Quest Lab JSONL/CSV archives into filtered canonical action tables, raw-versus-coalesced summaries, and a formula-safe multi-tab XLSX/CSV bundle for Google Sheets without network credentials or Derek-operated setup. Strict schema validation, explicit crash-tail handling, queue-loss notices, mirror suppression, bounded inputs, hashed runtime identities, and descriptive failures keep the white-glove export honest and safe.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add privacy-safe Quest Lab event parsing and Sheets workbooks",
        "verification": [
          "15 focused event-parser tests and the full 156-test Python suite passed with 2 environment skips; generated XLSX reopened successfully with openpyxl and exposed Events, Summary, Metadata, Raw Witnesses, and Read Me tabs."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809150018-add-privacy-safe-quest-lab-event-parsing-and-she",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T15:00:18.328Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L521",
        "sha256": "466ebf9754d9f5c80e524c947fc9b5fdaab90015ca528dc6245783f2a75fb418"
      },
      "summary": "Creators can turn one or many rotated Quest Lab JSONL/CSV archives into filtered canonical action tables, raw-versus-coalesced summaries, and a formula-safe multi-tab XLSX/CSV bundle for Google Sheets without network credentials or Derek-operated setup. Strict schema validation, explicit crash-tail handling, queue-loss notices, mirror suppression, bounded inputs, hashed runtime identities, and descriptive failures keep the white-glove export honest and safe.",
      "title": "Add privacy-safe Quest Lab event parsing and Sheets workbooks",
      "updated_at": "2026-08-09T15:00:18.328Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809150018-add-privacy-safe-quest-lab-event-parsing-and-she"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T15:04:11.895Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809150411-archive-canonical-quest-lab-events-safely",
        "impact": "Creators now get descriptive per-session JSONL and atomic spreadsheet CSV event files with privacy-safe defaults, bounded background buffering, rotation, retention, and explicit loss accounting without changing quest matching.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Archive canonical Quest Lab events safely",
        "verification": [
          "318/318 shared .NET tests and 141 Python tests pass (2 environment skips); ComfyQuestLab and ComfyNetworkSense Release builds succeed with zero warnings/errors; 91-row/90-signature generators and 86/86 practical patch checks are current."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809150411-archive-canonical-quest-lab-events-safely",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T15:04:11.895Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L522",
        "sha256": "c4577ce6856d94b02b628e08d760b3489529d9f8cb42b8bab296af7a264004d5"
      },
      "summary": "Creators now get descriptive per-session JSONL and atomic spreadsheet CSV event files with privacy-safe defaults, bounded background buffering, rotation, retention, and explicit loss accounting without changing quest matching.",
      "title": "Archive canonical Quest Lab events safely",
      "updated_at": "2026-08-09T15:04:11.895Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809150411-archive-canonical-quest-lab-events-safely"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T15:24:25.650Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809152425-add-local-first-quest-lab-event-exports-and-narr",
        "impact": "Creators can validate multipart canonical-event sessions, download formula-safe CSV, and after one explicit Desktop OAuth setup create a polished three-tab Google Sheet in one click using only per-file drive.file access. The fixed loopback dashboard, DPAPI token storage, integrity states, bounded batching, and package allowlist keep local evidence usable when Google or tenant policy is unavailable.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Add local-first Quest Lab event exports and narrow Google Sheets handoff",
        "verification": [
          "21 focused Sheets parser/OAuth/export security tests; 44 combined Sheets/package/panel tests; 156 full Python tests with 2 environment skips before final archive-contract hardening; 312 shared .NET tests; ComfyQuestLab Release build 0 warnings/errors; Workbench quest-lab package build and privacy scan clean with exact companion allowlist; Windows DPAPI dummy round trip passed; no Google API call or credential used."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809152425-add-local-first-quest-lab-event-exports-and-narr",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T15:24:25.650Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L523",
        "sha256": "afee8feb53fae8814aef68a4622a76f80808a9bb46e4b4d8a58c28959238d7ac"
      },
      "summary": "Creators can validate multipart canonical-event sessions, download formula-safe CSV, and after one explicit Desktop OAuth setup create a polished three-tab Google Sheet in one click using only per-file drive.file access. The fixed loopback dashboard, DPAPI token storage, integrity states, bounded batching, and package allowlist keep local evidence usable when Google or tenant policy is unavailable.",
      "title": "Add local-first Quest Lab event exports and narrow Google Sheets handoff",
      "updated_at": "2026-08-09T15:24:25.650Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809152425-add-local-first-quest-lab-event-exports-and-narr"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T19:49:20.172Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809194920-certify-the-r24-creator-event-export-contract",
        "impact": "Creators now receive a privacy-safe canonical JSONL ledger, atomic five-second CSV projections, a strict offline parser with filtered JSON/CSV/XLSX evidence bundles, and an optional localhost one-click Google Sheets handoff whose exact drive.file OAuth boundary remains creator-controlled.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Certify the r24 creator event export contract",
        "verification": [
          "208/208 Python tests with 2 environment skips; 319/319 shared .NET tests; both Release builds 0 warnings/errors; 86/86 focused export and capability tests; atlas 91 rows/90 signatures/77 methods/34 creator events, creator-safe patches 57/57, practical patches 86/86, three gallery profiles and generated tomes current; privacy-clean package SHA-256 CFF5C8F246014A1B00FAB443D66F7B78901BA9D5E224249E38FD454386CD8437; independent release audit found no remaining material contract mismatch."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809194920-certify-the-r24-creator-event-export-contract",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T19:49:20.172Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L524",
        "sha256": "28b7380fb8fb7f02823008ce706987f538aef9dcb2cb32ede04416add51cf9ad"
      },
      "summary": "Creators now receive a privacy-safe canonical JSONL ledger, atomic five-second CSV projections, a strict offline parser with filtered JSON/CSV/XLSX evidence bundles, and an optional localhost one-click Google Sheets handoff whose exact drive.file OAuth boundary remains creator-controlled.",
      "title": "Certify the r24 creator event export contract",
      "updated_at": "2026-08-09T19:49:20.172Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809194920-certify-the-r24-creator-event-export-contract"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-09T21:17:07.097Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260809211707-document-the-quest-lab-r24-retrospective-and-fin",
        "impact": "The creator handoff now records the exact OMEN event/archive receipts, parser and local Sheets limits, corrected Gallery v2 fixture geometry, Derek's visual acceptance, and the remaining optional evidence gaps without overstating Google or rendered-proof claims.",
        "kind": "implementation",
        "milestones": [
          "A4"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Document the Quest Lab r24 retrospective and final acceptance",
        "verification": [
          "Retrospective and mod README/changelog updated; 208 Python tests with 2 expected environment skips, 319 shared .NET tests, both Release builds clean, package SHA B7F3D6F785388D4513F19ABD4FD70FEF24E177562167FFDE05DB05C8E0734576, OMEN archive 309 rows clean, and Truth Lens 9/9 fixture clearances pass."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A4"
        ]
      },
      "id": "roadmap:20260809211707-document-the-quest-lab-r24-retrospective-and-fin",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-09T21:17:07.097Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L525",
        "sha256": "1b8aba8a73f678f5258c4a8823febce5e95eb84ed2bf44d2a84a856a6db69a9b"
      },
      "summary": "The creator handoff now records the exact OMEN event/archive receipts, parser and local Sheets limits, corrected Gallery v2 fixture geometry, Derek's visual acceptance, and the remaining optional evidence gaps without overstating Google or rendered-proof claims.",
      "title": "Document the Quest Lab r24 retrospective and final acceptance",
      "updated_at": "2026-08-09T21:17:07.097Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260809211707-document-the-quest-lab-r24-retrospective-and-fin"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer"
      ],
      "data": {
        "at": "2026-08-10T12:56:51.785Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260810125651-quest-studio-to-runtime-vertical-and-native-auth",
        "impact": "Split browser authoring, compact gameplay runtime, and Quest Lab rehearsal around one certified file contract; OMEN listen-host mutation passed while the identical i5 peer failed closed.",
        "kind": "verification",
        "milestones": [
          "M5"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Quest Studio-to-Runtime vertical and native authority acceptance",
        "verification": [
          "351 shared tests pass; 26 Companion tests pass; Runtime Release builds with zero warnings; quest-peer-20260810-native-r2 passed all host action, terminal, peer denial, zero-action, and byte-exact cleanup gates."
        ]
      },
      "facets": {
        "kind": "verification",
        "milestones": [
          "M5"
        ]
      },
      "id": "roadmap:20260810125651-quest-studio-to-runtime-vertical-and-native-auth",
      "kind": "roadmap-note",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": "2026-08-10T12:56:51.785Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L526",
        "sha256": "f2af68a6e8f4ae94cd7d9ef8fe97e0d32cefb3ffe0e930ed6731de6ee2bef10d"
      },
      "summary": "Split browser authoring, compact gameplay runtime, and Quest Lab rehearsal around one certified file contract; OMEN listen-host mutation passed while the identical i5 peer failed closed.",
      "title": "Quest Studio-to-Runtime vertical and native authority acceptance",
      "updated_at": "2026-08-10T12:56:51.785Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260810125651-quest-studio-to-runtime-vertical-and-native-auth"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-08-12T07:22:59.840Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260812072259-decouple-the-repo-seams-in-place-ahead-of-the-so",
        "impact": "Quest glue and transport contracts now travel as source packages (Comfy.Quest.Contracts, Comfy.Transport.Contracts); the fused test project split along the quest seam with count conservation (166+185=351); Quest Studio carved behind IQuestStudioHost with route parity 10/10; cross-seam scripts parameterized behavior-preserving. Extraction of networksense, lumberjacks-platform, and comfy-quest can now proceed from one green tag.",
        "kind": "decision",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Decouple the repo seams in place ahead of the sovereign split",
        "verification": [
          "xunit 166/166 + 185/185, python unittest 210/210, Game.sln 0 errors on SDK9, roadmap:test green, mod DLLs IL-identical to pre-change baseline; ledger at docs/internal/repo-split/HANDOFF-RECOVERY.md"
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260812072259-decouple-the-repo-seams-in-place-ahead-of-the-so",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-08-12T07:22:59.840Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L527",
        "sha256": "a9c2642da196bd44e9620903204a3af67eba2f756bde3cad06b4bc9e4c8ef809"
      },
      "summary": "Quest glue and transport contracts now travel as source packages (Comfy.Quest.Contracts, Comfy.Transport.Contracts); the fused test project split along the quest seam with count conservation (166+185=351); Quest Studio carved behind IQuestStudioHost with route parity 10/10; cross-seam scripts parameterized behavior-preserving. Extraction of networksense, lumberjacks-platform, and comfy-quest can now proceed from one green tag.",
      "title": "Decouple the repo seams in place ahead of the sovereign split",
      "updated_at": "2026-08-12T07:22:59.840Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260812072259-decouple-the-repo-seams-in-place-ahead-of-the-so"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "at": "2026-08-12T08:41:38.080Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260812084138-transferred-lumberjacks-platform-ownership-to-it",
        "impact": "Gateway, Companion, P7 infrastructure, live FieldLab harnesses, and the roadmap journal now live in djcdevelopment/lumberjacks-platform. The roadmap command and pre-commit ceremony move with that implementation authority; baseline remains the evidence archive and fleet index rather than a source fallback.",
        "kind": "decision",
        "milestones": [
          "M7",
          "A7"
        ],
        "repository": "lumberjacks-platform",
        "schema_version": 1,
        "summary": "Transferred Lumberjacks platform ownership to its sovereign repository",
        "verification": [
          "SDK 9 Game.sln build and 649 tests passed, including 26 Companion tests; Docker Gateway verify and standalone Companion builds passed; G1-G4 boundary guards and runtime identity endpoints passed."
        ]
      },
      "facets": {
        "kind": "decision",
        "milestones": [
          "M7",
          "A7"
        ]
      },
      "id": "roadmap:20260812084138-transferred-lumberjacks-platform-ownership-to-it",
      "kind": "roadmap-note",
      "primary_audiences": [
        "admin"
      ],
      "published_at": "2026-08-12T08:41:38.080Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L528",
        "sha256": "6194d94fb053af2eae4adc2ade709f55451eb5decb5d98491c6c7feedd887a29"
      },
      "summary": "Gateway, Companion, P7 infrastructure, live FieldLab harnesses, and the roadmap journal now live in djcdevelopment/lumberjacks-platform. The roadmap command and pre-commit ceremony move with that implementation authority; baseline remains the evidence archive and fleet index rather than a source fallback.",
      "title": "Transferred Lumberjacks platform ownership to its sovereign repository",
      "updated_at": "2026-08-12T08:41:38.080Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260812084138-transferred-lumberjacks-platform-ownership-to-it"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-12T09:08:02.765Z",
        "author": "Codex",
        "evidence": [
          "PROVENANCE.md",
          "DECISIONS-PENDING.md",
          "fieldlab/experiments/creative-runtime/"
        ],
        "id": "20260812090802-restored-live-fieldlab-authority-inputs",
        "impact": "lumberjacks-platform now owns the complete executable creative-runtime and patch-load experiment surface, its active retro ceremony, and a policy-filtered decision queue while baseline remains the historical evidence and run-output home.",
        "kind": "implementation",
        "milestones": [
          "M2",
          "M7"
        ],
        "repository": "lumberjacks-platform",
        "schema_version": 1,
        "summary": "Restored omitted live FieldLab authority inputs and repaired hosted guest-package portability",
        "verification": [
          "23 copied experiment inputs plus the patch-load configuration match split-base-20260811 blobs; the CRE-E06 runner differs only by its repository identity guard; no creative-runtime runs were copied.",
          "CRE-E06 bundle adapter fixture passed against the platform-owned summarizer.",
          "Guest-package Python suite passed 8 tests with 2 expected sealed-artifact skips."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "M2",
          "M7"
        ]
      },
      "id": "roadmap:20260812090802-restored-live-fieldlab-authority-inputs",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-12T09:08:02.765Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L529",
        "sha256": "72414038891fd304dddd73e729f512411beb8198323e2e6781278a87ef3979f9"
      },
      "summary": "lumberjacks-platform now owns the complete executable creative-runtime and patch-load experiment surface, its active retro ceremony, and a policy-filtered decision queue while baseline remains the historical evidence and run-output home.",
      "title": "Restored omitted live FieldLab authority inputs and repaired hosted guest-package portability",
      "updated_at": "2026-08-12T09:08:02.765Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260812090802-restored-live-fieldlab-authority-inputs"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-12T09:49:13.390Z",
        "author": "Codex",
        "evidence": [
          "docs/RELEASE-READINESS.md",
          ".github/workflows/publish-nuget.yml",
          "infra/gcp/p7/scripts/Test-ModReleaseArtifact.ps1",
          "tools/workbench/Import-QuestRelease.ps1"
        ],
        "id": "20260812094913-make-cross-repository-release-boundaries-executa",
        "impact": "Transport now has a fail-closed NuGet tag lane and exact dependency profiles; NetworkSense releases are admitted by a pure manifest-and-checksum verifier with an executed tamper negative; Quest assets have a four-asset importer, explicit manifest-hash pin, deterministic lock check, and an honestly unpinned state. No package, release, tag, deployment, or public-profile activation occurred; missing credentials and producer artifacts remain explicit blockers.",
        "kind": "implementation",
        "milestones": [
          "A7",
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make cross-repository release boundaries executable before publication",
        "verification": [
          "SDK 9 solution build and 649 tests passed, including 26 Companion tests; authority lab 7/7; Python 10/10 with 2 environment skips; roadmap and Workbench checks passed; both CI-equivalent Docker builds passed.",
          "Transport package rehearsal validated exact ID, version, source bytes, repository commit, payload, and tamper rejection without publication. Quest fixture proved positive import plus manifest-hash, ZIP, source, and extra-asset negatives. NetworkSense fixture tamper was executed and rejected.",
          "The retained NetworkSense split-proof candidate passes the manifest-v1 consumer contract; full 676-commit gitleaks scan and changed-worktree scan found zero leaks."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7",
          "M7"
        ]
      },
      "id": "roadmap:20260812094913-make-cross-repository-release-boundaries-executa",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-12T09:49:13.390Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L530",
        "sha256": "278fbb91c8819f9848f5bdda9fc19eaf09b286d3758092678652dcbcbb09dd12"
      },
      "summary": "Transport now has a fail-closed NuGet tag lane and exact dependency profiles; NetworkSense releases are admitted by a pure manifest-and-checksum verifier with an executed tamper negative; Quest assets have a four-asset importer, explicit manifest-hash pin, deterministic lock check, and an honestly unpinned state. No package, release, tag, deployment, or public-profile activation occurred; missing credentials and producer artifacts remain explicit blockers.",
      "title": "Make cross-repository release boundaries executable before publication",
      "updated_at": "2026-08-12T09:49:13.390Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260812094913-make-cross-repository-release-boundaries-executa"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-12T10:01:11.150Z",
        "author": "Codex",
        "evidence": [
          "tools/workbench/Test-QuestReleaseImporter.ps1",
          "tools/Test-ArtifactHashGate.ps1"
        ],
        "id": "20260812100111-make-release-fixture-gates-type-stable-across-po",
        "impact": "The Quest importer now canonicalizes timestamps whether ConvertFrom-Json returns a string on Windows PowerShell 5.1 or a DateTime on PowerShell 7. The NetworkSense tamper fixture now builds a named managed assembly through the SDK because Add-Type stamps different names and file versions between those shells; the pure release verifier itself remains build-free.",
        "kind": "implementation",
        "milestones": [
          "A7",
          "M7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make release fixture gates type-stable across PowerShell generations",
        "verification": [
          "The complete guards job command sequence passes under PowerShell 7.6.4, including Transport rehearsal, Quest positive and all tamper negatives, and the executed NetworkSense DLL tamper negative.",
          "The Quest importer suite also passes under Windows PowerShell 5.1 and carries direct string/DateTime canonicalization regression assertions."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7",
          "M7"
        ]
      },
      "id": "roadmap:20260812100111-make-release-fixture-gates-type-stable-across-po",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-12T10:01:11.150Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L531",
        "sha256": "9f8af490c8389ba2e7bd5b7cf38b7906ffe61e37e7c58d527e3eeaf4adad3d28"
      },
      "summary": "The Quest importer now canonicalizes timestamps whether ConvertFrom-Json returns a string on Windows PowerShell 5.1 or a DateTime on PowerShell 7. The NetworkSense tamper fixture now builds a named managed assembly through the SDK because Add-Type stamps different names and file versions between those shells; the pure release verifier itself remains build-free.",
      "title": "Make release fixture gates type-stable across PowerShell generations",
      "updated_at": "2026-08-12T10:01:11.150Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260812100111-make-release-fixture-gates-type-stable-across-po"
    },
    {
      "audiences": [
        "developer",
        "modder",
        "contributor"
      ],
      "data": {
        "at": "2026-08-12T10:08:02.365Z",
        "author": "Codex",
        "evidence": [],
        "id": "20260812100802-make-the-parallel-dispatch-regression-runner-sta",
        "impact": "The concurrency proof now uses an asynchronous rendezvous instead of blocking every available thread-pool worker, preserving the overlap assertion without depending on hosted runner hill-climbing timing.",
        "kind": "implementation",
        "milestones": [
          "A7"
        ],
        "repository": "Lumberjacks",
        "schema_version": 1,
        "summary": "Make the parallel dispatch regression runner-stable",
        "verification": [
          "The focused concurrency test passed 25 consecutive runs; the full SDK 9 solution passed all 649 tests, including 250 Simulation and 26 Companion tests."
        ]
      },
      "facets": {
        "kind": "implementation",
        "milestones": [
          "A7"
        ]
      },
      "id": "roadmap:20260812100802-make-the-parallel-dispatch-regression-runner-sta",
      "kind": "roadmap-note",
      "primary_audiences": [
        "developer"
      ],
      "published_at": "2026-08-12T10:08:02.365Z",
      "source": {
        "authority": "append-only-roadmap-journal",
        "locator": "corpus/mirrors/lumberjacks/commit-notes.jsonl#L532",
        "sha256": "e58dd865c4e2f54eab3b784688cd63af22a09ddf26fe20b86d6dc92bccf1de4c"
      },
      "summary": "The concurrency proof now uses an asynchronous rendezvous instead of blocking every available thread-pool worker, preserving the overlap assertion without depending on hosted runner hill-climbing timing.",
      "title": "Make the parallel dispatch regression runner-stable",
      "updated_at": "2026-08-12T10:08:02.365Z",
      "url": "https://am4.tail8e749c.ts.net/roadmap#note-20260812100802-make-the-parallel-dispatch-regression-runner-sta"
    },
    {
      "audiences": [
        "creator",
        "moderator",
        "curious",
        "player-tester",
        "admin",
        "modder",
        "developer"
      ],
      "data": {
        "$schema": "../../corpus/schemas/artifact.schema.json",
        "audiences": {
          "primary": [
            "creator",
            "moderator"
          ],
          "relevant": [
            "curious",
            "player-tester",
            "admin",
            "modder",
            "developer"
          ]
        },
        "canonical_url": "https://djcdevelopment.github.io/baseline/absorption-loop/",
        "facets": {
          "result_first": true,
          "system": "quest-absorption"
        },
        "id": "story:absorption-loop",
        "kind": "story",
        "published_at": "2026-08-07T06:57:12-07:00",
        "schema_version": 1,
        "source_files": [
          "index.html"
        ],
        "summary": "Historical 2026-08-06 evidence of a guild tracker becoming a player picker, in-game objective, and human-review evidence; current authority is comfy-quest.",
        "title": "From a leader's spreadsheet to a killing blow, and back with proof"
      },
      "facets": {
        "result_first": true,
        "system": "quest-absorption"
      },
      "id": "story:absorption-loop",
      "kind": "story",
      "primary_audiences": [
        "creator",
        "moderator"
      ],
      "published_at": "2026-08-07T06:57:12-07:00",
      "source": {
        "authority": "colocated-artifact",
        "files": [
          "site/absorption-loop/index.html"
        ],
        "locator": "site/absorption-loop/artifact.json",
        "sha256": "01dd642d5aff60679255882a098d161c4ec33fb68d589e15589fb0b4a0631a97"
      },
      "summary": "Historical 2026-08-06 evidence of a guild tracker becoming a player picker, in-game objective, and human-review evidence; current authority is comfy-quest.",
      "title": "From a leader's spreadsheet to a killing blow, and back with proof",
      "updated_at": "2026-08-07T06:57:12-07:00",
      "url": "https://djcdevelopment.github.io/baseline/absorption-loop/"
    },
    {
      "audiences": [
        "curious",
        "creator",
        "admin",
        "modder",
        "developer",
        "contributor"
      ],
      "data": {
        "$schema": "../../../corpus/schemas/artifact.schema.json",
        "audiences": {
          "primary": [
            "curious",
            "creator"
          ],
          "relevant": [
            "admin",
            "modder",
            "developer",
            "contributor"
          ]
        },
        "canonical_url": "https://djcdevelopment.github.io/baseline/selfie-stick/",
        "facets": {
          "result_first": true,
          "system": "world-photography"
        },
        "id": "story:selfie-stick",
        "kind": "story",
        "published_at": "2026-08-06T17:18:30-07:00",
        "schema_version": 1,
        "source_files": [
          "template.html",
          "build.py",
          "README.md"
        ],
        "summary": "Three million building pieces become 1,833 structures and 1,411 photographs framed by arithmetic rather than a human camera operator.",
        "title": "Photographing a world nobody had time to look at"
      },
      "facets": {
        "result_first": true,
        "system": "world-photography"
      },
      "id": "story:selfie-stick",
      "kind": "story",
      "primary_audiences": [
        "curious",
        "creator"
      ],
      "published_at": "2026-08-06T17:18:30-07:00",
      "source": {
        "authority": "colocated-artifact",
        "files": [
          "tools/selfie-stick/article/template.html",
          "tools/selfie-stick/article/build.py",
          "tools/selfie-stick/article/README.md"
        ],
        "locator": "tools/selfie-stick/article/artifact.json",
        "sha256": "66183890cf61234d1ab4b32bc2ab4b0080b4e08c431262dacaea28cd822a054f"
      },
      "summary": "Three million building pieces become 1,833 structures and 1,411 photographs framed by arithmetic rather than a human camera operator.",
      "title": "Photographing a world nobody had time to look at",
      "updated_at": "2026-08-06T17:18:30-07:00",
      "url": "https://djcdevelopment.github.io/baseline/selfie-stick/"
    },
    {
      "audiences": [
        "creator",
        "curious",
        "player-tester",
        "admin",
        "modder",
        "developer",
        "contributor"
      ],
      "data": {
        "access": {
          "href": null,
          "kind": "not-published",
          "published_at": null,
          "sha256": null,
          "size_bytes": null
        },
        "audiences": [
          "creator",
          "curious",
          "player-tester",
          "admin",
          "modder",
          "developer",
          "contributor"
        ],
        "contribution": {
          "code_contributions": true,
          "stage_3_reward": "Commit access to the revived pipeline once it lands in baseline, and you triage this tool's thread. The comfy archive it is recovered from stays read-only."
        },
        "discussion": {
          "href": "https://discord.com/channels/1531911987074957442/1535091188464357496",
          "label": "World photography → gallery thread"
        },
        "docs": [
          {
            "href": "https://djcdevelopment.github.io/baseline/selfie-stick/",
            "label": "How it works, and what it found (the write-up)"
          },
          {
            "href": "https://github.com/djcdevelopment/baseline/tree/main/tools/selfie-stick",
            "label": "tools/selfie-stick/ — the planning half, in this repo"
          },
          {
            "href": "https://github.com/djcdevelopment/comfy/blob/main/handoffs/README.md",
            "label": "Handoff overview (handoffs/README.md)"
          },
          {
            "href": "https://github.com/djcdevelopment/baseline/tree/main/recipes/camera-gallery",
            "label": "Landed raw material (recipes/camera-gallery/)"
          }
        ],
        "first_tasks": [
          {
            "done_when": "The BepInEx plugin builds from a checkout of this repo and a capture run completes without reaching into the comfy archive. This is the claiming task for this tool. It supersedes the old CG-1, which asked for a waypoints sample from segment 1 — tools/selfie-stick/ already emits that.",
            "id": "CG-1",
            "size": "medium",
            "title": "Bring the camera plugin into this repo so the capture half runs here"
          },
          {
            "done_when": "A one-time in-game dump of ZNetScene's prefab table lands as a committed lookup, and the scanner reports \"dominant material: wood_wall\" instead of \"hash:538325542\". The offline classification.json does not cover building pieces — it holds 617 item names and none of them are pieces.",
            "id": "CG-2",
            "size": "small",
            "title": "Resolve prefab hashes to names so a structure can be described by material"
          }
        ],
        "id": "camera-gallery",
        "license": "MIT — everything recoverable here lives in the public comfy archive, which is MIT-licensed. A revival landing in this repo would land under BUSL-1.1; see LICENSING.md.",
        "name": "World Photography → Gallery Pipeline",
        "one_liner": "Find every structure in a world save, place a camera at each one from its own geometry, and photograph them unattended into a ranked gallery.",
        "ownership": {
          "claimed_at": null,
          "claimed_by": null,
          "record": null,
          "state": "unclaimed"
        },
        "privacy_note": "This photographs other people's builds. The pipeline withholds coordinates and builder IDs from anything it publishes, and every record it emits is marked unpublished by default — ingest is automatic, exposure is not. Ask before publishing a gallery of a world you do not own.",
        "recovery": null,
        "requires": [
          "Python 3, with duckdb",
          "A ComfyStewardView analytics cache for the world you want to photograph",
          "A BepInEx Valheim install, plus the camera plugin built from the comfy archive",
          "Optional: a local CLIP ViT-L/14 and LAION aesthetic head, to score the frames"
        ],
        "roadmap_milestones": [
          "A3",
          "A7"
        ],
        "source": {
          "href": "https://github.com/djcdevelopment/baseline/tree/main/tools/selfie-stick",
          "kind": "public-repo",
          "note": "Split across two public repos on purpose. The planning, scoring and gallery half is in this repo at tools/selfie-stick/. The BepInEx camera plugin stays in the public comfy archive so that claiming the in-game half remains a real, available piece of work rather than something already finished here."
        },
        "status": "local-only",
        "status_detail": "Runs today, end to end, on the operator's machine. On 2026-08-06 it photographed 161 structures across 54 unattended sessions and produced 1,411 frames, none of them framed by a human. The planning half is in this repo at tools/selfie-stick/: it clusters a world save's building pieces into structures in 3-D, ranks them as camera subjects, and computes a standoff distance, bearing and elevation for each. The in-game half reads that plan, flies it, and writes a receipt per frame. Why local-only and not live: the in-game half is a BepInEx plugin that lives in the public comfy archive rather than in this repo, and the pipeline also wants a ComfyStewardView DuckDB cache for the world plus a local CLIP model to score the frames. Nothing is packaged and there is no download — a stranger cannot run this tonight, and that is the honest gap, not the code. Note the original plan was superseded rather than revived: the four-segment flythrough (waypoints → flight → ffmpeg video cut) gave way to stills, so there is no video step and segments 2 and 4 are unlikely to be built as written. Prune history and the segment-by-segment story are in Lumberjacks/docs/workbench/tools/camera-gallery.md. Written up in full at https://djcdevelopment.github.io/baseline/selfie-stick/ .",
        "time_to_first_result": "about 2 minutes to scan a world and get a ranked shot list; capture is unattended after that and scales with how many structures you asked for",
        "what_it_does": "Clusters a world save's building pieces into structures on a 16 m grid, scores each as a camera subject, and derives a camera position, bearing, elevation and time of day from its bounding box. An in-game plugin reads that shot plan as tab-separated text, teleports, aims, forces the sun and weather, checks the view is not blocked, and writes one JSON receipt per frame recording what was asked for against what the engine actually did. A final pass joins receipts to the files on disk, scores every photograph with a CLIP aesthetic head, and emits a filterable gallery.",
        "who_its_for": "Anyone who wants to show a server's builds to people who will never log into it — especially on a world too large to tour by hand."
      },
      "facets": {
        "access": "not-published",
        "ownership": "unclaimed",
        "status": "local-only"
      },
      "id": "tool:camera-gallery",
      "kind": "tool",
      "primary_audiences": [
        "creator"
      ],
      "published_at": null,
      "source": {
        "authority": "workbench-catalog",
        "locator": "corpus/mirrors/lumberjacks/workbench.json#/tools/camera-gallery",
        "sha256": "5600fcf7c8a559e0cec689c97c6eb29b76f0a3a5ce727dea2a6d4426db5a29d0"
      },
      "summary": "Find every structure in a world save, place a camera at each one from its own geometry, and photograph them unattended into a ranked gallery.",
      "title": "World Photography → Gallery Pipeline",
      "updated_at": null,
      "url": "https://am4.tail8e749c.ts.net/workbench#camera-gallery"
    },
    {
      "audiences": [
        "admin",
        "developer",
        "curious",
        "moderator",
        "contributor"
      ],
      "data": {
        "access": {
          "href": "/workbench/downloads/community-telemetry",
          "kind": "site-download",
          "published_at": "2026-07-29T01:12:00Z",
          "sha256": "bf065eb47da01f3305ec10c4c6b8ec03d99329cf6a5dc02c2ba5f26eded32211",
          "size_bytes": 8485
        },
        "audiences": [
          "admin",
          "developer",
          "curious",
          "moderator",
          "contributor"
        ],
        "contribution": {
          "code_contributions": true,
          "stage_3_reward": "Commit access to the telemetry stack and the operator viewer in baseline, and you triage this tool's thread."
        },
        "discussion": {
          "href": "https://discord.com/channels/1531911987074957442/1531977728390205613",
          "label": "Community telemetry thread"
        },
        "docs": [
          {
            "href": "/community",
            "label": "The live community view"
          },
          {
            "href": "https://github.com/djcdevelopment/lumberjacks-platform/blob/main/Lumberjacks/docs/api/telemetry-v0.md",
            "label": "Telemetry v0 API reference — Lumberjacks/docs/api/telemetry-v0.md"
          },
          {
            "href": "https://github.com/djcdevelopment/lumberjacks-platform/blob/main/Lumberjacks/docs/dashboard/viewing-the-surfaces.md",
            "label": "Viewing the surfaces — Lumberjacks/docs/dashboard/viewing-the-surfaces.md"
          }
        ],
        "first_tasks": [
          {
            "done_when": "Any stack you like — a static page, a spreadsheet, a terminal script — renders live data from a v0 endpoint, and the thread has a screenshot plus how you made it. Needs no repo access; the starter kit includes a Python poller.",
            "id": "CT-1",
            "size": "small",
            "suggested": true,
            "title": "Build one chart, tile, or widget from the public v0 API and post it"
          },
          {
            "done_when": "The compose stack runs on your machine and a new aggregate is exposed by the v0 API and rendered, with the existing privacy tests passing unmodified. This is the claim path — the source is already public, so nothing blocks you from starting today.",
            "id": "CT-2",
            "size": "medium",
            "title": "Bring the local stack up, then add one new aggregate tile the privacy tests still pass on"
          }
        ],
        "id": "community-telemetry",
        "license": "BUSL-1.1 with the community-steward safe harbor, converting to AGPL-3.0-only; see LICENSING.md.",
        "name": "Live Community Telemetry",
        "one_liner": "An aggregates-only telemetry API with privacy tests that fail if a player ID, name, or position ever shows up — plus the whole stack, runnable on your machine.",
        "ownership": {
          "claimed_at": null,
          "claimed_by": null,
          "record": null,
          "state": "unclaimed"
        },
        "privacy_note": "The v0 API is aggregates-only by tested design — no player ID, no name, no position, ever. Keep that bar: a change that makes the privacy tests fail is a change that does not land.",
        "recovery": null,
        "requires": [
          "A browser (or Python 3) for the live aggregates API — that is all CT-1 needs",
          "Docker and docker compose, for the local stack",
          "The .NET 9 SDK, only if you want to rebuild the gateway rather than run the composed image"
        ],
        "roadmap_milestones": [
          "A4",
          "A7"
        ],
        "source": {
          "href": "https://github.com/djcdevelopment/lumberjacks-platform/tree/main/Lumberjacks/tools/omen-dashboard",
          "kind": "public-repo",
          "note": "Public and readable now: Lumberjacks/infra/docker/docker-compose.yml for the stack, Lumberjacks/tools/omen-dashboard/ for the operator viewer."
        },
        "status": "local-only",
        "status_detail": "The aggregates API is live on P7 and the public /community page reads it. What is local-only is everything you would need to run or change it yourself: the docker stack that reproduces the whole thing and the loopback operator dashboard both run on your machine, and neither is published as a download.",
        "time_to_first_result": "about 5 minutes against the live API; about 30 for the local stack once claimed",
        "what_it_does": "An aggregates-only v0 telemetry API (GET /api/v0/telemetry/server, /tick, /sessions, /delivery, /regions, /events, /valheim, /cutover) whose test suite asserts that no player ID, name, or position ever appears in a response. A self-contained /community page polls it. A local dev stack brings up the real thing end to end (docker compose: postgres 5435, gateway 4000, eventlog 4002, progression 4003, operatorapi 4004), and a loopback-only operator viewer renders it for a single operator.",
        "who_its_for": "Anyone who wants to run the telemetry surface themselves — and anyone who would rather check the privacy claim than take it on faith."
      },
      "facets": {
        "access": "site-download",
        "ownership": "unclaimed",
        "status": "local-only"
      },
      "id": "tool:community-telemetry",
      "kind": "tool",
      "primary_audiences": [
        "admin"
      ],
      "published_at": null,
      "source": {
        "authority": "workbench-catalog",
        "locator": "corpus/mirrors/lumberjacks/workbench.json#/tools/community-telemetry",
        "sha256": "79be5d124fbe86929fc8c05dfaff654532e42eef8a61e2399cb3b65f4fc09ce9"
      },
      "summary": "An aggregates-only telemetry API with privacy tests that fail if a player ID, name, or position ever shows up — plus the whole stack, runnable on your machine.",
      "title": "Live Community Telemetry",
      "updated_at": null,
      "url": "https://am4.tail8e749c.ts.net/workbench#community-telemetry"
    },
    {
      "audiences": [
        "modder",
        "developer",
        "curious",
        "contributor"
      ],
      "data": {
        "access": {
          "href": null,
          "kind": "not-published",
          "published_at": null,
          "sha256": null,
          "size_bytes": null
        },
        "audiences": [
          "modder",
          "developer",
          "curious",
          "contributor"
        ],
        "contribution": {
          "code_contributions": true,
          "stage_3_reward": "Commit access to network/mcp/ in baseline, and you triage this tool's thread."
        },
        "discussion": {
          "href": "https://discord.com/channels/1531911987074957442/1532310779402129438",
          "label": "MCP mod channel thread"
        },
        "docs": [
          {
            "href": "https://github.com/djcdevelopment/isolate/blob/main/contracts/commands.json",
            "label": "Command contract — network/mcp/contracts/commands.json"
          }
        ],
        "first_tasks": [
          {
            "done_when": "The tool list from your own client is in the thread, along with which client you used and anything in the setup that was not obvious.",
            "id": "MC-1",
            "size": "small",
            "title": "Run the gateway and list its tools from any MCP client, then post the tool list"
          }
        ],
        "id": "mcp-mod-channel",
        "license": "BUSL-1.1 with the community-steward safe harbor, converting to AGPL-3.0-only; see LICENSING.md.",
        "name": "MCP Mod Channel",
        "one_liner": "A localhost MCP server that talks to the running game mod: apply a config profile, run a bounded lab test, read back what happened.",
        "ownership": {
          "claimed_at": null,
          "claimed_by": null,
          "record": null,
          "state": "unclaimed"
        },
        "privacy_note": "Bound to 127.0.0.1 on purpose. Do not expose it — it drives a live game process, and its whole safety story is that only you can reach it.",
        "recovery": null,
        "requires": [
          "Python 3",
          "The mod running locally",
          "An MCP client",
          "Optional: a local Ollama, only for the explanation tools"
        ],
        "roadmap_milestones": [
          "A7"
        ],
        "source": {
          "href": "https://github.com/djcdevelopment/isolate",
          "kind": "public-repo",
          "note": "Public and readable now — the comfy_gateway kernel plus the valheim toolsurface, contracts/commands.json, and 6 tests. An older snapshot also exists in the comfy repo."
        },
        "status": "dev-only",
        "status_detail": "It runs, and it really does drive the live mod. It is reachable only from 127.0.0.1 with a dev key, and that is deliberate rather than unfinished: it is a development channel, never a console or shell bridge, and every mutation it can perform is whitelisted and bounded. The Workbench migration requires an explicit project-owned port and machine-readable endpoint identity; the legacy shared :8720 listener is not accepted as Baseline evidence until proven. There is no download and no remote mode.",
        "time_to_first_result": "about 20 minutes",
        "what_it_does": "A local Python MCP server on an explicit Workbench Dev/Lab loopback port (current candidate 8721; header X-Comfy-Key, dev value comfy-dev-local) speaks bidirectionally with the running mod: apply config profiles, run bounded lab motion tests through an atomic mailbox, tail mod telemetry and logs, assemble session bundles, and get local-Ollama explanations of what it just saw.",
        "who_its_for": "Mod developers, and anyone curious about wiring an AI tool to a live game process without handing it a shell."
      },
      "facets": {
        "access": "not-published",
        "ownership": "unclaimed",
        "status": "dev-only"
      },
      "id": "tool:mcp-mod-channel",
      "kind": "tool",
      "primary_audiences": [
        "modder"
      ],
      "published_at": null,
      "source": {
        "authority": "workbench-catalog",
        "locator": "corpus/mirrors/lumberjacks/workbench.json#/tools/mcp-mod-channel",
        "sha256": "96275277f6b59a87979f27e9fac17cd8df425e5a1c5373d8d89eb595eaf63d3d"
      },
      "summary": "A localhost MCP server that talks to the running game mod: apply a config profile, run a bounded lab test, read back what happened.",
      "title": "MCP Mod Channel",
      "updated_at": null,
      "url": "https://am4.tail8e749c.ts.net/workbench#mcp-mod-channel"
    },
    {
      "audiences": [
        "creator",
        "modder",
        "developer",
        "curious",
        "player-tester",
        "contributor"
      ],
      "data": {
        "access": {
          "href": "/workbench/downloads/quest-lab",
          "kind": "site-download",
          "published_at": "2026-08-08T06:05:00Z",
          "sha256": "d49a20dbf3408eaf64edd281c550b457839b18e076c99ac2b546a3aa2d748b9e",
          "size_bytes": 74949
        },
        "audiences": [
          "creator",
          "modder",
          "developer",
          "curious",
          "player-tester",
          "contributor"
        ],
        "contribution": {
          "code_contributions": true,
          "stage_3_reward": "Commit access to the mod."
        },
        "discussion": {
          "href": "https://discord.com/channels/1531911987074957442/1531926985314668635",
          "label": "Quest Lab thread"
        },
        "docs": [
          {
            "href": "/questlab",
            "label": "The Web Tome (Learn what's possible)"
          },
          {
            "href": "https://github.com/djcdevelopment/lumberjacks-platform/blob/main/Lumberjacks/docs/workbench/tools/quest-lab.md",
            "label": "One-pager (what it is, what's rough)"
          },
          {
            "href": "https://github.com/djcdevelopment/comfy-quest/tree/main/network/mod/ComfyQuestLab",
            "label": "Source Code"
          }
        ],
        "first_tasks": [
          {
            "done_when": "Run the lab, try the actions for one school, and post in the thread whether the in-game events fired as the Tome predicted. Combat and harvest have live receipts; the other six schools remain unclaimed ground until the i5 suite witnesses them.",
            "id": "QL-1",
            "size": "small",
            "title": "Try it and verify one school"
          },
          {
            "done_when": "Edit the starter quest file into a quest of your own, get `lab_reload` to report it armed, make it fire, and post the file. A second worked example is worth more than any amount of documentation.",
            "id": "QL-2",
            "size": "small",
            "title": "Author a quest that fires"
          }
        ],
        "id": "quest-lab",
        "license": "BUSL-1.1",
        "name": "Quest Lab Turnkey Package",
        "one_liner": "An arcane tome in-game that teaches you exactly what quests are possible, letting you practice writing them before trying them out for real.",
        "ownership": {
          "claimed_at": null,
          "claimed_by": null,
          "record": null,
          "state": "unclaimed"
        },
        "privacy_note": "Runs entirely locally. No data leaves your machine.",
        "recovery": null,
        "requires": [
          "A private Valheim world",
          "BepInEx installed on your client"
        ],
        "roadmap_milestones": [],
        "source": {
          "href": "https://github.com/djcdevelopment/comfy-quest/tree/main/network/mod/ComfyQuestLab",
          "kind": "public-repo",
          "note": "A client-only BepInEx plugin."
        },
        "status": "local-only",
        "status_detail": "A turnkey client-side mod. Install it, run `lab_setup` in the F5 console, and start learning. All 8 rune schools are hooked, and `lab_setup` also writes you a starter quest file you can edit and reload without restarting. The expansion routes all 34 safe canonical events through the exact evaluator shared with ComfyNetworkSense and prevents local/RPC or overload witnesses from double-completing a quest. Verified live so far: combat, harvest, gallery construction, and the seeded kill quest. The other six schools pass headless contract and game-assembly checks but still need bounded i5 live-suite receipts before they are described as witnessed.",
        "time_to_first_result": "10 minutes. Download the zip, drop the DLL in your BepInEx/plugins folder, launch a private world, and run `lab_setup` in the F5 console. It builds you a practice ground and writes a starter quest aimed at something standing in it, so you are never hunting for the thing your quest is about — `lab_target` puts a fresh one in front of you whenever you need another.",
        "what_it_does": "Draws an interactive console over the screen and covers all 86 practical atlas signatures across all 8 schools. Fifty-seven safe signatures normalize into 34 stable creator-facing quest events; low-level witnesses are visible only in a diagnostic profile and cannot bind quests. Edit a JSON file, run `lab_reload`, and watch the shared evaluator fire it or explain why it cannot.",
        "who_its_for": "Creators and leaders who want to learn how to write custom quests without guessing."
      },
      "facets": {
        "access": "site-download",
        "ownership": "unclaimed",
        "status": "local-only"
      },
      "id": "tool:quest-lab",
      "kind": "tool",
      "primary_audiences": [
        "creator"
      ],
      "published_at": null,
      "source": {
        "authority": "workbench-catalog",
        "locator": "corpus/mirrors/lumberjacks/workbench.json#/tools/quest-lab",
        "sha256": "87ceadcf5cd6326fe44a356dda4fd765da44f2516045ee68d1ffa77a1dc129ea"
      },
      "summary": "An arcane tome in-game that teaches you exactly what quests are possible, letting you practice writing them before trying them out for real.",
      "title": "Quest Lab Turnkey Package",
      "updated_at": null,
      "url": "https://am4.tail8e749c.ts.net/workbench#quest-lab"
    },
    {
      "audiences": [
        "creator",
        "moderator",
        "admin",
        "player-tester",
        "developer",
        "contributor"
      ],
      "data": {
        "access": {
          "href": "/workbench/downloads/quest-picker",
          "kind": "site-download",
          "published_at": "2026-07-29T01:12:00Z",
          "sha256": "d0b53016cbce5febb6f35d24b581a2112298f3650d48cf3190e44ece7ac4b65a",
          "size_bytes": 36335
        },
        "audiences": [
          "creator",
          "moderator",
          "admin",
          "player-tester",
          "developer",
          "contributor"
        ],
        "contribution": {
          "code_contributions": true,
          "stage_3_reward": "Commit access to recipes/quest-catalogs/ in baseline, and you triage this tool's thread."
        },
        "discussion": {
          "href": "https://discord.com/channels/1531911987074957442/1531977720790257866",
          "label": "Quest Picker thread"
        },
        "docs": [
          {
            "href": "https://github.com/djcdevelopment/comfy/blob/main/recipes/quest-catalogs/schema.md",
            "label": "Catalog schema (schema.md)"
          },
          {
            "href": "https://github.com/djcdevelopment/comfy/blob/main/recipes/quest-catalogs/quest-view-schema.md",
            "label": "Personal quest-view schema (quest-view-schema.md)"
          },
          {
            "href": "https://github.com/djcdevelopment/comfy/blob/main/recipes/quest-catalogs/sources.json",
            "label": "Source config seam (sources.json)"
          }
        ],
        "first_tasks": [
          {
            "done_when": "validate.py accepts the file and a GM can author a quest through the gm-template seam without editing harvest.py. sources.json already points at this path (entry rangers-example, currently disabled) but the file has never been written.",
            "id": "QP-1",
            "size": "small",
            "title": "Write gm-template-example.json"
          },
          {
            "done_when": "A new catalog JSON renders in the picker and every anomaly the harvest reported has an explanation — zero left unexplained.",
            "id": "QP-2",
            "size": "medium",
            "title": "Run the harvest against your own guild's tracker export"
          }
        ],
        "id": "quest-picker",
        "license": "BUSL-1.1 in this repo (community-steward safe harbor, converting to AGPL-3.0-only; see LICENSING.md). The byte-identical copies in the public comfy archive carry that repo's MIT license.",
        "name": "Quest Picker + Absorption Engine",
        "one_liner": "Turns a guild's real quest tracker into a single offline page where a player checks the quests they care about — and the game mod reads the result.",
        "ownership": {
          "claimed_at": null,
          "claimed_by": null,
          "record": null,
          "state": "unclaimed"
        },
        "privacy_note": "Harvested catalogs from a live guild tracker contain member names. The published sample uses synthetic data only — do not commit a real harvested catalog.",
        "recovery": null,
        "requires": [
          "Python 3",
          "openpyxl (only for .xlsx sources)",
          "A browser — the picker is a local file:// page, not a service"
        ],
        "roadmap_milestones": [
          "A5",
          "A7"
        ],
        "source": {
          "href": "https://github.com/djcdevelopment/comfy/tree/main/recipes/quest-catalogs",
          "kind": "public-repo",
          "note": "The same code lives in this repo at recipes/quest-catalogs/ and is byte-identical to the public copy."
        },
        "status": "live",
        "status_detail": "Runs today against real guild tracker exports: the harvest, the validator, and the picker all work end to end, and the mod reads the quest-view.json the picker saves. The download below is a cold-start kit with a synthetic sample guild — verified to run from a fresh folder with nothing but Python and openpyxl.",
        "time_to_first_result": "about 10 minutes",
        "what_it_does": "Python (standard library, plus openpyxl for .xlsx sources) harvests real guild quest trackers into one JSON catalog per guild. render_quest_picker.py folds a catalog into a single self-contained file:// HTML page with no server and no network calls. A player opens that page, checks the quests they want, and saves a personal quest-view.json that the game mod reads at runtime.",
        "who_its_for": "Guild stewards and GMs who already keep a quest tracker and want it to reach players in-game instead of dying in a spreadsheet tab."
      },
      "facets": {
        "access": "site-download",
        "ownership": "unclaimed",
        "status": "live"
      },
      "id": "tool:quest-picker",
      "kind": "tool",
      "primary_audiences": [
        "creator"
      ],
      "published_at": null,
      "source": {
        "authority": "workbench-catalog",
        "locator": "corpus/mirrors/lumberjacks/workbench.json#/tools/quest-picker",
        "sha256": "b5382085070d06fdf266769f8a8962e50f28192e7596210ec24e7b59aa0f2654"
      },
      "summary": "Turns a guild's real quest tracker into a single offline page where a player checks the quests they care about — and the game mod reads the result.",
      "title": "Quest Picker + Absorption Engine",
      "updated_at": null,
      "url": "https://am4.tail8e749c.ts.net/workbench#quest-picker"
    },
    {
      "audiences": [
        "creator",
        "moderator",
        "admin",
        "modder",
        "developer",
        "contributor"
      ],
      "data": {
        "access": {
          "href": null,
          "kind": "not-published",
          "published_at": null,
          "sha256": null,
          "size_bytes": null
        },
        "audiences": [
          "creator",
          "moderator",
          "admin",
          "modder",
          "developer",
          "contributor"
        ],
        "contribution": {
          "code_contributions": true,
          "stage_3_reward": "Commit access to the bridge once the back half lands in baseline, and you triage this tool's thread. The comfy archive it is recovered from stays read-only."
        },
        "discussion": {
          "href": "https://discord.com/channels/1531911987074957442/1535176938879066223",
          "label": "Quest submission → review bridge thread"
        },
        "docs": [
          {
            "href": "https://github.com/djcdevelopment/comfy/blob/main/handoffs/comfy-control-surface/QUEST.md",
            "label": "Quest handoff brief (QUEST.md)"
          },
          {
            "href": "https://github.com/djcdevelopment/comfy/blob/main/handoffs/comfy-control-surface/PROOF.md",
            "label": "What was proved (PROOF.md)"
          },
          {
            "href": "https://github.com/djcdevelopment/baseline/tree/main/recipes/quest-submission-bridge",
            "label": "Landed raw material (recipes/quest-submission-bridge/)"
          },
          {
            "href": "https://github.com/djcdevelopment/lumberjacks-platform/blob/main/fieldlab/docs/adr/0018-quest-proof-is-the-eventlog-row.md",
            "label": "The design decision (ADR 0018 — the proof is the EventLog row)"
          },
          {
            "href": "https://github.com/djcdevelopment/comfy-quest/tree/main/tools/quest-bridge",
            "label": "Ported bridge (tools/quest-bridge/)"
          }
        ],
        "first_tasks": [
          {
            "done_when": "A real in-game quest completion, produced by the live mod with QuestEvaluatorEnabled on, is fetched from the durable EventLog by tools/quest-bridge/fetch_completions.py and comes out as one human-readable review record with the quest's guild-command draft. The design call this task used to hide — re-materialize the old screenshot/trace evidence envelope, or accept a thinner record — is decided in ADR 0018 (the EventLog row is the evidence), and the fixture-driven path already passes in tests/test_quest_bridge.py; what remains is the live run. This is the claiming task for this tool.",
            "id": "QB-1",
            "size": "small",
            "title": "Prove the ported bridge live: one real in-game completion, EventLog to review record (design: ADR 0018)"
          }
        ],
        "id": "quest-submission-bridge",
        "license": "Split: the live front half (in this repo's mod) is BUSL-1.1 per LICENSING.md; the recoverable back half lives in the public comfy archive under MIT.",
        "name": "Quest Submission → Review Bridge",
        "one_liner": "The back half of quest capture: package what a player did in-game, land it in a review inbox, and turn it into a record a GM can read.",
        "ownership": {
          "claimed_at": null,
          "claimed_by": null,
          "record": null,
          "state": "unclaimed"
        },
        "privacy_note": "A submission record carries a player's name and what they did. Keep the review inbox off any public surface.",
        "recovery": null,
        "requires": [
          "Python 3, for the bridge consumer",
          "The mod running locally with QuestEvaluatorEnabled on",
          "Access to the durable EventLog (private plane — the lab box or a tunnel); the review inbox is operator tooling and stays off public surfaces"
        ],
        "roadmap_milestones": [
          "A5",
          "A7"
        ],
        "source": {
          "href": "https://github.com/djcdevelopment/comfy-quest/tree/main/tools/quest-bridge",
          "kind": "public-repo",
          "note": "The ported bridge is in this repo at tools/quest-bridge/, with its design recorded in fieldlab/docs/adr/0018-quest-proof-is-the-eventlog-row.md. The retired ComfyControlSurface originals stay byte-exact and unwired at recipes/quest-submission-bridge/ as raw material."
        },
        "status": "local-only",
        "status_detail": "Ported, not yet live-proven. The front half is alive in the mod today with tests — QuestViewLoader.cs reads a player's quest-view and QuestTriggerEvaluator.cs evaluates triggers in-game. The back half was never a matter of pointing a script at a folder: the old consumer expected an evidence envelope (screenshot, trace, position) that the live mod deliberately does not produce — its proof is the durable EventLog row (ADR 0012). That design call is now decided (ADR 0018: the EventLog row IS the evidence; no re-materialized screenshots) and implemented at tools/quest-bridge/ — EventLog row → thin submission → review record → guild-command export, fixture-proven in tests/test_quest_bridge.py. What remains for QB-1 is the live proof: one real in-game completion through that path. The archive copies at recipes/quest-submission-bridge/ stay as raw material.",
        "time_to_first_result": "About 10 minutes against the test fixture (tools/quest-bridge/, tests/test_quest_bridge.py). The live measurement — a real in-game completion out the other end — is QB-1.",
        "what_it_does": "Packages an in-game quest submission, lands it in a review inbox, and renders human-readable quest records a GM can act on without chasing screenshots.",
        "who_its_for": "GMs who want players to submit completions without a screenshot and a Discord message."
      },
      "facets": {
        "access": "not-published",
        "ownership": "unclaimed",
        "status": "local-only"
      },
      "id": "tool:quest-submission-bridge",
      "kind": "tool",
      "primary_audiences": [
        "creator"
      ],
      "published_at": null,
      "source": {
        "authority": "workbench-catalog",
        "locator": "corpus/mirrors/lumberjacks/workbench.json#/tools/quest-submission-bridge",
        "sha256": "6f9226ccf5073b62b952b8a161c0d3aa53b3302e6a52d6ffd77fc13379872ead"
      },
      "summary": "The back half of quest capture: package what a player did in-game, land it in a review inbox, and turn it into a record a GM can read.",
      "title": "Quest Submission → Review Bridge",
      "updated_at": null,
      "url": "https://am4.tail8e749c.ts.net/workbench#quest-submission-bridge"
    },
    {
      "audiences": [
        "player-tester",
        "admin",
        "developer",
        "contributor"
      ],
      "data": {
        "access": {
          "href": null,
          "kind": "not-published",
          "published_at": null,
          "sha256": null,
          "size_bytes": null
        },
        "audiences": [
          "player-tester",
          "admin",
          "developer",
          "contributor"
        ],
        "contribution": {
          "code_contributions": true,
          "stage_3_reward": "Commit access to Lumberjacks/src/Game.Gateway/Valheim/ in baseline, and you triage this tool's thread."
        },
        "discussion": {
          "href": "https://discord.com/channels/1531911987074957442/1531977732769058898",
          "label": "Self-service join thread"
        },
        "docs": [
          {
            "href": "https://github.com/djcdevelopment/lumberjacks-platform/blob/main/Lumberjacks/docs/workbench/tools/steam-join.md",
            "label": "What the flow does, and what is not wired up yet"
          },
          {
            "href": "/roadmap",
            "label": "Volunteer roadmap — the M2 and M5 gates this sits behind"
          },
          {
            "href": "https://github.com/djcdevelopment/lumberjacks-platform/blob/main/infra/gcp/p7/VOLUNTEER-ENDPOINT.md",
            "label": "Operator runbook — infra/gcp/p7/VOLUNTEER-ENDPOINT.md"
          }
        ],
        "first_tasks": [
          {
            "done_when": "You went from invite link to a running modded client, and every point where you hesitated, guessed, or had to ask is written down in the thread — including the ones that turned out to be your fault.",
            "id": "SJ-1",
            "size": "small",
            "title": "Walk the join flow end-to-end as a tester and file friction notes"
          },
          {
            "done_when": "A page answers the questions SJ-1 actually produced, in a tester's words rather than the operator's, and the next tester gets through without asking any of them.",
            "id": "SJ-2",
            "size": "medium",
            "title": "Write the tester-facing FAQ from the friction notes"
          }
        ],
        "id": "steam-join",
        "license": "BUSL-1.1 with the community-steward safe harbor, converting to AGPL-3.0-only; see LICENSING.md.",
        "name": "Steam Self-Service Join",
        "one_liner": "An invite link, a Steam sign-in, and a mod-pack zip with your credentials already in it — no config file to hand-edit.",
        "ownership": {
          "claimed_at": null,
          "claimed_by": null,
          "record": null,
          "state": "unclaimed"
        },
        "privacy_note": "The per-player token is stored only as a hash. The zip you receive carries your own credential — do not re-share it; ask for a reissue instead.",
        "recovery": null,
        "requires": [
          "Nothing yet — there is no public endpoint to try",
          "When it opens: a Steam account, Valheim, and an invite link from the operator"
        ],
        "roadmap_milestones": [
          "M2",
          "M5",
          "A7"
        ],
        "source": {
          "href": "https://github.com/djcdevelopment/lumberjacks-platform/tree/main/Lumberjacks/src/Game.Gateway/Valheim",
          "kind": "public-repo",
          "note": "Public and readable now — SteamEnrollmentEndpoints, SteamEnrollmentService, EnrollmentPages, ModpackReleaseCatalog, with real test suites, plus the operator runbook at infra/gcp/p7/VOLUNTEER-ENDPOINT.md."
        },
        "status": "local-only",
        "status_detail": "Built and working on the Gateway, but NOT publicly reachable today — so there is nothing here for you to click yet. The public /join path on this host currently belongs to a different service entirely, so the enrollment flow is not routed to the internet; that has to be untangled before anyone outside the operator's machine can walk it. Beyond routing, stated plainly: the full Steam sign-in round-trip has never been walked end to end (that is exactly first task SJ-1), rate limiting is not in place, only one client can be admitted at a time while the enrollment queue is shared, and volunteer platform readiness is recorded as NOT READY. The world this would connect you to is not open either. Opening this is gated on the server opening, which has not happened.",
        "time_to_first_result": "not yet — nothing to run until the routing and the server both open",
        "what_it_does": "An invite link opens a page that hands off to Steam OpenID sign-in. A one-use bootstrap token is exchanged for a personalized mod-pack zip with the player's credentials already baked in. Self-service update and reissue run through the same path. The per-player token is stored only as a hash.",
        "who_its_for": "The next wave of playtesters — people who will want to join and play without being told to edit a config file first. Not yet available to them."
      },
      "facets": {
        "access": "not-published",
        "ownership": "unclaimed",
        "status": "local-only"
      },
      "id": "tool:steam-join",
      "kind": "tool",
      "primary_audiences": [
        "player-tester"
      ],
      "published_at": null,
      "source": {
        "authority": "workbench-catalog",
        "locator": "corpus/mirrors/lumberjacks/workbench.json#/tools/steam-join",
        "sha256": "77e7988c79db8b9dda22f5eb47719b4c196da2a97e51f768ac5772b48a7d725b"
      },
      "summary": "An invite link, a Steam sign-in, and a mod-pack zip with your credentials already in it — no config file to hand-edit.",
      "title": "Steam Self-Service Join",
      "updated_at": null,
      "url": "https://am4.tail8e749c.ts.net/workbench#steam-join"
    },
    {
      "audiences": [
        "admin",
        "moderator",
        "creator",
        "curious",
        "contributor"
      ],
      "data": {
        "access": {
          "href": "https://github.com/djcdevelopment/ComfyStewardView",
          "kind": "public-repo",
          "published_at": null,
          "sha256": null,
          "size_bytes": null
        },
        "audiences": [
          "admin",
          "moderator",
          "creator",
          "curious",
          "contributor"
        ],
        "contribution": {
          "code_contributions": false,
          "stage_3_reward": "Documentation and feedback stewardship: you own this tool's quickstart and probe-utility docs, and you triage its thread. The repository is all-rights-reserved, so code changes are not on offer here until that licence changes."
        },
        "discussion": {
          "href": "https://discord.com/channels/1531911987074957442/1531977724711931956",
          "label": "ComfyStewardView thread"
        },
        "docs": [
          {
            "href": "/steward/",
            "label": "The live hosted sample — frozen Comfy Era16 snapshot"
          },
          {
            "href": "/steward/whitepaper.html",
            "label": "The Steward workflow whitepaper"
          },
          {
            "href": "https://github.com/djcdevelopment/ComfyStewardView",
            "label": "ComfyStewardView repository and README"
          }
        ],
        "first_tasks": [
          {
            "done_when": "A heatmap image from your own world is in the thread, with the build command you actually used and anything that tripped you up.",
            "id": "SV-1",
            "size": "small",
            "title": "Run it against a copy of any world .db and post one heatmap screenshot"
          },
          {
            "done_when": "Each GM probe utility has one line saying what it answers and one copy-pasteable invocation, and a steward who has never opened the source can pick the right probe from that page alone.",
            "id": "SV-2",
            "size": "medium",
            "title": "Write the missing quickstart for the probe utilities"
          }
        ],
        "id": "steward-view",
        "license": "Proprietary — all rights reserved per the repo's own LICENSE.md, which requires written permission and a paid license for reuse. Catalogued here for running it and giving feedback; the license posture is under review, and until it changes, contributions mean docs and feedback, not code redistribution.",
        "name": "ComfyStewardView",
        "one_liner": "Reads a Valheim world file and answers the questions that stop being walkable once a server gets big: where is everyone building, and who owns this.",
        "ownership": {
          "claimed_at": null,
          "claimed_by": null,
          "record": null,
          "state": "unclaimed"
        },
        "privacy_note": "Run it on world copies, not the live save. Output can contain player names — share aggregates and screenshots, not raw dumps.",
        "recovery": null,
        "requires": [
          "Nothing at all for the hosted sample — just a browser",
          "Java (or Docker), for running it against your own world",
          "A copy of a Valheim world .db — a copy, never the live save"
        ],
        "roadmap_milestones": [
          "A3",
          "A7"
        ],
        "source": {
          "href": "https://github.com/djcdevelopment/ComfyStewardView",
          "kind": "public-repo",
          "note": "A standalone public repository, separate from baseline. Clone it and build."
        },
        "status": "live",
        "status_detail": "A hosted, read-only sample is live at https://am4.tail8e749c.ts.net/steward/ — the full dashboard, DB-backed drilldowns, and pre-rendered map layers over a frozen Comfy Era16 snapshot. The public repo builds the same fat JAR for your own worlds and now ships a Dockerfile plus a one-command deploy script. What is missing is a quickstart for the roughly twenty GM probe utilities — they work, but today you have to read the source to know what each one does.",
        "time_to_first_result": "instant for the hosted sample; about 15 minutes against your own world",
        "what_it_does": "A Java fat-JAR extracts and parses a Valheim world file (.db), exposes a REST API on localhost:7080 (/api/v1/heatmap, /api/v1/points), and serves a browser heatmap viewer. Around twenty GM probe utilities sit alongside it for build-density clustering and ownership investigation.",
        "who_its_for": "Server stewards and GMs on worlds big enough that walking around stopped being a way to find out what is happening."
      },
      "facets": {
        "access": "public-repo",
        "ownership": "unclaimed",
        "status": "live"
      },
      "id": "tool:steward-view",
      "kind": "tool",
      "primary_audiences": [
        "admin"
      ],
      "published_at": null,
      "source": {
        "authority": "workbench-catalog",
        "locator": "corpus/mirrors/lumberjacks/workbench.json#/tools/steward-view",
        "sha256": "4c3a67abbed8490483cc7d73af8536b5290b89763477e63d50a06a6cc1db7629"
      },
      "summary": "Reads a Valheim world file and answers the questions that stop being walkable once a server gets big: where is everyone building, and who owns this.",
      "title": "ComfyStewardView",
      "updated_at": null,
      "url": "https://am4.tail8e749c.ts.net/workbench#steward-view"
    }
  ],
  "schema_version": 1,
  "source_catalog": "corpus/sources.json",
  "streams": {
    "dispatches": {
      "authority": "Discord forum starter posts; this file is a rebuildable public mirror",
      "channel_url": "https://discord.com/channels/1531911987074957442/1535624779418181703",
      "mirror": "corpus/mirrors/discord/dispatches.json",
      "source_watermark": "2026-08-08T12:53:16.973000+00:00"
    }
  }
}
