instar 1.3.131 → 1.3.133

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 +92 -1
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/config/ConfigDefaults.d.ts.map +1 -1
  5. package/dist/config/ConfigDefaults.js +10 -0
  6. package/dist/config/ConfigDefaults.js.map +1 -1
  7. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  8. package/dist/core/PostUpdateMigrator.js +35 -2
  9. package/dist/core/PostUpdateMigrator.js.map +1 -1
  10. package/dist/core/types.d.ts +12 -0
  11. package/dist/core/types.d.ts.map +1 -1
  12. package/dist/core/types.js.map +1 -1
  13. package/dist/monitoring/AgentWorktreeReaper.d.ts +103 -0
  14. package/dist/monitoring/AgentWorktreeReaper.d.ts.map +1 -0
  15. package/dist/monitoring/AgentWorktreeReaper.js +159 -0
  16. package/dist/monitoring/AgentWorktreeReaper.js.map +1 -0
  17. package/dist/monitoring/CiFailurePoller.d.ts +1 -7
  18. package/dist/monitoring/CiFailurePoller.d.ts.map +1 -1
  19. package/dist/monitoring/CiFailurePoller.js +5 -12
  20. package/dist/monitoring/CiFailurePoller.js.map +1 -1
  21. package/dist/monitoring/CorrectionAnalyzer.d.ts +65 -0
  22. package/dist/monitoring/CorrectionAnalyzer.d.ts.map +1 -0
  23. package/dist/monitoring/CorrectionAnalyzer.js +78 -0
  24. package/dist/monitoring/CorrectionAnalyzer.js.map +1 -0
  25. package/dist/monitoring/CorrectionCaptureLoop.d.ts +130 -0
  26. package/dist/monitoring/CorrectionCaptureLoop.d.ts.map +1 -0
  27. package/dist/monitoring/CorrectionCaptureLoop.js +249 -0
  28. package/dist/monitoring/CorrectionCaptureLoop.js.map +1 -0
  29. package/dist/monitoring/CorrectionLedger.d.ts +149 -0
  30. package/dist/monitoring/CorrectionLedger.d.ts.map +1 -0
  31. package/dist/monitoring/CorrectionLedger.js +386 -0
  32. package/dist/monitoring/CorrectionLedger.js.map +1 -0
  33. package/dist/monitoring/CorrectionLoopDriver.d.ts +135 -0
  34. package/dist/monitoring/CorrectionLoopDriver.d.ts.map +1 -0
  35. package/dist/monitoring/CorrectionLoopDriver.js +185 -0
  36. package/dist/monitoring/CorrectionLoopDriver.js.map +1 -0
  37. package/dist/monitoring/HumanAsDetectorLog.d.ts +31 -1
  38. package/dist/monitoring/HumanAsDetectorLog.d.ts.map +1 -1
  39. package/dist/monitoring/HumanAsDetectorLog.js +70 -0
  40. package/dist/monitoring/HumanAsDetectorLog.js.map +1 -1
  41. package/dist/monitoring/agentWorktreeGit.d.ts +43 -0
  42. package/dist/monitoring/agentWorktreeGit.d.ts.map +1 -0
  43. package/dist/monitoring/agentWorktreeGit.js +194 -0
  44. package/dist/monitoring/agentWorktreeGit.js.map +1 -0
  45. package/dist/monitoring/scrubSecrets.d.ts +23 -0
  46. package/dist/monitoring/scrubSecrets.d.ts.map +1 -0
  47. package/dist/monitoring/scrubSecrets.js +41 -0
  48. package/dist/monitoring/scrubSecrets.js.map +1 -0
  49. package/dist/scaffold/templates.d.ts.map +1 -1
  50. package/dist/scaffold/templates.js +1 -0
  51. package/dist/scaffold/templates.js.map +1 -1
  52. package/dist/server/AgentServer.d.ts +4 -0
  53. package/dist/server/AgentServer.d.ts.map +1 -1
  54. package/dist/server/AgentServer.js +20 -0
  55. package/dist/server/AgentServer.js.map +1 -1
  56. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  57. package/dist/server/CapabilityIndex.js +8 -3
  58. package/dist/server/CapabilityIndex.js.map +1 -1
  59. package/dist/server/routes.d.ts +7 -0
  60. package/dist/server/routes.d.ts.map +1 -1
  61. package/dist/server/routes.js +213 -0
  62. package/dist/server/routes.js.map +1 -1
  63. package/package.json +1 -1
  64. package/src/data/builtin-manifest.json +63 -63
  65. package/src/scaffold/templates/jobs/instar/correction-analyzer.md +32 -0
  66. package/src/scaffold/templates.ts +1 -0
  67. package/upgrades/1.3.132.md +42 -0
  68. package/upgrades/1.3.133.md +70 -0
  69. package/upgrades/side-effects/agent-worktree-reaper.md +96 -0
  70. package/upgrades/side-effects/correction-preference-learning-sentinel-slice1b.md +79 -0
@@ -0,0 +1,70 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- bump: patch -->
4
+
5
+ ## What Changed
6
+
7
+ **A new reaper reclaims stale agent worktrees — the disk-and-CPU backlog behind
8
+ the macOS indexing load — safely, and only what it can prove is reclaimable.**
9
+
10
+ CLI-created worktrees under `~/.instar/agents/<agent>/.worktrees/` are full
11
+ source-tree checkouts that accumulate with no cleanup (measured: ~120 worktrees /
12
+ ~55 GB on one agent). The existing WorktreeReaper only manages a different,
13
+ binding-tracked worktree system; these CLI worktrees were entirely unmanaged.
14
+ That backlog is both a disk drain and the workload behind the macOS Spotlight CPU
15
+ problem the new `.metadata_never_index` marker mitigates.
16
+
17
+ The new `AgentWorktreeReaper` reclaims a worktree ONLY when ALL of these hold:
18
+ it is not in use (no live session/index lock AND no running process whose working
19
+ directory is inside it), clean (no uncommitted or untracked changes), and merged
20
+ (its branch's content is already in the default branch, detected via `git cherry`
21
+ patch-id so fast-forward, merge-commit, rebased, and single-commit-squash merges
22
+ all count). For a merged branch the work is already in main, so removing the
23
+ working-dir checkout loses nothing — the branch and its commits stay in the repo.
24
+ Any ambiguity keeps the worktree. It ships **OFF and dry-run by default** — the
25
+ only worktree path that deletes on a heuristic — with a bounded per-pass blast
26
+ radius. (Staleness is deliberately not a gate: on a high-velocity fleet every
27
+ branch is rebased onto recent main, so timestamps cannot distinguish abandoned
28
+ from active — "in use" is the real signal.)
29
+
30
+ This is the second piece of the **OS resource hygiene** facet of the Responsible
31
+ Resource Usage standard, paired with the Spotlight-exclusion marker.
32
+
33
+ ## What to Tell Your User
34
+
35
+ Nothing to configure yet — it is off by default on purpose, because it deletes
36
+ worktrees. There is a new read-only report that shows which old worktrees could be
37
+ safely reclaimed and why each one is being kept, so you can review before turning
38
+ it on. It is deliberately cautious: it will never remove a worktree that has
39
+ unsaved changes, an unmerged branch, or anyone actively using it. Once you have
40
+ looked at the report and are comfortable, you can enable it to keep the worktree
41
+ pile from growing and reclaim disk.
42
+
43
+ ## Summary of New Capabilities
44
+
45
+ - New `AgentWorktreeReaper` (`src/monitoring/AgentWorktreeReaper.ts`) — pure,
46
+ injectable classifier; reaps only merged + clean + not-in-use worktrees;
47
+ dry-run + dark by default; bounded `maxReapsPerPass`.
48
+ - Git-backed signals (`src/monitoring/agentWorktreeGit.ts`) — `git worktree list`
49
+ parsing bounded to `.worktrees/`, `git status` cleanliness, a lock + process-cwd
50
+ in-use check, `git cherry`-based conservative merged-detection, and `git worktree
51
+ remove` via SafeGitExecutor.
52
+ - New read-only endpoint `GET /worktrees/agent-reaper` — per-worktree verdict +
53
+ reclaimable count + whether reaping is armed.
54
+ - Config `monitoring.agentWorktreeReaper` (`enabled` false, `dryRun` true,
55
+ `maxReapsPerPass` 20), auto-migrated to existing agents.
56
+
57
+ ## Evidence
58
+
59
+ - `tests/unit/agent-worktree-reaper.test.ts` — the safety classifier on BOTH sides
60
+ of every gate (in-use / dirty / unmerged / detached all KEEP; reap-eligible only
61
+ when all clear), cheap-gates-first (no git merged-check on a dirty worktree),
62
+ dry-run never deletes, blast-radius cap, the `git cherry` merged-detection, and
63
+ the lock+process-cwd in-use check.
64
+ - `tests/integration/agent-worktree-reaper-routes.test.ts` — `GET
65
+ /worktrees/agent-reaper` 503 unwired / 200 with snapshot.
66
+ - `tests/e2e/agent-worktree-reaper-lifecycle.test.ts` — Phase-1 feature-alive
67
+ through the real AgentServer plumbing.
68
+ - Validated live on echo's real 112 worktrees: 49 merged+clean+idle reclaimable,
69
+ the rest correctly kept (dirty / unmerged / in-use).
70
+ - `capabilities-discoverability` + `feature-delivery-completeness` green; lint clean.
@@ -0,0 +1,96 @@
1
+ # Side-Effects Review — AgentWorktreeReaper
2
+
3
+ **Version / slug:** `agent-worktree-reaper`
4
+ **Date:** `2026-05-30`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `not required`
7
+
8
+ ## Summary of the change
9
+
10
+ A new `AgentWorktreeReaper` reclaims CLI worktrees under `.worktrees/` that are
11
+ **merged + clean + not-in-use** (for a merged branch the work is in main, so
12
+ removing the checkout loses nothing). Pure injectable classifier; git-backed
13
+ signals (`agentWorktreeGit.ts`, incl. a lock + process-cwd in-use check);
14
+ `GET /worktrees/agent-reaper` report; boot-wired in server.ts; config
15
+ `monitoring.agentWorktreeReaper`. Ships OFF + dry-run.
16
+
17
+ ## Decision-point inventory
18
+
19
+ - **Per-worktree reap/keep decision** (new authority — DELETES worktrees). Gated
20
+ behind an AND of all safety signals; KEEPs on any ambiguity; dry-run + dark by
21
+ default; bounded blast radius.
22
+
23
+ ## 1. Over-block
24
+
25
+ **What legitimate inputs does this reject?** By design it KEEPs anything not
26
+ provably reclaimable — including multi-commit squash-merged branches (the merged-
27
+ detection is conservative). So it under-reclaims rather than ever deleting unmerged
28
+ work. That is the correct bias for a deleting authority.
29
+
30
+ ## 2. Under-block
31
+
32
+ **What does it miss?** Multi-commit squash-merged branches are kept (not detected
33
+ as merged by `git cherry`). This is acceptable: the goal is safe reclamation, and
34
+ the dry-run report makes the kept-set inspectable so detection can be refined before
35
+ broader enablement. (Validation on echo: ~49 of 112 worktrees are merged + clean +
36
+ idle and would be reclaimed; the rest are kept for genuine uncommitted work or
37
+ unmerged/multi-commit-squash branches.)
38
+
39
+ ## 3. Level-of-abstraction fit
40
+
41
+ **Right layer?** Yes. The classifier is a pure monitoring component (mirrors
42
+ SessionReaper's injectable design); git/fs signals are isolated in a separate
43
+ module so the classifier is unit-testable with fakes; the destructive op routes
44
+ through SafeGitExecutor. Distinct from the binding-based WorktreeReaper (different
45
+ worktree system) — no overlap.
46
+
47
+ ## 4. Signal vs authority compliance
48
+
49
+ **Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
50
+
51
+ It IS a deleting authority, so it is gated behind POSITIVE proof (merged + clean +
52
+ not-active + stale) and KEEPs on any failed/ambiguous signal — never reaping on the
53
+ absence of evidence. The `GET /worktrees/agent-reaper` report is a pure signal for
54
+ human review. Ships dark + dry-run so the authority is inert until reviewed-enabled.
55
+
56
+ ## 5. Interactions
57
+
58
+ No interaction with the SessionReaper, the binding-based WorktreeReaper, sentinels,
59
+ or recovery paths. Reads the same instar git repo via SafeGitExecutor.readSync;
60
+ the only write is `git worktree remove` via execSync (audited). Config auto-migrates
61
+ via ConfigDefaults. Pairs with (does not depend on) the Spotlight-exclusion marker.
62
+
63
+ ## 6. External surfaces
64
+
65
+ One new read-only HTTP route (`GET /worktrees/agent-reaper`, Bearer-auth, classified
66
+ in the discoverability lint as operational observability). No notifications, no
67
+ Telegram, no new on-disk state. The only filesystem effect — when enabled+live —
68
+ is removing already-merged, clean, stale worktrees.
69
+
70
+ ## 7. Rollback cost
71
+
72
+ Trivial. Dark + dry-run by default ⇒ deletes nothing until explicitly enabled and
73
+ reviewed. `enabled:false` neutralizes with no deploy. A PR revert removes the class,
74
+ route, and config. No state, no schema, no irreversible op (git worktree remove only
75
+ detaches an already-merged checkout; the branch + commits remain in the repo).
76
+
77
+ ## Conclusion
78
+
79
+ A deleting authority built conservatively: AND-of-all-safety-gates, KEEP-on-
80
+ ambiguity, dry-run + dark default, bounded blast radius, read-only review surface,
81
+ and the destructive op funneled + audited. Directly targets a measured ~55 GB / ~120-
82
+ worktree backlog that also drives macOS indexing load.
83
+
84
+ ## Second-pass review (if required)
85
+
86
+ Not required for the ship (dark + dry-run, zero auto-delete risk). A second-pass /
87
+ operator review of the dry-run report on real worktrees is the gate before
88
+ enabling live reaping.
89
+
90
+ ## Evidence pointers
91
+
92
+ - `tests/unit/agent-worktree-reaper.test.ts` — safety classifier (both sides),
93
+ dry-run, blast cap, merged-detection.
94
+ - `tests/integration/agent-worktree-reaper-routes.test.ts` — the route.
95
+ - `tests/e2e/agent-worktree-reaper-lifecycle.test.ts` — feature-alive.
96
+ - `upgrades/NEXT.md` — upgrade guide.
@@ -0,0 +1,79 @@
1
+ # Side-Effects Review — Correction & Preference Learning Sentinel, Slice 1b
2
+
3
+ **Version / slug:** `correction-preference-learning-sentinel-slice1b`
4
+ **Date:** `2026-05-30`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `not required` (signal-only, ships dark; see §"Phase 5 trigger check")
7
+
8
+ ## Summary of the change
9
+
10
+ Slice 1b adds the sentinel loop that consumes the Slice-1a preferences read-surface: a broadened, distinctly-tagged Layer-0 signal family (preference/frustration) excluded from the guardian-failure heat map; a privacy-safe per-topic ephemeral capture → Tier-1 distillation → both-sided deterministic scrub → `CorrectionLedger` hop, fired VOID off the message-delivery path; a 3-pronged restart-proof recurrence gate (`CorrectionAnalyzer`); and a by-construction authority-bounded router (`CorrectionLoopDriver`) that writes explicit preferences via `recordPreference()`, routes infra-gaps to a human-approved `/feedback` proposal, and downgrades policy-relaxation phrasing to the Attention queue. Plus inline `/corrections` routes, a `correction-analyzer` cron template (off by default), boot wiring, and CLAUDE.md awareness.
11
+
12
+ The loop is **SIGNAL-ONLY** — it never blocks or rewrites an outbound message (that idea, an "EnforcementGate", was explicitly rejected in the approved spec). It ships **dark** behind `monitoring.correctionLearning.enabled` (default false); only the free, metadata-only Layer-0 classification is always-on.
13
+
14
+ **Files touched:**
15
+ - `src/monitoring/HumanAsDetectorLog.ts` (Layer-0 extension; learning-only categories excluded from `summarizeByLayer()`; `deterministicWeight`/`learningKind` exposed; drift-canary counter).
16
+ - `src/monitoring/scrubSecrets.ts` (new — shared, extended-coverage scrub) + `src/monitoring/CiFailurePoller.ts` (imports + re-exports it; back-compat preserved).
17
+ - `src/monitoring/CorrectionLedger.ts`, `CorrectionAnalyzer.ts`, `CorrectionLoopDriver.ts`, `CorrectionCaptureLoop.ts` (new core).
18
+ - `src/server/routes.ts` (inline `/corrections` + `/corrections/analyze`; `RouteContext.correctionLedger`), `src/server/AgentServer.ts` (construct iff enabled), `src/server/CapabilityIndex.ts` (entry), `src/commands/server.ts` (capture-loop boot wiring).
19
+ - `src/scaffold/templates/jobs/instar/correction-analyzer.md` (new, off by default), `src/scaffold/templates.ts` + `src/core/PostUpdateMigrator.ts` (agent awareness + backfill).
20
+ - `tests/unit/*` (5 logic + 1 wiring), `tests/integration/corrections-routes.test.ts`, `tests/e2e/correction-learning-lifecycle.test.ts`.
21
+ - `upgrades/NEXT.md`, this side-effects artifact.
22
+
23
+ ## Decision-point inventory
24
+
25
+ - **Layer-0 learning classification** — *new signal*. Deterministic regex; biased toward precision (lone weak rule never fires). Excluded from the heat map by category tag. No authority.
26
+ - **`kind` (infra-gap / user-preference / noise)** — *signal*. LLM-set but enum-validated (cannot widen) and ADVISORY for routing only; never blocks or mutates on its own.
27
+ - **deterministic-provenance gate field** — *code-determined*. The recurrence gate keys on the Layer-0 weight (code-set), never on `llm_confidence`. An injected prompt cannot steer the gate.
28
+ - **policy-keyword filter** — *route-to-human, not veto*. A regex match downgrades to Attention; it does NOT silently block (per the spec's signal-vs-authority P2).
29
+ - **routing split** — *pass-through to existing authorities*. `recordPreference()` (Slice-1a primitive), the real `/feedback` route guards, the Attention queue, the Evolution Action / Initiative board (needs-user). No new authority.
30
+
31
+ ## 1. Over-block
32
+
33
+ No block/allow surface — over-block not applicable. The loop never blocks a message, a tool call, or a user. The strongest action it can take autonomously is writing a preference to `.instar/preferences.json` (which the session-start hook injects as an advisory, envelope-wrapped block) or queuing a human-disposable Attention item.
34
+
35
+ ## 2. Under-block
36
+
37
+ No block/allow surface — under-block not applicable. The closest analog is a missed learning (regex recall drift); the drift-canary counter exists precisely to make that observable over time, and a missed learning is a lost data point, never an unsafe action.
38
+
39
+ ## 3. Level-of-abstraction fit
40
+
41
+ Right layer. The new modules sit in `src/monitoring/` alongside the Failure-Learning Loop they are the conversational twin of (`FailureLedger`/`FailureAnalyzer`/`FailureLoopDriver`), mirroring their construction, dedupe-upsert, prune-in-transaction, `toApiView` redaction, and by-construction authority-guard patterns. The capture hop chains onto the same `telegram.onMessageLogged` seam the existing HumanAsDetectorLog / Usher / TopicIntent capture loops use, with the same VOID fire-and-forget + `shouldShed` + per-topic `rateCeiling` discipline. The `/corrections` routes are inline in `routes.ts` (the discoverability-lint allowlist is fixed).
42
+
43
+ ## 4. Signal vs authority compliance
44
+
45
+ **Required reference:** docs/signal-vs-authority.md
46
+
47
+ **Does this change hold blocking authority with brittle logic?**
48
+
49
+ - [x] **No — every output is a signal consumed by an existing smart gate or a human.** The loop never blocks/rewrites a message. The by-construction authority guard is re-proven for this loop's two new capabilities (`/feedback` loopback, `recordPreference`): `CorrectionLoopDeps` carries EXACTLY `addAction`, `createInitiative`, `feedbackLoopbackPost`, `recordPreference`, `attentionRoute` — there is no proposal-mint field and no memory-file-write field to forge or misplace. A wiring-integrity test pins the dep surface is exactly those five, and that under "autonomy ON" the loop mints zero proposals and every draft Initiative carries `needsUser: true`.
50
+ - The deterministic policy-keyword filter is the one place a regex touches a routing decision, and it does NOT veto — it routes to a human (Attention) per P2. The `/feedback` path traverses the real route's anomaly/quality/length guards (a test pins it refuses to count a blocked POST).
51
+
52
+ ## 5. Interactions
53
+
54
+ - **Shadowing:** the capture loop chains AFTER the existing TopicIntent/Usher capture loops in the `onMessageLogged` chain; it calls the prior callback first, so it never shadows them. Layer-0 `classify()` is the only thing it runs synchronously on the seam (free, metadata-only).
55
+ - **Double-fire:** dedupe is owned by `CorrectionLedger`'s `kind:normalizedLearningHash` upsert (a recurrence increments occurrenceCount, never duplicates). The analyzer's `status:'open'` filter means a routed record is acted on once; the closed-loop verify keys on `dedupeKey`, not the coarse kind, so an unrelated learning in the same regex bucket can't false-reopen.
56
+ - **Races:** the capture hop is single-pass per message; the ledger upsert is transactional (occurrence insert + prune + record upsert in one txn). The `LlmQueue` is the sentinel's own instance, so a distill burst cannot starve PresenceProxy/Usher (which share a different queue).
57
+ - **Feedback loops:** the `entry.fromUser` gate (not origin threading) is the self-feed guard — the loop never learns from its own outbound text. The loopback `/feedback` POST is bearer-authed to the agent's own route and carries the `X-Instar-Origin: correction-loop` header; it does not re-enter the capture path (capture only observes inbound human Telegram turns).
58
+ - **Startup ordering:** the capture loop wires inside the Telegram-up block, after PresenceProxy/TopicIntent/Usher and before `presenceProxy.start()`. The `CorrectionLedger` for the read routes is constructed earlier in `AgentServer` (gated on the flag) so the routes 503-stub cleanly when off.
59
+
60
+ ## 6. External surfaces
61
+
62
+ - **Other agents on the same machine:** none directly. The infra-gap path's cross-agent consensus is delegated to the existing Rising Tide `/feedback` clustering (single-agent gate-crossing routes a propose-only draft by default; `autoFeedback` is off).
63
+ - **Other users of the install base:** purely additive and dark. Existing agents that don't flip `monitoring.correctionLearning.enabled` see byte-identical behavior except the always-on Layer-0 metadata classification, which only grows the existing human-as-detector heat map's metadata (and the new learning categories are excluded from `summarizeByLayer()`, so even that is unchanged).
64
+ - **External systems:** **LLM provider egress (disclosed).** When enabled, captured (pre-scrubbed) conversation context is sent to the configured LLM provider for distillation, through the sentinel's own `LlmQueue` (background lane, dedicated daily cap, default 25¢/day per agent). If the operator's provider is unacceptable for this content, the loop stays off — no hidden egress. The `/feedback` loopback (only when `autoFeedback` is on) reaches Dawn's Rising Tide webhook through the real route, carrying the scrubbed summary only.
65
+ - **Persistent state:** new `<stateDir>/correction-ledger.db` (SQLite, distilled + scrubbed records only — raw conversation never persists). New `<stateDir>/logs/correction-learning-audit.jsonl` (one metadata line per capture decision, `origin: correction-loop`). Preference writes land in the Slice-1a `<stateDir>/preferences.json` via `recordPreference()`, tagged `provenance: correction-loop` for one-shot bulk removal.
66
+ - **Timing:** capture/distill is fully off the delivery path (VOID fire-and-forget); a thrown distill error never propagates. Layer-0 `classify()` adds a single synchronous regex pass per inbound human message.
67
+
68
+ ## 7. Rollback cost
69
+
70
+ - **Code:** flip `monitoring.correctionLearning.enabled` back to false (or revert the commits). With the flag off, the capture loop is not wired and the `/corrections` + `/preferences/session-context` routes 503; records stay inert.
71
+ - **Persistent state:** the `correction-ledger.db` and audit JSONL stay on disk but are read by nothing while disabled. Preference entries written by the loop carry `provenance: correction-loop` so a single filter against `.instar/preferences.json` removes exactly the loop's contributions, leaving any human-authored ones intact.
72
+ - **Agent state repair:** none required. Removing the ledger db is safe (absent file ≡ no records).
73
+ - **User visibility during rollback:** none. The feature is dark by default; turning it off returns to the always-on Layer-0 metadata classification, which is invisible.
74
+
75
+ Total rollback time: under 1 minute (flip one config flag).
76
+
77
+ ## Conclusion
78
+
79
+ Signal-only, dark-by-default, off the hot path, with the by-construction authority guard re-proven for both new capabilities and the privacy boundary (both-sided deterministic scrub + metadata-only persistence + disclosed LLM egress) enforced in code. No new blocking authority is introduced. The change mirrors the established Failure-Learning Loop architecture and reuses existing authorities (preferences endpoint, `/feedback` route guards, Attention queue, Evolution/Initiative board) rather than minting new ones.