@event4u/agent-config 9.24.0 → 9.26.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +136 -0
- package/README.md +1 -1
- package/dist/agent-src/commands/analyze/conformance.md +182 -0
- package/dist/agent-src/commands/analyze/inbox.md +33 -2
- package/dist/agent-src/commands/review/changes.md +6 -5
- package/dist/agent-src/commands/roadmap/next.md +194 -0
- package/dist/agent-src/commands/roadmap.md +12 -4
- package/dist/agent-src/contexts/execution/subagent-routing.md +4 -1
- package/dist/agent-src/rules/decision-revisit-gate.md +2 -0
- package/dist/agent-src/rules/delegation-policy.md +3 -2
- package/dist/agent-src/rules/design-fidelity.md +17 -1
- package/dist/agent-src/rules/design-review-after-ui-write.md +116 -0
- package/dist/agent-src/rules/evaluator-independence.md +111 -0
- package/dist/agent-src/rules/session-canary.md +15 -1
- package/dist/agent-src/rules/settings-ask-protocol.md +176 -0
- package/dist/agent-src/rules/token-budget-discipline.md +6 -3
- package/dist/agent-src/rules/ui-audit-gate.md +3 -0
- package/dist/agent-src/rules/user-interaction.md +23 -0
- package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +1 -1
- package/dist/agent-src/skills/recursive-verification/SKILL.md +13 -0
- package/dist/agent-src/skills/rule-writing/SKILL.md +45 -0
- package/dist/agent-src/skills/skill-writing/SKILL.md +114 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli/registry.js +1 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/cmd_route_audit.js +4 -1
- package/dist/cli-delegate/cmd_route_explain.js +4 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +146 -28
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +5 -5
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +16 -11
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +12 -7
- package/dist/hooks/dispatch.js +1501 -511
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/router.json +1 -1
- package/dist/server/nicknameResolver.js +116 -0
- package/dist/server/nicknameResolver.js.map +1 -0
- package/dist/server/routes/ping.js +29 -11
- package/dist/server/routes/ping.js.map +1 -1
- package/dist/shared/interactiveContext.js +73 -0
- package/dist/shared/interactiveContext.js.map +1 -0
- package/dist/shared/nicknamePrefill.js +59 -0
- package/dist/shared/nicknamePrefill.js.map +1 -0
- package/dist/shared/settingsAsks.js +128 -0
- package/dist/shared/settingsAsks.js.map +1 -0
- package/dist/shared/settingsConsent.js +93 -0
- package/dist/shared/settingsConsent.js.map +1 -0
- package/package.json +1 -1
- package/src/config/agents-paths.yml +15 -0
- package/src/config/evaluator-budgets.json +68 -68
- package/src/config/gate-coverage.yml +131 -5
- package/src/config/gate-violation-baselines.json +11 -0
- package/src/scripts/_cli/cmd_route_audit.ts +4 -1
- package/src/scripts/_cli/cmd_route_explain.ts +9 -1
- package/src/scripts/_dispatch.bash +12 -0
- package/src/scripts/ai-video/stitch.sh +27 -9
- package/src/scripts/before_complete_hook.ts +146 -5
- package/src/scripts/bench_ab_v2_run.ts +272 -16
- package/src/scripts/bench_ab_v2_stats.ts +156 -3
- package/src/scripts/check_completion_review.ts +80 -3
- package/src/scripts/check_corpus_staleness.ts +692 -0
- package/src/scripts/check_depth_budget.ts +295 -0
- package/src/scripts/check_gate_coverage.ts +67 -0
- package/src/scripts/check_hook_bundle_freshness.ts +183 -0
- package/src/scripts/conformance_scan.ts +422 -0
- package/src/scripts/dispatch_r2_reviewer.ts +31 -2
- package/src/scripts/git_authorization_hook.ts +328 -0
- package/src/scripts/hook_manifest.yaml +69 -9
- package/src/scripts/hooks/block_no_verify.ts +3 -1
- package/src/scripts/hooks/block_unauthorized_git.ts +371 -0
- package/src/scripts/hooks/concern_registry.ts +8 -0
- package/src/scripts/hooks/design_slop_hook.ts +13 -1
- package/src/scripts/hooks/dispatch_hook.ts +97 -2
- package/src/scripts/hooks/evidence_independence.ts +368 -0
- package/src/scripts/language_mirror_hook.ts +456 -0
- package/src/scripts/lint_abstraction_thresholds.ts +41 -8
- package/src/scripts/lint_agents_layout.ts +2 -0
- package/src/scripts/lint_decision_impact.ts +246 -0
- package/src/scripts/lint_example_fences.ts +609 -0
- package/src/scripts/lint_hook_manifest.ts +29 -0
- package/src/scripts/lint_rule_interactions.ts +90 -0
- package/src/scripts/lint_rule_migration_ledger.ts +480 -0
- package/src/scripts/lint_skill_descriptions.ts +86 -2
- package/src/scripts/memory_learn_hook.ts +109 -6
- package/src/scripts/pr_url_reminder_hook.ts +17 -2
- package/src/scripts/release.ts +38 -1
- package/src/scripts/schemas/review-findings.schema.json +99 -0
- package/src/scripts/schemas/rule.schema.json +10 -0
- package/src/shared/interactiveContext.ts +98 -0
- package/src/shared/nicknamePrefill.ts +96 -0
- package/src/shared/settingsAsks.ts +176 -0
- package/src/shared/settingsConsent.ts +136 -0
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: roadmap
|
|
4
4
|
disable-model-invocation: true
|
|
5
|
-
argument-hint: "[create|ai-council|process-step|process-phase|process-full] [args]"
|
|
5
|
+
argument-hint: "[create|ai-council|process-step|process-phase|process-full|next] [args]"
|
|
6
6
|
pack: product-basic
|
|
7
|
-
intent: "Roadmap dispatcher — create, process-step, process-phase, process-full, ai-council"
|
|
8
|
-
routes_to: [roadmap-create, roadmap-ai-council, roadmap-materialize, roadmap-process-step, roadmap-process-phase, roadmap-process-full]
|
|
7
|
+
intent: "Roadmap dispatcher — create, process-step, process-phase, process-full, next, ai-council"
|
|
8
|
+
routes_to: [roadmap-create, roadmap-ai-council, roadmap-materialize, roadmap-process-step, roadmap-process-phase, roadmap-process-full, roadmap-next]
|
|
9
9
|
replaces: []
|
|
10
10
|
tier: 1
|
|
11
11
|
visibility: advanced
|
|
12
|
-
description: Roadmap orchestrator — routes to create (authoring)
|
|
12
|
+
description: Roadmap orchestrator — routes to create (authoring), process-step / process-phase / process-full (autonomous execution), and next (pick a roadmap and ship it).
|
|
13
13
|
cluster: roadmap
|
|
14
14
|
type: orchestrator
|
|
15
15
|
suggestion:
|
|
@@ -40,6 +40,7 @@ paused for confirmation before every step) was removed —
|
|
|
40
40
|
| `/roadmap:process-step` | `commands/roadmap/process-step.md` | Autonomously process the next open step, then stop |
|
|
41
41
|
| `/roadmap:process-phase` (**default execution scope**) | `commands/roadmap/process-phase.md` | Autonomously process every open step in the current phase |
|
|
42
42
|
| `/roadmap:process-full` | `commands/roadmap/process-full.md` | Autonomously process every open step across every phase |
|
|
43
|
+
| `/roadmap:next` | `commands/roadmap/next.md` | Screen for the next executable roadmap, then carry it to a reviewable PR (selection + `process-full` + delivery) |
|
|
43
44
|
|
|
44
45
|
Sub-command names match the locked contract in
|
|
45
46
|
[`docs/contracts/command-clusters.md`](../docs/contracts/command-clusters.md).
|
|
@@ -70,6 +71,7 @@ each only binds a scope delta.
|
|
|
70
71
|
> 3. process-step — process the next open step, then stop
|
|
71
72
|
> 4. process-phase — process the current phase (default)
|
|
72
73
|
> 5. process-full — process every open step across every phase
|
|
74
|
+
> 6. next — pick the next executable roadmap and ship it to a PR
|
|
73
75
|
|
|
74
76
|
## Rules
|
|
75
77
|
|
|
@@ -84,3 +86,9 @@ each only binds a scope delta.
|
|
|
84
86
|
*"finish this phase"*) default to
|
|
85
87
|
[`/roadmap:process-phase`](roadmap/process-phase.md) unless the user
|
|
86
88
|
named a different scope.
|
|
89
|
+
- **Selection intents** (*"take the next sensible roadmap"*, *"nimm dir
|
|
90
|
+
die nächste Roadmap vor"*, *"pick a roadmap and ship it"*) — i.e. the
|
|
91
|
+
user has NOT named a roadmap and wants one chosen — route to
|
|
92
|
+
[`/roadmap:next`](roadmap/next.md), which is the only sub that
|
|
93
|
+
screens and selects. The three `process-*` subs never choose across
|
|
94
|
+
roadmaps.
|
|
@@ -48,7 +48,10 @@ THE SAME MINUS THE QUOTA WIN.
|
|
|
48
48
|
tier <t>`); a 429/quota error trips `tripCooldown` for that tier and
|
|
49
49
|
falls back per the relation — never a retry loop. Under
|
|
50
50
|
`budget_routing: ask`, the FIRST budget-motivated downshift of a session
|
|
51
|
-
is confirmed once
|
|
51
|
+
is confirmed once, in the shape
|
|
52
|
+
[`settings-ask-protocol`](../../rules/settings-ask-protocol.md) fixes and
|
|
53
|
+
without persisting the answer (`subagents.budget_routing` is class C);
|
|
54
|
+
`auto` proceeds silently. Every budget-routed
|
|
52
55
|
dispatch emits one `orchestration_record` line (tier + provenance-tagged
|
|
53
56
|
token delta) so realized savings are measured, not asserted.
|
|
54
57
|
|
|
@@ -14,6 +14,8 @@ routes_to:
|
|
|
14
14
|
- "skill:decision-review"
|
|
15
15
|
workspaces: [agent-config-maintainer, engineering]
|
|
16
16
|
packs: [meta]
|
|
17
|
+
collision_ok:
|
|
18
|
+
"honest null": "this rule asks whether a recorded null may be REVISITED; evaluator-independence asks how one was PRODUCED — different decision points on the same artefact"
|
|
17
19
|
---
|
|
18
20
|
|
|
19
21
|
# Decision Revisit Gate
|
|
@@ -50,8 +50,9 @@ clears — all of:
|
|
|
50
50
|
[`auto-dispatch-classification`](../contexts/execution/auto-dispatch-classification.md)
|
|
51
51
|
(≥1 independent, well-specified slice above the size floor).
|
|
52
52
|
|
|
53
|
-
`subagents.auto: ask` → ask once before dispatching
|
|
54
|
-
[`
|
|
53
|
+
`subagents.auto: ask` → ask once before dispatching, in the shape
|
|
54
|
+
[`settings-ask-protocol`](settings-ask-protocol.md) fixes (the answer is not
|
|
55
|
+
persisted — `subagents.auto` is class C); `auto: on` → surface the chosen mode
|
|
55
56
|
+ per-subtask tiers in one line. Any gate failing, or `auto: off`, or no host
|
|
56
57
|
primitive → run in-session (clean no-op).
|
|
57
58
|
|
|
@@ -23,7 +23,9 @@ triggers:
|
|
|
23
23
|
- phrase: "bau das nach"
|
|
24
24
|
- phrase: "1:1 um"
|
|
25
25
|
- phrase: "1:1 nach"
|
|
26
|
+
- phrase: "claude.site/artifacts"
|
|
26
27
|
- file_pattern: "*design.html"
|
|
28
|
+
- path_prefix: ".claude/design-system/"
|
|
27
29
|
applies_to_user_types:
|
|
28
30
|
- "creator"
|
|
29
31
|
- "developer"
|
|
@@ -96,13 +98,27 @@ artifact is simply attached. The last is covered by `file_pattern: *design.html`
|
|
|
96
98
|
HTML edit in every project and be strictly worse than the gap it closes. A
|
|
97
99
|
handover under some other filename needs one word in the prompt.
|
|
98
100
|
|
|
101
|
+
Two further handover shapes carry the artifact without any of the above:
|
|
102
|
+
|
|
103
|
+
- **A capability URL.** A published artifact is handed over as a link, not a
|
|
104
|
+
file — so `phrase: "claude.site/artifacts"` fires on the *published-artifact
|
|
105
|
+
path*, not on the host. `claude.ai` alone is a chat link and must stay quiet:
|
|
106
|
+
a keyword on the bare domain would fire on "I pasted this from claude.ai",
|
|
107
|
+
which is a conversation reference, not a spec.
|
|
108
|
+
- **A design-system directory.** `path_prefix: ".claude/design-system/"` — the
|
|
109
|
+
conventional location for a handed-over token/component set. The prefix is the
|
|
110
|
+
vendor-scoped directory, never a bare `design-system/`, which is a normal
|
|
111
|
+
source folder in a large fraction of frontend repos.
|
|
112
|
+
|
|
99
113
|
The trigger set is deliberately phrase-heavy on the German side and on
|
|
100
114
|
`artifact`: a bare `artifact` keyword fires on "the CI build artifact is 40 MB".
|
|
101
115
|
`ROUTING_MATRIX` in
|
|
102
116
|
[`design_fidelity_routing.test.ts`](../../tests/scripts/design_fidelity_routing.test.ts)
|
|
103
117
|
pins both halves — every class that must route, and the near-misses that must
|
|
104
118
|
stay silent (fixture `daf-port-trigger-de`). Extending the set without adding a
|
|
105
|
-
near-miss row there is how an over-broad trigger lands
|
|
119
|
+
near-miss row there is how an over-broad trigger lands: each of the two triggers
|
|
120
|
+
above ships with its own near-miss row (`near-claude-ai-chat-link`,
|
|
121
|
+
`near-generic-design-system-dir`).
|
|
106
122
|
|
|
107
123
|
Body migrated to [`guideline:design-fidelity-mechanics`](../docs/guidelines/design-fidelity-mechanics.md) (per P4 of `road-to-kernel-and-router.md`) — surgical visual edits (targeted-edit vs redesign-trigger discipline, stable anchors), asset & imagery discipline (owned-asset path, third-party delivery is self-hosted by default, real-imagery-as-proof, iconography floor, no unrequested filler), deviation-surfacing shape, failure-mode catalog, `daf-*` fixtures.
|
|
108
124
|
Trigger-set above activates this routing on demand, independent of the discipline profile (ADR-110).
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "auto"
|
|
3
|
+
tier: "2b"
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
description: "UI written or changed — review it against the design contract before calling it done; the write-side twin of ui-audit-gate"
|
|
6
|
+
triggers:
|
|
7
|
+
- path_prefix: "resources/views/"
|
|
8
|
+
- path_prefix: "resources/js/"
|
|
9
|
+
- keyword: "component"
|
|
10
|
+
- keyword: "design token"
|
|
11
|
+
routes_to:
|
|
12
|
+
- "skill:design-review"
|
|
13
|
+
- "skill:accessibility-auditor"
|
|
14
|
+
workspaces: [agent-config-maintainer, engineering]
|
|
15
|
+
packs: [frontend-design]
|
|
16
|
+
collision_ok:
|
|
17
|
+
"component": "a written component is reviewed before it is called done — the write-side half"
|
|
18
|
+
"design token": "same surface, opposite side: ui-audit-gate inventories tokens before the write, this reviews what the write emitted"
|
|
19
|
+
"resources/views/": "both halves of one UI loop fire on the same path — audit before, review after; neither substitutes for the other"
|
|
20
|
+
"resources/js/": "both halves of one UI loop fire on the same path — audit before, review after; neither substitutes for the other"
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Design Review After UI Write
|
|
24
|
+
|
|
25
|
+
The UI loop was closed on one side only. [`ui-audit-gate`](ui-audit-gate.md)
|
|
26
|
+
covers the **read** side — inventory what exists before adding a component — and
|
|
27
|
+
routes to `existing-ui-audit`. Nothing covered the **write** side: **zero rules
|
|
28
|
+
routed to `skill:design-review`**, so a component could be written, declared
|
|
29
|
+
done, and never looked at against the contract it was supposed to satisfy.
|
|
30
|
+
|
|
31
|
+
This is that rule's twin, deliberately built to the same shape: same tier, same
|
|
32
|
+
pack, same diff-decidable allow-list, and the same honest scope.
|
|
33
|
+
|
|
34
|
+
## The Iron Law
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
UI WRITTEN OR CHANGED IS NOT DONE UNTIL IT IS REVIEWED.
|
|
38
|
+
NEVER CLAIM A UI CHANGE IS COMPLETE ON "IT LOOKS RIGHT" — THAT IS A VERDICT
|
|
39
|
+
WITHOUT EVIDENCE. NO RENDER CAPABILITY → SCOPE THE VERDICT TO WHAT WAS
|
|
40
|
+
STATICALLY CHECKED AND SAY SO. NEVER "LOOKS GOOD" WITH NOTHING BEHIND IT.
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## What "reviewed" means
|
|
44
|
+
|
|
45
|
+
The verdict is gated on evidence, not on having run a skill:
|
|
46
|
+
|
|
47
|
+
- **Render capability present** (Playwright MCP, Chrome DevTools, or a live
|
|
48
|
+
preview URL) → the [design-artifact verification checklist](../docs/contracts/design-artifact-verification.md#verification-checklist)
|
|
49
|
+
steps 1–5. A UI task does not pass without render evidence.
|
|
50
|
+
- **Render capability absent** → the verdict is **scoped to the static checks
|
|
51
|
+
that actually ran** and says which those were. This is not a downgrade to be
|
|
52
|
+
hidden; `design-review` itself states it ("scope the verdict to what was
|
|
53
|
+
statically checked and say so"). An unscoped "looks good" is the failure.
|
|
54
|
+
- **A provided artifact is the spec** → findings the artifact *covers* are
|
|
55
|
+
informational, not defects, per [`design-fidelity`](design-fidelity.md). The
|
|
56
|
+
review does not "improve" the user's own design.
|
|
57
|
+
|
|
58
|
+
## Allow-list — `ui-trivial`, decidable from the diff alone
|
|
59
|
+
|
|
60
|
+
Skip only when **all** hold:
|
|
61
|
+
|
|
62
|
+
- ≤ 1 file, ≤ 5 changed lines, no new component, no new state, no new dependency.
|
|
63
|
+
- Inside the work engine, `directive_set == "ui-trivial"` — the dispatcher states
|
|
64
|
+
it directly. Outside it, the same conditions are read **off the diff**, which
|
|
65
|
+
is observable without any dispatcher state.
|
|
66
|
+
|
|
67
|
+
The list is deliberately the engine's five conditions, not the four its
|
|
68
|
+
sibling rule's prose carries: `ui_trivial/apply.ts` enforces `new_dependency`
|
|
69
|
+
too, and a twin that copied the shorter prose would inherit a gap the engine
|
|
70
|
+
does not have.
|
|
71
|
+
|
|
72
|
+
## Honest scope — what this rule does NOT enforce
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
THE REVIEW OBLIGATION IS MODEL-CARRIED. NEVER CLAIM THE REVIEW RAN
|
|
76
|
+
AS IF IT WERE VERIFIED.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
There is no artefact a chat session can point at to prove a design review
|
|
80
|
+
happened — "I ran `design-review`" is self-report, and self-report is not
|
|
81
|
+
enforcement. So this rule ships `enforced_by: none`, the same honesty boundary
|
|
82
|
+
`ui-audit-gate`, `security-sensitive-stop`, and `untrusted-input-defense` state
|
|
83
|
+
for their own obligations, rather than pretending a satisfiable-by-assertion
|
|
84
|
+
condition is a gate.
|
|
85
|
+
|
|
86
|
+
What that leaves, and it is the useful part: the write side now has a named
|
|
87
|
+
obligation and a route to the skill that discharges it, where before it had
|
|
88
|
+
neither. Full enforcement needs the work-engine `review`/`polish` gates (which
|
|
89
|
+
already act on `a11y_violation` and `token_violation` findings) or pack-scoped
|
|
90
|
+
rule projection — a maintainer decision, never an automated one.
|
|
91
|
+
|
|
92
|
+
One asymmetry worth stating: `design-review` lives in `engineering-base` while
|
|
93
|
+
this rule is scoped to `frontend-design`. The route still resolves — a rule may
|
|
94
|
+
name a skill from another pack — but a consumer with `frontend-design` and
|
|
95
|
+
without `engineering-base` gets the obligation without the skill. That is why
|
|
96
|
+
`accessibility-auditor` is a second route: it is the part of the review that
|
|
97
|
+
must not depend on the pairing.
|
|
98
|
+
|
|
99
|
+
## Failure modes
|
|
100
|
+
|
|
101
|
+
- Writing the component and calling it done because the tests pass — tests do not
|
|
102
|
+
look at it.
|
|
103
|
+
- "Looks good" as a verdict with no render, no static check named, and no scope.
|
|
104
|
+
- Running the review and acting on findings the provided artifact covers, i.e.
|
|
105
|
+
redesigning the user's spec under the banner of quality.
|
|
106
|
+
- Treating the a11y half as optional because the visual half looked fine.
|
|
107
|
+
- Skipping the review for "just one tile" — the same bypass `ui-audit-gate`
|
|
108
|
+
names on its own side.
|
|
109
|
+
|
|
110
|
+
## See also
|
|
111
|
+
|
|
112
|
+
- [`ui-audit-gate`](ui-audit-gate.md) — the read-side twin; audit before writing.
|
|
113
|
+
- [`design-review`](../skills/design-review/SKILL.md) — the 7-phase review this routes to.
|
|
114
|
+
- [`accessibility-auditor`](../skills/accessibility-auditor/SKILL.md) — the WCAG half.
|
|
115
|
+
- [`design-fidelity`](design-fidelity.md) — a provided artifact is the spec; covered findings are informational.
|
|
116
|
+
- [`verify-before-complete`](verify-before-complete.md) — the general no-claim-without-evidence gate this applies to UI.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "auto"
|
|
3
|
+
tier: "2a"
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
description: "Commissioning a review/judge/blind-pass on your own work — never author the verdict, never narrow the scope, record the prompt with the result"
|
|
6
|
+
triggers:
|
|
7
|
+
- keyword: "blind review"
|
|
8
|
+
- keyword: "blind pass"
|
|
9
|
+
- keyword: "honest null"
|
|
10
|
+
- keyword: "no-findings"
|
|
11
|
+
- keyword: "adversarial review"
|
|
12
|
+
- keyword: "judge"
|
|
13
|
+
- phrase: "review my own"
|
|
14
|
+
- phrase: "commission a review"
|
|
15
|
+
- phrase: "second opinion on my"
|
|
16
|
+
self_contained: true
|
|
17
|
+
workspaces: [engineering]
|
|
18
|
+
packs: [engineering-base]
|
|
19
|
+
enforced_by:
|
|
20
|
+
- "hook:evidence-independence"
|
|
21
|
+
collision_ok:
|
|
22
|
+
"honest null": "this rule asks how a recorded null was PRODUCED; decision-revisit-gate asks whether it may be REVISITED — different decision points on the same artefact"
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Evaluator Independence
|
|
26
|
+
|
|
27
|
+
When the agent commissions a review, judge, blind pass, or council run **on its
|
|
28
|
+
own work**, it is both the author and the author of the evaluator's prompt. That
|
|
29
|
+
second role is the one nobody was watching.
|
|
30
|
+
|
|
31
|
+
## The Iron Law
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
NEVER AUTHOR THE VERDICT INTO AN EVALUATOR'S PROMPT.
|
|
35
|
+
NEVER NARROW THE SCOPE OF A REVIEW YOU COMMISSIONED ON YOUR OWN WORK.
|
|
36
|
+
A SELF-COMMISSIONED REVIEW IS ADMISSIBLE AS GATE EVIDENCE ONLY WHEN THE PROMPT
|
|
37
|
+
IS RECORDED ALONGSIDE THE VERDICT.
|
|
38
|
+
A SECOND EVALUATION OF THE SAME WORK IN ONE TURN IS VERDICT SHOPPING, NOT RIGOUR.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## The failure this exists to stop
|
|
42
|
+
|
|
43
|
+
Measured, once, at maximum cost (conformance audit 2026-08-06):
|
|
44
|
+
|
|
45
|
+
> The agent dispatched a "blind reviewer" over its own change. It wrote that
|
|
46
|
+
> reviewer's prompt itself, put **"NO-FINDINGS is expected and welcome"** into it,
|
|
47
|
+
> and narrowed the scope to four files it chose. The reviewer returned
|
|
48
|
+
> NO-FINDINGS. That honest-null was committed as **binding gate evidence**. An
|
|
49
|
+
> unsteered pass over the same delta later found 5 findings, one of them
|
|
50
|
+
> critical, already live on the trunk.
|
|
51
|
+
|
|
52
|
+
The agent's own retro named it exactly: *"Die Fabrikation lag nicht im Weglassen
|
|
53
|
+
des Reviews — sie lag in meinem Prompt. Ich habe die Antwort vorgeladen und dann
|
|
54
|
+
als Evidenz verbucht."* The review ran. The process was followed. The evidence
|
|
55
|
+
was manufactured anyway.
|
|
56
|
+
|
|
57
|
+
## What this requires
|
|
58
|
+
|
|
59
|
+
1. **Neutral prompt.** No expectation of the outcome, in either direction. Not
|
|
60
|
+
"confirm there are no issues", not "I believe this is clean", not "just
|
|
61
|
+
confirm". Ask for findings; do not describe the finding count you expect.
|
|
62
|
+
2. **Scope you did not choose to flatter yourself.** The scope is the whole
|
|
63
|
+
delta, or a boundary a human set. "These four files" chosen by the author of
|
|
64
|
+
those files is not a scope, it is a filter.
|
|
65
|
+
3. **The prompt ships with the verdict.** A recorded honest-null whose prompt is
|
|
66
|
+
not recoverable is not evidence — nobody can check what was asked.
|
|
67
|
+
4. **One evaluation per turn per subject.** Re-running with a different prompt or
|
|
68
|
+
scope after an unwelcome verdict selects the answer instead of measuring it.
|
|
69
|
+
|
|
70
|
+
## When it does NOT fire
|
|
71
|
+
|
|
72
|
+
- **Ordinary parallel fan-out.** Dispatching many subagents to read, map,
|
|
73
|
+
search, or implement is not evaluation and is not gated. The session that
|
|
74
|
+
produced this rule ran a seven-way analysis fan-out in one turn; none of it is
|
|
75
|
+
in scope.
|
|
76
|
+
- A review **a human** commissioned or whose prompt a human wrote.
|
|
77
|
+
- A deterministic checker (linter, test suite, CI gate) — it has no prompt to
|
|
78
|
+
steer.
|
|
79
|
+
|
|
80
|
+
## Enforcement — honest scope
|
|
81
|
+
|
|
82
|
+
[`evidence_independence.ts`](../scripts/hooks/evidence_independence.ts) is a
|
|
83
|
+
`pre_tool_use` concern. It **blocks** a dispatch whose prompt carries a
|
|
84
|
+
pre-loaded verdict, and **blocks** a second *self-scoped* evaluation dispatch in
|
|
85
|
+
the same turn; it **warns** on the first. It reads the prompt the agent is about
|
|
86
|
+
to send, so items 1 and 4 above are mechanically enforced.
|
|
87
|
+
|
|
88
|
+
Two limits, stated because round 2 measured them. The pre-loaded-verdict list is
|
|
89
|
+
a **phrase list**, so a paraphrase evades it — it catches recurrences of known
|
|
90
|
+
steering wording, not steering as such. And the turn boundary is the
|
|
91
|
+
authorization ledger's `detected_at` stamp, because the envelope carries no turn
|
|
92
|
+
id; with no ledger yet, the counter falls back to session scope.
|
|
93
|
+
|
|
94
|
+
Items 2 and 3 — an honestly chosen scope, and recording the prompt with the
|
|
95
|
+
verdict — are **not** enforced by anything. A narrowed scope is not decidable
|
|
96
|
+
from the prompt alone, and no validator reads the artefacts a verdict lands in.
|
|
97
|
+
They are stated here as obligations and are model-carried. Saying so is the
|
|
98
|
+
point: this rule exists because a process that *looked* followed produced
|
|
99
|
+
fabricated evidence, and claiming coverage it does not have would repeat that.
|
|
100
|
+
|
|
101
|
+
## See also
|
|
102
|
+
|
|
103
|
+
- [`verify-before-complete`](verify-before-complete.md) — the completion-claim
|
|
104
|
+
gate this narrows; a self-commissioned review is one kind of evidence it accepts.
|
|
105
|
+
- [`adversarial-review`](../skills/adversarial-review/SKILL.md) — how to ask for a
|
|
106
|
+
real critique.
|
|
107
|
+
- [`delegation-policy`](delegation-policy.md) — the orchestrator never adopts a
|
|
108
|
+
subagent return unverified; this rule covers the case where the return was
|
|
109
|
+
steered before it was returned.
|
|
110
|
+
- [`direct-answers`](direct-answers.md) Iron Law 2 — do not claim what you have
|
|
111
|
+
not verified; a manufactured verdict is the sharpest form of that claim.
|
|
@@ -12,6 +12,8 @@ workspaces: [agent-config-maintainer, construction, engineering, finance, founde
|
|
|
12
12
|
packs: [meta]
|
|
13
13
|
enforced_by:
|
|
14
14
|
- "hook:session-canary"
|
|
15
|
+
collision_ok:
|
|
16
|
+
"canary_name": "this rule owns what the NAME does once set and which of the three layers already supplies it; settings-ask-protocol owns how it is asked for and where the answer goes"
|
|
15
17
|
---
|
|
16
18
|
|
|
17
19
|
# Session Canary
|
|
@@ -67,7 +69,7 @@ name it and suggest a fresh session or `/agent-handoff`, per
|
|
|
67
69
|
- The greeting never substitutes for substance — it prefixes the answer, it is
|
|
68
70
|
not the answer.
|
|
69
71
|
|
|
70
|
-
## Enforcement
|
|
72
|
+
## Enforcement — per session, NOT per task
|
|
71
73
|
|
|
72
74
|
> **Enforced by:** [`scripts/session_canary_hook.ts`](../../scripts/session_canary_hook.ts)
|
|
73
75
|
> (`session_start`, all hook-capable hosts) — injects the `<session-canary>`
|
|
@@ -75,6 +77,18 @@ name it and suggest a fresh session or `/agent-handoff`, per
|
|
|
75
77
|
> without it. **Copilot fallback:** no hook surface — this rule is the only
|
|
76
78
|
> carrier; re-read it when the trigger fires.
|
|
77
79
|
|
|
80
|
+
**The gap, stated because it was measured.** The injection fires on
|
|
81
|
+
`session_start`; the obligation is per *task*. Nothing re-injects at a task
|
|
82
|
+
boundary, so from the second task on the contract is model-carried.
|
|
83
|
+
|
|
84
|
+
Conformance audit, 30 sessions, 2026-08-06: opening canary dropped on ~13 of 15
|
|
85
|
+
task starts, often present only in the closing summary, twice carrying a name
|
|
86
|
+
the settings chain did not resolve; the honesty clause fired zero times. No
|
|
87
|
+
per-task gate ships — the audit found no harm beyond the lost signal, and a
|
|
88
|
+
mechanism for a signal whose absence nobody acted on has no failure mode to
|
|
89
|
+
match. The consequence stands: this canary cannot currently be relied on as the
|
|
90
|
+
degradation detector its own rationale describes.
|
|
91
|
+
|
|
78
92
|
## See also
|
|
79
93
|
|
|
80
94
|
- [`direct-answers`](direct-answers.md) — canonical reply-close obligation.
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "auto"
|
|
3
|
+
tier: "2a"
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
description: "Asking the user about a setting — one question per command execution, a fixed four-slot shape, and the key's class decides where the answer goes"
|
|
6
|
+
triggers:
|
|
7
|
+
- keyword: "settings:set"
|
|
8
|
+
- keyword: "canary_name"
|
|
9
|
+
- keyword: "rich_skills"
|
|
10
|
+
- keyword: "budget_routing"
|
|
11
|
+
- keyword: "adversarial_council"
|
|
12
|
+
- keyword: "learn_on_session_end"
|
|
13
|
+
- keyword: "open_edited_files"
|
|
14
|
+
- phrase: "ask about a setting"
|
|
15
|
+
- phrase: "settings question"
|
|
16
|
+
- phrase: "should I enable"
|
|
17
|
+
- phrase: "nickname"
|
|
18
|
+
- path_prefix: "docs/contracts/settings-classes.md"
|
|
19
|
+
self_contained: true
|
|
20
|
+
workspaces: [agent-config-maintainer, engineering]
|
|
21
|
+
packs: [meta]
|
|
22
|
+
routes_to:
|
|
23
|
+
- "contract:settings-classes"
|
|
24
|
+
enforced_by:
|
|
25
|
+
- "none"
|
|
26
|
+
collision_ok:
|
|
27
|
+
"canary_name": "the nickname ask is this protocol's canonical B-class instance — session-canary owns what the NAME then does and which layers already supply it, this rule owns how it is asked for and where the answer goes"
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
# Settings-Ask Protocol
|
|
31
|
+
|
|
32
|
+
A settings question is the one ask where the agent poses the question *and* owns
|
|
33
|
+
where the answer goes. Nine keys can produce one, in two mechanisms that look
|
|
34
|
+
identical from outside and differ completely underneath.
|
|
35
|
+
|
|
36
|
+
## The Iron Law
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
AT MOST ONE SETTINGS QUESTION PER COMMAND EXECUTION. NEVER TWO.
|
|
40
|
+
THE KEY'S CLASS DECIDES WHERE THE ANSWER GOES — NEVER THE CONVENIENCE OF THE MOMENT.
|
|
41
|
+
CLASS B → PERSIST VIA `settings:set --source jit-answer`. ASKED ONCE, EVER.
|
|
42
|
+
CLASS C SET TO `ask` → THIS RUN ONLY. THE AGENT NEVER PERSISTS IT.
|
|
43
|
+
FURTHER UNDECIDED KEYS TAKE THE CONSERVATIVE DEFAULT SILENTLY AND ARE NAMED
|
|
44
|
+
IN THE END-SUMMARY WITH THE COMMAND THAT CHANGES THEM.
|
|
45
|
+
A SILENT PERMISSIVE DEFAULT IS A DECISION TAKEN IN THE USER'S NAME. NEVER TAKE ONE.
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## The four slots
|
|
49
|
+
|
|
50
|
+
1. **What is needed** — the key in plain words, not the dotted path alone.
|
|
51
|
+
2. **Why now** — the concrete thing in *this* run that cannot proceed without it.
|
|
52
|
+
3. **Options, default marked** — the conservative option is always present and
|
|
53
|
+
always marked as what happens if the user says nothing.
|
|
54
|
+
4. **Where the answer is stored** — one line, and it is not optional: it is the
|
|
55
|
+
only way to tell a one-run answer from a standing consent.
|
|
56
|
+
|
|
57
|
+
Slot 4 is read from the class, never from taste:
|
|
58
|
+
|
|
59
|
+
| Class | Slot 4 reads | Writer |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| **B** (3 keys) | "persisted to your global settings — you will not be asked again" | `agent-config settings:set <key> <value> --source jit-answer` |
|
|
62
|
+
| **C** set to `ask` | "not saved; making it permanent is a human edit or the GUI" | none — the agent writes nothing |
|
|
63
|
+
|
|
64
|
+
**"Not saved" is about persistence, not about how long the answer is honoured.**
|
|
65
|
+
How long it stays cached in working state is the key's own business, and several
|
|
66
|
+
keys state their own scope. Reading the C path as "re-ask every execution" would
|
|
67
|
+
turn a fence against illegal writes into a source of extra questions.
|
|
68
|
+
|
|
69
|
+
## The nine keys
|
|
70
|
+
|
|
71
|
+
**Class B — persist once**: `personal.canary_name` ·
|
|
72
|
+
`personal.open_edited_files` · `memory.learn_on_session_end`. Each ships a
|
|
73
|
+
conservative default (`""`, `false`, `false`), so absent is indistinguishable
|
|
74
|
+
from *no* and never from *yes*.
|
|
75
|
+
|
|
76
|
+
**Class C carrying an `ask` value in its own enum** — a runtime question whose
|
|
77
|
+
answer dies with the run: `subagents.budget_routing` and `worktrees.mode` (both
|
|
78
|
+
**ship** as `ask`), plus `tokens.rich_skills`, `subagents.auto`,
|
|
79
|
+
`subagents.adversarial_council`, `decision_engine.on_block` (which can be set to
|
|
80
|
+
`ask` by a human but do not ship that way).
|
|
81
|
+
|
|
82
|
+
## The budget
|
|
83
|
+
|
|
84
|
+
The first key that genuinely blocks the run gets the question. Every other
|
|
85
|
+
undecided key resolves to its conservative default **without a question** and
|
|
86
|
+
appears in the end-summary as one line: key, value taken, command that changes it.
|
|
87
|
+
|
|
88
|
+
**The split is computed, not chosen.** `planSettingsAsks` in
|
|
89
|
+
`src/shared/settingsAsks.ts` returns the single key asked, the keys taking their
|
|
90
|
+
default silently, and the keys skipped with a reason; `silentDefaultsSummary`
|
|
91
|
+
renders lines that ride **inside** the one end-summary
|
|
92
|
+
([`direct-answers`](direct-answers.md) Iron Law 3).
|
|
93
|
+
|
|
94
|
+
Two questions in one execution is the violation this rule prevents.
|
|
95
|
+
Batching them into a single numbered-options block is the same violation wearing
|
|
96
|
+
a different shape: one *block* is one question only when a single number answers
|
|
97
|
+
it ([`user-interaction`](user-interaction.md) § question pacing).
|
|
98
|
+
|
|
99
|
+
## Non-interactive executions ask nothing, ever
|
|
100
|
+
|
|
101
|
+
CI, a pipe, a hook, MCP serving, `AGENT_CONFIG_NO_UI`, a headless display: the
|
|
102
|
+
budget is **zero**, not one. `nonInteractiveReason` in
|
|
103
|
+
`src/shared/interactiveContext.ts` is the predicate; `interactive: false` makes
|
|
104
|
+
`planSettingsAsks` carry no ask by construction. Defaults taken are still named —
|
|
105
|
+
silent is not invisible. A question nobody can answer is not a question; it is a
|
|
106
|
+
hang, or a default taken in the user's name wearing a prompt's clothes.
|
|
107
|
+
|
|
108
|
+
## Who picks the moment — the half no gate can check
|
|
109
|
+
|
|
110
|
+
The class contract's B invariant has two halves. Half one (a conservative
|
|
111
|
+
default) is linted. Half two binds here: the trigger must be the **user's own
|
|
112
|
+
request arriving at a point where the setting is genuinely required**. A
|
|
113
|
+
threshold the agent watched, a moment it judged favourable, or a convenient lull
|
|
114
|
+
are not triggers. If the run would complete without the setting, there is no
|
|
115
|
+
question.
|
|
116
|
+
|
|
117
|
+
## Worked example — the nickname, the canonical B ask
|
|
118
|
+
|
|
119
|
+
`personal.canary_name` is un-inferrable and arms the session-degradation canary,
|
|
120
|
+
so it is the one settings question a fresh session legitimately asks. Prefill so
|
|
121
|
+
accepting costs one keypress:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
git config user.name # first choice — the name they already chose here
|
|
125
|
+
# then: $USER, then $USERNAME (Windows). Never $USER alone.
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
On an answer: `agent-config settings:set personal.canary_name "<name>" --source jit-answer`.
|
|
129
|
+
|
|
130
|
+
**Do not ask an already-armed user.** The browser wizard writes `identity.name`
|
|
131
|
+
into `settings/.agent-user.yml`, the canary's third resolution layer, so a wizard
|
|
132
|
+
user is already covered ([`session-canary`](session-canary.md) resolves all
|
|
133
|
+
three). Check before asking.
|
|
134
|
+
|
|
135
|
+
## Before a consent-gated action — verify the record, not the value
|
|
136
|
+
|
|
137
|
+
`true` a human chose and `true` the machine inferred are the same byte and not
|
|
138
|
+
the same permission. `consentVerdict` in `src/shared/settingsConsent.ts` grants on
|
|
139
|
+
`jit-answer` / `gui` / `manual` and on a hand-edited file (which the class
|
|
140
|
+
contract guarantees carries no stamp); it withholds on the conservative default,
|
|
141
|
+
on a permissive value nothing records, and on `auto-detected` — an agent that may
|
|
142
|
+
write its own provenance must not reach its own permission by observing the
|
|
143
|
+
world. This is also the reader the provenance sidecar was missing: it was written
|
|
144
|
+
by `settings:set` and only *displayed* by the GUI.
|
|
145
|
+
|
|
146
|
+
## When NOT to fire
|
|
147
|
+
|
|
148
|
+
- Class A — resolves to its default, never asked.
|
|
149
|
+
- Class C **not** set to `ask` — no question; a change is a human edit.
|
|
150
|
+
- Already decided on any resolution layer, or the run completes without it.
|
|
151
|
+
- **The `ask` routes to a permission gate.** `worktrees.mode: ask` means
|
|
152
|
+
`scope-control`'s per-creation gate applies — a permission ask about an
|
|
153
|
+
*action*, which that rule owns; a storage line there would store nothing.
|
|
154
|
+
- **The `ask` is code, not agent-carried.** `decision_engine.on_block: ask` is a
|
|
155
|
+
TTY prompt in `work_engine/hooks/builtin/decision_gate.ts`.
|
|
156
|
+
|
|
157
|
+
## Honest enforcement — `enforced_by: none`
|
|
158
|
+
|
|
159
|
+
No gate counts the questions in a chat turn, and no B key currently gates an
|
|
160
|
+
action through a guard: the two that gate behaviour
|
|
161
|
+
(`personal.open_edited_files`, `memory.learn_on_session_end`) are read as values,
|
|
162
|
+
and the action they govern is prose. So the budget, the four slots, the
|
|
163
|
+
who-picks-the-moment half, and the obligation to consult `consentVerdict` are all
|
|
164
|
+
model-carried. On a prose-only host ask-once can degrade to ask-never. The
|
|
165
|
+
deterministic fences sit one layer down and guard a different thing:
|
|
166
|
+
`settings:set` and the GUI write route both refuse every C key and fail closed on
|
|
167
|
+
an unreadable contract, so a protocol violation cannot become an illegal *write* —
|
|
168
|
+
only a badly-shaped *ask*.
|
|
169
|
+
|
|
170
|
+
## See also
|
|
171
|
+
|
|
172
|
+
- [`docs/contracts/settings-classes.md`](../docs/contracts/settings-classes.md) — the A/B/C source of truth; slot 4 is read from it.
|
|
173
|
+
- [`ask-when-uncertain`](ask-when-uncertain.md) — one question per turn; this narrows it to one *settings* question per execution.
|
|
174
|
+
- [`no-cheap-questions`](no-cheap-questions.md) — the floor a settings question clears before it is asked at all.
|
|
175
|
+
- [`user-interaction`](user-interaction.md) — the numbered-options shape slot 3 uses.
|
|
176
|
+
- [`session-canary`](session-canary.md) — what the nickname answer activates, and the layers to check first.
|
|
@@ -31,9 +31,12 @@ TO THE FULL FRUGALITY CANON (telegraph-speak, thin-projector).
|
|
|
31
31
|
| `rich` | Must be declared + justified | **Exempt** | **Never trimmed** | 2000–3500 tokens |
|
|
32
32
|
|
|
33
33
|
Read `tokens.rich_skills` from `.agent-settings.yml` (default `on`) to determine
|
|
34
|
-
whether rich skills may load in full. If `off`, treat them as
|
|
35
|
-
`
|
|
36
|
-
|
|
34
|
+
whether rich skills may load in full. If `off`, treat them as `standard`. If
|
|
35
|
+
`ask`, the question's shape is
|
|
36
|
+
[`settings-ask-protocol`](settings-ask-protocol.md)'s, not this rule's; what only
|
|
37
|
+
this rule knows is the number to put in it — the estimated token delta, ≈ skill
|
|
38
|
+
file size in chars / 4. The answer is cached for the session and never persisted
|
|
39
|
+
(`tokens.rich_skills` is class C).
|
|
37
40
|
|
|
38
41
|
## Requirements for `token_budget_class: rich`
|
|
39
42
|
|
|
@@ -16,6 +16,9 @@ workspaces: [agent-config-maintainer, engineering]
|
|
|
16
16
|
packs: [frontend-design]
|
|
17
17
|
collision_ok:
|
|
18
18
|
"component": "no new component without audit findings — its core subject"
|
|
19
|
+
"design token": "same surface, opposite side: this inventories tokens before the write, design-review-after-ui-write reviews what the write emitted"
|
|
20
|
+
"resources/views/": "both halves of one UI loop fire on the same path — audit before, review after; neither substitutes for the other"
|
|
21
|
+
"resources/js/": "both halves of one UI loop fire on the same path — audit before, review after; neither substitutes for the other"
|
|
19
22
|
---
|
|
20
23
|
|
|
21
24
|
# UI Audit Gate
|
|
@@ -52,6 +52,29 @@ the script is the deterministic safety net.
|
|
|
52
52
|
|
|
53
53
|
If in doubt, split into serial turns — never a long batched prompt.
|
|
54
54
|
|
|
55
|
+
## The trigger is a decision, not a format
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
THE OBLIGATION FIRES ON HANDING A DECISION TO THE USER — IN ANY FORM.
|
|
59
|
+
NOT ON THE PRESENCE OF A NUMBERED LIST.
|
|
60
|
+
A TRAILING FREE-TEXT OFFER IS AN ASK. A BARE YES/NO IS AN ASK.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Measured (30-session conformance audit, 2026-08-06): **every** malformed ask was
|
|
64
|
+
a one-line parenthetical or a trailing free-text offer — *"sag Bescheid, wenn
|
|
65
|
+
ich die drei Zeilen mitnehmen soll"*, *"Soll ich das so umsetzen?"* — while the
|
|
66
|
+
same sessions formatted their **large** asks perfectly. So the rule is being
|
|
67
|
+
read as *if numbered options, then a recommendation line*. It is the other way
|
|
68
|
+
round, and an ask that feels too small for a block is exactly the one that
|
|
69
|
+
escapes the format. Three further caught shapes: a contentless filler option; an
|
|
70
|
+
inline `(Empfohlen)` tag **beside** the recommendation line (the dual source
|
|
71
|
+
Iron Law 1 forbids); an option set answerable only as `1,3,4`.
|
|
72
|
+
|
|
73
|
+
**No gate ships for this.** `check_reply_consistency` can read a draft on stdin,
|
|
74
|
+
but it inspects *numbered-option blocks* — and every measured failure had no
|
|
75
|
+
block by construction, so it scans exactly the surface that did not fail. `conformance:behavior` deliberately does not score ask-shape,
|
|
76
|
+
so an unmoved rate is a finding rather than a silence.
|
|
77
|
+
|
|
55
78
|
## Mechanics — rationale, failure modes, format details, examples
|
|
56
79
|
|
|
57
80
|
The "why take a position", position-agnostic clause, format
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: finishing-a-development-branch
|
|
4
|
-
description: "Use when the feature is implementation-complete and the next step is 'ship it' — verifies, cleans up,
|
|
4
|
+
description: "Use when the feature is implementation-complete and the next step is 'ship it' — verifies, cleans up, routes to merge/PR/park/discard; never destroys work without explicit confirmation."
|
|
5
5
|
domain: process
|
|
6
6
|
workspaces:
|
|
7
7
|
- engineering
|
|
@@ -48,6 +48,19 @@ until a benchmark gate authorises it per host.
|
|
|
48
48
|
> major unless external evidence appears first. This skill is NOT sold as a
|
|
49
49
|
> quality-lift mechanism.
|
|
50
50
|
|
|
51
|
+
> **Scope of that null — what it does NOT close.** It measured a loop that ADDS
|
|
52
|
+
> a critic to judge whether an attempt was good enough (deterministic
|
|
53
|
+
> scorer-as-critic, `max_depth=1`, weak host, `capH-debug`). It is not evidence
|
|
54
|
+
> about retrying on a check that has **already returned red**: there the verdict
|
|
55
|
+
> is deterministic and in hand, and no critic is introduced, so there is nothing
|
|
56
|
+
> for the null to be null about. The measurement's own decisive finding inverts
|
|
57
|
+
> in that case — recursion was redundant because the first attempt already
|
|
58
|
+
> passed the critic 72% of the time, so cost scaled with every task while benefit
|
|
59
|
+
> sat in the ~28% tail; a red-triggered retry costs nothing on the passing
|
|
60
|
+
> majority and fires only on the tail. What the null DOES bind, for any such
|
|
61
|
+
> loop, is the falsification shape: pre-register the reduction it must deliver,
|
|
62
|
+
> and revert rather than narrate if it does not.
|
|
63
|
+
|
|
51
64
|
## The Iron Law
|
|
52
65
|
|
|
53
66
|
```
|