@event4u/agent-config 9.7.0 → 9.8.0

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 (185) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +144 -0
  3. package/README.md +5 -5
  4. package/dist/agent-src/commands/commit/in-chunks.md +8 -0
  5. package/dist/agent-src/commands/commit.md +17 -0
  6. package/dist/agent-src/commands/pr/create.md +4 -0
  7. package/dist/agent-src/contexts/override-system.md +75 -5
  8. package/dist/agent-src/rules/context-hygiene.md +2 -0
  9. package/dist/agent-src/rules/doc-screenshot-hygiene.md +97 -0
  10. package/dist/agent-src/rules/domain-safety-pii.md +1 -0
  11. package/dist/agent-src/rules/external-code-graph-interop.md +13 -3
  12. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +2 -0
  13. package/dist/agent-src/rules/git-history-discipline.md +2 -0
  14. package/dist/agent-src/rules/language-and-tone.md +2 -0
  15. package/dist/agent-src/rules/lethal-trifecta-guard.md +3 -0
  16. package/dist/agent-src/rules/media-governance-routing.md +2 -0
  17. package/dist/agent-src/rules/minimal-safe-diff.md +2 -0
  18. package/dist/agent-src/rules/no-roadmap-references.md +3 -0
  19. package/dist/agent-src/rules/non-destructive-by-default.md +20 -0
  20. package/dist/agent-src/rules/onboarding-gate.md +2 -0
  21. package/dist/agent-src/rules/output-discipline.md +2 -0
  22. package/dist/agent-src/rules/persona-governance.md +2 -0
  23. package/dist/agent-src/rules/preservation-guard.md +3 -0
  24. package/dist/agent-src/rules/roadmap-progress-sync.md +2 -0
  25. package/dist/agent-src/rules/secret-vcs-guard.md +106 -0
  26. package/dist/agent-src/rules/security-sensitive-stop.md +1 -1
  27. package/dist/agent-src/rules/skill-quality.md +2 -0
  28. package/dist/agent-src/rules/source-confidentiality.md +2 -0
  29. package/dist/agent-src/rules/source-of-truth.md +2 -0
  30. package/dist/agent-src/rules/telegraph-speak.md +2 -0
  31. package/dist/agent-src/rules/token-optimizer-maintenance.md +2 -0
  32. package/dist/agent-src/rules/tool-safety.md +1 -0
  33. package/dist/agent-src/rules/verify-before-complete.md +2 -0
  34. package/dist/agent-src/skills/adr-create/SKILL.md +17 -1
  35. package/dist/agent-src/skills/code-intelligence/SKILL.md +94 -0
  36. package/dist/agent-src/skills/gated-reach/SKILL.md +185 -0
  37. package/dist/agent-src/skills/gated-reach/evals/triggers.json +72 -0
  38. package/dist/agent-src/skills/image-analyser/SKILL.md +14 -12
  39. package/dist/agent-src/skills/image-editing/SKILL.md +1 -0
  40. package/dist/agent-src/skills/readme-writing/SKILL.md +6 -1
  41. package/dist/agent-src/skills/screenshot-hygiene/SKILL.md +171 -0
  42. package/dist/agent-src/skills/secrets-management/SKILL.md +44 -1
  43. package/dist/agent-src/skills/subagent-orchestration/prompts/adversarial-verification-council.md +29 -0
  44. package/dist/agent-src/skills/subagent-orchestration/prompts/do-and-judge-two-stage.md +29 -0
  45. package/dist/agent-src/skills/subagent-orchestration/prompts/do-and-judge.md +29 -0
  46. package/dist/agent-src/skills/subagent-orchestration/prompts/do-competitively.md +29 -0
  47. package/dist/agent-src/skills/subagent-orchestration/prompts/do-in-parallel.md +29 -0
  48. package/dist/agent-src/skills/subagent-orchestration/prompts/do-in-steps.md +29 -0
  49. package/dist/agent-src/skills/subagent-orchestration/prompts/do-in-worktrees.md +29 -0
  50. package/dist/agent-src/skills/subagent-orchestration/prompts/judge-with-debate.md +29 -0
  51. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +4 -0
  52. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  53. package/dist/agent-src/templates/github-workflows/secret-scan.yml +65 -0
  54. package/dist/cli/configRoot.js +112 -0
  55. package/dist/cli/configRoot.js.map +1 -0
  56. package/dist/cli/configRoot.test.js +97 -0
  57. package/dist/cli/configRoot.test.js.map +1 -0
  58. package/dist/cli/help.js +4 -1
  59. package/dist/cli/help.js.map +1 -1
  60. package/dist/cli/main.js +19 -2
  61. package/dist/cli/main.js.map +1 -1
  62. package/dist/cli/registry.js +1 -0
  63. package/dist/cli/registry.js.map +1 -1
  64. package/dist/discovery/deprecation-report.md +1 -1
  65. package/dist/discovery/discovery-manifest.json +161 -44
  66. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  67. package/dist/discovery/discovery-manifest.summary.md +4 -4
  68. package/dist/discovery/orphan-report.md +1 -1
  69. package/dist/discovery/packs.json +13 -8
  70. package/dist/discovery/trust-report.md +11 -11
  71. package/dist/discovery/workspaces.json +11 -6
  72. package/dist/install/install.mjs +16 -0
  73. package/dist/mcp/registry-manifest.json +3 -3
  74. package/dist/router.json +1 -1
  75. package/dist/server/app.js +10 -0
  76. package/dist/server/app.js.map +1 -1
  77. package/dist/server/routes/ping.js +18 -0
  78. package/dist/server/routes/ping.js.map +1 -1
  79. package/dist/server/schemas/settings.js +8 -0
  80. package/dist/server/schemas/settings.js.map +1 -1
  81. package/dist/server/serverInfo.js +6 -2
  82. package/dist/server/serverInfo.js.map +1 -1
  83. package/dist/server/token.js +11 -4
  84. package/dist/server/token.js.map +1 -1
  85. package/dist/server/writeRoot.js +15 -1
  86. package/dist/server/writeRoot.js.map +1 -1
  87. package/dist/shared/capabilities.js +33 -0
  88. package/dist/shared/capabilities.js.map +1 -0
  89. package/dist/shared/capabilities.test.js +39 -0
  90. package/dist/shared/capabilities.test.js.map +1 -0
  91. package/dist/ui/assets/{index-BiEZiZ31.js → index-CrmZ34Rg.js} +16 -16
  92. package/dist/ui/assets/index-CrmZ34Rg.js.map +1 -0
  93. package/dist/ui/index.html +14 -5
  94. package/docs/CLAIMS.md +62 -37
  95. package/docs/architecture.md +2 -2
  96. package/docs/benchmark.md +137 -0
  97. package/docs/catalog.md +8 -3
  98. package/docs/comparison.yaml +44 -2
  99. package/docs/contracts/local-server-ports.md +53 -0
  100. package/docs/contracts/no-runtime-boundary.md +1 -1
  101. package/docs/contracts/subagent-boundary.md +15 -0
  102. package/docs/customization.md +14 -3
  103. package/docs/decisions/ADR-016-installer-architecture.md +2 -0
  104. package/docs/decisions/ADR-088-no-external-runtime-federation.md +1 -1
  105. package/docs/decisions/ADR-094-agent-memory-layer-removal.md +1 -1
  106. package/docs/decisions/ADR-109-subagent-v1-contract.md +2 -0
  107. package/docs/decisions/ADR-110-discipline-profile-resolution-locus.md +2 -0
  108. package/docs/decisions/ADR-113-ci-native-release-label-trigger.md +11 -3
  109. package/docs/decisions/ADR-124-embedded-engine-doctrine.md +255 -0
  110. package/docs/decisions/ADR-125-doc-screenshot-anonymization.md +131 -0
  111. package/docs/decisions/ADR-126-internet-reach-operator-tooling.md +254 -0
  112. package/docs/decisions/ADR-127-enforcement-claims-must-resolve.md +150 -0
  113. package/docs/decisions/ADR-128-executable-evidence-and-measured-escalation.md +201 -0
  114. package/docs/decisions/INDEX.md +21 -0
  115. package/docs/decisions/engine-reclassification-2026-07.md +104 -0
  116. package/docs/distribution/awesome-list-submission.md +1 -1
  117. package/docs/distribution/registries.md +36 -27
  118. package/docs/enforcement-by-host.md +7 -0
  119. package/docs/featured-skills.md +2 -2
  120. package/docs/getting-started-by-role.md +1 -1
  121. package/docs/getting-started.md +1 -1
  122. package/docs/governance-advantage.md +1 -1
  123. package/docs/guides/gated-platform-reads.md +221 -0
  124. package/docs/positioning-evidence.md +1 -1
  125. package/docs/proof.md +92 -16
  126. package/docs/threat-model.md +1 -0
  127. package/package.json +5 -2
  128. package/src/config/agent-settings.template.yml +43 -0
  129. package/src/config/reach-channels.yml +217 -0
  130. package/src/config/reach-prescriptions-intake.yml +200 -0
  131. package/src/scripts/_dispatch.bash +15 -0
  132. package/src/scripts/_lib/exec_evidence.ts +251 -0
  133. package/src/scripts/_lib/fixtures/secret-detector/negatives.txt +10 -0
  134. package/src/scripts/_lib/fixtures/secret-detector/positives.txt +11 -0
  135. package/src/scripts/_lib/kernel_rules.ts +46 -0
  136. package/src/scripts/_lib/reddit_thread_parse.ts +598 -0
  137. package/src/scripts/_lib/risk_paths.ts +160 -0
  138. package/src/scripts/_lib/secret_detector.test.ts +103 -0
  139. package/src/scripts/_lib/secret_detector.ts +319 -0
  140. package/src/scripts/_lib/tool_probe.ts +359 -0
  141. package/src/scripts/adr/regenerate_index.ts +81 -6
  142. package/src/scripts/audit_adr_coverage.ts +33 -0
  143. package/src/scripts/build_proof.ts +162 -0
  144. package/src/scripts/check_adr_frontmatter.ts +195 -0
  145. package/src/scripts/check_artefact_count_messaging.ts +4 -0
  146. package/src/scripts/check_backstop_debt.ts +200 -0
  147. package/src/scripts/check_claims.ts +188 -8
  148. package/src/scripts/check_comparison.ts +12 -0
  149. package/src/scripts/check_enforcement_coverage.ts +592 -0
  150. package/src/scripts/check_kernel_rule_bundle.ts +16 -12
  151. package/src/scripts/check_reach_channels.ts +407 -0
  152. package/src/scripts/check_reach_staleness.ts +364 -0
  153. package/src/scripts/check_secret_leak.test.ts +47 -0
  154. package/src/scripts/check_secret_leak.ts +290 -0
  155. package/src/scripts/code_graph/build.ts +0 -0
  156. package/src/scripts/code_graph/cli.ts +207 -0
  157. package/src/scripts/code_graph/detect.ts +134 -0
  158. package/src/scripts/code_graph/extract.ts +386 -0
  159. package/src/scripts/code_graph/loader.ts +123 -0
  160. package/src/scripts/code_graph/query.ts +176 -0
  161. package/src/scripts/code_graph/sanitize.ts +30 -0
  162. package/src/scripts/code_graph/types.ts +83 -0
  163. package/src/scripts/code_graph/validate.ts +63 -0
  164. package/src/scripts/external_sources_denylist.json +3 -1
  165. package/src/scripts/generate_subagent_floor.ts +194 -0
  166. package/src/scripts/hook_manifest.yaml +13 -3
  167. package/src/scripts/hooks/code_graph_nudge_hook.ts +184 -0
  168. package/src/scripts/iron_law_sha.ts +3 -12
  169. package/src/scripts/lint_override_kernel_guard.ts +219 -0
  170. package/src/scripts/measure_rule_budget.ts +3 -12
  171. package/src/scripts/postinstall_gui.ts +129 -0
  172. package/src/scripts/reach_doctor.ts +1651 -0
  173. package/src/scripts/release.ts +24 -3
  174. package/src/scripts/risk_escalation_shadow.ts +160 -0
  175. package/src/scripts/schemas/agent-settings.schema.json +23 -0
  176. package/src/scripts/schemas/reach-channels.schema.json +134 -0
  177. package/src/scripts/schemas/reach-doctor-payload.schema.json +220 -0
  178. package/src/scripts/schemas/rule.schema.json +10 -0
  179. package/src/scripts/skill_linter.ts +55 -0
  180. package/src/scripts/validate_reach_prescriptions.ts +751 -0
  181. package/src/server/schemas/settings.ts +16 -0
  182. package/src/shared/capabilities.test.ts +43 -0
  183. package/src/shared/capabilities.ts +75 -0
  184. package/src/templates/minimal/agents-overrides-readme.md +20 -0
  185. package/dist/ui/assets/index-BiEZiZ31.js.map +0 -1
@@ -43,6 +43,21 @@ the whole of its authority.
43
43
  - **Verify, never adopt blind** — a subagent return is evidence, not truth; the orchestrator verifies per [`delegation-policy`](../../src/rules/delegation-policy.md)'s Iron Law before adopting it.
44
44
  - **Tier-size the slice, not the agent** — dispatch at the slice's complexity, not the session's.
45
45
  - **Own the safety decision** — a Hard-Floor or egress action surfaced by a subagent is decided by the orchestrator + human, never executed by the subagent.
46
+ - **Re-confirm; the subagent's confirmation does not count** — a destructive or irreversible mutation *proposed by a subagent* is subject to the same Hard Floor as one the orchestrator proposed, and the subagent's own "I checked, it's fine" does not satisfy the gate. Without this clause, delegation is a detour around it: ask a subagent, receive a blessing, act.
47
+ - **Deliver the floor, do not assume it** — the floor reaches a worker because [`generate_subagent_floor.ts`](../../src/scripts/generate_subagent_floor.ts) writes it into every dispatch prompt and CI fails on drift.
48
+
49
+ ### Honest scope of the floor guarantee
50
+
51
+ The invariant above — *a subagent cannot do what its parent may not* — is now
52
+ **delivered** for subagents dispatched through this package's prompt templates:
53
+ the floor is generated from the kernel rules and drift-gated. It was previously
54
+ asserted here and carried by nothing; the brief schema, the spawn composer, and
55
+ all eight prompt templates contained no floor text at all.
56
+
57
+ What stays unproven, and is therefore not claimed: whether a subagent spawned by
58
+ a host primitive outside these templates inherits any of it. That is a host
59
+ property this package does not control and does not test. A contract that
60
+ quietly covered it would repeat the exact defect this section exists to close.
46
61
 
47
62
  ## Failure modes
48
63
 
@@ -473,6 +473,14 @@ defaults"* above). The cascade is **per-file** by basename — the
473
473
  deepest existing `agents/<kind>/<name>.md` wins; the rest are silently
474
474
  shadowed.
475
475
 
476
+ **One exception, and it is not silent.** Kernel and `tier: safety-floor`
477
+ rules sit outside the cascade: a `Mode: replace` override on one is
478
+ refused and reported, and a `Mode: extend` (a tightening) needs a
479
+ registered entry in `agents/overrides/kernel-exceptions.yml`. See
480
+ [`override-system`](../src/agent-src/contexts/override-system.md)
481
+ § *The non-overridable class* — including its stated limit, since the
482
+ class is a norm with a partial gate, not a proof.
483
+
476
484
  | Subdir | Cascade? | User-global allowed? | Why |
477
485
  |---|---|---|---|
478
486
  | `agents/overrides/` | ✅ Yes — deepest wins by basename. | ✅ Yes — weakest layer. | Personal developer overrides. |
@@ -489,10 +497,13 @@ fallback). Files under `~/.event4u/agent-config/agents/settings/contexts/` or
489
497
  project-shaped and must not leak across projects.
490
498
 
491
499
  The resolver lives at
492
- [`scripts/_lib/agents_overlay.py`](../src/scripts/_lib/agents_overlay.py)
493
- and is enforced by `scripts/check_overlay_cascade_subdirs.py` — drift
494
- between the code constants (`CASCADE_ELIGIBLE_KINDS`,
500
+ [`scripts/_lib/agents_overlay.ts`](../src/scripts/_lib/agents_overlay.ts)
501
+ and is enforced by
502
+ [`scripts/check_overlay_cascade_subdirs.ts`](../src/scripts/check_overlay_cascade_subdirs.ts)
503
+ — drift between the code constants (`CASCADE_ELIGIBLE_KINDS`,
495
504
  `USER_GLOBAL_OVERLAY_KINDS`) and the table above breaks the build.
505
+ (Both were `.py` before the ADR-200 TypeScript port; the old paths were
506
+ cited here long after they were deleted.)
496
507
 
497
508
  ---
498
509
 
@@ -7,6 +7,8 @@ supersedes: —
7
7
  superseded_by: —
8
8
  phase: v2.x · monorepo-phase-3-typescript-installer
9
9
  type: prospective
10
+ review_trigger: >-
11
+ When a consumer reports losing a local edit to a framework-authoritative file on update, OR when any framework file legitimately needs to move between the force-update and scaffold classes — the conflict-resolution half (skip | overwrite | merge) is the part under review, not the TypeScript choice
10
12
  ---
11
13
 
12
14
  # ADR-016 — TypeScript Installer Architecture
@@ -4,7 +4,7 @@ status: accepted
4
4
  date: 2026-06-11
5
5
  decision: no-external-runtime-federation
6
6
  supersedes: —
7
- superseded_by: —
7
+ superseded_by: ADR-124 (engine-adoption interpretation only)
8
8
  phase: external-runtime-coexistence
9
9
  type: structural
10
10
  ---
@@ -4,7 +4,7 @@ status: accepted
4
4
  date: 2026-06-14
5
5
  decision: agent-memory-layer-removal
6
6
  supersedes: —
7
- superseded_by: —
7
+ superseded_by: ADR-124 (engine-adoption interpretation only)
8
8
  phase: memory-layer-cleanup
9
9
  type: structural
10
10
  ---
@@ -7,6 +7,8 @@ supersedes: —
7
7
  superseded_by: —
8
8
  phase: road-to-final-state-and-market-readiness
9
9
  type: standing
10
+ review_trigger: >-
11
+ When a host ships a spawn primitive whose memory-inheritance semantics are documented, OR when a dispatched subagent is observed taking an action the floor forbids
10
12
  ---
11
13
 
12
14
  # ADR-109 — The `subagent-v1` contract (new discovery category, default-off, static projection)
@@ -7,6 +7,8 @@ supersedes: —
7
7
  superseded_by: —
8
8
  phase: road-to-discipline-profile-tiering
9
9
  type: standing
10
+ review_trigger: >-
11
+ When a diff in a downstream-trust-boundary path (installer, provenance, kernel rules, spawn path) is found to have run under minimum discipline because the HOST was weak — host capability is only one axis, and diff risk is the missing one
10
12
  ---
11
13
 
12
14
  # ADR-110 — `discipline_profile` resolves at runtime (agent-in-the-loop); projection stays configuration-independent
@@ -112,9 +112,17 @@ maintainer approves the run once per release.
112
112
  on deploys, a single human checkpoint before a release's own CI even
113
113
  runs is arguably a feature, not friction.
114
114
  - `RELEASE_PR_TOKEN` (a fine-grained PAT or GitHub App installation
115
- token with `contents: write` + `pull-requests: write` on this repo)
116
- removes the approval requirement entirely — documented as the
117
- zero-friction upgrade path in `release.yml`'s header comment. Adding
115
+ token with `contents: write` + `pull-requests: write` + `actions: write`
116
+ on this repo) removes the approval requirement entirely — documented as
117
+ the zero-friction upgrade path in `release.yml`'s header comment. The
118
+ `actions: write` scope ("Actions: read and write" on a fine-grained PAT,
119
+ or the classic `workflow` scope) is required by release.ts step 9's
120
+ explicit `gh workflow run` dispatch of the tag-triggered workflows
121
+ (release-guard / publish-npm / cloud-release); without it that dispatch
122
+ returns HTTP 403. As of 2026-07-21 that dispatch is **non-fatal** — the
123
+ release is already complete when it runs, and a PAT-pushed tag fires
124
+ those workflows on the push regardless — so a missing scope degrades to
125
+ a logged warning, never a failed-but-shipped release. Adding
118
126
  it is a maintainer action, not part of this ADR.
119
127
 
120
128
  ## Verified facts (not assumed)
@@ -0,0 +1,255 @@
1
+ ---
2
+ adr: 124
3
+ status: accepted
4
+ date: 2026-07-23
5
+ decision: embedded-engine-doctrine
6
+ supersedes: ADR-088 (engine-adoption interpretation only), ADR-094 (engine-adoption interpretation only)
7
+ superseded_by: —
8
+ phase: road-to-native-code-intelligence
9
+ type: structural
10
+ ---
11
+
12
+ # ADR-124 — Embedded-engine doctrine: this suite may own deterministic in-process engines; the service/daemon prohibition stands
13
+
14
+ ## Status
15
+
16
+ **Accepted** · 2026-07-23. **Maintainer-directed reversal** of the
17
+ engine-rejection *interpretation* accumulated across ADR-088, ADR-094 and the
18
+ archived harvest-cycle REJECT records of 2026-06/07. The council ratification
19
+ round reviewed the *boundary wording*, not the direction — the direction is a
20
+ maintainer product decision: the prior councils optimized for scope discipline
21
+ and, in doing so, systematically excluded a capability class (deterministic
22
+ code/corpus intelligence) that competing suites ship as their headline
23
+ feature. The ratification round ran 2026-07-23 (see References); its three
24
+ convergent wording patches — the tightened `--watch` termination clause, the
25
+ maintainer-approves-per-dep ladder note, and the "changes *what* the tool can
26
+ answer, not just *how fast*" state-store test in § 6 — are folded in, and the
27
+ ADR is accepted on that sealed wording.
28
+
29
+ ## Context
30
+
31
+ ### What the record actually prohibits (verified 2026-07-23)
32
+
33
+ The "no runtime" identity rests on instruments whose literal scope is narrower
34
+ than the posture they produced:
35
+
36
+ 1. **ADR-088** prohibits **cross-vendor runtime federation**: "agent-config
37
+ does not bridge to, or drive, external tool runtimes. It is a content suite
38
+ (skills, rules, commands) for AI coding tools — not a runtime coordinator."
39
+ It says nothing about whether this suite may run an in-process algorithm of
40
+ its own. The frequently-cited gloss "no runtime orchestration (work
41
+ stealing, load balancing)" is a harvest-cycle REJECT line (council,
42
+ 2026-07-07) that *cites* ADR-088 — it is not ADR-088's text.
43
+ 2. **ADR-094** removed one specific companion package (Layer 2:
44
+ PostgreSQL + pgvector + MCP memory server + decay engine) because "its
45
+ PostgreSQL + MCP runtime contradicted the suite's 'no app runtime'
46
+ positioning." It is a removal record, not a forward-looking ban list.
47
+ 3. **Archived REJECT records** (council convergences, 2026-06 → 2026-07,
48
+ quoted inline per the transient-reference rule): the MCP deferred-rule
49
+ retrieval **server** ("council REJECT, 2026-07-07", three re-open
50
+ conditions); "SQLite memory *service*, vector clocks, distributed memory —
51
+ the second-brain verdict and Layer-2 sunset stand"; a web console ("no
52
+ runtime to monitor"); a browser daemon + compiled runtime ("compiled
53
+ runtime betrays no-runtime identity" — routed to `agent-ide-plugin`); an
54
+ in-process swarm/topology engine ("an in-process actor runtime is
55
+ identity-rejected").
56
+ 4. **`src/rules/external-code-graph-interop.md`** codified the resulting
57
+ ceiling: "This suite is an **orchestrator, not a competitor**: query the
58
+ existing index first … NEVER REBUILD WHAT THE INDEX ALREADY ANSWERS." This
59
+ is the single most on-point prior commitment against a native code-graph
60
+ engine — an active tier-2a rule, and it is amended by this ADR (§ 2).
61
+
62
+ In practice these instruments were *interpreted* wider than written: a
63
+ 2026-07-23 inventory sweep across all roadmap dispositions (active, archive,
64
+ later, skipped, stubs) found **44 engine-shaped rejects across ~30 cycles** —
65
+ harvests of at least six external references (a code-graph suite, an
66
+ orchestration runtime, a control-plane/enforcement suite, and three memory
67
+ systems) adopted **protocol discipline only** and reflexively rejected every
68
+ **engine**, including engines that are neither services nor daemons.
69
+
70
+ ### The precedent — read honestly
71
+
72
+ **ADR-116** pre-decided SQLite FTS5 via `node:sqlite` — a persisted,
73
+ incrementally-updated engine, in-process — as compatible with the Layer-2
74
+ sunset: "no service, no always-on worker, zero npm dependency." Two facts keep
75
+ this precedent honest rather than convenient:
76
+
77
+ - **That engine was never built.** The activation path was re-resolved to a
78
+ hand-rolled stdlib BM25 + trigram prefilter (`_lib/lexical_index.ts`); only
79
+ the engine choice moved, per the ADR-116 amendment banner.
80
+ - **Its compatibility argument rested on being a zero-npm-dep Node built-in.**
81
+ ADR-116 explicitly rejected `better-sqlite3` and a minisearch dependency
82
+ *for being npm deps*. It is therefore precedent for "embedded engine ≠
83
+ runtime" **in principle**, and **counter-precedent on the dependency axis**.
84
+ This ADR does its own work on that axis (§ 1, Class A) instead of borrowing
85
+ authority ADR-116 does not carry.
86
+
87
+ ### Dependency reality
88
+
89
+ The package ships **13 runtime npm dependencies** today (fastify, commander,
90
+ execa, tsx, zod, js-yaml, the MCP SDK, …). No package-wide "zero
91
+ dependencies" commitment exists — the closest claim was a README bullet
92
+ deliberately dropped before 2.2.0. The zero-dep virtue in ADR-061/ADR-116 is a
93
+ *feature-level* stdlib preference, not a distribution-level promise. An engine
94
+ dependency is therefore a **cost to justify per adoption**, not a broken vow.
95
+
96
+ ### The product goal has changed
97
+
98
+ The maintainer directs: the suite should be able to natively own capability
99
+ classes (deterministic code intelligence first) when owning them makes the
100
+ package better, closes gaps and improves agent behavior — not merely defer to
101
+ whatever index a consumer happens to ship.
102
+
103
+ ## Decision
104
+
105
+ ### 1. Three engine classes; the boundary moves, it does not vanish
106
+
107
+ | Class | Definition | Verdict |
108
+ |---|---|---|
109
+ | **A — Embedded engine** | Deterministic, in-process, invoked-per-command, no resident process, no listening socket, no network in the build path; state only as gitignored, rebuildable build/index artifacts under the suite's own runtime dirs (`agents/runtime/state/`). **Termination clause (council patch, 2026-07-23): a Class-A engine terminates after command completion; in-memory state never spans CLI invocations** — a memory-only long-lived process that "never touches disk" is Class B regardless of its storage story. The sole exception is an explicit `--watch` flag on a stateless file-regeneration command where (a) the process lifecycle is bounded to file-system event observation, (b) **each regeneration cycle is a fresh Class-A invocation with no shared in-memory state between cycles**, and (c) the flag emits a first-launch notice that a long-running process started; any other persistent process (REPL, server, daemon, background worker) is Class B regardless of flag naming, and the `--watch` mode itself is a Class-B escalation under § 5. Implementation preference in order: Node built-ins / stdlib → exact-pinned pure-npm or WASM dependencies (admissible with a per-dependency justification in the adopting ADR — the justification states why a lighter dependency does not suffice, and the maintainer approves it in that ADR, not in a downstream feature PR) → native-compiled (node-gyp) deps only via an explicit per-dependency exception on the same terms. Every subprocess it spawns routes through `hardenedSpawnEnv()` per ADR-123 and `docs/spawn-site-policy.md`. | **ADOPTABLE.** This suite may build, fork, or vendor Class-A engines natively. |
110
+ | **B — Resident service / daemon** | Anything with a lifecycle beyond one command: DB servers, MCP *servers* run as memory/retrieval backends, watchers, browser daemons, background workers, web consoles. (In-process actor runtimes/swarms are equally out of scope, but by the ADR-109 identity floor preserved in § 3 — not by this lifecycle definition; they can terminate within one command and are still excluded.) | **PROHIBITED in core**, unchanged. Route to `agent-ide-plugin` or a sibling package where genuinely needed. ADR-088/094 remain authoritative here. |
111
+ | **C — Network/LLM-dependent build path** | Any index/graph/corpus *build* step that requires network or model calls (embedding pipelines included — ADR-061's "embeddings only on measured recall failure" remains the sole doorway). | **PROHIBITED by default**, unchanged. Query-time LLM use follows existing council/budget governance. |
112
+
113
+ ### 2. What is explicitly superseded
114
+
115
+ - The **blanket engine-rejection interpretation** of ADR-088 and ADR-094.
116
+ Their literal text (no cross-vendor federation; Layer-2 removal) stands; any
117
+ archived REJECT that cites them against a Class-A engine is void and must be
118
+ re-evaluated (§ 4).
119
+ - The **"orchestrator, not a competitor" ceiling** in
120
+ `external-code-graph-interop.md`. New wording: "orchestrator *first* —
121
+ query a consumer-shipped index when present and fresh; owner *where it
122
+ wins* — the suite's native engines cover the gap when none is shipped or
123
+ ours is measurably better." Interop behavior toward existing indexes is
124
+ unchanged.
125
+
126
+ ### 3. What is explicitly NOT superseded
127
+
128
+ - **Falsifiability-first.** Every native engine ships **default-off**,
129
+ activates via tripwire or explicit setting, and earns default-on only
130
+ through a pre-registered benchmark with an honest-null publication path.
131
+ The evidence gates now govern *defaults*, no longer *existence*.
132
+ - Claims Ledger, budget/spend gates, minimal-safe-diff, source
133
+ confidentiality, and the security posture (ADR-123 spawn hardening applies
134
+ to every engine subprocess; the no-network floor applies to every build
135
+ path).
136
+ - The `agent-ide-plugin` routing for genuinely runtime-shaped capability.
137
+ - ADR-109's no-runtime identity floor for subagent artifacts (no daemon, no
138
+ auto-write, no in-process swarm, no dispatch we enforce) — a command-invoked,
139
+ non-dispatching engine does not touch it.
140
+
141
+ ### 4. Mandatory re-evaluation sweep
142
+
143
+ Every engine-shaped REJECT recorded 2026-06-01 → 2026-07-22 is re-classified
144
+ A/B/C. Class-A rejects are re-opened as candidates (adoption still demand- and
145
+ benchmark-gated); Class-B/C rejects are re-affirmed with the class cited. The
146
+ population was inventoried on 2026-07-23 (44 entries); the classification
147
+ table is committed as `docs/decisions/engine-reclassification-2026-07.md` by
148
+ the implementing roadmap — no silent re-openings, no silent re-affirmations.
149
+
150
+ ### 5. Extension clause
151
+
152
+ Opening Class B (e.g., a resident index server for very large fleets) requires
153
+ its own ADR with: a named consumer demand signal, a measured Class-A failure
154
+ (the embedded engine demonstrably cannot serve the need), and a security
155
+ review under ADR-123. This clause exists so the next escalation is a decision,
156
+ not a drift.
157
+
158
+ ### 6. Contract reconciliation — obligations this ADR creates
159
+
160
+ The doctrine is not landed until the published claims agree with it. The
161
+ implementing roadmap carries, in the same change-set as the first engine:
162
+
163
+ - **`docs/contracts/no-runtime-boundary.md`** — the "Cross-session persistent
164
+ state stores" prohibition row gains an explicit carve-out: *gitignored,
165
+ deterministic, rebuildable build/index artifacts under
166
+ `agents/runtime/state/` are build outputs, not state stores* (they carry no
167
+ authority, are reproducible from the working tree, and are never
168
+ auto-written memory). One-shot subprocess spawning is already sanctioned by
169
+ the contract's Allowed table; daemons remain prohibited. **State-store test
170
+ (council ratification patch): if deleting the artifact changes *what* the
171
+ tool can answer rather than only *how fast* it answers, it is a state store,
172
+ not a build artifact — even if deterministically rebuildable.** A code-graph
173
+ cache passes the test (deleting it only slows the next query; the answer is
174
+ identical, recomputed from source); a learned index that enables query
175
+ semantics absent from the source tree (vector/embedding search) fails it and
176
+ stays Class C.
177
+ - **`docs/comparison.yaml` row 1** — "no state database" is reworded to "no
178
+ resident database or service; deterministic, rebuildable file indexes only",
179
+ so the machine-checked claim stays true rather than quietly weakening.
180
+ - **`src/rules/external-code-graph-interop.md`** — ceiling sentence amended
181
+ per § 2.
182
+ - **Config-surface guard alignment** — a planned no-runtime config-surface
183
+ guard (parked in a later-disposition roadmap) denylists `vector`/`daemon`/
184
+ `decay`/`pgvector` keys and `setInterval`/`setTimeout` outside dev tooling.
185
+ Its denylist must except Class-A engine surfaces when it lands, or Class-A
186
+ engines will fail CI after this doctrine flips; this ADR is the anchor that
187
+ guard must cite.
188
+
189
+ ## Consequences
190
+
191
+ - The suite may natively own: code-graph extraction/query (first instance —
192
+ WASM tree-sitter, Class A), lexical/FTS index engines (in-principle
193
+ precedent: ADR-116, with the honest reading above), deterministic
194
+ clustering/analysis over its own graph outputs, and comparable future
195
+ engines — each behind the § 3 gates.
196
+ - **Sequencing rule:** no second native engine starts before the first has a
197
+ published benchmark verdict. The § 4 table is the queue, not a starting gun.
198
+ - Positioning language changes from "no engines, governance only" to "no
199
+ *resident runtime*; deterministic embedded intelligence is in scope."
200
+ README/docs claims still bind to bench rows via the Claims Ledger.
201
+ - **Named cost:** the first engine introduces parser-class runtime
202
+ dependencies (exact-pinned WASM). That breaks the feature-level stdlib
203
+ pattern ADR-061/116 prize — accepted deliberately, justified per dependency
204
+ in the adopting artifact, never silently.
205
+ - **Named risk:** scope-dilution pressure on a single-maintainer package with
206
+ a live adoption gap. Mitigation is structural, not aspirational — the § 3
207
+ gates, the sequencing rule, and the § 4 table as the only intake path for
208
+ further engines.
209
+
210
+ ## Alternatives considered
211
+
212
+ - **Keep the orchestrator-only posture** — rejected by maintainer directive:
213
+ it structurally cedes the headline capability class to peer suites and makes
214
+ the interop rule a promise with no machine behind it when consumers ship no
215
+ index (the common case).
216
+ - **Repeal ADR-088/094 outright** — rejected: their literal scope
217
+ (cross-vendor federation; resident memory runtime) is correct and keeps the
218
+ differentiation that a reversal must not destroy.
219
+ - **Class-A via native node-gyp bindings** — rejected: perpetual
220
+ consumer-install failure tax on a solo-maintainer package; WASM carries the
221
+ same fidelity without the toolchain.
222
+
223
+ ## References
224
+
225
+ - ADR-061 (engine-fork ban; embeddings doorway) · ADR-088 (no external-runtime
226
+ federation) · ADR-094 (Layer-2 removal) · ADR-109 (subagent contract,
227
+ no-runtime identity floor) · ADR-116 (FTS5 pre-decision + amendment) ·
228
+ ADR-123 (spawn hardening).
229
+ - `docs/contracts/no-runtime-boundary.md` · `docs/comparison.yaml` ·
230
+ `docs/spawn-site-policy.md` · `src/rules/external-code-graph-interop.md`.
231
+ - Pre-landing adversarial council review: 2026-07-23, debate mode, 2 rounds,
232
+ members claude-sonnet-4-5 (Anthropic) + gpt-4o (OpenAI). Convergence:
233
+ A/B/C taxonomy well-drawn; the rebuildable-build-artifact carve-out judged
234
+ honest (deterministic from source, no runtime decisions recorded, byte-stable
235
+ rebuild) and categorically distinct from a state store; code-graph confirmed
236
+ as the correct first engine (retriever too incremental, policy evaluator
237
+ needs its predicate language designed first); benchmark thresholds sound.
238
+ Adopted patches: the Class-A termination clause (§ 1) and the benchmark
239
+ confound controls (implementing roadmap, Phase 5). A round-1 proposal to
240
+ block engine *construction* on an external adoption signal was rebutted by
241
+ both members in round 2 (capability-before-adoption causality; the engine is
242
+ the differentiation the launch story needs) — the adopted middle path is the
243
+ bench-as-launch-story inversion plus the existing default-off gates.
244
+ - Council ratification round on wording: 2026-07-23, debate mode, 1 round,
245
+ members claude-sonnet-4-5 (Anthropic, verdict FLAG-with-patches) + gpt-4o
246
+ (OpenAI, verdict RATIFY-with-patches). Both converged on three wording
247
+ patches, all folded in on acceptance: (1) the `--watch` termination clause
248
+ now requires each regeneration cycle to be a fresh Class-A invocation with
249
+ no shared in-memory state (§ 1); (2) the dependency ladder names the
250
+ maintainer as the per-dep approver in the adopting ADR, not a downstream PR
251
+ (§ 1); (3) the state-store test — "changes *what* the tool can answer, not
252
+ just *how fast*" — is added to the § 6 no-runtime-boundary carve-out, which
253
+ explicitly keeps vector/embedding indexes on the Class-C side. No member
254
+ flagged the direction; the round sealed the wording and the ADR is accepted
255
+ on it.
@@ -0,0 +1,131 @@
1
+ ---
2
+ adr: 125
3
+ status: accepted
4
+ date: 2026-07-23
5
+ decision: doc-screenshot-anonymization
6
+ supersedes: —
7
+ superseded_by: —
8
+ phase: road-to-doc-screenshot-anonymization
9
+ type: structural
10
+ ---
11
+
12
+ # ADR-125 — Doc-screenshot anonymization: human-gated, capture-delegated, detection-as-helper
13
+
14
+ - **Status:** Accepted (2026-07-23)
15
+ - **Closes:** `agents/roadmaps/road-to-doc-screenshot-anonymization.md`
16
+ - **Related:** `src/rules/doc-screenshot-hygiene.md`; `src/skills/screenshot-hygiene/SKILL.md`; `src/rules/non-destructive-by-default.md` (the egress Hard Floor this routes into); `src/rules/domain-safety-pii.md` (text-surface sibling); `src/rules/lethal-trifecta-guard.md`; `src/skills/image-analyser/SKILL.md` (detection helper); `src/skills/readme-writing/SKILL.md` (unrequested-screenshot check).
17
+
18
+ ## Context
19
+
20
+ The maintainer wants agents to create screenshots for documentation when
21
+ genuinely useful — e.g. when generating a Starlight docs site — and embed them,
22
+ with a hard requirement: **sensitive data visible on a screenshot must be
23
+ anonymized / pixelated before the screenshot ships.**
24
+
25
+ A code sweep established the gap: the package has image *generation* skills and a
26
+ Starlight docs path (`docs/media/` → `site/sync-docs.mjs` auto-copy/rewrite), but
27
+ **no screenshot-capture discipline and no anonymization of sensitive content
28
+ inside a captured screenshot.** `domain-safety-pii` scopes to text surfaces only
29
+ (drafts / logs / exports / legal privilege); media governance
30
+ (`media-governance-routing`, `image-likeness-and-rights`) scopes to *generated*-
31
+ image rights/likeness. Neither covers redacting sensitive data inside a captured
32
+ screenshot.
33
+
34
+ An AI council debate (2026-07-23, anthropic/claude-sonnet-4-5 + openai/gpt-4o,
35
+ 2 rounds) surfaced the load-bearing tension: agents creating screenshots
36
+ autonomously + a "must anonymize" security guarantee + imperfect detection are
37
+ mutually constraining. Automated detection (OCR + pattern-match + allowlist)
38
+ cannot *prove* a screenshot is safe — it misses semantic leaks (aggregate counts,
39
+ real-vs-fake data tells, re-identification via name structure), and an allowlist
40
+ of "known-fake data" degenerates into an unmaintainable cross-cultural dictionary
41
+ and an identity-resolution hazard.
42
+
43
+ ## Decision
44
+
45
+ Build the feature (the maintainer has decided *whether*; the council informed
46
+ *how*), with these locked choices:
47
+
48
+ 1. **Capture is delegated to the host** (`claude-in-chrome` / Playwright). The
49
+ package ships NO bundled capture engine — respects the no-runtime-floor
50
+ doctrine (ADR-109 §7). The package owns only the anonymization + embedding
51
+ discipline.
52
+
53
+ 2. **Standalone rule + skill, not a "Surface 5" on `domain-safety-pii`.**
54
+ Screenshots are opaque binary artifacts requiring OCR/vision, not the
55
+ text-pattern surfaces `domain-safety-pii` contracts around. Bolting them on
56
+ would break that rule's scope contract.
57
+
58
+ 3. **Detection is a HELPER, never a CLEARANCE.** The automated OCR + pattern
59
+ pass flags candidate regions and pre-redacts to make review cheap; it never
60
+ certifies a screenshot as safe. **The gate is human confirmation** for
61
+ data-bearing screenshots.
62
+
63
+ 4. **Egress teeth via the kernel, not a new kernel rule.** A data-bearing
64
+ screenshot embedded into shipped docs is an *irreversible published egress*.
65
+ The rule's Iron Law routes that embed INTO the existing kernel
66
+ `non-destructive-by-default` Hard Floor (publish/commit already require
67
+ this-turn confirmation). This gives the gate real teeth **without** adding a
68
+ new `always`/kernel rule — which would demand an ADR-gated kernel-membership
69
+ re-run + 24 h soak and would fail the kernel cross-cutting criterion (the
70
+ concern is docs/media-scoped, not cross-cutting across all work). The rule
71
+ ships as `auto` tier-2a; its severity is borrowed from the kernel Hard Floor
72
+ it routes into. ("Route, don't rebuild.")
73
+
74
+ 5. **Conservative default:** uncertain / unresolved / cannot-confirm-safe →
75
+ redact-or-refuse, never ship-and-hope.
76
+
77
+ 6. **Terminal / CLI / IDE screenshots are forbidden.** They are the highest leak
78
+ vector (absolute local paths, env tokens) and least reliably OCR-able. Steer
79
+ to text code blocks with text redaction — cheaper and safer.
80
+
81
+ 7. **Redaction is a deterministic opaque box/blur** over flagged regions; reject
82
+ lossy provider inpaint (docs need visual accuracy). The redaction tool is
83
+ **optional / tool-agnostic** — `sharp` is a `site` dependency only, not a
84
+ package dependency; mandating it breaks framework-neutrality + no-runtime-
85
+ floor. Missing tool → STOP and hand off to the maintainer; never silently
86
+ downgrade the guarantee.
87
+
88
+ 8. **The identity allowlist is the maintainer's OWN public handles + a small
89
+ fake-data seed** (`screenshots.identity_allowlist`, default `[]`) — NOT a
90
+ global fake-data dictionary and NOT identity-resolution. Default: everything
91
+ is treated as sensitive unless a human decides or it matches the allowlist. A
92
+ public handle co-located with a real name does not whitelist the name.
93
+
94
+ ## Consequences
95
+
96
+ - New `auto` tier-2a rule `doc-screenshot-hygiene` (obligation surface + taxonomy
97
+ + risk tiers) routing to a new `screenshot-hygiene` skill (the decide →
98
+ capture → detect → redact → audit → embed workflow + the human-gate checklist).
99
+ - New `screenshots.*` config keys (allowlist + terminal-forbid policy + gate)
100
+ with conservative defaults.
101
+ - `readme-writing` strengthens its unrequested-screenshot check for data-bearing
102
+ shots; illustrative/no-data docs screenshots are the reconciled exception.
103
+ - The "must anonymize" requirement is honored as a **human-gated** guarantee,
104
+ not a false-confidence automated one — the failure mode the council flagged
105
+ (agent ships PII because the automated audit "passed") is structurally avoided.
106
+ - Cost: agents cannot autonomously embed data-bearing screenshots; a human
107
+ confirmation is required. This friction is intentional and symmetric with the
108
+ irreversibility of the egress.
109
+
110
+ ## Alternatives considered
111
+
112
+ - **New `always`/kernel rule (Anthropic Round 1).** Rejected: fails the kernel
113
+ cross-cutting criterion, and the ADR+24 h-soak gate is disproportionate. The
114
+ route-into-Hard-Floor synthesis delivers the same teeth without kernel churn.
115
+ - **Fully automated redaction pipeline as the gate (OpenAI Round 1).** Rejected
116
+ as a *clearance*: detection can't prove safety; "audit passed" would license
117
+ agents to skip human review — the exact inversion the gate exists to prevent.
118
+ Kept only as a *helper* that flags + pre-redacts.
119
+ - **Extend `domain-safety-pii` with Surface 5.** Rejected: breaks the text-
120
+ surface scope contract of that rule.
121
+ - **Bundle a `sharp`-based capture+redaction engine.** Rejected: `sharp` is a
122
+ site-only dep; bundling breaks framework-neutrality + no-runtime-floor.
123
+ - **"Don't build it at all" (Anthropic Round 1 core).** Out of scope — the
124
+ maintainer decided to build; the ADR records the safe *how*.
125
+
126
+ ## References
127
+
128
+ - AI council debate 2026-07-23 (anthropic/claude-sonnet-4-5 + openai/gpt-4o,
129
+ 2 rounds), inlined in `agents/roadmaps/road-to-doc-screenshot-anonymization.md`.
130
+ - ADR-109 (no-runtime-floor doctrine); `src/rules/non-destructive-by-default.md`;
131
+ `docs/contracts/kernel-membership.md`; `docs/threat-model.md`.