@event4u/agent-config 14.16.0 → 14.18.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 +177 -213
- package/README.md +2 -2
- package/dist/agent-src/commands/analyze/inbox.md +172 -6
- package/dist/agent-src/commands/fix/commit-messages.md +336 -0
- package/dist/agent-src/commands/fix.md +5 -3
- package/dist/agent-src/commands/pr/merge.md +35 -44
- package/dist/agent-src/rules/commit-conventions.md +1 -1
- package/dist/agent-src/skills/accessibility-auditor/SKILL.md +2 -0
- package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +27 -1
- package/dist/agent-src/skills/aws-infrastructure/SKILL.md +41 -0
- package/dist/agent-src/skills/code-intelligence/SKILL.md +60 -12
- package/dist/agent-src/skills/complexity-first-planning/SKILL.md +27 -0
- package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +234 -4
- package/dist/agent-src/skills/design-review/SKILL.md +2 -0
- package/dist/agent-src/skills/feature-planning/SKILL.md +34 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +37 -12
- package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +176 -0
- package/dist/agent-src/skills/laravel-mail/SKILL.md +44 -0
- package/dist/agent-src/skills/terraform/SKILL.md +29 -0
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +40 -0
- package/dist/agent-src/skills/threat-modeling/data/reasoning.csv +1 -0
- package/dist/agent-src/skills/threat-modeling/data/surfaces.csv +1 -0
- package/dist/agent-src/skills/threat-modeling/data/threats.csv +5 -0
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +12 -0
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +53 -8
- package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli-delegate/cmd_conformance.js +335 -659
- package/dist/cli-delegate/cmd_explain.js +24 -112
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +55 -29
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +6 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +5 -4
- package/dist/hooks/dispatch.js +959 -1304
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +671 -1002
- package/dist/shared/settingsConsent.js +1 -1
- package/package.json +1 -1
- package/src/config/conformance-claim-baseline.json +9 -0
- package/src/config/gate-violation-baselines.json +3 -3
- package/src/config/release-gate-locality.yml +129 -0
- package/src/config/web-launch-readiness.json +1 -1
- package/src/scripts/_cli/explain_last/index.ts +1 -1
- package/src/scripts/_cli/explain_last/memory.ts +8 -104
- package/src/scripts/_lib/release_highlights.ts +172 -1
- package/src/scripts/_lib/release_material.ts +66 -0
- package/src/scripts/_lib/repeated_run.ts +77 -0
- package/src/scripts/_lib/tamper_vocabulary.ts +242 -0
- package/src/scripts/_lib/unified_diff.ts +121 -0
- package/src/scripts/check_artefact_count_messaging.ts +9 -0
- package/src/scripts/check_finding_dispositions.ts +179 -3
- package/src/scripts/check_installed_hooks_fresh.ts +381 -0
- package/src/scripts/check_release_highlights.ts +89 -4
- package/src/scripts/check_suppression_hygiene.ts +11 -0
- package/src/scripts/check_web_launch_readiness.ts +295 -15
- package/src/scripts/code_graph/build.ts +230 -33
- package/src/scripts/code_graph/extract.ts +168 -33
- package/src/scripts/code_graph/types.ts +37 -2
- package/src/scripts/code_graph/validate.ts +12 -1
- package/src/scripts/conformance_scan.ts +2 -2
- package/src/scripts/detect_silent_catch.ts +403 -0
- package/src/scripts/detect_verification_tampering.ts +538 -0
- package/src/scripts/git_authorization_hook.ts +153 -17
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +33 -19
- package/src/scripts/hooks/block_no_verify.ts +3 -3
- package/src/scripts/hooks/concern_registry.ts +2 -2
- package/src/scripts/hooks/evidence_independence.ts +21 -2
- package/src/scripts/hooks/{block_unauthorized_git.ts → git_command_classifier.ts} +25 -369
- package/src/scripts/hooks/push_settle_hook.ts +250 -0
- package/src/scripts/hooks/ship_diff_volume_hook.ts +1 -1
- package/src/scripts/install-hooks.sh +134 -1
- package/src/scripts/language_mirror_hook.ts +27 -5
- package/src/scripts/measure_release_mix.ts +384 -0
- package/src/scripts/release.ts +31 -143
- package/src/scripts/release_drill.ts +71 -1
- package/src/scripts/release_mix_taxonomy.json +172 -0
- package/src/scripts/release_publication.ts +243 -3
- package/src/scripts/release_verify.ts +220 -0
- package/src/scripts/schemas/review-findings.schema.json +1 -1
- package/src/scripts/schemas/skill.schema.json +11 -1
- package/src/scripts/self_review_gate.ts +10 -1
- package/src/shared/settingsConsent.ts +1 -1
- package/src/scripts/attest_artifact.ts +0 -193
|
@@ -34,12 +34,13 @@ ACTIVATION NEEDS THE OWNER DECISION IN THE `merge-authority` BLOCKER OF
|
|
|
34
34
|
`road-to-drain-commands` — NEVER A COMMAND EDIT, AND NEVER A GUARD EDIT.
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
**The invocation is the authorization, and nothing else is.** `pr-merge` is
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
**The invocation is the authorization, and nothing else is.** `pr-merge` is
|
|
38
|
+
irreversible, and since 2026-09-04 (ADR-254) NOTHING MECHANICAL CHECKS IT —
|
|
39
|
+
the gate that did was removed after it refused authorizations the owner had in
|
|
40
|
+
fact given. The per-session ledger still records what the user's own prompt
|
|
41
|
+
authorized, and this command still reads it as an audit trail; it introduces no
|
|
42
|
+
second authorization store, and it never writes one. When the work left is
|
|
43
|
+
outside what the owner authorized, the run stops and reports (§ 7).
|
|
43
44
|
|
|
44
45
|
Why it ships inert rather than not at all: everything before § 9 — the target
|
|
45
46
|
manifest, the four conflict classes, the superseded check, the bounded CI
|
|
@@ -266,54 +267,44 @@ exceeds the remaining window, stop entering CI-fix loops and merge everything
|
|
|
266
267
|
already green first. Pre-greening several PRs ahead of their merge is forbidden
|
|
267
268
|
under window pressure.
|
|
268
269
|
|
|
269
|
-
**
|
|
270
|
-
|
|
271
|
-
|
|
270
|
+
**No mechanical window remains, and that is the change.** Until 2026-09-04 the
|
|
271
|
+
run read a freshness bound off the authorization ledger and paused when it
|
|
272
|
+
closed. The owner removed the enforcing gate (ADR-254) after it was measured
|
|
273
|
+
refusing authorizations that had in fact been given, so there is no constant to
|
|
274
|
+
read and no expiry to schedule against. Authorization is carried by the
|
|
275
|
+
conversation and by `non-destructive-by-default`, not by a clock.
|
|
276
|
+
|
|
277
|
+
The per-session ledger is still written, and is still read-only to this run:
|
|
272
278
|
|
|
273
279
|
```bash
|
|
274
280
|
cat "agents/state/git-authorization/$(<session-slug>).json" # detected_at
|
|
275
281
|
```
|
|
276
282
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
source and the executing bundle agree — reading the source alone is the
|
|
280
|
-
2026-08-21 failure re-expressed as an instruction, since the bundle is what
|
|
281
|
-
enforces the value and a source edit without a rebuild is silently inert. Under
|
|
282
|
-
pressure means
|
|
283
|
-
the remaining window is shorter than one CI cycle on this repository. The read
|
|
284
|
-
is the whole interaction: the run never edits that file, the constant, or the
|
|
285
|
-
built bundle.
|
|
283
|
+
It records what a turn authorized. It no longer gates anything, so treat it as
|
|
284
|
+
an audit trail, never as permission. The run never edits that file.
|
|
286
285
|
|
|
287
|
-
## 7.
|
|
286
|
+
## 7. Authorization is the owner's sentence, not a timer
|
|
288
287
|
|
|
289
288
|
```
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
289
|
+
THE RUN MERGES WHAT THE OWNER AUTHORIZED AND NOTHING ELSE. WHEN THE WORK LEFT
|
|
290
|
+
IS OUTSIDE WHAT WAS AUTHORIZED, THE RUN PAUSES, REPORTS, AND ASKS. IT NEVER
|
|
291
|
+
INFERS A WIDER MANDATE FROM A LONG RUN OR FROM MOMENTUM.
|
|
293
292
|
```
|
|
294
293
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
against — no new mechanism, and the signal still comes from text the user typed.
|
|
310
|
-
Re-verify the manifest entry (number and head SHA) before resuming, exactly as
|
|
311
|
-
§ 8 requires: the pause is a window in which the world can move.
|
|
312
|
-
|
|
313
|
-
Widening `LEDGER_MAX_AGE_MS` is still forbidden practice, and ADR-251 kept the
|
|
314
|
-
30-minute value deliberately rather than by omission: on 2026-08-21 it was
|
|
315
|
-
patched to six hours for a drain run and the widening reached the trunk. The run proposes no value for it, edits neither it nor its bundles,
|
|
316
|
-
and treats a refusal as the answer.
|
|
294
|
+
With the gate removed nothing refuses an unauthorized merge, which makes this
|
|
295
|
+
section the whole control rather than a second layer behind one. Two rules
|
|
296
|
+
follow, and they are stricter than the ones they replace:
|
|
297
|
+
|
|
298
|
+
- **A cardinality word does not authorize a PR the owner never named.** "All the
|
|
299
|
+
open PRs" is an instruction to work the queue as it stood when the owner said
|
|
300
|
+
it. A PR opened after that sentence is new work and needs its own go-ahead.
|
|
301
|
+
- **A one-shot authorization is spent on the operation it named.** Per
|
|
302
|
+
`commit-policy`, "merge #1499" does not authorize the next merge, and a
|
|
303
|
+
conflict cycle or a CI fix in between does not renew it.
|
|
304
|
+
|
|
305
|
+
Write the summary as-is with an `unauthorized` disposition per unprocessed PR
|
|
306
|
+
and name the exact authorization needed. Then STOP and wait — do not end the
|
|
307
|
+
run, and do not proceed to the next PR.
|
|
317
308
|
|
|
318
309
|
## 8. Kill switches, and what happens after a merge
|
|
319
310
|
|
|
@@ -18,7 +18,7 @@ obligation_frequency: "per-commit"
|
|
|
18
18
|
|
|
19
19
|
# Commit Conventions
|
|
20
20
|
|
|
21
|
-
**Iron Law.**
|
|
21
|
+
**Iron Law.** Match the repo's configured or approved convention; else Conventional Commits (`feat:`, `fix:` …), branches `<type>/<short-slug>`; never invent one. Subjects + branch names stay emoji-free per [`no-decorative-emojis-in-git-surfaces`](no-decorative-emojis-in-git-surfaces.md); body emojis need an in-artifact legend.
|
|
22
22
|
|
|
23
23
|
Body migrated to `skill:conventional-commits-writing` (per P4 of `road-to-kernel-and-router.md`).
|
|
24
24
|
Trigger-set above activates this routing on demand, independent of the discipline profile (ADR-110).
|
|
@@ -47,7 +47,7 @@ Run the row(s) for what you touched. The grep is a fast authoring-time backstop
|
|
|
47
47
|
| **HTTP endpoint / route** | authorization (this principal may act on this resource — not just authenticated); tenant scope; **the three negative tests** (unauth→401, non-owner→403/404, cross-tenant→403/404); input validation at the boundary; rate limit actually wired; state-changing → CSRF + audit log | `broken-access-control`, `authz-review`, `threat-modeling` |
|
|
48
48
|
| **DB query / ORM** | parameterized, never string-built; tenant predicate present; no `SELECT *` across a serialization boundary; N+1 avoided (eager load) | `source-discovery`, `security` |
|
|
49
49
|
| **Migration** | reversible (`down`); expand-contract for drop/rename (never a bare `DROP COLUMN` before code stops reading it); transaction; index on new FK/filter column | `engineering-safety-floor`, `migration-architect` |
|
|
50
|
-
| **User-controlled render (FE)** | output-encoded; no `dangerouslySetInnerHTML`/`v-html`/`innerHTML`/`eval` on non-constant input; no secret/token in client code; token not in `localStorage
|
|
50
|
+
| **User-controlled render (FE)** | output-encoded; no `dangerouslySetInnerHTML`/`v-html`/`innerHTML`/`eval` on non-constant input; no secret/token in client code; token not in `localStorage`. **This surface also carries the four completeness rows below — they are part of it, not an optional extra.** | `frontend-render-security` |
|
|
51
51
|
| **Third-party asset in shipped markup / CSS** | delivery is self-hosted through the project's own route (framework font/asset primitive, bundled package, or locally-served file) — a font/icon/stylesheet CDN link transmits the **visitor's IP** to that third party on every page view; a hotlink only on a stated consumer opt-in; `integrity` + `crossorigin` if a CDN link stays | `design-fidelity-mechanics` § Asset & imagery discipline (owner), `typography-system` |
|
|
52
52
|
| **File / outbound fetch** | path confined to an allowed base; SSRF allow-list + private-IP block on user-supplied URLs; size limit; **explicit timeout** (no unbounded/default-infinite wait); server-side validation (never client-only) | `security`, `defense-in-depth` |
|
|
53
53
|
| **Infra / IaC** | least-privilege (no `Action:*`/`Resource:*`); encryption at rest; no `0.0.0.0/0` to mgmt/DB ports; no hardcoded creds; scanner-verified, not `plan`-verified | `engineering-safety-floor`, `terraform`, `secrets-management` |
|
|
@@ -57,6 +57,32 @@ Run the row(s) for what you touched. The grep is a fast authoring-time backstop
|
|
|
57
57
|
| **Concurrency / shared state** | check-then-act guarded (DB lock / atomic op / transaction — not a read-modify-write race); retried write carries an idempotency key; no unbounded parallel fan-out; shared mutable state synchronized | `source-discovery`, `security` |
|
|
58
58
|
| **Test** | asserts general behavior; expected derived from inputs/seeded data, not hardcoded; boundary + error + abuse cases, not only happy path | `testing-anti-patterns`, `test-driven-development` |
|
|
59
59
|
|
|
60
|
+
### Render surface — the completeness rows
|
|
61
|
+
|
|
62
|
+
Every row above is a **security** control. These four are the **completeness**
|
|
63
|
+
controls for the same surface — the states an agent most reliably omits, because
|
|
64
|
+
the prompt named the happy path and nothing else. A render that ships only the
|
|
65
|
+
populated state is not finished; it is one of four states written.
|
|
66
|
+
|
|
67
|
+
**The grep polarity is INVERTED here, and reading it the other way is the failure
|
|
68
|
+
mode this table has.** Above, zero hits is the pass. Below, **zero hits next to a
|
|
69
|
+
render that fetches or iterates is the prompt to look** — the state is probably
|
|
70
|
+
absent. A hit is not a pass either: the column is a `heuristic`, a locator for
|
|
71
|
+
code to read, never proof the state behaves. A framework abstraction can
|
|
72
|
+
implement all four correctly and match none of these patterns, and a codebase can
|
|
73
|
+
match all four while shipping a broken empty state.
|
|
74
|
+
|
|
75
|
+
| State | Assert on the render you wrote | Backstop grep (heuristic — zero hits is the prompt) |
|
|
76
|
+
|---|---|---|
|
|
77
|
+
| **Empty** | the zero-rows / no-results case renders a deliberate state, not a bare frame or a collapsed layout; it says what is missing and what the user can do next | `rg -n -e '\.length\s*[=<]' -e '\bisEmpty\b' -e 'count\(\)\s*[=<]' -e '\bempty\b'` — over the file that maps the collection |
|
|
78
|
+
| **Loading** | the pending case renders (skeleton, spinner, disabled control); no layout shift on arrival; the state is reachable from the actual async call, not only defined | `rg -n -e 'isLoading' -e 'isPending' -e 'isFetching' -e 'Skeleton' -e 'Spinner' -e 'aria-busy'` |
|
|
79
|
+
| **Error** | the failed case renders a recoverable state with a retry or a next step; the message carries no stack, secret or PII (the `frontend-render-security` row owns that half) | `rg -n -e 'isError' -e 'onError' -e 'ErrorBoundary' -e '\.catch\(' -e 'role="alert"'` |
|
|
80
|
+
| **Keyboard path** | every interactive element is reachable and operable by keyboard alone, with a visible focus ring; a click handler on a non-button element carries a role, `tabindex` and a key handler | `rg -n -e 'onClick' -e '@click' -e 'v-on:click'` lists the handlers, then `rg -n -e 'tabIndex' -e 'tabindex' -e 'onKeyDown' -e '@keydown' -e 'role='` on the same file — a handler with no match on the second is the prompt |
|
|
81
|
+
|
|
82
|
+
Route to `accessibility-auditor` for the keyboard row when the surface is more
|
|
83
|
+
than a handful of controls — this row asserts the path exists, it is not a WCAG
|
|
84
|
+
pass.
|
|
85
|
+
|
|
60
86
|
### Backstop greps (authoring-time, cross-stack)
|
|
61
87
|
|
|
62
88
|
```bash
|
|
@@ -127,6 +127,47 @@ are typically managed via **Terraform + Terragrunt** in a separate infrastructur
|
|
|
127
127
|
|
|
128
128
|
See the `terraform` and `terragrunt` skills for general IaC conventions.
|
|
129
129
|
|
|
130
|
+
### Least privilege and permissive defaults
|
|
131
|
+
|
|
132
|
+
The conventions above describe how this project deploys. This section is the
|
|
133
|
+
floor underneath them, and it holds whether or not a given resource is managed
|
|
134
|
+
here or in the infrastructure repo.
|
|
135
|
+
|
|
136
|
+
- **Least-privilege IAM, always.** A task role, an OIDC role, or an execution
|
|
137
|
+
role enumerates its actions and its resource ARNs. `Action: *` and
|
|
138
|
+
`Resource: *` are not shorthand for "we will scope it later" - one
|
|
139
|
+
compromised task credential then reaches every service and object in the
|
|
140
|
+
account. A wildcard needs a named, reviewed exception written beside it.
|
|
141
|
+
- **Least-privilege networking.** A security group opens a port to the
|
|
142
|
+
narrowest source that works: another security group id, a prefix list, a
|
|
143
|
+
known CIDR. An internet-wide source belongs to a public listener and nothing
|
|
144
|
+
else.
|
|
145
|
+
- **Permissive defaults are decisions.** A bucket with no public-access block,
|
|
146
|
+
a database with `publicly_accessible` left true, a volume or snapshot with no
|
|
147
|
+
encryption block - each of these works either way, which is why it survives
|
|
148
|
+
review. Treat an absent security block as a finding, not as a silence.
|
|
149
|
+
- **Credentials come from Secrets Manager, never from a vars file.** A literal
|
|
150
|
+
password, token, or key in a `.vars.yaml` or a task-definition template is
|
|
151
|
+
the same defect as one in `.tf`, and the state and template files are as
|
|
152
|
+
readable as the code.
|
|
153
|
+
|
|
154
|
+
Do not restate the mitigation here. The abuse case, the required controls, and
|
|
155
|
+
the negative test for each of the four live in the `infrastructure` surface
|
|
156
|
+
class of [`threat-modeling`](../threat-modeling/SKILL.md)'s corpus, which is
|
|
157
|
+
their single authority. Ask that skill's grounded-corpus step for the
|
|
158
|
+
`infrastructure` surface class - it carries the invocation - describing the
|
|
159
|
+
change, e.g. *iam role with a wildcard action*.
|
|
160
|
+
|
|
161
|
+
Those rows carry a `Decided by:` clause naming the check that actually decides
|
|
162
|
+
each one. For the IAM, networking, storage, and encryption rows it reads NO
|
|
163
|
+
CHECK IN THIS REPOSITORY; only the credential-in-a-file row names a real gate.
|
|
164
|
+
Nothing here parses IAM policy documents or cloud config, so the discipline
|
|
165
|
+
above is the enforcement, and saying otherwise would claim coverage this
|
|
166
|
+
package does not have.
|
|
167
|
+
|
|
168
|
+
See also the `terraform` skill's *Permissive defaults and missing security
|
|
169
|
+
blocks* section for the backstop greps over a `.tf` tree.
|
|
170
|
+
|
|
130
171
|
## Output format
|
|
131
172
|
|
|
132
173
|
1. Modified infrastructure config/template files
|
|
@@ -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 used, what imports, change-impact) to
|
|
4
|
+
description: "Route codebase-structure questions (who calls X, where is this used, what imports, change-impact) to an existing code-graph first: cheaper, never more precise; grep stays routine. Also 'call graph'."
|
|
5
5
|
domain: engineering
|
|
6
6
|
workspaces:
|
|
7
7
|
- engineering
|
|
@@ -14,11 +14,14 @@ requires_skills:
|
|
|
14
14
|
# code-intelligence
|
|
15
15
|
|
|
16
16
|
> For a **structure** question — *who calls X*, *where is Y used*, *what
|
|
17
|
-
> imports Z*, *what breaks if I change this symbol* —
|
|
18
|
-
>
|
|
19
|
-
>
|
|
20
|
-
>
|
|
21
|
-
>
|
|
17
|
+
> imports Z*, *what breaks if I change this symbol* — ask an index that already
|
|
18
|
+
> exists before rebuilding the relationship by hand: it is already built, its
|
|
19
|
+
> answer is structured, and it costs a fraction of the tokens. It is **not** more
|
|
20
|
+
> precise than a blind `grep` — measured on this repository's own source, zero
|
|
21
|
+
> classes met the win bar (§ Measured twice) — so grep is the arm you fall back
|
|
22
|
+
> to routinely and **with a stated reason**, not grudgingly. This skill routes
|
|
23
|
+
> such questions to the native code-graph engine (ADR-124, Class A) or a
|
|
24
|
+
> consumer-shipped index first. It is the executable side of
|
|
22
25
|
> [`external-code-graph-interop`](../../rules/external-code-graph-interop.md):
|
|
23
26
|
> *orchestrator first, owner where it wins*.
|
|
24
27
|
|
|
@@ -50,9 +53,15 @@ code-graph and no appetite to build one — plain `grep`/read is right there.
|
|
|
50
53
|
- `agent-config code-graph path <a> <b>` — how two symbols connect.
|
|
51
54
|
- `agent-config code-graph explain <symbol>` — 2-hop neighbourhood.
|
|
52
55
|
Pass `--budget <tokens>` to cap output.
|
|
53
|
-
4. **Read the confidence.** `EXTRACTED` = syntactic fact
|
|
54
|
-
|
|
56
|
+
4. **Read the confidence.** `EXTRACTED` = syntactic fact — a symbol declared in
|
|
57
|
+
the file, or a name bound to the module specifier the file names; `INFERRED`
|
|
58
|
+
= resolved by hierarchy, or by a repo-wide same-name lookup with no binding
|
|
59
|
+
in the file to justify it; `AMBIGUOUS` = dynamic dispatch / facade, carries
|
|
55
60
|
candidates — treat its target as *one of* the candidates, never as certain.
|
|
61
|
+
Two target shapes are **not nodes** and resolve to nothing you can read:
|
|
62
|
+
`symbol:<name>` (a name this repository does not declare) and
|
|
63
|
+
`external:<module>` / `external:<module>#<name>` (a name imported from
|
|
64
|
+
outside the indexed root — `external:node:path`).
|
|
56
65
|
5. **Fall back honestly.** If the graph has no entry for the symbol, grep — and
|
|
57
66
|
say so: *"the graph has no entry for X, so I grepped."* If this command is
|
|
58
67
|
not available, grep and say so.
|
|
@@ -72,10 +81,22 @@ Every answer built with this skill MUST:
|
|
|
72
81
|
- **A stale graph lies confidently.** If `detect` reports the index is N commits
|
|
73
82
|
behind, rebuild (`agent-config code-graph build --update`) before trusting
|
|
74
83
|
relationship answers, or say the answer is from a stale index.
|
|
75
|
-
- **Dynamic dispatch is honestly ambiguous
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
by guessing.
|
|
84
|
+
- **Dynamic dispatch is honestly ambiguous — where there is anything to be
|
|
85
|
+
ambiguous ABOUT.** A `$obj->m()` whose name matches a method declared
|
|
86
|
+
somewhere in the repo is `AMBIGUOUS` and carries those candidates: the engine
|
|
87
|
+
being honest, not broken — do not "resolve" them yourself by guessing. A
|
|
88
|
+
dynamic call whose name matches **no** in-repo method (`xs.push()`,
|
|
89
|
+
`map.get()`) is not emitted at all, and the count is published as
|
|
90
|
+
`suppressed_edge_counts.dynamic_no_candidate`. It used to be 39 % of this
|
|
91
|
+
engine's own graph, pointing at `symbol:push`, which is not a node and which
|
|
92
|
+
no query verb could reach.
|
|
93
|
+
- **The AMBIGUOUS share is a property of the code, not a constant.** Measured
|
|
94
|
+
2026-09-04 over the three roots the v2 benchmark uses: `AMBIGUOUS` is 0 of 495
|
|
95
|
+
edges under the package's own graph-engine root, 0 of 181 under `src/shared`, and 121 of
|
|
96
|
+
4,002 (3.0 %) under its council root — class-free TypeScript has
|
|
97
|
+
almost no in-repo method to be ambiguous between. A Laravel codebase, where
|
|
98
|
+
facades and injected services dispatch onto real in-repo methods, is the
|
|
99
|
+
opposite case. Read the counts in the graph rather than a remembered ratio.
|
|
79
100
|
|
|
80
101
|
## Measured twice, and it has not won (v2, 2026-08-29)
|
|
81
102
|
|
|
@@ -113,6 +134,33 @@ engine on this repository's own code. The rule now gives the reasons that surviv
|
|
|
113
134
|
measurement — an index that exists is already built and structured, so it is the
|
|
114
135
|
cheap first question — and drops the precision claim its own benchmark refuted.
|
|
115
136
|
|
|
137
|
+
## Re-run after the extractor repair (2026-09-04) — still no class won
|
|
138
|
+
|
|
139
|
+
`internal/bench/reports/code-graph-vs-grep-inrepo-v2-rerun-2026-09-04.md`. The
|
|
140
|
+
SAME registration, the same corpus SHA, the same per-class bars and the same
|
|
141
|
+
arm-B verbs, re-run after the import-binding repair. The 2026-08-29 report is
|
|
142
|
+
untouched; this is a second report beside it, which is how v1 was handled too.
|
|
143
|
+
|
|
144
|
+
| Class | graph R then | graph R now | graph P then | graph P now | verdict then → now |
|
|
145
|
+
|---|---|---|---|---|---|
|
|
146
|
+
| `callers` | 1.000 | 1.000 | 0.667 | 0.667 | TIE → TIE |
|
|
147
|
+
| `transitive-impact` | 0.500 | **0.611** | 0.667 | **1.000** | **NULL → TIE** |
|
|
148
|
+
| `path-between` | 1.000 | 1.000 | 1.000 | 1.000 | TIE → TIE |
|
|
149
|
+
| `references` | 0.333 | **1.000** | 0.333 | **1.000** | **NULL → TIE** |
|
|
150
|
+
|
|
151
|
+
**Zero classes met the win bar, again.** Two NULLs became TIEs and nothing
|
|
152
|
+
regressed, so the routing verdict below is unchanged — a TIE is not a win, and
|
|
153
|
+
no bar was renegotiated after the repair.
|
|
154
|
+
|
|
155
|
+
Read with two caveats the report states in full. A measured root is live source:
|
|
156
|
+
`src/shared` is byte-identical between the runs, the council root moved
|
|
157
|
+
by 27 files on `main` in between, and the graph-engine root IS the engine, so
|
|
158
|
+
its content necessarily moves whenever the engine does — which is also why the
|
|
159
|
+
GREP arm's macro precision moved (0.806 → 0.764) in a run that changed nothing
|
|
160
|
+
about grep. Both classes that changed verdict did so on rows whose root did not
|
|
161
|
+
drift: `references` moved on the graph-engine and shared roots, `transitive-impact` on
|
|
162
|
+
`shared` alone.
|
|
163
|
+
|
|
116
164
|
**No class is graph-first.** Query the index first because an index that already
|
|
117
165
|
exists is cheap to ask and its answer is structured — not because it answers
|
|
118
166
|
better. When it returns nothing, that is the common case, and grep remains the
|
|
@@ -62,6 +62,33 @@ unknown to resolve), or when the user has already fixed the sequence.
|
|
|
62
62
|
A short ordered plan that leads with the load-bearing unknown + how it will be
|
|
63
63
|
proven, then the dependent steps. One recommendation, not a survey.
|
|
64
64
|
|
|
65
|
+
## The four plan criteria — what a reviewer fails the ordered plan on
|
|
66
|
+
|
|
67
|
+
Risk-first ordering is one of four things a plan is judged on. All four are
|
|
68
|
+
stated so a reviewer can **fail** a plan on them — each names what failing looks
|
|
69
|
+
like. This skill owns the third; the other three are stated here because a plan
|
|
70
|
+
reviewed on ordering alone passes while being unnecessary, insufficient, or
|
|
71
|
+
built on verbs that do not exist. The same four are carried in
|
|
72
|
+
`feature-planning` (pack `product-basic`), which is pruned under `projection.mode: scoped` and so is named rather than linked.
|
|
73
|
+
|
|
74
|
+
1. **Necessity** — every step traces to a stated problem or acceptance criterion.
|
|
75
|
+
**Fails when** the plan carries work nothing asked for — a spike for an
|
|
76
|
+
unknown that is not load-bearing is the version of this failure this skill
|
|
77
|
+
causes.
|
|
78
|
+
2. **Sufficiency** — every requirement is discharged by at least one step.
|
|
79
|
+
**Fails when** a requirement owns no step, or its only step has no verifiable
|
|
80
|
+
outcome. Walk the requirements, not the steps.
|
|
81
|
+
3. **Ordering** — the load-bearing unknown is resolved before anything that
|
|
82
|
+
assumes it, and no step consumes what a later step creates. **Fails when** the
|
|
83
|
+
plan front-loads the easy parts, or ranks by effort instead of dependency
|
|
84
|
+
blast radius (see Gotchas). This is the criterion this skill exists for.
|
|
85
|
+
4. **Groundedness** — every command, skill and tool the plan tells someone to run
|
|
86
|
+
exists. **Fails when** the plan names a verb that is not in the index. Check
|
|
87
|
+
it against [`CAPABILITIES.yaml`](../../../CAPABILITIES.yaml) at the repository
|
|
88
|
+
root — the generated capability index of every shipped skill and command —
|
|
89
|
+
plus the project's own script/task entry points. It is the only one of the
|
|
90
|
+
four decidable without judgement, so it is never waved through.
|
|
91
|
+
|
|
65
92
|
## Do NOT
|
|
66
93
|
|
|
67
94
|
- Build the easy parts first to show progress, then discover the hard part breaks them.
|