instar 1.3.587 → 1.3.589

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +237 -9
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/LiveTestArtifactStore.d.ts +129 -0
  5. package/dist/core/LiveTestArtifactStore.d.ts.map +1 -0
  6. package/dist/core/LiveTestArtifactStore.js +184 -0
  7. package/dist/core/LiveTestArtifactStore.js.map +1 -0
  8. package/dist/core/LiveTestGate.d.ts +54 -0
  9. package/dist/core/LiveTestGate.d.ts.map +1 -0
  10. package/dist/core/LiveTestGate.js +124 -0
  11. package/dist/core/LiveTestGate.js.map +1 -0
  12. package/dist/core/LiveTestHarness.d.ts +99 -0
  13. package/dist/core/LiveTestHarness.d.ts.map +1 -0
  14. package/dist/core/LiveTestHarness.js +102 -0
  15. package/dist/core/LiveTestHarness.js.map +1 -0
  16. package/dist/core/LocalSessionOwnershipStore.d.ts +56 -0
  17. package/dist/core/LocalSessionOwnershipStore.d.ts.map +1 -0
  18. package/dist/core/LocalSessionOwnershipStore.js +130 -0
  19. package/dist/core/LocalSessionOwnershipStore.js.map +1 -0
  20. package/dist/core/OwnershipApplier.d.ts +78 -0
  21. package/dist/core/OwnershipApplier.d.ts.map +1 -0
  22. package/dist/core/OwnershipApplier.js +101 -0
  23. package/dist/core/OwnershipApplier.js.map +1 -0
  24. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  25. package/dist/core/PostUpdateMigrator.js +9 -0
  26. package/dist/core/PostUpdateMigrator.js.map +1 -1
  27. package/dist/core/WorkEvidence.d.ts +17 -0
  28. package/dist/core/WorkEvidence.d.ts.map +1 -1
  29. package/dist/core/WorkEvidence.js +17 -0
  30. package/dist/core/WorkEvidence.js.map +1 -1
  31. package/dist/core/devGatedFeatures.d.ts.map +1 -1
  32. package/dist/core/devGatedFeatures.js +12 -0
  33. package/dist/core/devGatedFeatures.js.map +1 -1
  34. package/dist/core/gapBCommitmentEvidence.d.ts +143 -0
  35. package/dist/core/gapBCommitmentEvidence.d.ts.map +1 -0
  36. package/dist/core/gapBCommitmentEvidence.js +138 -0
  37. package/dist/core/gapBCommitmentEvidence.js.map +1 -0
  38. package/dist/core/types.d.ts +21 -0
  39. package/dist/core/types.d.ts.map +1 -1
  40. package/dist/core/types.js.map +1 -1
  41. package/dist/monitoring/CommitmentTracker.d.ts +12 -0
  42. package/dist/monitoring/CommitmentTracker.d.ts.map +1 -1
  43. package/dist/monitoring/CommitmentTracker.js +14 -0
  44. package/dist/monitoring/CommitmentTracker.js.map +1 -1
  45. package/dist/monitoring/ReapLog.d.ts +11 -0
  46. package/dist/monitoring/ReapLog.d.ts.map +1 -1
  47. package/dist/monitoring/ReapLog.js +1 -0
  48. package/dist/monitoring/ReapLog.js.map +1 -1
  49. package/dist/monitoring/ResumeQueueDrainer.d.ts +15 -0
  50. package/dist/monitoring/ResumeQueueDrainer.d.ts.map +1 -1
  51. package/dist/monitoring/ResumeQueueDrainer.js +12 -1
  52. package/dist/monitoring/ResumeQueueDrainer.js.map +1 -1
  53. package/dist/scaffold/templates.d.ts.map +1 -1
  54. package/dist/scaffold/templates.js +2 -0
  55. package/dist/scaffold/templates.js.map +1 -1
  56. package/dist/server/AgentServer.d.ts +3 -0
  57. package/dist/server/AgentServer.d.ts.map +1 -1
  58. package/dist/server/AgentServer.js +2 -0
  59. package/dist/server/AgentServer.js.map +1 -1
  60. package/dist/server/routes.d.ts +4 -0
  61. package/dist/server/routes.d.ts.map +1 -1
  62. package/dist/server/routes.js +58 -0
  63. package/dist/server/routes.js.map +1 -1
  64. package/package.json +1 -1
  65. package/src/data/builtin-manifest.json +64 -64
  66. package/src/scaffold/templates.ts +2 -0
  67. package/upgrades/1.3.588.md +27 -0
  68. package/upgrades/1.3.589.md +68 -0
  69. package/upgrades/side-effects/autonomous-registration-guarantee.md +51 -0
  70. package/upgrades/side-effects/live-user-channel-proof-standard.md +54 -0
@@ -0,0 +1,68 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ A new constitutional standard — **"Live-User-Channel Proof Before Done"** — plus its
9
+ structural enforcement, plus the first feature held to it: the cross-machine topic-transfer
10
+ fix.
11
+
12
+ - **The standard** (`docs/STANDARDS-REGISTRY.md`): a user-facing feature is not "done"
13
+ until a user-role session has driven it end-to-end through its real user surface
14
+ (Telegram AND Slack for a channel feature) before the operator is ever asked to test.
15
+ Migrated to existing agents via the CLAUDE.md template + `PostUpdateMigrator`.
16
+ - **The completion gate** (`LiveTestGate` + `LiveTestArtifactStore`, wired into
17
+ `POST /autonomous/evaluate-completion`): refuses a "done" verdict for a user-facing
18
+ feature without a verified, signed live-test artifact. Ships DARK + dev-gated
19
+ (`monitoring.liveTestGate`, mode dry-run) — it COMPUTES the veto and logs it, but only
20
+ `mode:veto` overrides a verdict, and even then the only effect is keeping the run
21
+ working (the safe direction).
22
+ - **The user-role harness core** (`LiveTestHarness`): runs a scenario matrix as the user
23
+ over an injected channel driver, writes the signed artifact the gate reads, and refuses
24
+ volatile/permission scenarios on a non-demo channel.
25
+ - **The transfer fix** (`LocalSessionOwnershipStore` + `OwnershipApplier`, wired DARK
26
+ behind `multiMachine.durableOwnership`): the cross-machine ownership store is now durable
27
+ and replicated (it materializes ownership on the target from the replicated placement
28
+ journal), so a topic seat genuinely moves between machines. `POST /pool/transfer` now
29
+ reports an honest `seatMoved` instead of a bare `ok:true`.
30
+
31
+ ## What to Tell Your User
32
+
33
+ Nothing changes in normal use yet — everything ships dark behind flags and is dogfooded on
34
+ development agents first. The point of the work: I should never again report a feature
35
+ "done" without having tested it the way *you* would — by acting as you, through the real
36
+ channels — so you stop being the one who discovers a broken feature. The first feature held
37
+ to that bar is the "move a conversation between my machines" fix.
38
+
39
+ ## Summary of New Capabilities
40
+
41
+ - `GET`/route surface: the completion gate post-checks `/autonomous/evaluate-completion`
42
+ (dark/dev-gated, dry-run default).
43
+ - `POST /pool/transfer` now returns `seatMoved` (+ a reason when false).
44
+ - New dev-gated flags: `monitoring.liveTestGate.{enabled,mode}`,
45
+ `multiMachine.durableOwnership.enabled` (both omit `enabled` → live-on-dev / dark-fleet).
46
+ - The constitution carries the "Live-User-Channel Proof Before Done" standard, migrated to
47
+ existing agents.
48
+
49
+ ## Evidence
50
+
51
+ **The bug being fixed (transfer):** 2026-06-15, the operator ran `POST /pool/transfer
52
+ {topic, to:"Mini"}` on a live Telegram topic. Observed BEFORE: response `ok:true`, but the
53
+ seat never moved — the next message routed back to the Laptop (the operator found it on the
54
+ first live interaction). Root cause, grounded in the running code (v1.3.586):
55
+ `SessionOwnershipRegistry` used `InMemorySessionOwnershipStore` with no cross-machine
56
+ replication — the placement was written into the source machine's in-memory Map and never
57
+ materialized on the target (`server.ts:16002` owner-resolution reads null → `SessionRouter`
58
+ treats it as unowned → places locally instead of forwarding).
59
+
60
+ **Observed AFTER (in tests — live hardware proof is the tracked next phase):** the durable
61
+ store + `OwnershipApplier` converge a transferred topic to exactly one owner (the target)
62
+ across a simulated crash mid-move (`tests/integration/ownership-transfer-crash-safety.test.ts`);
63
+ `POST /pool/transfer` now returns `seatMoved:false` with a reason when ownership did not
64
+ move. The gate's anti-hallucination check rejects a hand-edited artifact (hash-mismatch),
65
+ and the wired completion route overrides a `met:true` verdict for a user-facing feature with
66
+ no verified artifact (`tests/integration/live-test-gate-completion-route.test.ts`). 49 new
67
+ tests across 8 files, all green; full pre-commit lint suite + tsc clean. The end-to-end LIVE
68
+ Laptop↔Mini proof is the explicitly-tracked next phase (this ships the foundation dark).
@@ -0,0 +1,51 @@
1
+ # Side-Effects Review — Autonomous-Registration Guarantee (GAP-B)
2
+
3
+ **Spec:** `docs/specs/autonomous-registration-guarantee.md` (CONVERGED 2 rounds + Part-D focused re-converge, approved:true) · P1 GAP-B
4
+ **Change:** revive an UNregistered-but-actively-working autonomous run after an age-limit reap, by injecting commitment-evidence into the reaper's existing eligibility path (Part B, DARK) + promoting the inert `recentUserMessage` KEEP-predicate to real (Part D, the one live part) + an observe-only attention surface (Part A). Part C was already shipped (#1186).
5
+
6
+ ## Phase 1 — Principle check (signal vs authority)
7
+ Touches the reaper eligibility decision, so the principle applies. **No new brittle blocking authority:** Part B injects a *signal* (a fresh qualifying open-commitment) into the **existing** `evidenceEligible`/ResumeQueue authority — it never decides revival itself. Part A is observe-only (an aggregated attention signal). Part D promotes a KEEP-*predicate* (a signal ReapGuard already consults). The load-bearing safety is the **D8 agreement-invariant**: KEEP and the new eligibility compute from ONE shared `recentUserMessage` predicate, so they cannot disagree (the 2026-06-13 13-session loop came from disagreement). Compliant (`docs/signal-vs-authority.md`).
8
+
9
+ ## Phase 2 — Plan
10
+ Built in `.worktrees/gapb-autonomous-registration` (rebased onto current `JKHeadley/main c41b27db5`). Decision points: the `sessionReaped` evidence wiring (gains an additive, dark, corroborated source) + ReapGuard/SessionReaper KEEP behavior (Part D un-stub). Rollback: dark by default (Part B needs explicit `enabled:true`) + revert the PR.
11
+
12
+ ## 1. Over-block
13
+ The change does not block — it injects evidence to REVIVE. The inverse risk is **over-revive** (resurrecting a finished/idle run). Bounded by: the D2 qualifying filter (pending + agent-driven + this-machine + not-beacon-paused), D1 createdAt-freshness (6h), the **D8 agreement** (also needs a recent user message — a stale-per-KEEP commitment can't revive), drain-time D9 re-validation (`commitmentStillActiveForTopic` — a since-closed commitment is invalidated), the existing **resurrection cap** (≤2 resumes/24h/topic, then gives up loudly), and — decisively — Part B ships **DARK** (no injection ⇒ no revival) until `enabled:true`.
14
+
15
+ ## 2. Under-block
16
+ A genuinely-working unregistered run with **no open commitment AND no recent user message** is not revived — the structural registration guarantee (make "go autonomous" always write the state file) is the root fix, an explicitly tracked follow-up (Follow-ups section), not this PR. Part B is a *corroborated* backstop (commitment + recent activity), not a universal catch.
17
+
18
+ ## 3. Level-of-abstraction fit
19
+ Correct layer. The evidence feeds the **existing** `evidenceEligible`/ResumeQueue authority (no parallel revival path; no new WorkEvidence enum value — reuses `build-or-autonomous-active` + a distinct reason tag). Part D shares ONE predicate across all consumers (`gapBCommitmentEvidence.recentUserMessageFromHistory`), so KEEP and eligibility are computed identically — the right place to enforce agreement.
20
+
21
+ ## 4. Signal vs authority compliance
22
+ See Phase 1. No brittle check gains blocking authority. Part B = signal → existing gate; Part A = observe-only; Part D = a shared predicate. Fail-open throughout (D7). Compliant.
23
+
24
+ ## 5. Interactions
25
+ - **The D8 loop-prevention** is the central interaction: ReapGuard's KEEP (`ReapGuard.ts:149`, 8h) and the new eligibility both call the same `recentUserMessage` — verified by the anti-loop regression test (a stale-per-KEEP commitment is NOT eligible).
26
+ - **Part D un-stubs FIVE live sites consistently** via one shared closure spread into the single `reapGuardDeps` object backing BOTH `ReapGuard` (:137 standalone 30min, :149 commitment 8h, :221/:239 terminate-path) AND `SessionReaper` (:489 `staleIdle` inversion). All safe-direction (keep-more) — none makes the reaper kill more.
27
+ - **Drain-time D9** re-checks liveness for `COMMITMENT_ACTIVE_RUN_REASON` (state-file source is untouched, routed by the distinct reason).
28
+ - No double-fire: the commitment branch is mutually exclusive with the state-file branch (PRESENT vs ABSENT).
29
+
30
+ ## 6. External surfaces
31
+ - Part A: ONE aggregated attention signal (`unregistered-autonomous:<topic>`, dedup'd via the existing chokepoint) — only when Part B fires LIVE. No new HTTP route.
32
+ - Reap-log gains an optional `evidenceSource` field (additive, back-compat, no PII — D3).
33
+ - Observable via the existing reap-log; dark by default so no user-visible behavior change until enabled.
34
+
35
+ ## 7. Multi-machine posture
36
+ **Machine-local by design.** Part B's qualifying filter requires `originMachineId` is this machine or absent — a *replicated peer* commitment is advisory data, never revival authority (it can't revive a session on the wrong machine). `recentUserMessage` reads THIS machine's `TelegramAdapter.getTopicHistory`. No replicated/persisted state introduced; the per-topic state file source is unchanged. No generated URL, no cross-machine notice.
37
+
38
+ ## 8. Rollback cost
39
+ Cheap and dark. (a) **Dark by default:** Part B is inert unless `monitoring.resumeQueue.commitmentEvidence.enabled === true`; even when armed it defaults to `dryRun:true` (no spawn). (b) **The one live change** (Part D `recentUserMessage` promotion) is safe-direction (keep-more) and bounded by the window — to revert just that, restore the stub. (c) **Full back-out:** revert the PR — additive code, no data migration, no state repair. The config keys are code-defaulted (absent from ConfigDefaults) so removal is clean.
40
+
41
+ ## No-deferrals (Phase 4.5)
42
+ The structural registration guarantee (root fix) and the stopGate per-topic plumbing are explicitly **tracked** follow-ups (Follow-ups section, `<!-- tracked -->` markers) — Part B is a deliberate *corroborated backstop*, the honest scope, not a partial fix papering over the root.
43
+
44
+ ## Phase 5 — Second-pass review
45
+ *(appended below)*
46
+ **Concur with the review.** An independent reaper-class reviewer verified the load-bearing safety against the real code (file:line), not the artifact:
47
+ - D8 agreement: the SAME closure `recentUserMessageShared` backs both GAP-B eligibility (`gapBCommitmentEvidence.ts:150`) and ReapGuard's commitment KEEP (`ReapGuard.ts:149`/:239), with a single-sourced window (`staleCommitmentWindowMinutes ?? 480`); GAP-B's `commitmentQualifies` is a strict superset-filter of ReapGuard's, so a GAP-B revive structurally implies KEEP would have fired — the 2026-06-13 loop is impossible.
48
+ - Dark containment airtight: armed only on `enabled===true`, dryRun-default-true; dryRun fires the Part A surface only, tags/injects nothing; disarmed skips the cost-bearing eligibility entirely.
49
+ - All 5 `recentUserMessage` sites (ReapGuard 137/149/221/239 + SessionReaper 489) consume the real shared predicate (stub at server.ts removed); tsc-clean proves no mismatch; all safe-direction (keep-more).
50
+ - Fail-open (D7) + D9 drain-revalidation verified both sides (`safeBool(..., true)` → throw resolves still-active, never a wrong drop); multi-machine strand closed by the `originMachineId` local-origin filter.
51
+ - No new failure mode, double-fire (commitment vs state-file branches mutually exclusive), or cross-machine revival risk.
@@ -0,0 +1,54 @@
1
+ # Side-Effects Review — Live-User-Channel Proof standard + multi-machine transfer fix
2
+
3
+ **Spec:** docs/specs/live-user-channel-proof-standard.md (CONVERGED iter 6, cross-model external review, self-approved under standing autonomous pre-approval — Justin topic 13481). **Tracking:** CMT-1568. **Parent principle:** Structure beats Willpower / Observation Needs Structure.
4
+ **Ships DARK + dev-gated:** `monitoring.liveTestGate` (mode dry-run) and `multiMachine.durableOwnership` — both OMIT `enabled` so `resolveDevAgentGate` flips them live-on-dev / dark-on-fleet. Single-machine installs are a strict no-op for the transfer fix.
5
+ **Files:** src/core/LocalSessionOwnershipStore.ts (new), src/core/OwnershipApplier.ts (new), src/core/LiveTestArtifactStore.ts (new), src/core/LiveTestGate.ts (new), src/core/LiveTestHarness.ts (new), src/core/devGatedFeatures.ts, src/commands/server.ts, src/server/AgentServer.ts, src/server/routes.ts, src/scaffold/templates.ts, src/core/PostUpdateMigrator.ts, docs/STANDARDS-REGISTRY.md, docs/specs/live-user-channel-proof-standard.md (+ .eli16.md + report), tests/unit/* + tests/integration/* (8 new test files, 49 tests).
6
+
7
+ ## What changed
8
+
9
+ 1. **LocalSessionOwnershipStore.ts (new):** a DURABLE per-session ownership substrate implementing the existing store-agnostic `SessionOwnershipStore` interface (read + casWrite). Per-session JSON files, atomic tmp+rename, in-memory hot-path cache, fast-forward CAS. Replaces the in-memory-only store (the transfer bug's root) behind the dev-gate.
10
+ 2. **OwnershipApplier.ts (new):** off-hot-path tick that materializes durable LOCAL ownership from the REPLICATED coherence-journal placement entries (read via `CoherenceJournalReader.query({kind:'topic-placement'})`), so the machine a topic moved TO resolves the right owner. Fast-forward CAS only (a stale replicated entry can never clobber a fresher local decision).
11
+ 3. **server.ts:** behind `resolveDevAgentGate(multiMachine.durableOwnership.enabled)`, swaps `InMemorySessionOwnershipStore` → `LocalSessionOwnershipStore` and ticks the `OwnershipApplier` (interval + boot). Off → today's exact behavior.
12
+ 4. **routes.ts (`POST /pool/transfer`):** adds an honest `seatMoved` field computed from the real post-transfer owner (+ `seatMoveReason` when false). `ok:true` now means "request processed", `seatMoved` means "the conversation actually runs on the target". Closes the 2026-06-15 `ok:true`-but-never-moved lie.
13
+ 5. **LiveTestArtifactStore.ts (new):** the §4.4 signed, hash-chained artifact contract. Canonical serialization → sha256 → Ed25519 signature; per-machine ledger segments (`state/live-test-ledger.<machineId>.jsonl`, union-on-read — no cross-machine concurrent append). The gate re-reads + recomputes the hash, so a hand-edited "I tested it" record fails (the anti-hallucination core). Threat model: drift-correction, NOT an adversarial-runner security boundary (git-commit anchor is the backstop).
14
+ 6. **LiveTestGate.ts (new):** the §4 completion-gate brain. allow/veto/nudge over surfaces (§4.5) + risk categories (§4.6) + BLOCKED taxonomy + the seatMoved poison rule. Signal-vs-Authority: the keyword classifier holds NO standalone blocking authority — a HARD veto requires a DECLARED `userFacing:true` + no verified artifact; an undeclared-but-classified goal gets a soft return-to-work NUDGE.
15
+ 7. **server.ts + AgentServer.ts + routes.ts (gate wiring):** server.ts constructs the gate dev-gated (mode dry-run default), signing+verifying with the machine-identity keypair (`idMgr.loadSigningKey()` + derived public key). Threaded through `AgentServer` options → `RouteContext`. `POST /autonomous/evaluate-completion` post-checks a `met:true` verdict: veto-mode overrides `met:true`→`met:false`; dry-run/warn surface the would-block but honor the verdict; a gate error falls through (completion judge stays primary authority).
16
+ 8. **LiveTestHarness.ts (new):** the §5 user-role scenario runner over an injected `ChannelDriver` (send/awaitReply/isDemoChannel). §5.3 structural guard refuses volatile/permission scenarios on a non-demo channel BEFORE any send. Deterministic verdicts off captured protocol evidence (reply text + responder machine id). §5.5 timeout=FAIL after bounded retries. (Real Telegram/Slack/dashboard drivers + the live proof are the tracked follow-on phase.)
17
+ 9. **devGatedFeatures.ts:** two new entries — `liveTestGate` (monitoring.liveTestGate.enabled) and `durableOwnership` (multiMachine.durableOwnership.enabled), each with a non-destructive justification.
18
+ 10. **STANDARDS-REGISTRY.md + templates.ts + PostUpdateMigrator.ts:** the "Live-User-Channel Proof Before Done" standard article + the CLAUDE.md awareness section (generateClaudeMd + content-sniffed migrateClaudeMd), registered in the feature-delivery-completeness parity gate (legacyMigratorSections).
19
+
20
+ ## Blast radius
21
+
22
+ - **Config-gated, not wiring-gated.** With both flags dark (fleet default), every seam is a strict no-op: server.ts keeps `InMemorySessionOwnershipStore` + never constructs the applier; the gate is never constructed (`ctx.liveTestGate` null) so `/autonomous/evaluate-completion` returns the raw verdict exactly as today. On a dev agent the durable store + applier go live (no destructive write — atomic per-session JSON, reversible to InMemory) and the gate runs in dry-run (computes + logs, never overrides).
23
+ - **The gate cannot cause a false "done."** It only ever turns a `met:true` into `met:false` (keep working — the safe direction) and only in `mode:veto`; it can NEVER turn `met:false` into `met:true`. A gate error falls through to the original verdict.
24
+ - **The transfer fix changes cross-machine routing authority but only on dev.** The applier adopts only strictly-newer placements (epoch fast-forward), so it can't strand a topic ownerless or create a second owner (crash-safety proven by the integration test). Single-machine = no peer placements = no-op.
25
+ - **No new HTTP route.** The gate post-checks an EXISTING route; the transfer fix adds a field to an EXISTING route. No new MeshRpc verb, no broadcast.
26
+
27
+ ## Risk + mitigation
28
+
29
+ - **Risk:** the durable store / applier mis-routes on a dev agent. **Mitigation:** dev-gated + 18 tests (durable persistence, restart-survival, fast-forward CAS, crash-safety single-owner convergence, no-split-brain). Reversible by flipping the flag (the journal remains the source of truth).
30
+ - **Risk:** the gate wrongly vetoes a legitimate completion. **Mitigation:** dry-run default (never overrides); HARD veto only on the objective `userFacing:true` + no-artifact; a gate error falls through; 11 gate-logic tests + 6 route wiring-integrity tests cover both sides of every boundary.
31
+ - **Risk:** an agent hand-writes an artifact to buy the exit. **Mitigation:** the artifact is canonical-hashed + Ed25519-signed + re-verified from disk at gate time; a hand-edit fails the hash check (proven). Honest threat model: drift-correction, not adversarial-runner.
32
+ - **Risk:** a gate/store error fails the completion route or server boot. **Mitigation:** every new path is try/catch-guarded toward the safe direction (no veto / today's verdict / InMemory store); server boot never fails on a gate-wiring error.
33
+
34
+ ## Migration parity
35
+
36
+ - New dev-gated flags OMIT `enabled` in config (resolveDevAgentGate handles them) — no `migrateConfig` change needed; registered in `DEV_GATED_FEATURES` (the wiring test guards them).
37
+ - The "Live-User-Channel Proof Before Done" CLAUDE.md section ships in `generateClaudeMd` (new agents) + an idempotent content-sniffed `migrateClaudeMd` patcher (existing agents), and is tracked in `feature-delivery-completeness` `legacyMigratorSections`.
38
+ - The STANDARDS-REGISTRY.md article ships with the package (auto-distributed to existing agents).
39
+
40
+ ## Dark-gate line-map
41
+
42
+ - UNCHANGED. No new inline `enabled: false` line was added to `ConfigDefaults.ts` — both new flags rely on OMISSION (the dev-gate convention), so no `enabled:` line shifted. Verified: `node scripts/lint-dev-agent-dark-gate.js` → clean.
43
+
44
+ ## Rollback
45
+
46
+ - Revert the branch, OR leave the flags dark (fleet default = no behavior change). The durable-ownership flag is reversible to `InMemorySessionOwnershipStore` with no data loss (the coherence journal remains authoritative). The gate flag dark = the completion route returns the raw verdict as today.
47
+
48
+ ## Evidence
49
+
50
+ - 49 new tests across 8 files (unit + integration), all green. Full unit suite green (the one transient passes in isolation — a flaky port race, not a regression). tsc clean; the full pre-commit lint suite (14 lints) clean; dark-gate lint, dev-gate wiring test, no-silent-fallbacks ratchet, feature-delivery-completeness all green.
51
+ - Spec converged through 6 rounds (6 internal reviewers + cross-model GPT + Gemini external); convergence report at docs/specs/reports/live-user-channel-proof-standard-convergence.md.
52
+ - **NOT yet done by its own standard:** the live Laptop↔Mini proof (the real-channel drivers + the deploy) is the tracked next phase; this PR ships the structural foundation DARK, with the flag flip gated on that live proof.
53
+
54
+ <!-- decision-audit trace anchor: CMT-1568 -->