@event4u/agent-config 16.0.0 → 16.2.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 (382) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +289 -140
  5. package/CONTRIBUTING.md +9 -0
  6. package/README.md +2 -2
  7. package/dist/agent-src/commands/analyze/inbox.md +26 -0
  8. package/dist/agent-src/commands/analyze/roadmap-repos.md +27 -0
  9. package/dist/agent-src/commands/challenge-me/closure.md +178 -0
  10. package/dist/agent-src/commands/challenge-me.md +9 -2
  11. package/dist/agent-src/commands/council/default.md +25 -5
  12. package/dist/agent-src/commands/feature/plan.md +28 -1
  13. package/dist/agent-src/commands/feature/roadmap.md +28 -1
  14. package/dist/agent-src/commands/implement-ticket.md +27 -0
  15. package/dist/agent-src/commands/jira-ticket.md +27 -0
  16. package/dist/agent-src/commands/pr/create.md +29 -0
  17. package/dist/agent-src/commands/pr/merge.md +60 -9
  18. package/dist/agent-src/commands/roadmap/ai-council.md +7 -1
  19. package/dist/agent-src/commands/roadmap/create.md +74 -27
  20. package/dist/agent-src/commands/roadmap/materialize.md +27 -0
  21. package/dist/agent-src/commands/roadmap/process-full.md +123 -18
  22. package/dist/agent-src/commands/team.md +22 -0
  23. package/dist/agent-src/commands/work.md +4 -0
  24. package/dist/agent-src/contexts/authority/scope-growth-ownership.md +80 -0
  25. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +47 -0
  26. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +44 -3
  27. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +19 -23
  28. package/dist/agent-src/contexts/execution/decision-closure-execution.md +93 -0
  29. package/dist/agent-src/contexts/execution/fix-loop-ladder.md +108 -0
  30. package/dist/agent-src/contexts/execution/plan-confidence-gate.md +4 -2
  31. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +75 -6
  32. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
  33. package/dist/agent-src/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
  34. package/dist/agent-src/guidelines/design-fidelity-routing.md +29 -0
  35. package/dist/agent-src/rules/autonomous-execution.md +15 -8
  36. package/dist/agent-src/rules/delegation-policy.md +23 -45
  37. package/dist/agent-src/rules/design-fidelity.md +32 -37
  38. package/dist/agent-src/rules/evaluator-independence.md +43 -49
  39. package/dist/agent-src/rules/test-first.md +41 -0
  40. package/dist/agent-src/rules/ui-audit-gate.md +1 -2
  41. package/dist/agent-src/skills/accessibility-auditor/data/aria-patterns.csv +1 -1
  42. package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +3 -3
  43. package/dist/agent-src/skills/ai-council/SKILL.md +11 -3
  44. package/dist/agent-src/skills/api-design/data/manifest.json +3 -3
  45. package/dist/agent-src/skills/database/data/manifest.json +4 -4
  46. package/dist/agent-src/skills/database/data/query-tuning.csv +3 -3
  47. package/dist/agent-src/skills/design-review/SKILL.md +80 -4
  48. package/dist/agent-src/skills/design-review/references/verification-automation.md +32 -0
  49. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +30 -5
  50. package/dist/agent-src/skills/existing-ui-audit/references/component-taxonomy-detection.md +56 -0
  51. package/dist/agent-src/skills/experiment-loop/SKILL.md +31 -1
  52. package/dist/agent-src/skills/markitdown/SKILL.md +4 -0
  53. package/dist/agent-src/skills/playwright-testing/SKILL.md +30 -6
  54. package/dist/agent-src/skills/roadmap-writing/SKILL.md +1 -1
  55. package/dist/agent-src/skills/storybook-workshop/SKILL.md +42 -3
  56. package/dist/agent-src/skills/threat-modeling/SKILL.md +9 -4
  57. package/dist/agent-src/skills/threat-modeling/data/manifest.json +4 -4
  58. package/dist/agent-src/skills/ui-component-architect/SKILL.md +23 -0
  59. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +37 -3
  60. package/dist/agent-src/templates/agent-settings.md +1 -1
  61. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  62. package/dist/agent-src/templates/roadmaps.md +218 -0
  63. package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
  64. package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
  65. package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
  66. package/dist/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +10 -4
  67. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +260 -21
  68. package/dist/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +22 -3
  69. package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +6 -1
  70. package/dist/agent-src/templates/scripts/work_engine/state.ts +57 -7
  71. package/dist/agent-src/templates/scripts/work_engine/taxonomy/detect.ts +500 -0
  72. package/dist/agent-src/templates/scripts/work_engine/taxonomy/place.ts +183 -0
  73. package/dist/cli/python/knowledge_ingest.js +1 -1
  74. package/dist/cli/python/workspace_drive.js +1 -1
  75. package/dist/cli-delegate/check_update_banner.js +40 -2
  76. package/dist/cli-delegate/chunk-4E2W63DA.js +335 -0
  77. package/dist/cli-delegate/{chunk-S3VFXMTM.js → chunk-4XFP2Y3E.js} +1 -1
  78. package/dist/cli-delegate/chunk-5R7HOLAF.js +99 -0
  79. package/dist/cli-delegate/{chunk-IVBPRCQO.js → chunk-6KFEC3G7.js} +1 -1
  80. package/dist/cli-delegate/{chunk-2TAQ2K4V.js → chunk-6KM6ORRY.js} +55 -386
  81. package/dist/cli-delegate/{chunk-AK6HODNQ.js → chunk-7XGBX6ZH.js} +973 -555
  82. package/dist/cli-delegate/{chunk-2XY7ILBT.js → chunk-FC75PGJE.js} +42 -2
  83. package/dist/cli-delegate/{chunk-55ACLDUE.js → chunk-FP36SWJD.js} +587 -141
  84. package/dist/cli-delegate/{chunk-3FKR64R5.js → chunk-IGD6ERX6.js} +62 -7
  85. package/dist/cli-delegate/{chunk-GYC3VRYN.js → chunk-JNMVLWLR.js} +99 -14
  86. package/dist/cli-delegate/{chunk-H32DGUJH.js → chunk-P6ZHP5W2.js} +1 -1
  87. package/dist/cli-delegate/{chunk-57PN4GYJ.js → chunk-RGNIWTEA.js} +1 -1
  88. package/dist/cli-delegate/chunk-ROYYTEZU.js +39 -0
  89. package/dist/cli-delegate/{chunk-2DK2VJWG.js → chunk-WGXTVKCQ.js} +20 -6
  90. package/dist/cli-delegate/chunk-YDPILCOL.js +152 -0
  91. package/dist/cli-delegate/{chunk-QJWAUMJW.js → chunk-YJ72UIAK.js} +730 -15
  92. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  93. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  94. package/dist/cli-delegate/cmd_conformance.js +985 -831
  95. package/dist/cli-delegate/cmd_doctor.js +7 -5
  96. package/dist/cli-delegate/cmd_explain.js +2 -2
  97. package/dist/cli-delegate/cmd_export.js +9 -7
  98. package/dist/cli-delegate/cmd_fleet.js +4 -2
  99. package/dist/cli-delegate/cmd_handoff.js +7 -7
  100. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  101. package/dist/cli-delegate/cmd_memory_get.js +1 -1
  102. package/dist/cli-delegate/cmd_migrate.js +2 -2
  103. package/dist/cli-delegate/cmd_packs_active.js +2 -2
  104. package/dist/cli-delegate/cmd_preflight.js +4 -2
  105. package/dist/cli-delegate/cmd_prune.js +10 -8
  106. package/dist/cli-delegate/cmd_route_audit.js +3 -3
  107. package/dist/cli-delegate/cmd_route_explain.js +1 -1
  108. package/dist/cli-delegate/cmd_session_recycle.js +4 -4
  109. package/dist/cli-delegate/cmd_settings_get.js +28 -2
  110. package/dist/cli-delegate/cmd_settings_migrate.js +9 -7
  111. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  112. package/dist/cli-delegate/cmd_sync.js +10 -8
  113. package/dist/cli-delegate/cmd_uninstall.js +16 -13
  114. package/dist/cli-delegate/cmd_update.js +1 -1
  115. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  116. package/dist/cli-delegate/cmd_validate.js +12 -10
  117. package/dist/cli-delegate/cmd_versions.js +1 -1
  118. package/dist/discovery/deprecation-report.md +1 -1
  119. package/dist/discovery/discovery-manifest.json +90 -43
  120. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  121. package/dist/discovery/discovery-manifest.summary.md +4 -4
  122. package/dist/discovery/dormancy-report.md +1 -1
  123. package/dist/discovery/orphan-report.md +1 -1
  124. package/dist/discovery/packs.json +10 -8
  125. package/dist/discovery/trust-report.md +3 -3
  126. package/dist/discovery/workspaces.json +8 -6
  127. package/dist/hooks/dispatch.js +7682 -2772
  128. package/dist/hooks/dispatch.sha256 +1 -0
  129. package/dist/install/claudeRuleRewrite.js +14 -3
  130. package/dist/install/conflict.js +60 -10
  131. package/dist/install/conflictTracker.js +218 -0
  132. package/dist/install/fsPrimitives.js +54 -0
  133. package/dist/install/install.mjs +2200 -1559
  134. package/dist/install/manifestFiles.js +259 -0
  135. package/dist/install/preflight.js +14 -2
  136. package/dist/install/preserve.js +157 -0
  137. package/dist/install/recordedOwnership.js +132 -0
  138. package/dist/install/txlog.js +11 -2
  139. package/dist/mcp/registry-manifest.json +3 -3
  140. package/dist/mcp/server.json +2 -2
  141. package/dist/mcp/server.mjs +3066 -1470
  142. package/dist/router.json +1 -1
  143. package/dist/scripts/_lib/agent_settings.js +3 -2
  144. package/dist/scripts/_lib/fs_atomic.js +167 -0
  145. package/dist/scripts/_lib/installed_tools.js +460 -0
  146. package/dist/scripts/_lib/lean_projection_mode.js +3 -2
  147. package/dist/scripts/_lib/settings_renamed_keys.js +78 -0
  148. package/dist/server/routes/install.js +8 -0
  149. package/dist/server/routes/wizard.js +9 -3
  150. package/dist/server/schemas/settings.js +40 -5
  151. package/dist/shared/missionExecution.js +97 -0
  152. package/dist/ui/assets/index-Cwq4d0hX.js +23 -0
  153. package/dist/ui/assets/index-Cyjy8bWO.css +1 -0
  154. package/dist/ui/index.html +2 -2
  155. package/docs/MIGRATION.md +103 -0
  156. package/docs/contracts/settings-classes.md +28 -7
  157. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
  158. package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
  159. package/docs/guidelines/design-fidelity-routing.md +29 -0
  160. package/package.json +4 -4
  161. package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
  162. package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
  163. package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
  164. package/src/agent-src/templates/scripts/work_engine/directives/ui/app_spec.ts +10 -4
  165. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +260 -21
  166. package/src/agent-src/templates/scripts/work_engine/directives/ui/audit.ts +22 -3
  167. package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +6 -1
  168. package/src/agent-src/templates/scripts/work_engine/state.ts +57 -7
  169. package/src/agent-src/templates/scripts/work_engine/taxonomy/detect.ts +500 -0
  170. package/src/agent-src/templates/scripts/work_engine/taxonomy/place.ts +183 -0
  171. package/src/config/agent-settings.template.yml +168 -27
  172. package/src/config/auto-rule-budget.json +16 -0
  173. package/src/config/ci-local-parity.yml +36 -5
  174. package/src/config/continuity-surface.json +23 -2
  175. package/src/config/gate-coverage.yml +377 -13
  176. package/src/config/gate-violation-baselines.json +10 -6
  177. package/src/config/hook-latency-budget.json +21 -0
  178. package/src/config/hook-token-budget.json +4 -2
  179. package/src/config/loop-surfaces.yaml +215 -0
  180. package/src/config/metric-registry.yml +114 -0
  181. package/src/config/placeholder-drift-budget.json +10 -0
  182. package/src/config/platform-anchor.json +3 -2
  183. package/src/config/release-gate-locality.yml +11 -0
  184. package/src/config/routing-coverage-seed.json +33 -5
  185. package/src/config/rule-enforcement-baseline.json +0 -1
  186. package/src/install/claudeRuleRewrite.ts +16 -2
  187. package/src/install/conflict.ts +65 -9
  188. package/src/install/conflictTracker.ts +299 -0
  189. package/src/install/fsPrimitives.ts +54 -0
  190. package/src/install/manifestFiles.ts +312 -0
  191. package/src/install/preflight.ts +16 -2
  192. package/src/install/preserve.ts +205 -0
  193. package/src/install/recordedOwnership.ts +149 -0
  194. package/src/install/txlog.ts +11 -2
  195. package/src/install/types.ts +19 -4
  196. package/src/scripts/_cli/cmd_conformance.ts +88 -15
  197. package/src/scripts/_cli/cmd_doctor.ts +7 -20
  198. package/src/scripts/_cli/cmd_route_explain.ts +9 -2
  199. package/src/scripts/_cli/cmd_settings_get.ts +44 -0
  200. package/src/scripts/_cli/doctor_execution.ts +173 -0
  201. package/src/scripts/_cli/doctor_network_posture.ts +226 -0
  202. package/src/scripts/_lib/activation_payload.ts +247 -0
  203. package/src/scripts/_lib/agent_settings.ts +4 -2
  204. package/src/scripts/_lib/authority_path.ts +102 -0
  205. package/src/scripts/_lib/body_portable.ts +102 -0
  206. package/src/scripts/_lib/cascade_base.ts +94 -0
  207. package/src/scripts/_lib/cc_transcript.ts +132 -1
  208. package/src/scripts/_lib/changelog_eras.ts +7 -2
  209. package/src/scripts/_lib/concern_sla_window.ts +200 -0
  210. package/src/scripts/_lib/continuation_ladder.ts +149 -2
  211. package/src/scripts/_lib/council_transport.ts +129 -0
  212. package/src/scripts/_lib/delivery_ready.ts +112 -0
  213. package/src/scripts/_lib/forge_protection.ts +381 -0
  214. package/src/scripts/_lib/forge_reader.ts +558 -0
  215. package/src/scripts/_lib/hook_platform_keys.ts +27 -0
  216. package/src/scripts/_lib/host_env_write.ts +111 -0
  217. package/src/scripts/_lib/json_python_parity.ts +127 -0
  218. package/src/scripts/_lib/lean_projection_mode.ts +14 -3
  219. package/src/scripts/_lib/llm_proposer_transport.ts +14 -4
  220. package/src/scripts/_lib/loop_surfaces.ts +382 -0
  221. package/src/scripts/_lib/mission_record.ts +190 -0
  222. package/src/scripts/_lib/obligation_frequency.ts +217 -0
  223. package/src/scripts/_lib/obligations.ts +513 -0
  224. package/src/scripts/_lib/orchestration_record.ts +11 -20
  225. package/src/scripts/_lib/probe_inputs.ts +271 -0
  226. package/src/scripts/_lib/read_surface_scan.ts +322 -0
  227. package/src/scripts/_lib/release_highlights.ts +201 -11
  228. package/src/scripts/_lib/release_holds.ts +493 -0
  229. package/src/scripts/_lib/release_migration_gate.ts +184 -0
  230. package/src/scripts/_lib/retrieval_sanitize.ts +77 -16
  231. package/src/scripts/_lib/rides_along.ts +102 -0
  232. package/src/scripts/_lib/settings_renamed_keys.ts +82 -0
  233. package/src/scripts/_lib/shell_write_shapes.ts +108 -0
  234. package/src/scripts/_lib/structural_hiding.ts +622 -0
  235. package/src/scripts/_lib/test_delta.ts +166 -0
  236. package/src/scripts/_lib/test_provenance.ts +171 -0
  237. package/src/scripts/_lib/turn_end_refusals.ts +525 -4
  238. package/src/scripts/_lib/turn_end_transcript.ts +216 -0
  239. package/src/scripts/_lib/typed_op_grant.ts +246 -0
  240. package/src/scripts/_lib/typed_op_watch.ts +185 -0
  241. package/src/scripts/_lib/verification_command.ts +324 -0
  242. package/src/scripts/_lib/verification_evidence.ts +647 -0
  243. package/src/scripts/_lib/verify_clause.ts +280 -0
  244. package/src/scripts/ai_council/config.ts +8 -11
  245. package/src/scripts/ai_council/fallback_config.ts +5 -3
  246. package/src/scripts/ai_council/ownership_classes.ts +118 -0
  247. package/src/scripts/ai_team/team_dispatch.ts +4 -0
  248. package/src/scripts/ask_block_census.ts +285 -15
  249. package/src/scripts/before_complete_hook.ts +340 -23
  250. package/src/scripts/bench_hook_latency.ts +412 -5
  251. package/src/scripts/cache_realization_report.ts +61 -1
  252. package/src/scripts/check_argument_hint.ts +287 -0
  253. package/src/scripts/check_claims.ts +125 -1
  254. package/src/scripts/check_enforcement_coverage.ts +38 -9
  255. package/src/scripts/check_enforcement_matrix.ts +866 -0
  256. package/src/scripts/check_finding_dispositions.ts +22 -3
  257. package/src/scripts/check_gate_reachability.ts +173 -10
  258. package/src/scripts/check_generator_sync.ts +1025 -0
  259. package/src/scripts/check_host_docs_digest.ts +786 -0
  260. package/src/scripts/check_host_format_column.ts +559 -0
  261. package/src/scripts/check_input_references.ts +228 -0
  262. package/src/scripts/check_inputs_parity.ts +235 -0
  263. package/src/scripts/check_kernel_edit_ratified.ts +47 -5
  264. package/src/scripts/check_kill_switch_table.ts +294 -0
  265. package/src/scripts/check_placeholder_drift.ts +221 -0
  266. package/src/scripts/check_preamble_payload_budget.ts +75 -2
  267. package/src/scripts/check_read_surface_coverage.ts +515 -0
  268. package/src/scripts/check_release_highlights.ts +33 -1
  269. package/src/scripts/check_release_holds.ts +568 -0
  270. package/src/scripts/check_routing_coverage.ts +378 -11
  271. package/src/scripts/check_rule_projection_integrity.ts +22 -12
  272. package/src/scripts/check_static_parity.ts +17 -0
  273. package/src/scripts/check_test_delta.ts +294 -0
  274. package/src/scripts/check_test_weakening.ts +299 -0
  275. package/src/scripts/ci_settle.ts +145 -19
  276. package/src/scripts/closure_scan.ts +447 -0
  277. package/src/scripts/compile_hook_manifest.ts +102 -18
  278. package/src/scripts/council_record_shape.ts +209 -0
  279. package/src/scripts/external_sources_denylist.json +29 -4
  280. package/src/scripts/hook_manifest.json +1 -1
  281. package/src/scripts/hook_manifest.yaml +127 -11
  282. package/src/scripts/hooks/block_config_weakening.ts +229 -4
  283. package/src/scripts/hooks/block_kernel_rule_writes.ts +9 -78
  284. package/src/scripts/hooks/block_plumbing_writes.ts +314 -0
  285. package/src/scripts/hooks/bundle_integrity.ts +291 -0
  286. package/src/scripts/hooks/chain_nudge_hook.ts +1 -2
  287. package/src/scripts/hooks/code_graph_context_hook.ts +1 -2
  288. package/src/scripts/hooks/comment_discipline_hook.ts +1 -3
  289. package/src/scripts/hooks/concern_registry.ts +6 -0
  290. package/src/scripts/hooks/concern_timings.ts +94 -0
  291. package/src/scripts/hooks/delegation_nudge_hook.ts +1 -2
  292. package/src/scripts/hooks/design_pass_hook.ts +221 -5
  293. package/src/scripts/hooks/design_slop_hook.ts +1 -2
  294. package/src/scripts/hooks/dispatch_hook.ts +25 -19
  295. package/src/scripts/hooks/edit_shape_hook.ts +1 -2
  296. package/src/scripts/hooks/end_review_nudge_hook.ts +1 -1
  297. package/src/scripts/hooks/evidence_independence.ts +97 -2
  298. package/src/scripts/hooks/exit_codes.ts +128 -0
  299. package/src/scripts/hooks/host_lowering.json +1 -0
  300. package/src/scripts/hooks/host_lowering.ts +128 -3
  301. package/src/scripts/hooks/host_lowering.yaml +262 -46
  302. package/src/scripts/hooks/host_semantics.ts +30 -2
  303. package/src/scripts/hooks/injection_budget.ts +9 -2
  304. package/src/scripts/hooks/interruption_ledger_hook.ts +1 -2
  305. package/src/scripts/hooks/journal_record_hook.ts +1 -2
  306. package/src/scripts/hooks/memory_recall_hook.ts +539 -0
  307. package/src/scripts/hooks/obligation_settle_hook.ts +328 -0
  308. package/src/scripts/hooks/one_question_per_ask_hook.ts +25 -4
  309. package/src/scripts/hooks/orchestration_record_hook.ts +1 -2
  310. package/src/scripts/hooks/permission_gate.ts +1 -2
  311. package/src/scripts/hooks/push_settle_hook.ts +1 -3
  312. package/src/scripts/hooks/replay_hook.ts +2 -1
  313. package/src/scripts/hooks/reread_guard_hook.ts +1 -2
  314. package/src/scripts/hooks/review_baseline_hook.ts +1 -2
  315. package/src/scripts/hooks/rtk_wrap_hook.ts +1 -2
  316. package/src/scripts/hooks/rule_inject_hook.ts +55 -4
  317. package/src/scripts/hooks/run_continuation_hook.ts +30 -35
  318. package/src/scripts/hooks/skill_route_hook.ts +1 -2
  319. package/src/scripts/hooks/source_first_gate_hook.ts +1 -2
  320. package/src/scripts/hooks/spawn_guard_shadow_hook.ts +1 -2
  321. package/src/scripts/hooks/subagent_ledger_hook.ts +1 -2
  322. package/src/scripts/hooks/suggestion_capture_hook.ts +1 -1
  323. package/src/scripts/hooks/table_fingerprint.ts +49 -0
  324. package/src/scripts/hooks/telemetry_flush_hook.ts +1 -2
  325. package/src/scripts/hooks/telemetry_usage_hook.ts +1 -2
  326. package/src/scripts/hooks/tool_result_bytes_hook.ts +93 -9
  327. package/src/scripts/hooks/turn_end_gate_hook.ts +337 -324
  328. package/src/scripts/hooks/ui_route_nudge_hook.ts +1 -2
  329. package/src/scripts/hooks_doctor.ts +85 -0
  330. package/src/scripts/hooks_status.ts +19 -0
  331. package/src/scripts/install.ts +109 -210
  332. package/src/scripts/janitor.ts +7 -0
  333. package/src/scripts/lint_decision_classes.ts +464 -0
  334. package/src/scripts/lint_deny_text.ts +419 -0
  335. package/src/scripts/lint_exit_codes.ts +262 -0
  336. package/src/scripts/lint_hook_manifest.ts +66 -0
  337. package/src/scripts/lint_major_migration_sections.ts +450 -0
  338. package/src/scripts/lint_plan_risk_register.ts +47 -3
  339. package/src/scripts/lint_roadmap_blockers.ts +139 -12
  340. package/src/scripts/lint_roadmap_producers.ts +202 -0
  341. package/src/scripts/lint_skill_descriptions.ts +1 -1
  342. package/src/scripts/lint_skill_scripts_readonly.ts +1 -1
  343. package/src/scripts/mcp_server/prompts.ts +142 -1
  344. package/src/scripts/measure_rule_budget.ts +101 -5
  345. package/src/scripts/measure_skill_ranker_baseline.ts +305 -51
  346. package/src/scripts/measure_turn_end_gate.ts +193 -0
  347. package/src/scripts/memory_lookup.ts +1 -1
  348. package/src/scripts/new_roadmap.ts +37 -0
  349. package/src/scripts/orchestration_record.ts +0 -5
  350. package/src/scripts/prepack-check.mjs +53 -0
  351. package/src/scripts/release.ts +14 -98
  352. package/src/scripts/release_drill.ts +267 -1
  353. package/src/scripts/release_publication.ts +64 -1
  354. package/src/scripts/report_enforcement_drift.ts +566 -0
  355. package/src/scripts/report_host_injection_effect.ts +3 -11
  356. package/src/scripts/report_invocation_surface.ts +383 -0
  357. package/src/scripts/report_obligation_carriers.ts +699 -0
  358. package/src/scripts/report_obligation_writer_split.ts +236 -0
  359. package/src/scripts/report_skill_menu_census.ts +208 -0
  360. package/src/scripts/report_standing_payload_by_host.ts +26 -152
  361. package/src/scripts/roadmap_verify_share.ts +213 -0
  362. package/src/scripts/schemas/agent-settings.schema.json +23 -0
  363. package/src/scripts/schemas/command.schema.json +48 -0
  364. package/src/scripts/schemas/review-findings.schema.json +4 -0
  365. package/src/scripts/schemas/skill.schema.json +44 -0
  366. package/src/scripts/scope_growth.ts +219 -0
  367. package/src/scripts/self_review_gate.ts +359 -10
  368. package/src/scripts/semantic_parity_census.ts +314 -0
  369. package/src/scripts/session_eol_report.ts +54 -1
  370. package/src/scripts/sweep_dead_scan_roots.ts +1 -1
  371. package/src/scripts/trigger_eval_grandfather.json +0 -3
  372. package/src/scripts/trigger_eval_rotation.ts +122 -27
  373. package/src/scripts/ui_conformance_probe.ts +774 -0
  374. package/src/scripts/update_prices.ts +85 -3
  375. package/src/scripts/write_bundle_digest.mjs +74 -0
  376. package/src/server/schemas/settings.ts +62 -7
  377. package/src/shared/missionExecution.ts +126 -0
  378. package/src/templates/consumer-settings/ONBOARDING.md +1 -0
  379. package/dist/cli-delegate/chunk-523HCFYO.js +0 -90
  380. package/dist/ui/assets/index-D0jaCRPM.js +0 -29
  381. package/dist/ui/assets/index-jSfMW8_t.css +0 -1
  382. /package/dist/cli-delegate/{chunk-YUM5KURG.js → chunk-7RQP4UDH.js} +0 -0
@@ -20,13 +20,17 @@
20
20
  * Usage:
21
21
  * tsx src/scripts/install.ts # defaults: rule_loading_tier=balanced
22
22
  * tsx src/scripts/install.ts --profile=minimal # set rule_loading_tier=minimal (kernel only)
23
- * tsx src/scripts/install.ts --force # accepted (no-op): installs always overwrite
23
+ * tsx src/scripts/install.ts --force # replace managed files the user has edited
24
24
  * tsx src/scripts/install.ts --skip-bridges # only create .agent-settings.yml
25
25
  * tsx src/scripts/install.ts --project <dir> # override project root
26
26
  *
27
- * Idempotent — safe to run multiple times. A run always refreshes every
28
- * deployed file with the current package content; user configuration
29
- * (.agent-settings.yml) is merged by the settings layer, never clobbered.
27
+ * Idempotent — safe to run multiple times. A run refreshes every deployed file
28
+ * with the current package content, EXCEPT a managed file whose bytes diverge
29
+ * from the digest the install manifest recorded: that one is preserved, package
30
+ * content is staged beside it as `<path>.agent-config.new`, and the run exits 3
31
+ * rather than 0 so the staleness is stated, not silent; `--force` replaces it
32
+ * instead. Contract + state machine: `install/preserve.ts`, `conflictTracker.ts`.
33
+ * User config (.agent-settings.yml) is settings-layer merged, never clobbered.
30
34
  *
31
35
  * --- Parity notes (ADR-200) ---
32
36
  *
@@ -72,11 +76,17 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
72
76
  import type * as YamlModule from 'yaml';
73
77
 
74
78
  import { build_merge_entries } from './_lib/json_pointers.js';
79
+ import { withHostEnv } from './_lib/host_env_write.js';
80
+ import { jsonDumpsCompact, jsonDumpsIndent } from './_lib/json_python_parity.js';
75
81
  import { is_claude_builtin_name } from './_lib/claude_builtin_names.js';
76
82
  import * as installed_lock from './_lib/installed_lock.js';
77
83
  import * as mcp_bridge from './_lib/mcp_bridge.js';
78
84
  import * as mcp_consent from './_lib/mcp_consent_residual.js';
79
85
  import * as scoped_projection from './_lib/scoped_projection.js';
86
+ import { createConflictTracker } from '../install/conflictTracker.js';
87
+ import { mkdirp, pathExists, resolvePath, sha256OfFile } from '../install/fsPrimitives.js';
88
+ import { filesByToolFromBridges as _files_by_tool_from_bridges, filesByToolFromDeploy as _files_by_tool_from_deploy, hydrateRecordedInventories, preservedIndex, readRecordedByTool, reconcileToolFiles, type ManifestFileEntry } from '../install/manifestFiles.js';
89
+ import { EXIT_COMPLETED_WITH_CONFLICTS } from '../install/preserve.js';
80
90
  import * as surface_tiers from './_lib/surface_tiers.js';
81
91
  import * as global_deploy_inventory from './_lib/global_deploy_inventory.js';
82
92
  import * as rule_layer_overlap from './_lib/rule_layer_overlap.js';
@@ -113,6 +123,8 @@ import {
113
123
  } from './_lib/model_tier.js';
114
124
  import { main as cmdMigrateMain } from './_cli/cmd_migrate.js';
115
125
  import { SCOPE_DETECT_AI_DIRS, SCOPE_DETECT_MANIFESTS } from '../install/detect.js';
126
+ import { getLogPath } from '../install/paths.js';
127
+ import { appendTxLog } from '../install/txlog.js';
116
128
 
117
129
  // ---------------------------------------------------------------------------
118
130
  // Python-runtime parity helpers
@@ -143,15 +155,6 @@ function expanduser(p: string): string {
143
155
  return p;
144
156
  }
145
157
 
146
- /** `Path.resolve()` — absolute, symlink-resolved where possible. */
147
- function resolvePath(p: string): string {
148
- try {
149
- return fs.realpathSync(path.resolve(p));
150
- } catch {
151
- return path.resolve(p);
152
- }
153
- }
154
-
155
158
  function isFile(p: string): boolean {
156
159
  try {
157
160
  return fs.statSync(p).isFile();
@@ -168,15 +171,6 @@ function isDir(p: string): boolean {
168
171
  }
169
172
  }
170
173
 
171
- function pathExists(p: string): boolean {
172
- try {
173
- fs.statSync(p);
174
- return true;
175
- } catch {
176
- return false;
177
- }
178
- }
179
-
180
174
  function isSymlink(p: string): boolean {
181
175
  try {
182
176
  return fs.lstatSync(p).isSymbolicLink();
@@ -193,11 +187,6 @@ function writeText(p: string, content: string): void {
193
187
  fs.writeFileSync(p, content, 'utf-8');
194
188
  }
195
189
 
196
- /** `path.mkdir(parents=True, exist_ok=True)`. */
197
- function mkdirp(p: string): void {
198
- fs.mkdirSync(p, { recursive: true });
199
- }
200
-
201
190
  /**
202
191
  * `sorted(Path.glob(pattern))` with PyYAML/pathlib component-wise ordering.
203
192
  * We only need a non-recursive `*.glob("<pat>")`; pathlib sorts the matched
@@ -238,17 +227,6 @@ function countZips(directory: string): number {
238
227
  return n;
239
228
  }
240
229
 
241
- /** `hashlib.sha256(data).hexdigest()` of a file's bytes, or null when unreadable. */
242
- function sha256OfFile(p: string): string | null {
243
- let data: Buffer;
244
- try {
245
- data = fs.readFileSync(p);
246
- } catch {
247
- return null;
248
- }
249
- return crypto.createHash('sha256').update(data).digest('hex');
250
- }
251
-
252
230
  /**
253
231
  * Atomic write mirroring the Python `tempfile.mkstemp(...) → os.fdopen → write
254
232
  * → os.chmod(0o644) → os.replace` pattern in `_write_consumer_bridge_marker`
@@ -299,108 +277,6 @@ function utcStamp(now?: Date): string {
299
277
  );
300
278
  }
301
279
 
302
- // --- JSON byte-parity (ensure_ascii=False; insertion order) ---
303
-
304
- function _jsonStrNoAscii(s: string): string {
305
- // json.dumps(ensure_ascii=False): escape control chars + " + \, keep >=0x20
306
- let out = '"';
307
- for (const ch of s) {
308
- const code = ch.codePointAt(0) as number;
309
- switch (ch) {
310
- case '"':
311
- out += '\\"';
312
- break;
313
- case '\\':
314
- out += '\\\\';
315
- break;
316
- case '\n':
317
- out += '\\n';
318
- break;
319
- case '\r':
320
- out += '\\r';
321
- break;
322
- case '\t':
323
- out += '\\t';
324
- break;
325
- case '\b':
326
- out += '\\b';
327
- break;
328
- case '\f':
329
- out += '\\f';
330
- break;
331
- default:
332
- if (code < 0x20) {
333
- out += '\\u' + code.toString(16).padStart(4, '0');
334
- } else {
335
- out += ch;
336
- }
337
- }
338
- }
339
- return out + '"';
340
- }
341
-
342
- function _jsonScalar(value: unknown): string | null {
343
- if (value === null || value === undefined) return 'null';
344
- if (typeof value === 'boolean') return value ? 'true' : 'false';
345
- if (typeof value === 'number') {
346
- if (!Number.isFinite(value)) {
347
- if (Number.isNaN(value)) return 'NaN';
348
- return value > 0 ? 'Infinity' : '-Infinity';
349
- }
350
- // Our payloads carry only integers; render as-is.
351
- return String(value);
352
- }
353
- if (typeof value === 'string') return _jsonStrNoAscii(value);
354
- return null;
355
- }
356
-
357
- function _dumpIndent(value: unknown, indent: number, depth: number): string {
358
- const scalar = _jsonScalar(value);
359
- if (scalar !== null) return scalar;
360
- const pad = ' '.repeat(indent * (depth + 1));
361
- const closePad = ' '.repeat(indent * depth);
362
- if (Array.isArray(value)) {
363
- if (value.length === 0) return '[]';
364
- const items = value.map((v) => pad + _dumpIndent(v, indent, depth + 1));
365
- return `[\n${items.join(',\n')}\n${closePad}]`;
366
- }
367
- if (typeof value === 'object' && value !== null) {
368
- const obj = value as Record<string, unknown>;
369
- const keys = Object.keys(obj);
370
- if (keys.length === 0) return '{}';
371
- const items = keys.map(
372
- (k) => `${pad}${_jsonStrNoAscii(k)}: ${_dumpIndent(obj[k], indent, depth + 1)}`,
373
- );
374
- return `{\n${items.join(',\n')}\n${closePad}}`;
375
- }
376
- return _jsonStrNoAscii(String(value));
377
- }
378
-
379
- /** `json.dumps(data, indent=N, ensure_ascii=False)` (sort_keys=False). */
380
- function jsonDumpsIndent(value: unknown, indent: number): string {
381
- return _dumpIndent(value, indent, 0);
382
- }
383
-
384
- /** `json.dumps(obj, separators=(",", ":"))` — compact, ensure_ascii=False here. */
385
- function jsonDumpsCompact(value: unknown): string {
386
- const scalar = _jsonScalar(value);
387
- if (scalar !== null) return scalar;
388
- if (Array.isArray(value)) {
389
- return '[' + value.map((v) => jsonDumpsCompact(v)).join(',') + ']';
390
- }
391
- if (typeof value === 'object' && value !== null) {
392
- const obj = value as Record<string, unknown>;
393
- return (
394
- '{' +
395
- Object.keys(obj)
396
- .map((k) => `${_jsonStrNoAscii(k)}:${jsonDumpsCompact(obj[k])}`)
397
- .join(',') +
398
- '}'
399
- );
400
- }
401
- return _jsonStrNoAscii(String(value));
402
- }
403
-
404
280
  /** Lazy YAML safe_load mirroring PyYAML (version 1.1), `{}` on every error. */
405
281
  function yamlSafeLoad(text: string): unknown {
406
282
  let YAML: typeof YamlModule;
@@ -482,6 +358,11 @@ function _emit_progress_terminal(rc: number): void {
482
358
  if (!state.PROGRESS_NDJSON) return;
483
359
  if (rc === 0) {
484
360
  _emit_progress({ type: 'done' });
361
+ } else if (rc === EXIT_COMPLETED_WITH_CONFLICTS) {
362
+ // A conflict is a completion, not a failure, so the count rides on
363
+ // `done`, not an `error` frame. Zero conflicts never reach here, so that
364
+ // frame stays byte-identical to `{"type":"done"}`.
365
+ _emit_progress({ type: 'done', conflicts: tracker.conflictState.preserved.length });
485
366
  } else {
486
367
  _emit_progress({ type: 'error', code: 'E_INSTALL', exitCode: rc });
487
368
  }
@@ -553,10 +434,21 @@ function _is_interactive(): boolean {
553
434
  }
554
435
  }
555
436
 
556
- function _resolve_file_conflict(_target: string, _force_hint: boolean): string {
557
- // del force_hint / del target — deploys always overwrite our own content.
558
- return 'write';
559
- }
437
+ /**
438
+ * Per-run conflict tracking; the state machine, the sidecar staging and the
439
+ * exit-code folding live in `src/install/conflictTracker.ts`, and only the
440
+ * wiring is here. Module scope, like `state` above, because
441
+ * `_copy_dir_dereferencing_symlinks` is reached through six `_deploy_*` frames
442
+ * carrying no project root — `begin()` scopes the tracker to a run instead.
443
+ */
444
+ const tracker = createConflictTracker({
445
+ warn,
446
+ fail,
447
+ logWrite: (target) => _log_tx_entry('write', target),
448
+ emitProgress: (frame) => _emit_progress(frame),
449
+ tagDeployed: (target, source, package_root) =>
450
+ _inject_package_tag(target, source, package_root),
451
+ });
560
452
 
561
453
  // --- File utilities ---
562
454
 
@@ -1105,10 +997,8 @@ function _heal_legacy_claude_plugin_ids(p: string): string[] {
1105
997
  function ensure_claude_bridge(project_root: string, force: boolean): Record<string, unknown>[] {
1106
998
  const target = path.join(project_root, '.claude', 'settings.json');
1107
999
  const healed = _heal_legacy_claude_plugin_ids(target);
1108
- for (const pid of healed) {
1109
- success(`.claude/settings.json: removed stale plugin id \`${pid}\``);
1110
- }
1111
- const bridge = { enabledPlugins: { [CLAUDE_PLUGIN_ID]: true } };
1000
+ for (const pid of healed) success(`.claude/settings.json: removed stale plugin id \`${pid}\``);
1001
+ const bridge = withHostEnv({ enabledPlugins: { [CLAUDE_PLUGIN_ID]: true } }, project_root, success);
1112
1002
  return merge_json_file(target, bridge, force || healed.length > 0, '.claude/settings.json');
1113
1003
  }
1114
1004
 
@@ -2444,75 +2334,36 @@ void prompt_collision_choice;
2444
2334
 
2445
2335
  // --- Manifest / inventory helpers (lazy-import twins are eager static here) ---
2446
2336
 
2447
- function _sha256_of_file(p: string): string | null {
2448
- return sha256OfFile(p);
2449
- }
2450
-
2451
- function _file_entry(p: string, kind: string, hash_content: boolean): Record<string, unknown> {
2452
- return {
2453
- path: p,
2454
- kind,
2455
- sha256: hash_content ? _sha256_of_file(p) : null,
2456
- };
2457
- }
2458
-
2459
2337
  type DeployResult = scoped_projection.DeployTuple;
2460
2338
 
2461
- function _files_by_tool_from_deploy(
2462
- deploy_results: Record<string, DeployResult>,
2463
- ): Record<string, Record<string, unknown>[]> {
2464
- const out: Record<string, Record<string, unknown>[]> = {};
2465
- for (const tool_id of Object.keys(deploy_results)) {
2466
- const [, , status, paths] = deploy_results[tool_id] as DeployResult;
2467
- if (status === 'deployed') {
2468
- out[tool_id] = paths.map((p) => _file_entry(p, 'deployed', true));
2469
- } else if (status === 'marker') {
2470
- out[tool_id] = paths.map((p) => _file_entry(p, 'marker', true));
2471
- } else {
2472
- out[tool_id] = [];
2473
- }
2474
- }
2475
- return out;
2476
- }
2477
-
2478
- function _files_by_tool_from_bridges(
2479
- tools: Set<string>,
2480
- project_root: string,
2481
- scope: string,
2482
- ): Record<string, Record<string, unknown>[]> {
2483
- const out: Record<string, Record<string, unknown>[]> = {};
2484
- for (const tool_id of [...tools].sort()) {
2485
- const marker = _bridge_marker(tool_id, scope);
2486
- if (!marker) continue;
2487
- let marker_path = marker;
2488
- if (!path.isAbsolute(marker_path)) {
2489
- marker_path = path.join(project_root, marker_path);
2490
- }
2491
- out[tool_id] = [_file_entry(marker_path, 'bridge', false)];
2492
- }
2493
- return out;
2494
- }
2495
-
2496
2339
  function _update_installed_tools_manifest(
2497
2340
  project_root: string,
2498
2341
  tools: Set<string>,
2499
2342
  scope: string,
2500
2343
  force: boolean,
2501
- files_by_tool: Record<string, Record<string, unknown>[]> | null = null,
2344
+ files_by_tool: Record<string, ManifestFileEntry[] | null> | null = null,
2502
2345
  merged_keys_by_tool: Record<string, Record<string, unknown>[]> | null = null,
2503
2346
  ): number {
2504
2347
  const target = installed_tools.manifest_path(project_root);
2505
2348
  const existing = (installed_tools.read_manifest(target) ?? {}) as Record<string, unknown>;
2506
- let entries = Array.isArray(existing['tools'])
2507
- ? ([...(existing['tools'] as unknown[])] as Record<string, unknown>[])
2508
- : [];
2349
+ // Hydrated because `read_manifest` drops nested `files[]` by design: without
2350
+ // this, rewriting the manifest erases every recorded digest it did not just
2351
+ // rebuild, and an unrecorded managed file is overwritten on the next run.
2352
+ const prior = readRecordedByTool(target, project_root);
2353
+ const preserved = preservedIndex(tracker.conflictState.preserved, tracker.conflictState.staged);
2354
+ let entries = hydrateRecordedInventories(
2355
+ Array.isArray(existing['tools'])
2356
+ ? ([...(existing['tools'] as unknown[])] as Record<string, unknown>[])
2357
+ : [],
2358
+ prior,
2359
+ );
2509
2360
 
2510
2361
  const version = installed_lock.current_package_version();
2511
2362
 
2512
2363
  for (const tool_id of [...tools].sort()) {
2513
2364
  const marker = _bridge_marker(tool_id, scope);
2514
2365
  if (!marker) continue;
2515
- const files = files_by_tool ? (files_by_tool[tool_id] ?? null) : null;
2366
+ const files = reconcileToolFiles(files_by_tool?.[tool_id], prior.get(tool_id), preserved);
2516
2367
  const merged_keys = merged_keys_by_tool ? (merged_keys_by_tool[tool_id] ?? null) : null;
2517
2368
  try {
2518
2369
  entries = installed_tools.upsert_tool(entries, {
@@ -2890,6 +2741,25 @@ function _escapes_package_root(resolved: string, package_root: string | null): b
2890
2741
  return !global_deploy_inventory.is_ancestor(root, resolved);
2891
2742
  }
2892
2743
 
2744
+ /**
2745
+ * Append one `write`/`skip` entry to the transaction log, through the same
2746
+ * `appendTxLog` module the recovery-dismiss route calls — one writer, two
2747
+ * callers, identical entry shape. Failure is swallowed: the log is a recovery
2748
+ * aid, never a condition for the install itself to proceed.
2749
+ */
2750
+ function _log_tx_entry(kind: 'write' | 'skip', target: string): void {
2751
+ try {
2752
+ appendTxLog(getLogPath(), {
2753
+ ts: new Date().toISOString(),
2754
+ kind,
2755
+ path: target,
2756
+ sha256: kind === 'write' ? sha256OfFile(target) : null,
2757
+ });
2758
+ } catch {
2759
+ /* swallow — the log is a recovery aid, not a precondition */
2760
+ }
2761
+ }
2762
+
2893
2763
  /**
2894
2764
  * Copy `src` → `dest`, dereferencing symlinks, returning
2895
2765
  * `[written, skipped, written_paths]`.
@@ -2925,10 +2795,15 @@ function _copy_dir_dereferencing_symlinks(
2925
2795
  return [0, 0, written_paths];
2926
2796
  }
2927
2797
  mkdirp(path.dirname(dest));
2928
- const decision = _resolve_file_conflict(dest, force);
2929
- if (decision === 'skip') return [0, 1, written_paths];
2798
+ const decision = tracker.resolve(dest, force);
2799
+ if (decision === 'preserve') {
2800
+ tracker.preserve(dest, resolved_src, package_root);
2801
+ _log_tx_entry('skip', dest);
2802
+ return [0, 1, written_paths];
2803
+ }
2930
2804
  fs.copyFileSync(src, dest); // follow_symlinks=True is fs.copyFileSync default
2931
2805
  _inject_package_tag(dest, src, package_root);
2806
+ _log_tx_entry('write', dest);
2932
2807
  written_paths.push(dest);
2933
2808
  return [1, 0, written_paths];
2934
2809
  }
@@ -2995,14 +2870,17 @@ function _copy_dir_dereferencing_symlinks(
2995
2870
  if (file_filter !== null && !file_filter(entry)) {
2996
2871
  continue;
2997
2872
  }
2998
- const decision = _resolve_file_conflict(target, force);
2999
- if (decision === 'skip') {
2873
+ const decision = tracker.resolve(target, force);
2874
+ if (decision === 'preserve') {
2875
+ tracker.preserve(target, resolved, package_root);
3000
2876
  skipped += 1;
2877
+ _log_tx_entry('skip', target);
3001
2878
  continue;
3002
2879
  }
3003
2880
  mkdirp(path.dirname(target));
3004
2881
  fs.copyFileSync(resolved, target);
3005
2882
  _inject_package_tag(target, resolved, package_root);
2883
+ _log_tx_entry('write', target);
3006
2884
  written += 1;
3007
2885
  written_paths.push(target);
3008
2886
  }
@@ -3014,7 +2892,7 @@ function _claude_desktop_bundles_dir(): string {
3014
2892
  }
3015
2893
 
3016
2894
  function _write_claude_desktop_marker(
3017
- _force: boolean,
2895
+ force: boolean,
3018
2896
  lockfile_path: string,
3019
2897
  bundles_dir: string,
3020
2898
  bundle_count: number,
@@ -3023,7 +2901,15 @@ function _write_claude_desktop_marker(
3023
2901
  const target = path.join(anchor, 'agent-config.md');
3024
2902
  mkdirp(anchor);
3025
2903
  const body = claudeDesktopMarkerBody(lockfile_path, anchor, bundles_dir, bundle_count);
2904
+ // Generated, but manifest-recorded with a digest — so it is in the class the
2905
+ // preservation ruling covers, and it used to write unconditionally, ignoring
2906
+ // even `--force`, because the tracker was wired only into the copy loop.
2907
+ if (tracker.resolve(target, force) === 'preserve') {
2908
+ tracker.preserveContent(target, body);
2909
+ return [0, 1, []];
2910
+ }
3026
2911
  writeText(target, body);
2912
+ _log_tx_entry('write', target);
3027
2913
  return [1, 0, [target]];
3028
2914
  }
3029
2915
 
@@ -3217,6 +3103,7 @@ function _deploy_global_content(
3217
3103
  info,
3218
3104
  warn,
3219
3105
  res,
3106
+ new Set(tracker.conflictState.preserved.map((p) => path.resolve(p))),
3220
3107
  );
3221
3108
  }
3222
3109
 
@@ -4927,10 +4814,16 @@ function main(argv: string[]): number {
4927
4814
  const rc = _run_migrate_to_global(detect_root);
4928
4815
  if (rc !== 0) return rc;
4929
4816
  }
4930
- const rc = install_global(parsed_tools, opts.force, detect_root, opts.core_only);
4817
+ tracker.begin(detect_root);
4818
+ const rc = tracker.finalizeRc(
4819
+ install_global(parsed_tools, opts.force, detect_root, opts.core_only),
4820
+ );
4931
4821
  _emit_progress_terminal(rc);
4932
- if (rc === 0 && wizard_handoff) {
4933
- return _wizard_spawn(detect_root, false);
4822
+ // A preserved edit does not withhold the wizard, but it survives one: a
4823
+ // zero from the wizard must not erase the conflict signal this run earned.
4824
+ if ((rc === 0 || rc === EXIT_COMPLETED_WITH_CONFLICTS) && wizard_handoff) {
4825
+ const wizard_rc = _wizard_spawn(detect_root, false);
4826
+ return wizard_rc === 0 ? rc : wizard_rc;
4934
4827
  }
4935
4828
  return rc;
4936
4829
  }
@@ -4938,10 +4831,12 @@ function main(argv: string[]): number {
4938
4831
  const project_root =
4939
4832
  custom_path || resolvePath(opts.project || process.env['PROJECT_ROOT'] || process.cwd());
4940
4833
  const is_first_run = !pathExists(path.join(project_root, SETTINGS_FILE));
4941
- const rc = _main_project_install(opts, project_root, parsed_tools, is_first_run);
4834
+ tracker.begin(project_root);
4835
+ let rc = _main_project_install(opts, project_root, parsed_tools, is_first_run);
4942
4836
  if (rc === 0 && opts.interactive) {
4943
4837
  run_interactive_init(project_root, opts.force);
4944
4838
  }
4839
+ rc = tracker.finalizeRc(rc);
4945
4840
  _emit_progress_terminal(rc);
4946
4841
  return rc;
4947
4842
  }
@@ -5185,7 +5080,7 @@ function _main_project_install(
5185
5080
  }
5186
5081
 
5187
5082
  if (!opts.skip_bridges) {
5188
- const files_by_tool = _files_by_tool_from_bridges(parsed_tools, project_root, 'project');
5083
+ const files_by_tool = _files_by_tool_from_bridges(parsed_tools, project_root, 'project', _bridge_marker);
5189
5084
  const rc = _update_installed_tools_manifest(
5190
5085
  project_root,
5191
5086
  parsed_tools,
@@ -5301,6 +5196,7 @@ export {
5301
5196
  _format_global_root_for_marker,
5302
5197
  _files_by_tool_from_bridges,
5303
5198
  _files_by_tool_from_deploy,
5199
+ _update_installed_tools_manifest,
5304
5200
  _verify_deploy_targets,
5305
5201
  _wizard_should_launch,
5306
5202
  _dry_run_summary,
@@ -5363,6 +5259,9 @@ export {
5363
5259
  // road-to-local-ci-trust: exported for the symlink-confinement tests
5364
5260
  // (PR #1076 review-gate finding).
5365
5261
  _copy_dir_dereferencing_symlinks,
5262
+ // road-to-a-conformance-check-that-can-fail Phase 5.1: the wired tracker,
5263
+ // so the preservation path is testable (owner ruling 2026-09-21).
5264
+ tracker,
5366
5265
  _preview_global_reap,
5367
5266
  _resolve_global_rule_scope,
5368
5267
  _rule_filter_for_source,
@@ -87,6 +87,13 @@ const TTL_CONFIG: ReadonlyArray<{
87
87
  owner: 'maintainer',
88
88
  reviewBy: '2026-11-10',
89
89
  },
90
+ {
91
+ dir: 'agents/runtime/state/memory-recall',
92
+ ttlDays: 7,
93
+ description: 'Per-session memory-recall latch (one flag per delivered memory slug)',
94
+ owner: 'maintainer',
95
+ reviewBy: '2026-11-10',
96
+ },
90
97
  {
91
98
  dir: 'agents/runtime/state/end-review-nudge',
92
99
  ttlDays: 7,