@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.
- package/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +159 -380
- package/README.md +1 -1
- package/dist/agent-src/commands/pr/merge.md +47 -38
- package/dist/agent-src/commands/roadmap/next.md +8 -0
- package/dist/agent-src/contexts/execution/autonomy-mechanics.md +12 -0
- package/dist/agent-src/rules/notes-first-reasoning.md +36 -25
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +106 -4
- package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -1
- package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +9 -0
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +52 -2
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli/registry.js +1 -1
- package/dist/cli-delegate/archive_completed_roadmaps.js +52 -4
- package/dist/cli-delegate/{chunk-TGIPZBCW.js → chunk-2KKXJW25.js} +22 -8
- package/dist/cli-delegate/{chunk-4FS4WRXP.js → chunk-IAI3XL43.js} +15 -3
- package/dist/cli-delegate/{chunk-BIXEDQPZ.js → chunk-KCNTUSPI.js} +1 -1
- package/dist/cli-delegate/cmd_export.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +20 -12
- package/dist/cli-delegate/cmd_prune.js +2 -2
- package/dist/cli-delegate/cmd_session_recycle.js +3 -13
- package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +2 -2
- package/dist/cli-delegate/cmd_uninstall.js +2 -2
- package/dist/cli-delegate/cmd_validate.js +2 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +8 -8
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +880 -289
- package/dist/install/install.mjs +15 -3
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +5458 -2453
- package/dist/scripts/_lib/lean_projection_mode.js +108 -0
- package/dist/scripts/_lib/router_match.js +243 -0
- package/dist/scripts/_lib/rule_injection.js +216 -0
- package/dist/scripts/condense.js +20 -20
- package/dist/scripts/project_thin_rules.js +139 -19
- package/dist/server/schemas/settings.js +16 -3
- package/docs/MIGRATION.md +56 -0
- package/docs/contracts/settings-classes.md +39 -7
- package/docs/guidelines/agent-infra/notes-horizon-mechanics.md +90 -0
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +106 -4
- package/src/config/agent-settings.template.yml +47 -1
- package/src/config/continuity-surface.json +7 -0
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/gate-violation-baselines.json +2 -2
- package/src/config/hook-token-budget.json +7 -6
- package/src/config/packed-binary-manifest.json +1 -1
- package/src/config/routing-coverage-seed.json +9 -2
- package/src/scripts/_cli/cmd_session_recycle.ts +2 -25
- package/src/scripts/_cli/handoff_sessions.ts +14 -44
- package/src/scripts/_lib/continuity_slot.ts +295 -0
- package/src/scripts/_lib/continuity_writer.ts +253 -0
- package/src/scripts/_lib/hook_settings.ts +85 -0
- package/src/scripts/_lib/lean_projection_mode.ts +127 -0
- package/src/scripts/_lib/packed_binary_predicate.ts +37 -0
- package/src/scripts/_lib/recycle_envelope_paths.ts +109 -21
- package/src/scripts/_lib/regression_neighbourhood.ts +159 -22
- package/src/scripts/_lib/session_eol.ts +44 -0
- package/src/scripts/_lib/session_index_trust.ts +346 -0
- package/src/scripts/_lib/standing_bound_ratchet.ts +154 -0
- package/src/scripts/_lib/vendored_grammar_upstream.ts +280 -0
- package/src/scripts/audit_mcp_tools.ts +69 -25
- package/src/scripts/build_mcp_catalog.ts +24 -1
- package/src/scripts/check_host_tree_parity.ts +291 -0
- package/src/scripts/check_preamble_payload_budget.ts +136 -7
- package/src/scripts/check_rule_projection_integrity.ts +102 -2
- package/src/scripts/ci_settle.ts +205 -5
- package/src/scripts/code_graph/build.ts +79 -0
- package/src/scripts/code_graph/cli.ts +258 -7
- package/src/scripts/code_graph/detect.ts +38 -0
- package/src/scripts/code_graph/query.ts +25 -2
- package/src/scripts/code_graph/sqlite_store.ts +16 -1
- package/src/scripts/code_graph/types.ts +52 -3
- package/src/scripts/code_graph/validate.ts +3 -1
- package/src/scripts/code_graph/verbs.ts +590 -0
- package/src/scripts/condense.ts +20 -20
- package/src/scripts/handoff_context_hook.ts +39 -1
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +24 -1
- package/src/scripts/hooks/block_speaking_inbox_dir.ts +182 -16
- package/src/scripts/hooks/code_graph_context_hook.ts +7 -18
- package/src/scripts/hooks/push_settle_hook.ts +3 -2
- package/src/scripts/hooks/rule_inject_hook.ts +107 -20
- package/src/scripts/hooks/session_eol_hook.ts +120 -2
- package/src/scripts/hot_context_hook.ts +62 -7
- package/src/scripts/lint_roadmap_blockers.ts +164 -1
- package/src/scripts/mcp_server/consumer_tool_catalog.json +152 -2
- package/src/scripts/mcp_server/graph_tools.ts +294 -0
- package/src/scripts/mcp_server/path_util.ts +31 -0
- package/src/scripts/mcp_server/tool_catalog_source.ts +7 -1
- package/src/scripts/mcp_server/tools.ts +3 -13
- package/src/scripts/model_rule_injection.ts +61 -4
- package/src/scripts/project_thin_rules.ts +149 -16
- package/src/scripts/report_standing_payload_by_host.ts +650 -0
- package/src/scripts/schemas/agent-settings.schema.json +7 -1
- package/src/scripts/session_memory_index.ts +81 -8
- package/src/server/schemas/settings.ts +23 -4
- package/src/vendor/grammars/README.md +27 -2
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[](https://github.com/event4u-app/agent-config/actions/workflows/smoke.yml) [](https://github.com/event4u-app/agent-config/actions/workflows/smoke-public-install.yml) [](https://www.npmjs.com/package/@event4u/agent-config) [](https://glama.ai/mcp/servers/event4u-app/agent-config) [](https://mcptoplist.com/server/glama%2Fevent4u-app%2Fagent-config)
|
|
6
6
|
|
|
7
|
-
[](dist/agent-src/skills/) [](dist/agent-src/rules/) [](dist/agent-src/commands/) [](dist/agent-src/skills/) [](dist/agent-src/rules/) [](dist/agent-src/commands/) [](docs/guidelines/) [](dist/agent-src/personas/) [](dist/agent-src/personas/advisors/) <!-- claim:published-artifact-counts -->
|
|
8
8
|
|
|
9
9
|
<sub>**How these are counted** — one canonical counter, `agent-config` → `update_counts --check`, re-derives all six from the tree and fails CI on a drift of one. Two bases are not what the linked directory shows, so they are stated here rather than left to be inferred: **Commands 202** counts every command file **recursively** (the linked directory holds 61 at its top level), and **Rules 120** counts the **source** rules while the linked projection holds 119 — one rule is dormant and is not projected. **Personas 29** excludes the directory README. Counts are of files and directories: none of them measures quality, activation, or adoption. <!-- claim:published-artifact-counts --></sub>
|
|
10
10
|
|
|
@@ -4,13 +4,13 @@ name: git-pr-merge
|
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
argument-hint: "[all|<pr-number>] [--no-merge]"
|
|
6
6
|
pack: git
|
|
7
|
-
intent: "Prepare an open PR to mergeable — sync the base in, resolve conflicts semantically, drive required checks green —
|
|
7
|
+
intent: "Prepare an open PR to mergeable — sync the base in, resolve conflicts semantically, drive required checks green — then merge what the invocation named"
|
|
8
8
|
routes_to: [git-workflow, github-ci]
|
|
9
9
|
replaces: []
|
|
10
10
|
visibility: advanced
|
|
11
11
|
cluster: git-pr-merge
|
|
12
12
|
skills: [git-workflow, github-ci]
|
|
13
|
-
description: Prepare one open PR to mergeable, or the whole open-PR queue with `all
|
|
13
|
+
description: Prepare one open PR to mergeable, or the whole open-PR queue with `all`, then merge what the invocation named — `--no-merge` stops at mergeable-and-open
|
|
14
14
|
suggestion:
|
|
15
15
|
eligible: false
|
|
16
16
|
rationale: "Merging is irreversible and gated on the user's own word in the invocation — a suggested merge would manufacture the authorization the Hard Floor requires the user to give."
|
|
@@ -28,10 +28,13 @@ green on the head that will actually be merged — and then merge it, if and onl
|
|
|
28
28
|
if the invocation authorised that.
|
|
29
29
|
|
|
30
30
|
```
|
|
31
|
-
THE MERGE STEP (§ 9) IS
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
`
|
|
31
|
+
THE MERGE STEP (§ 9) IS ACTIVE. THE OWNER AUTHORISED IT ON 2026-09-08 AND
|
|
32
|
+
ADR-266 RECORDS THE AMENDMENT TO ADR-237 § 4 THAT ACTIVATED IT — THAT RECORD
|
|
33
|
+
IS WHAT ACTIVATED IT, NEVER A COMMAND EDIT AND NEVER A GUARD EDIT.
|
|
34
|
+
AN EXPLICIT `/pr:merge` INVOCATION IS THE THIS-TURN CONFIRMATION, AND IT
|
|
35
|
+
REACHES EXACTLY THE PRs § 1's MANIFEST SNAPSHOTTED FROM IT. IT NEVER REACHES
|
|
36
|
+
A PR THAT ARRIVED LATER, A HEAD THE MANIFEST DID NOT RECORD, OR ANY OTHER
|
|
37
|
+
HARD-FLOOR ACTION. `--no-merge` STILL STOPS BEFORE § 9.
|
|
35
38
|
```
|
|
36
39
|
|
|
37
40
|
**The invocation is the authorization, and nothing else is.** `pr-merge` is
|
|
@@ -42,11 +45,12 @@ authorized, and this command still reads it as an audit trail; it introduces no
|
|
|
42
45
|
second authorization store, and it never writes one. When the work left is
|
|
43
46
|
outside what the owner authorized, the run stops and reports (§ 7).
|
|
44
47
|
|
|
45
|
-
Why
|
|
46
|
-
manifest, the four conflict classes, the superseded check, the
|
|
47
|
-
repair, the cutoff — is the expensive, error-prone
|
|
48
|
-
runs actually proved
|
|
49
|
-
|
|
48
|
+
Why the preparation half is still the bulk of this command: everything before
|
|
49
|
+
§ 9 — the target manifest, the four conflict classes, the superseded check, the
|
|
50
|
+
bounded CI repair, the cutoff — is the expensive, error-prone part, and it is
|
|
51
|
+
what the live runs actually proved. `--no-merge` delivers exactly that half to
|
|
52
|
+
callers that want it, [`/roadmap:process-full`](../../../product-basic/roadmap/process-full/command.md)
|
|
53
|
+
among them.
|
|
50
54
|
|
|
51
55
|
## Sub-commands
|
|
52
56
|
|
|
@@ -62,15 +66,16 @@ different lifecycle, not a different count.
|
|
|
62
66
|
|
|
63
67
|
## Dispatch
|
|
64
68
|
|
|
65
|
-
Every row below **prepares**
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
Every row below **prepares** first; the last column says whether it then
|
|
70
|
+
merges. A row that merges reaches only the PRs its own manifest snapshotted
|
|
71
|
+
(§ 1), and only once that PR's required checks are green on the head being
|
|
72
|
+
merged (§ 5).
|
|
68
73
|
|
|
69
74
|
| Invocation | Selects | Prepares | Merges |
|
|
70
75
|
|---|---|---|---|
|
|
71
|
-
| `/pr:merge <N>` | exactly PR N | yes |
|
|
72
|
-
| `/pr:merge` | ONE PR: green first, then infrastructure/tooling before content, then smallest diff (`changedFiles`, then additions+deletions), tiebreak ascending number | yes |
|
|
73
|
-
| `/pr:merge all` | the whole open-PR list, under § 6's cutoff | yes |
|
|
76
|
+
| `/pr:merge <N>` | exactly PR N | yes | yes — PR N |
|
|
77
|
+
| `/pr:merge` | ONE PR: green first, then infrastructure/tooling before content, then smallest diff (`changedFiles`, then additions+deletions), tiebreak ascending number | yes | yes — the one PR it selected |
|
|
78
|
+
| `/pr:merge all` | the whole open-PR list, under § 6's cutoff | yes | yes — the manifest, in queue order |
|
|
74
79
|
| `… --no-merge` | as above | yes | **never**, explicitly. This is the form [`/roadmap:process-full`](../../../product-basic/roadmap/process-full/command.md) calls for its delivery loop. |
|
|
75
80
|
|
|
76
81
|
**Bare invocation** (`/pr:merge` with no argument) is a **documented default
|
|
@@ -81,7 +86,7 @@ to pick would hand back a decision the command can compute. When the open-PR
|
|
|
81
86
|
list is empty there is nothing to select and the command reports that and
|
|
82
87
|
stops.
|
|
83
88
|
|
|
84
|
-
## 1. Snapshot the target —
|
|
89
|
+
## 1. Snapshot the target — a manifest re-checked before every merge
|
|
85
90
|
|
|
86
91
|
Compute the queue ONCE at invocation and record it as a manifest of
|
|
87
92
|
`(PR number, head SHA)` pairs:
|
|
@@ -102,7 +107,11 @@ other than this run" is undetectable without a base SHA to compare against.
|
|
|
102
107
|
cap truncated.
|
|
103
108
|
|
|
104
109
|
The manifest is the authorization's target set and is **never silently
|
|
105
|
-
refreshed by a third party's push**. It
|
|
110
|
+
refreshed by a third party's push**. It lives in this run's own context and in
|
|
111
|
+
no file, so nothing verifies it and no gate would notice if it drifted — what
|
|
112
|
+
actually binds the target is the pre-merge re-read below, a check that fires,
|
|
113
|
+
not a property that holds. Say "re-checked", never "immutable" (ADR-266
|
|
114
|
+
§ What this record does not claim, finding 3). It is, by design, advanced by *this run's
|
|
106
115
|
own* commits — § 2 merges the base in and § 5 pushes, so a prepared PR's head
|
|
107
116
|
is never the snapshot head, and a naive "refuse when the SHA moved" check would
|
|
108
117
|
fire on every PR the run touches.
|
|
@@ -195,11 +204,12 @@ AND RECORD IT AS `blocked-external`.
|
|
|
195
204
|
```
|
|
196
205
|
|
|
197
206
|
The asymmetry is deliberate and worth stating, because it looks inconsistent:
|
|
198
|
-
merging is
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
207
|
+
merging is authorised once by the invocation, while closing needs a *per-object*
|
|
208
|
+
confirmation every time. Merging a PR this queue prepared is the action the
|
|
209
|
+
run's whole design is about, and § 1's manifest already binds it to a named
|
|
210
|
+
number and a recorded head; closing a PR someone else opened is neither, it
|
|
211
|
+
destroys their work in progress, and no guard in this tree sees it happen. The
|
|
212
|
+
stricter gate goes on the action nothing else watches.
|
|
203
213
|
|
|
204
214
|
## 5. Drive CI green — bounded
|
|
205
215
|
|
|
@@ -240,13 +250,12 @@ After each merge the base has moved, so the next PR is re-synced against the
|
|
|
240
250
|
NEW base — that is the loop, and it is why pre-greening several PRs ahead of
|
|
241
251
|
their merges is wasted work.
|
|
242
252
|
|
|
243
|
-
**
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
still cannot close it, for the reason § 7 gives.
|
|
253
|
+
**Under `--no-merge` that loop does not turn**, and the paragraph above is
|
|
254
|
+
written for the form that does. Nothing merges, so the base does not advance,
|
|
255
|
+
no PR leaves the open list, and the run is a **preparation sweep**: it syncs,
|
|
256
|
+
classifies, greens and reports each PR once, then stops. It does not re-prepare
|
|
257
|
+
a PR its own predecessor invalidated, because it has no predecessor that
|
|
258
|
+
landed. The cutoff below bounds both forms.
|
|
250
259
|
|
|
251
260
|
**Cutoff.** When the manifest is exhausted, recompute the open-PR list
|
|
252
261
|
**exactly once**. PRs that appeared during the run are drained as ONE final
|
|
@@ -308,10 +317,9 @@ run, and do not proceed to the next PR.
|
|
|
308
317
|
|
|
309
318
|
## 8. Kill switches, and what happens after a merge
|
|
310
319
|
|
|
311
|
-
**Armed during preparation, not only before a merge** — otherwise
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
of:
|
|
320
|
+
**Armed during preparation, not only before a merge** — otherwise a
|
|
321
|
+
`--no-merge` sweep would have no way to stop at all. Each one aborts the current
|
|
322
|
+
PR and ends the run on any of:
|
|
315
323
|
|
|
316
324
|
- target number or head SHA differs from the manifest;
|
|
317
325
|
- the base advanced by an actor other than this run;
|
|
@@ -365,9 +373,10 @@ conflict resolution. The disposition set is closed:
|
|
|
365
373
|
|
|
366
374
|
## Rules
|
|
367
375
|
|
|
368
|
-
- **Never merge
|
|
369
|
-
|
|
370
|
-
|
|
376
|
+
- **Never merge a PR the invocation did not name.** The authorization is the
|
|
377
|
+
owner's own `/pr:merge` sentence and reaches exactly the manifest § 1
|
|
378
|
+
snapshotted from it; a PR that arrived afterwards needs its own go-ahead.
|
|
379
|
+
`--no-merge` is the explicit way to say stop before § 9.
|
|
371
380
|
- **Never widen, patch, or rebuild-around the git guard.** Verification of the
|
|
372
381
|
authorization window is read-only.
|
|
373
382
|
- **Never rebase a pushed branch**; the base is merged in.
|
|
@@ -148,6 +148,14 @@ ONE THAT MOVES MORE CHECKBOXES. PICKING BY CHECKBOX COUNT IS THE
|
|
|
148
148
|
GOODHART MOVE THIS PACKAGE'S OWN DISCIPLINE FORBIDS.
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
+
**An owner-recorded precedence outranks the severity read.** Where an accepted ADR
|
|
152
|
+
states that a named roadmap or set is worked first, that record is the ranking and
|
|
153
|
+
this section does not re-derive one — the owner has already made the call the
|
|
154
|
+
council would otherwise settle. Precedence is not a bypass: a precedent roadmap
|
|
155
|
+
still passes every disqualifier in step 2, and a disqualified precedent roadmap is
|
|
156
|
+
skipped with its disqualifier named like any other. A `proposed` record carries no
|
|
157
|
+
precedence.
|
|
158
|
+
|
|
151
159
|
- **Exactly one survivor, or one that dominates** → take it, state the
|
|
152
160
|
one-line reason inline, proceed. Do not ask
|
|
153
161
|
([`no-cheap-questions`](../../rules/no-cheap-questions.md)).
|
|
@@ -193,6 +193,18 @@ decision. Engage per [`rdp-gate`](rdp-gate.md).
|
|
|
193
193
|
The suite states three retry numbers; they are **stages of one escalation
|
|
194
194
|
ladder on the same failing target**, not competing budgets:
|
|
195
195
|
|
|
196
|
+
0. **Attempt 1 fails → read the candidate list, if one exists, BEFORE retry 1.**
|
|
197
|
+
Where the run recorded a candidate set for this work
|
|
198
|
+
([`notes-first-reasoning`](../../rules/notes-first-reasoning.md)
|
|
199
|
+
§ Reopening), the first failure reads it first: a failure is evidence about
|
|
200
|
+
the CHOSEN FORM, and retrying the same approach spends the budget without
|
|
201
|
+
ever reaching the second-best candidate — which is how the mechanism that
|
|
202
|
+
discovers a form was wrong never routes back to the form. Where no candidate
|
|
203
|
+
list exists the ladder is unchanged and stage 1 runs immediately.
|
|
204
|
+
**This adds a branch; it does not move the budget.** Reading the list is not
|
|
205
|
+
an attempt and is not counted, and the reopen is capped at one per candidate:
|
|
206
|
+
the second contradiction on the same candidate continues down this ladder
|
|
207
|
+
rather than reopening again.
|
|
196
208
|
1. **Attempt 1 fails → up to 2 retries of the same approach**
|
|
197
209
|
([`think-before-action`](../../rules/think-before-action.md) "MAX 2
|
|
198
210
|
RETRIES PER APPROACH") — the soft, agent-side stage: rethink between
|
|
@@ -24,11 +24,8 @@ obligation_frequency: "per-turn"
|
|
|
24
24
|
# Notes-First Reasoning
|
|
25
25
|
|
|
26
26
|
Part of the Reasoning Discipline Protocol. Engage per
|
|
27
|
-
[`rdp-gate`](../contexts/execution/rdp-gate.md)
|
|
28
|
-
|
|
29
|
-
host. The notes file is grounded in the documented cross-run lessons memory
|
|
30
|
-
(consolidated via [`memory-consolidation`](../skills/memory-consolidation/SKILL.md));
|
|
31
|
-
the in-task sections below are a local derivation for within-task scope.
|
|
27
|
+
[`rdp-gate`](../contexts/execution/rdp-gate.md) — skip on trivial tasks, apply
|
|
28
|
+
lightly on a strong-reasoning host.
|
|
32
29
|
|
|
33
30
|
## The Iron Law
|
|
34
31
|
|
|
@@ -38,36 +35,50 @@ NOTES FILE — NEVER ECHOED INTO THE RESPONSE.
|
|
|
38
35
|
THE RESPONSE CARRIES CONCLUSIONS + EVIDENCE ONLY.
|
|
39
36
|
```
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
This is not "show your work in the reply" — it is the opposite. Why, and what
|
|
39
|
+
grounds the notes file:
|
|
40
|
+
[`notes-horizon-mechanics`](../docs/guidelines/agent-infra/notes-horizon-mechanics.md).
|
|
44
41
|
|
|
45
42
|
## Notes file structure (the file, not the response)
|
|
46
43
|
|
|
47
|
-
Use the sections that apply
|
|
48
|
-
no "write N hypotheses" instruction — record what the work actually surfaced.
|
|
44
|
+
Use the sections that apply — record what the work actually surfaced.
|
|
49
45
|
|
|
50
46
|
- `## In-Task Hypothesis Log` — competing explanations under consideration.
|
|
51
|
-
- `## Killed beliefs` — each discarded hypothesis + the
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
- `## Decisions` — decision · alternatives · reason · revisit-if
|
|
55
|
-
|
|
56
|
-
[`decision-record`](../skills/decision-record/SKILL.md)/ADR** when
|
|
57
|
-
|
|
58
|
-
next month need this context?).
|
|
47
|
+
- `## Killed beliefs` — each discarded hypothesis + the `killed-if` that killed
|
|
48
|
+
it.
|
|
49
|
+
- `## Predictions` — **chosen form** · prediction · confidence · result · lesson.
|
|
50
|
+
- `## Decisions` — decision · alternatives · reason · revisit-if ·
|
|
51
|
+
**next-commitment**. Tactical decisions stay here; **escalate to
|
|
52
|
+
[`decision-record`](../skills/decision-record/SKILL.md)/ADR** when cross-task
|
|
53
|
+
or architectural.
|
|
59
54
|
- `## Uncertainty` — per-dimension score (e.g. architecture/implementation/
|
|
60
55
|
requirements: high/medium/low); feeds the adaptive-effort decision.
|
|
61
56
|
|
|
57
|
+
### The horizon — where `next-commitment` ends
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
A CHOICE AUTHORISES WORK UP TO THE NEXT EVIDENCE-PRODUCING BOUNDARY.
|
|
61
|
+
NAME THE BOUNDARY FROM THE LIST. NEVER "THE WORK THE EVIDENCE SUPPORTS" —
|
|
62
|
+
THAT IS A JUDGEMENT, AND A JUDGEMENT IS NOT A HORIZON.
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Reopening — once, on contradiction, never on a schedule
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
AN OBSERVATION THAT CONTRADICTS THE PREDICTION REOPENS THE CHOICE BEFORE THE
|
|
69
|
+
NEXT STEP — FROM THE CANDIDATE LIST THAT ALREADY EXISTS, NEVER A FRESH
|
|
70
|
+
ENUMERATION. ONE REOPEN PER CANDIDATE. THE SECOND CONTRADICTION HANDS OVER TO
|
|
71
|
+
THE RETRY-BUDGET LADDER RATHER THAN REOPENING AGAIN.
|
|
72
|
+
```
|
|
73
|
+
|
|
62
74
|
## What stays out of notes
|
|
63
75
|
|
|
64
|
-
User-attribute facts, transient TODOs, and durable cross-run lessons
|
|
65
|
-
|
|
76
|
+
User-attribute facts, transient TODOs, and durable cross-run lessons go to the
|
|
77
|
+
memory system (`memory-consolidation`), not the in-task notes.
|
|
66
78
|
|
|
67
79
|
## See also
|
|
68
80
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
response carries comes from real tool results.
|
|
81
|
+
[`notes-horizon-mechanics`](../docs/guidelines/agent-infra/notes-horizon-mechanics.md)
|
|
82
|
+
— every mechanic this rule points at. Also
|
|
83
|
+
[`rdp-gate`](../contexts/execution/rdp-gate.md) and
|
|
84
|
+
[`verify-before-complete`](verify-before-complete.md).
|
|
@@ -58,7 +58,11 @@ import * as path from 'node:path';
|
|
|
58
58
|
import process from 'node:process';
|
|
59
59
|
import { fileURLToPath } from 'node:url';
|
|
60
60
|
|
|
61
|
-
import {
|
|
61
|
+
import {
|
|
62
|
+
blocker_is_resolved,
|
|
63
|
+
collect,
|
|
64
|
+
parse_blockers,
|
|
65
|
+
} from './update_roadmap_progress.js';
|
|
62
66
|
import { guardedBaselineProblems, parseGuardedBaselines } from './guarded_baseline.js';
|
|
63
67
|
|
|
64
68
|
import { isCliEntry } from './_cli_entry.js';
|
|
@@ -265,6 +269,80 @@ function _git_mv(root: string, src_rel: string, dst_rel: string, dry_run: boolea
|
|
|
265
269
|
}
|
|
266
270
|
}
|
|
267
271
|
|
|
272
|
+
// ---------------------------------------------------------------------
|
|
273
|
+
// The index/working-tree blocker divergence check (1b) + staging (1a)
|
|
274
|
+
// ---------------------------------------------------------------------
|
|
275
|
+
//
|
|
276
|
+
// The open-blocker refusal below reads the file with `fs.readFileSync`, i.e.
|
|
277
|
+
// the WORKING TREE. `git mv` then moves the INDEX ENTRY, which still carries
|
|
278
|
+
// whatever was staged. When the two disagree the commit ships the index
|
|
279
|
+
// content — content this gate never read.
|
|
280
|
+
//
|
|
281
|
+
// Measured, once, at full cost (2026-09-08): an edit removing a roadmap's
|
|
282
|
+
// blocker was made and never staged; `git mv` moved the stale index entry; the
|
|
283
|
+
// archived file shipped a blocker declared `Status: open` that had already been
|
|
284
|
+
// relocated to an active roadmap. The same blocker was open in two files at
|
|
285
|
+
// once, one of them archived, and it was caught by a human reading
|
|
286
|
+
// `git status` rather than by any gate.
|
|
287
|
+
//
|
|
288
|
+
// The check is scoped to blocker id → status and deliberately NOT to whole-file
|
|
289
|
+
// equality. An unstaged typo fix in a roadmap title has nothing to do with the
|
|
290
|
+
// defect, and refusing archival for it trains `git add -A`, which destroys the
|
|
291
|
+
// staging discipline this check depends on. AI council 2026-09-08, 2/2 present
|
|
292
|
+
// (anthropic/claude-sonnet-4-5 + openai/gpt-4o), on that scoping specifically:
|
|
293
|
+
// broad scoping is "user-hostile, trains developers to `git add -A`
|
|
294
|
+
// reflexively, defeating staging discipline".
|
|
295
|
+
|
|
296
|
+
/** Blocker id → status, as the archive-transition check compares them. */
|
|
297
|
+
function _blockerStatuses(text: string): Map<string, string> {
|
|
298
|
+
const out = new Map<string, string>();
|
|
299
|
+
for (const b of parse_blockers(text)) {
|
|
300
|
+
out.set(b.id, blocker_is_resolved(b) ? 'resolved' : 'open');
|
|
301
|
+
}
|
|
302
|
+
return out;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* `git show :<rel>` — the STAGED content of a path, or null when the path has
|
|
307
|
+
* no index entry.
|
|
308
|
+
*
|
|
309
|
+
* Null is the untracked / pre-first-commit case, which `_git_mv` already
|
|
310
|
+
* handles by falling back to a plain rename. There is no index entry to
|
|
311
|
+
* disagree with, so the divergence check has nothing to assert and says so by
|
|
312
|
+
* returning null rather than by guessing at an empty string — an empty staged
|
|
313
|
+
* file and an absent one differ, and only the second is legitimate here.
|
|
314
|
+
*/
|
|
315
|
+
function _indexContent(root: string, rel: string): string | null {
|
|
316
|
+
const cp = _run(['git', 'show', `:${rel}`], root);
|
|
317
|
+
return cp.returncode === 0 ? cp.stdout : null;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Human-readable disagreements between the staged and working-tree blocker
|
|
322
|
+
* maps of one path. Empty array = the two agree, or there is no index entry.
|
|
323
|
+
*/
|
|
324
|
+
function _blockerDivergence(root: string, rel: string, workTreeText: string): string[] {
|
|
325
|
+
const staged = _indexContent(root, rel);
|
|
326
|
+
if (staged === null) {
|
|
327
|
+
return [];
|
|
328
|
+
}
|
|
329
|
+
const wt = _blockerStatuses(workTreeText);
|
|
330
|
+
const idx = _blockerStatuses(staged);
|
|
331
|
+
const ids = [...new Set([...wt.keys(), ...idx.keys()])].sort();
|
|
332
|
+
const out: string[] = [];
|
|
333
|
+
for (const id of ids) {
|
|
334
|
+
const a = idx.get(id);
|
|
335
|
+
const b = wt.get(id);
|
|
336
|
+
if (a === b) {
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
out.push(
|
|
340
|
+
`blocker '${id}': staged=${a ?? 'absent'} vs working tree=${b ?? 'absent'}`,
|
|
341
|
+
);
|
|
342
|
+
}
|
|
343
|
+
return out;
|
|
344
|
+
}
|
|
345
|
+
|
|
268
346
|
/**
|
|
269
347
|
* Repo-relative paths of files containing `needle`, by walking the filesystem.
|
|
270
348
|
*
|
|
@@ -547,9 +625,8 @@ function archive_completed(
|
|
|
547
625
|
// and invisible in a sweep that only reports what it moved; a MALFORMED
|
|
548
626
|
// one on `[x]` would otherwise archive with an annotation claiming the
|
|
549
627
|
// opposite. Both are named here instead.
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
);
|
|
628
|
+
const roadmapText = fs.readFileSync(path.join(roadmap_root, stats.rel), 'utf-8');
|
|
629
|
+
const guarded = parseGuardedBaselines(roadmapText);
|
|
553
630
|
if (guarded.length > 0) {
|
|
554
631
|
process.stderr.write(
|
|
555
632
|
` ⚠️ ${stats.rel}: ${guarded.length} guarded-baseline step(s) — ` +
|
|
@@ -603,12 +680,37 @@ function archive_completed(
|
|
|
603
680
|
if (changed_only && !(touched as Set<string>).has(old_rel)) {
|
|
604
681
|
continue; // complete, but not this branch's work
|
|
605
682
|
}
|
|
683
|
+
// The gate above validated the WORKING TREE; `git mv` ships the INDEX.
|
|
684
|
+
// When they disagree about a blocker, the validated content is not the
|
|
685
|
+
// content that gets committed — see § the index/working-tree blocker
|
|
686
|
+
// divergence check above for the measured failure.
|
|
687
|
+
const divergence = _blockerDivergence(root, old_rel, roadmapText);
|
|
688
|
+
if (divergence.length > 0) {
|
|
689
|
+
process.stderr.write(
|
|
690
|
+
` ⚠️ ${stats.rel}: staged and working-tree blockers disagree ` +
|
|
691
|
+
`(${divergence.length}) — not archived. \`git mv\` would commit ` +
|
|
692
|
+
'the staged content, which this sweep never validated. Stage or ' +
|
|
693
|
+
'discard the change, then re-run.\n',
|
|
694
|
+
);
|
|
695
|
+
for (const d of divergence) {
|
|
696
|
+
process.stderr.write(` · ${d}\n`);
|
|
697
|
+
}
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
606
700
|
const new_rel = `agents/roadmaps/archive/${stats.rel}`;
|
|
607
701
|
const mv = _git_mv(root, old_rel, new_rel, dry_run);
|
|
608
702
|
if (!mv.ok) {
|
|
609
703
|
process.stderr.write(` ⚠️ could not archive ${old_rel} (mv failed)\n`);
|
|
610
704
|
continue;
|
|
611
705
|
}
|
|
706
|
+
// `git mv` moved the index ENTRY, not the working-tree content. Staging
|
|
707
|
+
// the destination makes what gets committed identical to what the checks
|
|
708
|
+
// above read — the divergence check refuses a disagreement that exists
|
|
709
|
+
// BEFORE the move, and this closes one created by an edit between the
|
|
710
|
+
// move and the commit.
|
|
711
|
+
if (!dry_run && mv.tracked) {
|
|
712
|
+
_run(['git', 'add', '--', new_rel], root);
|
|
713
|
+
}
|
|
612
714
|
const refs = _inbound_ref_rewrite(root, old_rel, new_rel, dry_run, mv.tracked);
|
|
613
715
|
// Stage rewritten refs only in a tracked repo; an untracked consumer's
|
|
614
716
|
// files are not in the index, so the filesystem rewrite is the whole job.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: inherit
|
|
3
3
|
name: code-intelligence
|
|
4
|
-
description: "Route codebase-structure questions (who calls X, where
|
|
4
|
+
description: "Route codebase-structure questions (who calls X, where used, change-impact) to an existing code-graph first: impact, tests-for, dead cheaper, never more precise; grep routine. Also 'call graph'."
|
|
5
5
|
domain: engineering
|
|
6
6
|
workspaces:
|
|
7
7
|
- engineering
|
|
@@ -204,6 +204,62 @@ refresh` first, or use grep and say so. This is a freshness obligation, not an
|
|
|
204
204
|
ordering claim; the rule's query-first ordering still governs which source to
|
|
205
205
|
reach for.
|
|
206
206
|
|
|
207
|
+
## The four gate verbs — a diff, not a symbol (2026-09-08)
|
|
208
|
+
|
|
209
|
+
`query` / `affected` / `path` / `explain` answer a question about a SYMBOL.
|
|
210
|
+
Four more answer a question about a DIFF, and they are documented here rather
|
|
211
|
+
than in § Procedure for a mechanical reason worth stating: step 4.3 of
|
|
212
|
+
`road-to-a-graph-that-is-shipped` verifies that this file's line 164 — the
|
|
213
|
+
**No class is graph-first** sentence — is unchanged, and inserting anything
|
|
214
|
+
above it moves that line. So the ordering claim K5 protects stays byte-fixed
|
|
215
|
+
and the new material sits below it.
|
|
216
|
+
|
|
217
|
+
Each of the four walks only edges whose resolution mechanism is a stated fact
|
|
218
|
+
(never a repo-wide same-name guess, never an untyped receiver), and each prints
|
|
219
|
+
the mechanisms it accepted, the mechanisms it refused, and the graph's
|
|
220
|
+
staleness — so a narrow answer is distinguishable from a decoupled one:
|
|
221
|
+
|
|
222
|
+
- `agent-config code-graph impact --diff <rev>` — callers, dependents and test
|
|
223
|
+
files reachable from the changed symbols, plus the producing edges and a
|
|
224
|
+
minimal read set.
|
|
225
|
+
- `agent-config code-graph tests-for <symbol>` — the test files that import it.
|
|
226
|
+
An empty list is a finding, not an error.
|
|
227
|
+
- `agent-config code-graph untested --diff <rev>` — changed symbols that no test
|
|
228
|
+
file imports.
|
|
229
|
+
- `agent-config code-graph dead [--entry-points F | --accept-missing-exports]` —
|
|
230
|
+
symbols with no accepted reference that no declared entry point names. It
|
|
231
|
+
**refuses** rather than answering while an entry-point source cannot be read:
|
|
232
|
+
this engine records no exportedness, so without a supplied list an
|
|
233
|
+
exported-but-unimported symbol is indistinguishable from a dead one, and a
|
|
234
|
+
confident false "dead" invites a deletion the graph cannot justify. Nothing it
|
|
235
|
+
lists is a deletion recommendation.
|
|
236
|
+
|
|
237
|
+
These answers reach an agent over MCP without shelling out, and the mapping is
|
|
238
|
+
**not** one tool per verb — corrected after an independent review found this
|
|
239
|
+
paragraph claiming "the same five answers" directly after a list of four:
|
|
240
|
+
|
|
241
|
+
| MCP tool | answers |
|
|
242
|
+
|---|---|
|
|
243
|
+
| `graph_impact` | `impact --diff`, **and** `untested --diff` via `untested_only: true` |
|
|
244
|
+
| `graph_tests_for` | `tests-for` |
|
|
245
|
+
| `graph_dead` | `dead` |
|
|
246
|
+
| `graph_query` | `query` |
|
|
247
|
+
| `graph_path` | `path` |
|
|
248
|
+
|
|
249
|
+
`untested` has no tool of its own; it is a flag on `graph_impact`, because the
|
|
250
|
+
two answer the same question over the same diff and a sixth tool would have cost
|
|
251
|
+
standing context for a boolean. `graph_impact` is the only one that is not
|
|
252
|
+
read-only — it runs `git diff --name-only` to resolve its rev — and
|
|
253
|
+
`graph_dead`'s refusal arrives as `status: "refused"`, never as `status: "ok"`
|
|
254
|
+
with an empty list.
|
|
255
|
+
|
|
256
|
+
**No ordering claim is added here, and no measurement claim either.** These
|
|
257
|
+
verbs are cheaper than reconstructing the same relationship by hand — that is a
|
|
258
|
+
claim about the ALTERNATIVE being a manual reconstruction, not about grep.
|
|
259
|
+
Nothing on this page says they beat grep, none of the four appears in the v2
|
|
260
|
+
benchmark corpus (which measures `callers`, `transitive-impact`, `path-between`
|
|
261
|
+
and `references`), and § Measured twice still governs that question.
|
|
262
|
+
|
|
207
263
|
## Do NOT
|
|
208
264
|
|
|
209
265
|
- Do NOT rebuild a **fresh** consumer-shipped index — query it (interop
|
|
@@ -68,6 +68,15 @@ returned 0, the turn closed, and the red arrived where the user found it.
|
|
|
68
68
|
ending the turn silently on one is what the reminder exists to stop. Whether
|
|
69
69
|
the reminder changes behavior is unmeasured — it ships as a carrier, not as a
|
|
70
70
|
claim.
|
|
71
|
+
- **`ci_settle` will not answer for a head that stopped mattering.** Since
|
|
72
|
+
2026-09-08 it reads the PR's `state` and compares its recorded head against
|
|
73
|
+
`git ls-remote` — before the wait and again at verdict time — and exits 2 with
|
|
74
|
+
a reason when the PR is merged, closed, or record-behind-branch. A green names
|
|
75
|
+
the head it is about. The measured reason: a merged PR's rollup kept answering
|
|
76
|
+
with its merge-time checks, so the tool reported `SETTLED GREEN — 40 check(s)`
|
|
77
|
+
for a commit that had zero check runs. The check does not apply to a fork PR
|
|
78
|
+
whose ref is not under this `origin`, and the line says so instead of claiming
|
|
79
|
+
it passed.
|
|
71
80
|
- **Neither reaches a host without the slot.** `agent-config hooks:status`
|
|
72
81
|
answers which slots are bound where you actually are; `post_tool_use` is
|
|
73
82
|
unbound on windsurf and copilot, and there the settle obligation is
|
|
@@ -51,6 +51,42 @@ radius, spacing, shadow, font-size to a configured token. If the design hands yo
|
|
|
51
51
|
(`bg-[#3B82F6]`, `mt-[17px]`) are a smell — accept only with a
|
|
52
52
|
one-line comment naming the design source.
|
|
53
53
|
|
|
54
|
+
**That paragraph is written for greenfield, and artifact-bound work inverts
|
|
55
|
+
it.** When a provided finished design is the spec
|
|
56
|
+
([`design-fidelity`](../../rules/design-fidelity.md)), `#3B82F6` is a decision
|
|
57
|
+
somebody already made and `bg-blue-500` is a guess about it. Three obligations
|
|
58
|
+
follow, and the third is the one this skill used to get wrong:
|
|
59
|
+
|
|
60
|
+
1. **Do not snap.** Replacing the artifact's value with the nearest configured
|
|
61
|
+
token is the deviation the rule's Iron Law forbids — *"NEVER SWAP … SPACING,
|
|
62
|
+
OR COLOUR"* without explicit confirmation. An artifact-derived exact value is
|
|
63
|
+
not a smell here: it *is* the spec, and the source-naming comment the
|
|
64
|
+
paragraph above asks for is what records it.
|
|
65
|
+
2. **Translate once, not per call site.** Where the artifact's literal genuinely
|
|
66
|
+
needs to live in the project's system, add **one** named project token
|
|
67
|
+
carrying that exact value and use it everywhere — one token the project owns
|
|
68
|
+
beats N approximations of the same colour. That is a token duty, not a
|
|
69
|
+
deviation: the value does not change.
|
|
70
|
+
3. **Reconcile as a proposal, never autonomously.** Report each value's
|
|
71
|
+
distance to the nearest project token on the `Reconciled:` line below, and
|
|
72
|
+
let the human decide. Writing a *different* project value because the
|
|
73
|
+
difference looks small is exactly the unconfirmed swap (1) rules out — the
|
|
74
|
+
mode table at `design-fidelity.md:117-121` grants no visibility exemption,
|
|
75
|
+
and `structural` grants only the filling of a spec that is genuinely
|
|
76
|
+
**silent**, which an artifact stating `#3B82F6` is not.
|
|
77
|
+
|
|
78
|
+
**Why not "just approximate within tolerance", which is the eventual intent:**
|
|
79
|
+
that needs a tolerance to exist. There is none — no `reconcile`, `tolerance`,
|
|
80
|
+
`approximat` or `nearest` in the rule or its guideline — and both the threshold
|
|
81
|
+
and whether approximation is autonomous by default are owner decisions, tracked
|
|
82
|
+
as `blocker: approximation-tolerance` and `blocker: fidelity-default-flip` on
|
|
83
|
+
`road-to-design-intent-conformance`. Until they land, a skill granting that
|
|
84
|
+
autonomy would be re-writing the rule from underneath it.
|
|
85
|
+
|
|
86
|
+
Structure, controls, icons, grid and breakpoints are never this skill's to
|
|
87
|
+
adjust; those stay 1:1 with the artifact and belong to the rule, not to a
|
|
88
|
+
utility-class decision.
|
|
89
|
+
|
|
54
90
|
Token authoring (DTCG 3-layer model, CSS-var/Tailwind generation) lives
|
|
55
91
|
in [`design-tokens`](../design-tokens/SKILL.md); its
|
|
56
92
|
`tokens.ts validate --dir <path>` is the **single token-discipline
|
|
@@ -103,7 +139,11 @@ When reviewing or proposing styles, return:
|
|
|
103
139
|
|
|
104
140
|
1. Token map — every colour, spacing, radius, shadow, font-size mapped
|
|
105
141
|
to its configured token; arbitrary values flagged with the design
|
|
106
|
-
source they cite.
|
|
142
|
+
source they cite. Artifact-bound work adds a **Reconciled** block here:
|
|
143
|
+
one line per value, as `<artifact value> → <kept, or the token that
|
|
144
|
+
carries it exactly> (<distance to the nearest project token>)`. This is
|
|
145
|
+
the destination "report the distance" means; without it the obligation
|
|
146
|
+
has nowhere to land and is unobservable in the deliverable.
|
|
107
147
|
2. Class list — ordered (layout → box-model → typography → colour →
|
|
108
148
|
state → responsive); inline-style use justified per element.
|
|
109
149
|
3. Extraction + risk call-out — component / constant / `@apply` / none
|
|
@@ -115,6 +155,7 @@ Concrete shape:
|
|
|
115
155
|
```
|
|
116
156
|
Element: <selector or component name>
|
|
117
157
|
Token map: <colour/spacing/etc → config token>
|
|
158
|
+
Reconciled: <artifact value → kept or exact-carrying token, + distance>
|
|
118
159
|
Class list: <ordered classes>
|
|
119
160
|
Inline style: <only if runtime-computed; else "none">
|
|
120
161
|
Extraction: <component | constant | @apply | none — reason>
|
|
@@ -128,7 +169,16 @@ Risks: <arbitrary values, !important, dark-mode gaps>
|
|
|
128
169
|
- `dark:` variants need a token map in both modes; one-sided dark
|
|
129
170
|
styling is half a feature.
|
|
130
171
|
- Arbitrary values (`mt-[17px]`) survive Tailwind upgrades but
|
|
131
|
-
break the design system; they accumulate silently.
|
|
172
|
+
break the design system; they accumulate silently. **Artifact-bound is the
|
|
173
|
+
exception, not a loophole:** a value the provided design specifies is not
|
|
174
|
+
accumulation, and step 1's three obligations decide it. An arbitrary value
|
|
175
|
+
nobody can trace to a source is still the smell this bullet is about.
|
|
176
|
+
- **The carrier is CSS or a utility class; the value is the design's.** Static
|
|
177
|
+
presentation belongs in CSS / tokens / classes — `style=` is for what only
|
|
178
|
+
the runtime knows (a computed width, a live transform, a measured offset).
|
|
179
|
+
Porting an artifact's inline `style=` into classes is therefore expected and
|
|
180
|
+
is not a deviation, **as long as the resolved value comes out identical**.
|
|
181
|
+
Changing the carrier is free; changing the number is not.
|
|
132
182
|
- `@apply` inside component CSS interacts with PurgeCSS — keep it
|
|
133
183
|
in files Tailwind scans, not in vendor CSS.
|
|
134
184
|
- **Anti-AI-slop catalog.** The bullets below are the Tailwind-specific
|
|
@@ -39,7 +39,7 @@ schema_version: 1
|
|
|
39
39
|
# CI guard: a release bump of `package.json` must update this value
|
|
40
40
|
# in lockstep — see scripts/check_template_pin_drift.ts (road-to-
|
|
41
41
|
# portable-runtime-and-update-check P3.3).
|
|
42
|
-
agent_config_version: "14.
|
|
42
|
+
agent_config_version: "14.23.0"
|
|
43
43
|
|
|
44
44
|
# --- Project identity ---
|
|
45
45
|
project:
|
package/dist/cli/registry.js
CHANGED
|
@@ -73,7 +73,7 @@ export const REGISTRY = [
|
|
|
73
73
|
{ name: 'affected', disposition: 'delegate', synopsis: 'Artefacts related to <artefact> via the discovery relation-graph (BFS).' },
|
|
74
74
|
{ name: 'graph-explain', disposition: 'delegate', synopsis: 'Seed on a <concept>, expand 2 hops over the discovery relation-graph with a node budget.' },
|
|
75
75
|
{ name: 'benchmark', disposition: 'delegate', synopsis: 'Report context-token reduction vs the full always-loaded projection.' },
|
|
76
|
-
{ name: 'code-graph', disposition: 'delegate', synopsis: 'Deterministic code-graph engine: build|detect|query|affected|path|explain|
|
|
76
|
+
{ name: 'code-graph', disposition: 'delegate', synopsis: 'Deterministic code-graph engine: build|detect|refresh|validate|query|affected|path|explain, plus the gate verbs impact|tests-for|untested|dead.' },
|
|
77
77
|
{ name: 'hooks:install', disposition: 'delegate', synopsis: 'Install the combined pre-commit hook.' },
|
|
78
78
|
{ name: 'hooks:status', disposition: 'delegate', synopsis: 'Print the runtime hook matrix (per-platform install + bindings).' },
|
|
79
79
|
{ name: 'hooks:doctor', disposition: 'delegate', synopsis: 'Diagnose hook health: concerns, posture, missing trampolines (read-only).' },
|