@event4u/agent-config 14.22.0 → 14.23.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 (111) 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 +159 -380
  5. package/README.md +1 -1
  6. package/dist/agent-src/commands/pr/merge.md +47 -38
  7. package/dist/agent-src/commands/roadmap/next.md +8 -0
  8. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +12 -0
  9. package/dist/agent-src/rules/notes-first-reasoning.md +36 -25
  10. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +106 -4
  11. package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -1
  12. package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +9 -0
  13. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +52 -2
  14. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  15. package/dist/cli/registry.js +1 -1
  16. package/dist/cli-delegate/archive_completed_roadmaps.js +52 -4
  17. package/dist/cli-delegate/{chunk-TGIPZBCW.js → chunk-2KKXJW25.js} +22 -8
  18. package/dist/cli-delegate/{chunk-4FS4WRXP.js → chunk-IAI3XL43.js} +15 -3
  19. package/dist/cli-delegate/{chunk-BIXEDQPZ.js → chunk-KCNTUSPI.js} +1 -1
  20. package/dist/cli-delegate/cmd_export.js +2 -2
  21. package/dist/cli-delegate/cmd_handoff.js +20 -12
  22. package/dist/cli-delegate/cmd_prune.js +2 -2
  23. package/dist/cli-delegate/cmd_session_recycle.js +3 -13
  24. package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
  25. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  26. package/dist/cli-delegate/cmd_sync.js +2 -2
  27. package/dist/cli-delegate/cmd_uninstall.js +2 -2
  28. package/dist/cli-delegate/cmd_validate.js +2 -2
  29. package/dist/discovery/deprecation-report.md +1 -1
  30. package/dist/discovery/discovery-manifest.json +8 -8
  31. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  32. package/dist/discovery/discovery-manifest.summary.md +1 -1
  33. package/dist/discovery/dormancy-report.md +1 -1
  34. package/dist/discovery/orphan-report.md +1 -1
  35. package/dist/discovery/packs.json +2 -2
  36. package/dist/discovery/trust-report.md +1 -1
  37. package/dist/discovery/workspaces.json +2 -2
  38. package/dist/hooks/dispatch.js +880 -289
  39. package/dist/install/install.mjs +15 -3
  40. package/dist/mcp/registry-manifest.json +2 -2
  41. package/dist/mcp/server.json +2 -2
  42. package/dist/mcp/server.mjs +5458 -2453
  43. package/dist/scripts/_lib/lean_projection_mode.js +108 -0
  44. package/dist/scripts/_lib/router_match.js +243 -0
  45. package/dist/scripts/_lib/rule_injection.js +216 -0
  46. package/dist/scripts/condense.js +20 -20
  47. package/dist/scripts/project_thin_rules.js +139 -19
  48. package/dist/server/schemas/settings.js +16 -3
  49. package/docs/MIGRATION.md +56 -0
  50. package/docs/contracts/settings-classes.md +39 -7
  51. package/docs/guidelines/agent-infra/notes-horizon-mechanics.md +90 -0
  52. package/llms.txt +1 -1
  53. package/package.json +1 -1
  54. package/src/agent-src/scripts/archive_completed_roadmaps.ts +106 -4
  55. package/src/config/agent-settings.template.yml +47 -1
  56. package/src/config/continuity-surface.json +7 -0
  57. package/src/config/evaluator-budgets.json +4 -4
  58. package/src/config/gate-violation-baselines.json +2 -2
  59. package/src/config/hook-token-budget.json +7 -6
  60. package/src/config/packed-binary-manifest.json +1 -1
  61. package/src/config/routing-coverage-seed.json +9 -2
  62. package/src/scripts/_cli/cmd_session_recycle.ts +2 -25
  63. package/src/scripts/_cli/handoff_sessions.ts +14 -44
  64. package/src/scripts/_lib/continuity_slot.ts +295 -0
  65. package/src/scripts/_lib/continuity_writer.ts +253 -0
  66. package/src/scripts/_lib/hook_settings.ts +85 -0
  67. package/src/scripts/_lib/lean_projection_mode.ts +127 -0
  68. package/src/scripts/_lib/packed_binary_predicate.ts +37 -0
  69. package/src/scripts/_lib/recycle_envelope_paths.ts +109 -21
  70. package/src/scripts/_lib/regression_neighbourhood.ts +159 -22
  71. package/src/scripts/_lib/session_eol.ts +44 -0
  72. package/src/scripts/_lib/session_index_trust.ts +346 -0
  73. package/src/scripts/_lib/standing_bound_ratchet.ts +154 -0
  74. package/src/scripts/_lib/vendored_grammar_upstream.ts +280 -0
  75. package/src/scripts/audit_mcp_tools.ts +69 -25
  76. package/src/scripts/build_mcp_catalog.ts +24 -1
  77. package/src/scripts/check_host_tree_parity.ts +291 -0
  78. package/src/scripts/check_preamble_payload_budget.ts +136 -7
  79. package/src/scripts/check_rule_projection_integrity.ts +102 -2
  80. package/src/scripts/ci_settle.ts +205 -5
  81. package/src/scripts/code_graph/build.ts +79 -0
  82. package/src/scripts/code_graph/cli.ts +258 -7
  83. package/src/scripts/code_graph/detect.ts +38 -0
  84. package/src/scripts/code_graph/query.ts +25 -2
  85. package/src/scripts/code_graph/sqlite_store.ts +16 -1
  86. package/src/scripts/code_graph/types.ts +52 -3
  87. package/src/scripts/code_graph/validate.ts +3 -1
  88. package/src/scripts/code_graph/verbs.ts +590 -0
  89. package/src/scripts/condense.ts +20 -20
  90. package/src/scripts/handoff_context_hook.ts +39 -1
  91. package/src/scripts/hook_manifest.json +1 -1
  92. package/src/scripts/hook_manifest.yaml +24 -1
  93. package/src/scripts/hooks/block_speaking_inbox_dir.ts +182 -16
  94. package/src/scripts/hooks/code_graph_context_hook.ts +7 -18
  95. package/src/scripts/hooks/push_settle_hook.ts +3 -2
  96. package/src/scripts/hooks/rule_inject_hook.ts +107 -20
  97. package/src/scripts/hooks/session_eol_hook.ts +120 -2
  98. package/src/scripts/hot_context_hook.ts +62 -7
  99. package/src/scripts/lint_roadmap_blockers.ts +164 -1
  100. package/src/scripts/mcp_server/consumer_tool_catalog.json +152 -2
  101. package/src/scripts/mcp_server/graph_tools.ts +294 -0
  102. package/src/scripts/mcp_server/path_util.ts +31 -0
  103. package/src/scripts/mcp_server/tool_catalog_source.ts +7 -1
  104. package/src/scripts/mcp_server/tools.ts +3 -13
  105. package/src/scripts/model_rule_injection.ts +61 -4
  106. package/src/scripts/project_thin_rules.ts +149 -16
  107. package/src/scripts/report_standing_payload_by_host.ts +650 -0
  108. package/src/scripts/schemas/agent-settings.schema.json +7 -1
  109. package/src/scripts/session_memory_index.ts +81 -8
  110. package/src/server/schemas/settings.ts +23 -4
  111. package/src/vendor/grammars/README.md +27 -2
@@ -22,10 +22,18 @@
22
22
  * default is off, per the roadmap's "off unless proven".
23
23
  */
24
24
 
25
- import { CURATED_TYPES, retrieve_v1 } from './memory_lookup.js';
25
+ import { CURATED_TYPES, MEMORY_ROOT, retrieve_v1 } from './memory_lookup.js';
26
26
  import { load_agent_settings } from './_lib/agent_settings.js';
27
+ import {
28
+ capRows,
29
+ orderRows,
30
+ SESSION_INDEX_ROW_CAP,
31
+ verifyMemoryRoot,
32
+ type TrustGrant,
33
+ type TrustVerdict,
34
+ } from './_lib/session_index_trust.js';
27
35
 
28
- export const SESSION_INDEX_ROW_CAP = 30;
36
+ export { SESSION_INDEX_ROW_CAP };
29
37
 
30
38
  interface IndexRow {
31
39
  id: string;
@@ -54,21 +62,72 @@ export function session_index_enabled(root: string): boolean {
54
62
  * Expects the caller to have chdir'd to the workspace root — memory roots
55
63
  * are cwd-relative, same contract as the MCP tool handlers.
56
64
  */
65
+ /**
66
+ * How many entries retrieval is asked for before the declared order picks.
67
+ *
68
+ * R2 finding 2: asking retrieval for the CAP made P4 decorative. Every curated
69
+ * hit scores an identical 0.1 with an empty key set, so `retrieve` sliced the
70
+ * first 30 in STORE order at `memory_lookup.ts:995` and `orderRows` then sorted
71
+ * a set the cap had already chosen. Measured by the reviewer: a 40-entry corpus
72
+ * with the 5 cheapest last emitted zero cheap rows.
73
+ *
74
+ * The number must therefore exceed any realistic curated corpus, not merely the
75
+ * cap. 500 is a STATED DEFAULT, not a measured optimum — the cost of asking for
76
+ * more than exists is bounded by what exists, since `detail: 'index'` returns a
77
+ * row rather than a body. Its falsifier is recorded in the roadmap: a corpus
78
+ * larger than this bound makes store order decide again, silently.
79
+ */
80
+ export const SESSION_INDEX_RETRIEVAL_LIMIT = 500;
81
+
57
82
  export function session_index_rows(cap: number = SESSION_INDEX_ROW_CAP): IndexRow[] {
58
- const envelope = retrieve_v1([...CURATED_TYPES], [], cap, { detail: 'index' });
83
+ // Retrieval is asked for far more than the cap, so the declared order below
84
+ // is what chooses which rows survive truncation. P4 and P6 are one
85
+ // decision: retrieve wide, order, THEN cap — and never the reverse.
86
+ const envelope = retrieve_v1([...CURATED_TYPES], [], SESSION_INDEX_RETRIEVAL_LIMIT, { detail: 'index' });
59
87
  const entries = (envelope['entries'] as Array<Record<string, unknown>>) ?? [];
60
- return entries.slice(0, cap).map((e) => ({
88
+ const rows: IndexRow[] = entries.map((e) => ({
61
89
  id: String(e['id'] ?? ''),
62
90
  title: String(e['title'] ?? ''),
63
91
  tokens_estimate: Number(e['tokens_estimate'] ?? 0),
64
92
  }));
93
+ return capRows(orderRows(rows), cap);
94
+ }
95
+
96
+ /**
97
+ * The trust gate, separated from the render so a caller can log WHY nothing
98
+ * was injected. `null` from {@link build_session_index_block} is ambiguous by
99
+ * construction — empty corpus and refused root look identical — and the
100
+ * distinction is the point of the contract, so it is available here.
101
+ *
102
+ * The workspace root is REQUIRED. `MEMORY_ROOT` is relative, so without a root
103
+ * to resolve it against there is nothing to check identity or containment
104
+ * against, and a default would be a bypass wearing a convenience.
105
+ */
106
+ export function session_index_trust(workspaceRoot: string, now?: Date): TrustVerdict {
107
+ // `exactOptionalPropertyTypes` refuses `now: undefined` on an optional
108
+ // field, so the key is omitted rather than passed as undefined.
109
+ return verifyMemoryRoot({
110
+ workspaceRoot,
111
+ relativeMemoryRoot: MEMORY_ROOT,
112
+ ...(now === undefined ? {} : { now }),
113
+ });
65
114
  }
66
115
 
67
116
  /**
68
- * Render the injectable block, or `null` when the corpus is empty (no
69
- * block beats an empty scaffold).
117
+ * RENDER a block from whatever `MEMORY_ROOT` currently resolves to. Checks
118
+ * nothing, serves nothing.
119
+ *
120
+ * Split out on R2 findings 6 and 7. The trust check used to be an OPTIONAL
121
+ * parameter, which made the serving path opt-in — and `session_index_cost()`
122
+ * omitted it, so the one function whose name suggests it only measures was also
123
+ * the one that could render unchecked. Now the two operations have two names:
124
+ * this one renders (for cost measurement and for the unit seam that injects an
125
+ * absolute fixture root via `_setMemoryRoot`, which by construction sits
126
+ * outside any workspace), and {@link serve_session_index_block} is the only way
127
+ * to obtain a block for INJECTION — it takes a granted verdict, so there is no
128
+ * unchecked serving path to forget.
70
129
  */
71
- export function build_session_index_block(cap: number = SESSION_INDEX_ROW_CAP): string | null {
130
+ export function render_session_index_block(cap: number = SESSION_INDEX_ROW_CAP): string | null {
72
131
  const rows = session_index_rows(cap);
73
132
  if (rows.length === 0) return null;
74
133
  const lines = [
@@ -81,13 +140,27 @@ export function build_session_index_block(cap: number = SESSION_INDEX_ROW_CAP):
81
140
  return lines.join('\n');
82
141
  }
83
142
 
143
+ /**
144
+ * The only path to a block that will be INJECTED.
145
+ *
146
+ * Takes a granted verdict rather than a root, so the check happens once, at the
147
+ * caller, and cannot be skipped here — R2 finding 7 was that the hook and the
148
+ * builder each computed it, for a diagnostic the dispatcher does not forward.
149
+ * The type is `TrustGrant`, not `TrustVerdict`: a refusal cannot be passed in,
150
+ * so "did you check?" is answered by the signature instead of by a convention.
151
+ */
152
+ export function serve_session_index_block(_grant: TrustGrant, cap: number = SESSION_INDEX_ROW_CAP): string | null {
153
+ return render_session_index_block(cap);
154
+ }
155
+
84
156
  /**
85
157
  * Deterministic fixed cost of the block in real tokens (cl100k_base) —
86
158
  * the measurable arm of the roadmap's ship-criterion. Lazy-loads the
87
159
  * tokenizer so the enabled=off fast path never pays it.
88
160
  */
89
161
  export async function session_index_cost(cap: number = SESSION_INDEX_ROW_CAP): Promise<number> {
90
- const block = build_session_index_block(cap);
162
+ // Renders rather than serves: this measures a cost, it injects nothing.
163
+ const block = render_session_index_block(cap);
91
164
  if (block === null) return 0;
92
165
  const { gpt_tokens } = await import('./_lib/token_count.js');
93
166
  return gpt_tokens(block).tokens;
@@ -31,7 +31,8 @@ const confidenceBand = z.enum(['off', 'low', 'medium', 'high']);
31
31
  const onBlock = z.enum(['stop', 'ask', 'warn']);
32
32
  const onBlockFallback = z.enum(['stop', 'warn']);
33
33
  const modelAutoSwitch = z.enum(['auto', 'suggest', 'off']);
34
- const leanProjectionMode = z.enum(['eager-all', 'thin']);
34
+ const leanProjectionMode = z.enum(['eager-all', 'thin', 'delivery']);
35
+ const leanProjectionHost = z.enum(['claude-code', 'cursor', 'cline']);
35
36
  const projectionMode = z.enum(['legacy-all', 'scoped']);
36
37
  const memoryCadence = z.enum(['auto', 'always', 'never']);
37
38
  const projectAudience = z.enum(['self', 'internal', 'client', 'public']);
@@ -64,9 +65,19 @@ export const settingsSchema = z.object({
64
65
  ),
65
66
  lean_projection: z.object({
66
67
  mode: leanProjectionMode.default('eager-all').describe(
67
- 'How the per-tool projector emits the rule layer. eager-all = every rule body inlined into every projection (default, safe). thin = kernel rules full-bodied + non-kernel rules as router-resolved pointers (~45k GPT-tok lighter per session). EXPERIMENTAL: validate with the live A/B before flipping; one-flip revert to eager-all.',
68
- ),
69
- }).default({ mode: 'eager-all' }),
68
+ 'How the per-tool projector emits the rule layer. eager-all = every rule body inlined into every projection (safe; what an ABSENT key still resolves to, per ADR-267 decision point 4). thin = kernel rules full-bodied + non-kernel rules as router-resolved pointers (~45k GPT-tok lighter per session), with no delivery mechanism. delivery = thin stubs PLUS the rule-inject hook concern, which delivers a body back on a trigger match; this is the value the SHIPPED TEMPLATE carries for Claude Code since ADR-267, and the activation charge for it is paid in src/config/hook-token-budget.json (user_prompt_submit slot sum 4,096 -> 16,384).',
69
+ ),
70
+ hosts: z.array(leanProjectionHost).default(['claude-code']).describe(
71
+ 'Which hosts a thinning mode may thin (ADR-267). Absent resolves to [claude-code]. '
72
+ + 'Only the three hosts with a per-rule rule tree are accepted, and this enum is the '
73
+ + 'AUTHORING layer: an id outside it is a hard validation FAILURE here and under '
74
+ + 'validate_agent_settings, never a warning. resolveLeanProjectionHosts is the '
75
+ + 'READ-TIME backstop for a hand-edited .agent-settings.yml that passed neither, and '
76
+ + 'THERE the id is dropped with a warning (R2 finding 6 — the two layers answer '
77
+ + 'differently and neither said so). Every host outside this list receives exactly '
78
+ + 'what eager-all writes, asserted byte-for-byte by check_host_tree_parity.',
79
+ ),
80
+ }).default({ mode: 'eager-all', hosts: ['claude-code'] }),
70
81
  cost: z.object({
71
82
  budgets: z.object({
72
83
  daily: z.number().min(0).default(0).describe(
@@ -438,6 +449,14 @@ export const settingsSchema = z.object({
438
449
  ),
439
450
  }),
440
451
  }),
452
+ continuity: z.object({
453
+ auto_record: z.enum(['on', 'off']).default('off').describe(
454
+ 'Deterministic continuity-record writer at session end (road-to-continuity-writer-activation Phase 1). on = the session-eol concern writes the continuity_record capsule variant on Stop for a substantive session that has claimed a roadmap; every field is computed from on-disk state, with no model spend and no subprocess. off (default) = no automatic record — while session:recycle is still the normal path, a second producer on it before the parity evidence is in would be unverified.',
455
+ ),
456
+ run_checkpoints: z.enum(['on', 'off']).default('on').describe(
457
+ 'Deterministic run-checkpoint production at session end (road-to-continuity-writer-activation Phase 1.4). on (default) = a session above the recycle threshold and inside a running roadmap contract leaves agents/runtime/state/checkpoints/<run>.json, so a killed run resumes from a derived checkpoint rather than from bookkeeping. off = no checkpoint; continuity writing, the recycle advisory and the context-fill surface are unaffected. Default ON because it is the behaviour the tree already had — the switch exists to make the three session-end handlers independently disableable, not to change what ships.',
458
+ ),
459
+ }),
441
460
  memory: z.object({
442
461
  cadence: memoryCadence.default('always').describe(
443
462
  'Cadence of the 🧠 memory-visibility line after a memory-consulting step. always (default) = show whenever a memory type was asked; auto = show only when 3+ types were consulted (less noise); never = suppress. Distinct from rule_loading_tier — owns its own key since the 2026-06-01 untangle.',
@@ -41,6 +41,27 @@ they are annotated MIT in `REUSE.toml` and credited in `CREDITS.md`.
41
41
  are refreshed from, and the ABI smoke test in `tests/scripts/code_graph.test.ts`
42
42
  runs against it. It is deliberately not a runtime dependency.
43
43
 
44
+ ## Verification
45
+
46
+ Two checks, and they answer different questions.
47
+
48
+ `src/config/packed-binary-manifest.json` plus `_lib/packed_binary_predicate.ts`
49
+ verify that these bytes are what the manifest says they are — eleven conditions,
50
+ all of them re-derived from the bytes. Every one of them reads the manifest, so
51
+ a commit that edits a row and its file together satisfies all eleven.
52
+
53
+ `_lib/vendored_grammar_upstream.ts` verifies that these bytes are what the
54
+ **locked upstream** says they are: it byte-compares each file against
55
+ `node_modules/tree-sitter-wasms/out/`, after asserting that the installed
56
+ version is the one `package-lock.json` pins. An absent or unlocked upstream is a
57
+ refusal, never a pass. It is exercised by
58
+ `tests/scripts/vendored_grammar_upstream.test.ts`, which also drives every
59
+ refusal path and a real mutated grammar to failure.
60
+
61
+ What neither check covers is a `package-lock.json` row pointing at a hostile
62
+ package; that is review's job, and `packed_binary_predicate.ts`'s docblock says
63
+ so in those words.
64
+
44
65
  ## Refreshing
45
66
 
46
67
  The pair is ABI-coupled and must move together:
@@ -55,7 +76,11 @@ shasum -a 256 src/vendor/grammars/*.wasm # update the table above
55
76
 
56
77
  Then update, in the same change:
57
78
 
58
- - the three `BINARY_PAYLOAD_EXCEPTIONS` entries in `src/scripts/check_pack_size.ts`
59
- (they are path-and-size-bound, so any size change invalidates them by design);
79
+ - the three entries in `src/config/packed-binary-manifest.json` (they are
80
+ path-, sha256- and size-bound, so any refresh invalidates them by design).
81
+ This used to name `BINARY_PAYLOAD_EXCEPTIONS` in `src/scripts/check_pack_size.ts`,
82
+ a constant that no longer exists — `grep -rn BINARY_PAYLOAD_EXCEPTIONS` returned
83
+ this line and nothing else, so a refresher following it would have skipped the
84
+ manifest and reddened the pack-size gate with no pointer to why;
60
85
  - `EXPECTED_GRAMMAR_ABI` in `src/scripts/code_graph/types.ts` if the ABI moved;
61
86
  - the install-size line in `MIGRATION.md`.