@event4u/agent-config 9.22.0 → 9.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +69 -256
- package/README.md +1 -1
- package/dist/agent-src/commands/optimize/deep.md +13 -0
- package/dist/agent-src/contexts/execution/cheap-question-mechanics.md +12 -2
- package/dist/agent-src/contexts/execution/mandated-lines.md +180 -0
- package/dist/agent-src/rules/context-hygiene.md +17 -0
- package/dist/agent-src/rules/downstream-changes.md +26 -0
- package/dist/agent-src/rules/think-before-action.md +25 -0
- package/dist/agent-src/rules/token-budget-discipline.md +46 -3
- package/dist/agent-src/rules/token-efficiency.md +13 -0
- package/dist/agent-src/rules/ui-audit-gate.md +33 -2
- package/dist/agent-src/skills/adversarial-review/SKILL.md +18 -4
- package/dist/agent-src/skills/decision-review/SKILL.md +49 -0
- package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +5 -1
- package/dist/agent-src/skills/judge-bug-hunter/SKILL.md +16 -0
- package/dist/agent-src/skills/judge-synthesis/SKILL.md +14 -1
- package/dist/agent-src/skills/rule-writing/SKILL.md +33 -0
- package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +31 -0
- package/dist/agent-src/skills/skill-reviewer/SKILL.md +1 -1
- 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/chunk-DVRS2KVR.js +4602 -0
- package/dist/cli-delegate/{chunk-ELMFOQPW.js → chunk-SJQMJI7M.js} +8 -4597
- package/dist/cli-delegate/cmd_export.js +2 -1
- package/dist/cli-delegate/cmd_prune.js +2 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +2 -1
- package/dist/cli-delegate/cmd_settings_set.js +3370 -0
- package/dist/cli-delegate/cmd_sync.js +2 -1
- package/dist/cli-delegate/cmd_uninstall.js +2 -1
- package/dist/cli-delegate/cmd_validate.js +2 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +17 -17
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.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 +79 -1
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/scripts/condense.js +47 -2
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/routes/settings.js +82 -0
- package/dist/server/routes/settings.js.map +1 -1
- package/dist/shared/settingsClasses.js +191 -0
- package/dist/shared/settingsClasses.js.map +1 -0
- package/docs/contracts/settings-classes.md +342 -0
- package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +23 -2
- package/docs/guidelines/agent-infra/false-green.md +187 -0
- package/docs/guidelines/agent-infra/gate-authoring.md +177 -0
- package/package.json +3 -1
- package/src/config/ci-local-parity.yml +12 -0
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/gate-coverage.yml +54 -12
- package/src/config/gate-violation-baselines.json +6 -0
- package/src/config/pack-size-budget.json +4 -3
- package/src/scripts/_cli/cmd_settings_set.ts +509 -0
- package/src/scripts/_dispatch.bash +16 -0
- package/src/scripts/_lib/gate_ledger.ts +295 -0
- package/src/scripts/_lib/gate_result.ts +101 -0
- package/src/scripts/_lib/gate_self_test.ts +129 -0
- package/src/scripts/_lib/measured_render.ts +97 -0
- package/src/scripts/_lib/ratchet_base_ref.ts +373 -0
- package/src/scripts/check_gate_completeness.ts +244 -0
- package/src/scripts/check_gate_coverage.ts +35 -6
- package/src/scripts/check_references.ts +125 -15
- package/src/scripts/check_review_dispositions.ts +14 -1
- package/src/scripts/check_suppression_hygiene.ts +503 -0
- package/src/scripts/condense.ts +47 -2
- package/src/scripts/hook_manifest.yaml +23 -0
- package/src/scripts/hooks/dispatch_hook.ts +65 -1
- package/src/scripts/hooks/host_semantics.ts +140 -0
- package/src/scripts/lint_framework_leakage.ts +147 -15
- package/src/scripts/lint_mandated_lines.ts +339 -0
- package/src/scripts/lint_roadmap_complexity.ts +102 -11
- package/src/scripts/lint_roadmap_family_cap.ts +191 -0
- package/src/scripts/lint_settings_classes.ts +397 -0
- package/src/scripts/lint_token_budget_discipline.ts +109 -1
- package/src/scripts/report_imperative_density.ts +229 -0
- package/src/scripts/verify_physical_move.ts +10 -1
- package/src/server/io/yamlIO.ts +173 -0
- package/src/shared/settingsClasses.ts +235 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Mandated Lines — the forced artifact at the decision point
|
|
2
|
+
|
|
3
|
+
Shared contract for the small closed set of **verbatim lines the run must emit
|
|
4
|
+
at a decision point**, and for the pre-send sweep that catches an owed line that
|
|
5
|
+
went missing. Routed from the rule that owns each decision point rather than
|
|
6
|
+
restated in each.
|
|
7
|
+
|
|
8
|
+
**Routing status, stated because a claimed edge that does not exist is worse
|
|
9
|
+
than a missing one.** Two rules link here today:
|
|
10
|
+
[`think-before-action`](../../rules/think-before-action.md) (the intent line)
|
|
11
|
+
and [`downstream-changes`](../../rules/downstream-changes.md) (the sibling
|
|
12
|
+
search). The authorization and commit lines belong to
|
|
13
|
+
[`non-destructive-by-default`](../../rules/non-destructive-by-default.md) and
|
|
14
|
+
[`commit-policy`](../../rules/commit-policy.md) — both **kernel** rules, whose
|
|
15
|
+
edits require their own pull request and a 24-hour soak under
|
|
16
|
+
[`scope-control`](../../rules/scope-control.md). Those two edges are therefore
|
|
17
|
+
deliberately absent from this change rather than smuggled into it, and until
|
|
18
|
+
they land those two lines are carried by this contract alone.
|
|
19
|
+
|
|
20
|
+
## Why a line and not a rule
|
|
21
|
+
|
|
22
|
+
An external source published the A/B of one obligation in three forms. Absent:
|
|
23
|
+
**0 of 4** runs surfaced a planted contradiction. Added as mid-list prose:
|
|
24
|
+
**1 of 4**, scoring *below* the no-instruction control. Converted into a
|
|
25
|
+
mandated verbatim line the run must emit *before* the behaviour-changing edit,
|
|
26
|
+
paired with a mechanical sweep for owed-but-missing lines: **4 of 4**. The rule
|
|
27
|
+
text did not change. Only its form did.
|
|
28
|
+
|
|
29
|
+
This suite has three recorded honest nulls on *reminder-shaped* interventions —
|
|
30
|
+
a decay-triggered restate, a reminder-injection experiment measuring zero delta,
|
|
31
|
+
a recursive-verification null. Those stand. This is a different mechanism: an
|
|
32
|
+
artifact the run must **produce**, not a reminder it must **receive**, with an
|
|
33
|
+
opposite measured result and its failing baseline published first. That is the
|
|
34
|
+
mechanism-match test in [`decision-revisit-gate`](../../rules/decision-revisit-gate.md),
|
|
35
|
+
passed rather than dodged.
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
A MANDATED LINE IS EMITTED AT THE DECISION POINT, BEFORE THE ACTION —
|
|
39
|
+
NEVER AS A TRAILING CHECKLIST THAT PROVES THE ACTION HAPPENED.
|
|
40
|
+
A LINE THAT IS OWED AND MISSING IS AN INCOMPLETE REPLY.
|
|
41
|
+
A LINE THAT IS NOT OWED IS NOT EMITTED. SILENCE IS THE DEFAULT.
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## The five lines
|
|
45
|
+
|
|
46
|
+
Each is bound to a **decision point**, not to a topic. One sentence each.
|
|
47
|
+
|
|
48
|
+
### 1. Intent — before a behaviour-changing edit
|
|
49
|
+
|
|
50
|
+
Three slots: **what the code does · what the failing check expects · what the
|
|
51
|
+
specification says.**
|
|
52
|
+
|
|
53
|
+
> Intent: `parseDate` returns null on an empty string · the failing test expects
|
|
54
|
+
> a thrown `RangeError` · the spec says empty input is a caller error.
|
|
55
|
+
|
|
56
|
+
The load-bearing consequence, and the whole reason the line has three slots
|
|
57
|
+
rather than one: **when the three disagree, the disagreement is the finding and
|
|
58
|
+
the edit does not proceed.** A line that reads the same three ways is a line
|
|
59
|
+
that was written after deciding.
|
|
60
|
+
|
|
61
|
+
### 2. Authorization — before an irreversible outward action
|
|
62
|
+
|
|
63
|
+
Carries **the user's own words**, quoted. Two denials are explicit:
|
|
64
|
+
|
|
65
|
+
- **Documentation is not authorization.** A roadmap step, a command file, or a
|
|
66
|
+
prior turn's plan describing the action is not the user asking for it.
|
|
67
|
+
- **Completing the task is not authorization.** Reaching the point where the
|
|
68
|
+
action would be natural is not permission to take it.
|
|
69
|
+
|
|
70
|
+
> Authorization: "push it and open the PR" (this turn) — covers this push and
|
|
71
|
+
> this PR, not the follow-up fix.
|
|
72
|
+
|
|
73
|
+
Fires for the [`non-destructive-by-default`](../../rules/non-destructive-by-default.md)
|
|
74
|
+
Hard-Floor set: push, deploy, prod-trunk merge, prod data or infra, bulk
|
|
75
|
+
destructive, and any irreversible external action (send · publish · post ·
|
|
76
|
+
purchase · submit).
|
|
77
|
+
|
|
78
|
+
### 3. Commit — before a commit
|
|
79
|
+
|
|
80
|
+
Three slots: **the authorization and its exact scope · that the staged set
|
|
81
|
+
matches the intended edit · that nothing unintended is staged.**
|
|
82
|
+
|
|
83
|
+
> Commit: authorized "commit this now" (this turn), scope = the parser fix ·
|
|
84
|
+
> staged set is the 2 files that fix names · nothing else staged.
|
|
85
|
+
|
|
86
|
+
This is the mandated-artifact form of an obligation
|
|
87
|
+
[`commit-policy`](../../rules/commit-policy.md) already carries as prose, and it
|
|
88
|
+
is the fifth line rather than a variant of the authorization line because its
|
|
89
|
+
failure mode is different: the authorization line asks *may I*, the commit line
|
|
90
|
+
asks *is what I am about to record what I meant to record*. A commit with a
|
|
91
|
+
stray file is authorized and still wrong.
|
|
92
|
+
|
|
93
|
+
### 4. Pending — when a prescribed follow-up was deliberately not taken
|
|
94
|
+
|
|
95
|
+
> Pending: the negative test for the tenant path is not written — the fixture
|
|
96
|
+
> needs a second tenant and I did not create one.
|
|
97
|
+
|
|
98
|
+
Unlike the other four this line gates nothing. It is a **disclosure**
|
|
99
|
+
obligation: it makes a deliberate skip visible to the human who reviews the
|
|
100
|
+
work, and it exists because this suite's work lands through reviewed pull
|
|
101
|
+
requests, so the line has a recipient. A skip nobody was told about is
|
|
102
|
+
indistinguishable from a step that was forgotten.
|
|
103
|
+
|
|
104
|
+
### 5. Sibling search — after a defect fix
|
|
105
|
+
|
|
106
|
+
Names **the exact wrong construct searched for, and the count found.**
|
|
107
|
+
|
|
108
|
+
> Sibling search: grepped `JSON.parse(` without a try — 3 sites, 2 fixed, 1 in
|
|
109
|
+
> a test fixture and left.
|
|
110
|
+
|
|
111
|
+
A defect found in one place is presumed to recur until searched. The count is
|
|
112
|
+
part of the line because "I checked" is not a finding and zero is a real answer.
|
|
113
|
+
|
|
114
|
+
## The pre-send sweep
|
|
115
|
+
|
|
116
|
+
Before a reply that claims completion, check each line above against what the
|
|
117
|
+
run **actually did**, and add any that is owed and missing.
|
|
118
|
+
|
|
119
|
+
- Fire only when something is owed. A reply owing nothing passes untouched, and
|
|
120
|
+
no line is emitted to prove the sweep ran.
|
|
121
|
+
- This is the same shape as the existing
|
|
122
|
+
[`roadmap-progress-sync`](../../rules/roadmap-progress-sync.md) and
|
|
123
|
+
[`no-cheap-questions`](../../rules/no-cheap-questions.md) pre-send checks — a
|
|
124
|
+
step in an existing sequence, not a new mechanism.
|
|
125
|
+
- The sweep is a backstop for a line that should already have been emitted at
|
|
126
|
+
its decision point. A reply where every owed line first appears in the sweep
|
|
127
|
+
is a reply that took the actions before thinking about them, and the sweep
|
|
128
|
+
cannot repair that — it can only surface it.
|
|
129
|
+
|
|
130
|
+
## Brevity — how these avoid becoming ceremony
|
|
131
|
+
|
|
132
|
+
This suite's [`direct-answers`](../../rules/direct-answers.md) Iron Law 3 treats
|
|
133
|
+
long replies as a failure mode, and its anti-ceremony discipline says not to
|
|
134
|
+
invent receipts solely to prove execution. Five mandated lines are in real
|
|
135
|
+
tension with both. Three constraints resolve it, and they are part of the
|
|
136
|
+
contract:
|
|
137
|
+
|
|
138
|
+
1. **One sentence per line.** A line that needs a paragraph is a line whose
|
|
139
|
+
decision was not made.
|
|
140
|
+
2. **Emitted at the decision point, never as a trailing checklist.** The
|
|
141
|
+
measured 4-of-4 result came from a line emitted *before* the action. A
|
|
142
|
+
checklist at the end of a reply is the ceremony shape, and it also loses the
|
|
143
|
+
only property that made the mechanism work — that writing it can still stop
|
|
144
|
+
the action.
|
|
145
|
+
3. **Two or more owed lines merge into one block, in execution order**, with
|
|
146
|
+
minimal labels — one interruption rather than five.
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
Intent (parser.ts): returns null on empty · test expects RangeError · spec says caller error
|
|
150
|
+
Sibling search: grepped `JSON.parse(` without a try — 3 sites, 2 fixed, 1 test fixture left
|
|
151
|
+
Commit: authorized "commit this" (this turn), scope = parser fix · 2 files staged · nothing else
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Honest scope — what this does not claim
|
|
155
|
+
|
|
156
|
+
**Enforced by:** partially. `src/scripts/lint_mandated_lines.ts` is the
|
|
157
|
+
deterministic half and it checks only what a **run report** can be checked for:
|
|
158
|
+
a report claiming a behaviour change carries an intent line, and a report
|
|
159
|
+
describing an outward action carries an authorization line. It cannot check that
|
|
160
|
+
the line was emitted *before* the action rather than reconstructed after, and it
|
|
161
|
+
cannot check that the three intent slots were honestly filled. Those are
|
|
162
|
+
model-carried, and saying so here is cheaper than discovering it later.
|
|
163
|
+
|
|
164
|
+
**The transfer risk, stated.** The 4-of-4 measurement came from one source on
|
|
165
|
+
one task family — contradiction detection. This suite's work is largely
|
|
166
|
+
construction, where there may be no planted contradiction to surface, and the
|
|
167
|
+
mechanism could reduce to ceremony without anyone noticing.
|
|
168
|
+
|
|
169
|
+
**The cheap observation that would detect it:** track how often an emitted
|
|
170
|
+
intent line has its three slots **disagree**. If disagreements are effectively
|
|
171
|
+
never found, the line is decorating decisions already made and the set should
|
|
172
|
+
shrink. If disagreements are found and the edit is then revised or stopped, the
|
|
173
|
+
mechanism is doing the thing it was adopted for. That observation costs one
|
|
174
|
+
counter and is the first thing to look at before adding a sixth line.
|
|
175
|
+
|
|
176
|
+
## See also
|
|
177
|
+
|
|
178
|
+
- [`docs/contracts/settings-classes.md`](../../../docs/contracts/settings-classes.md) — a sibling contract in the same shape: prose that a gate reads.
|
|
179
|
+
- [`verify-before-complete`](../../rules/verify-before-complete.md) — the evidence gate the pre-send sweep runs beside.
|
|
180
|
+
- `src/scripts/lint_mandated_lines.ts` — the deterministic half.
|
|
@@ -56,6 +56,8 @@ When **3 consecutive attempts** at the same task fail (code fix, test fix, confi
|
|
|
56
56
|
|
|
57
57
|
Calling the **same tool** more than **2 times in a row** with similar parameters = loop.
|
|
58
58
|
**Immediate action:** 1. STOP all tool calls. 2. Do the task directly. 3. Can't proceed → ask the user.
|
|
59
|
+
|
|
60
|
+
**"Similar parameters" is the load-bearing word — an enumerated set is not a loop.** Walking N *declared, distinct* targets (a downstream-caller sweep per [`downstream-changes`](downstream-changes.md), an override chain, the members of a grep result) is one operation whose parameters differ every call. Counting it as N repetitions makes `downstream-changes`' "find **ALL** callers, tests, imports" unsatisfiable — it cannot be done in two calls. The loop this detects is *repetition without new information*: same target, same parameters, hoping for a different answer. Mirrors the same carve-out in [`token-efficiency`](token-efficiency.md).
|
|
59
61
|
`sequentialthinking` is especially prone to loops: at most **once** per task, NEVER for simple file operations, command execution, or straightforward edits.
|
|
60
62
|
|
|
61
63
|
## Read-Loop Detection — the 15 / 25 rule
|
|
@@ -72,6 +74,21 @@ EVERY TURN MUST EDIT, RUN, OR ASK.
|
|
|
72
74
|
|
|
73
75
|
**25-min abort (5 read-only turns) — STOP and ask** with the abort block (template in the mechanics guideline). Non-bypassable: an autonomous mandate does **not** lift the abort — it is the safety net that protects autonomy from becoming a token sink.
|
|
74
76
|
|
|
77
|
+
### Declared read protocol — the cap goes UP, never off
|
|
78
|
+
|
|
79
|
+
A mandated analysis/audit/review protocol is exactly the case that legitimately needs *more* reads, not fewer — an 8-turn evidence sweep is the protocol working, not a loop. Capping a declared protocol tighter than an undeclared one is backwards. So:
|
|
80
|
+
|
|
81
|
+
- **Undeclared reading keeps 3-warn / 5-abort.** Unchanged.
|
|
82
|
+
- **A declared protocol raises the abort to 8 read-only turns** — and never suspends it. "Non-bypassable" narrows to **no *silent* bypass**: a declared protocol is not silent.
|
|
83
|
+
|
|
84
|
+
A declaration is only valid when it states, before the reading starts, all three of:
|
|
85
|
+
|
|
86
|
+
1. **the analysis goal**, falsifiably ("map every call chain that writes to the audit table" — not "understand the code");
|
|
87
|
+
2. **the expected read count**;
|
|
88
|
+
3. **the output shape** the reads feed (a table, an evidence report, a decision).
|
|
89
|
+
|
|
90
|
+
Free-text intent is not a declaration — the three fields exist so that "declared protocol: I need to read things" cannot buy the higher cap. Exceeding the declared count by more than 2 is itself the violation: stop, surface what the extra reads were for, and ask.
|
|
91
|
+
|
|
75
92
|
Body migrated to [`guideline:agent-infra/context-hygiene-mechanics`](../docs/guidelines/agent-infra/context-hygiene-mechanics.md) (per P4 of `road-to-kernel-and-router.md`) — the freshness-suggestion template, the read-loop self-check + abort block, the state-dump format + `/agent-handoff` pointer, the Augment ignored-skills recovery flow, and the Copilot no-hook fallback (manual `context_hygiene_hook` refresh).
|
|
76
93
|
Trigger-set above activates this routing on demand, independent of the discipline profile (ADR-110).
|
|
77
94
|
|
|
@@ -47,6 +47,32 @@ After editing any file, search for **all** of these:
|
|
|
47
47
|
| **Routes** | Search `routes/` for controller references | Update after controller rename/move |
|
|
48
48
|
| **Documentation** | Search `agents/`, `docs/`, `README`, examples for references | Update the doc that **describes** the changed surface — see Doc-Impact below |
|
|
49
49
|
|
|
50
|
+
## Defect-pattern search — one instance is a sample, not the population
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
A DEFECT FOUND IN ONE PLACE IS PRESUMED TO RECUR UNTIL SEARCHED.
|
|
54
|
+
NAME THE EXACT WRONG CONSTRUCT. SEARCH THE TREE. REPORT THE COUNT AND THE FILES.
|
|
55
|
+
"I FIXED IT" WITHOUT A COUNT IS A FIX OF ONE INSTANCE, NOT OF THE DEFECT.
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
After fixing a defect, before claiming the fix is complete: write down the
|
|
59
|
+
**exact wrong construct** — the literal pattern, not a description of it — grep
|
|
60
|
+
the tree for it, and report **how many sites matched and which**. Zero is a real
|
|
61
|
+
answer and is worth reporting; it is the difference between "this was unique"
|
|
62
|
+
and "I did not look".
|
|
63
|
+
|
|
64
|
+
The own-orphan sweep above greps identifiers your diff *stopped referencing*.
|
|
65
|
+
This greps for the **defect itself**, which nothing else does — the two run over
|
|
66
|
+
different sets and neither substitutes for the other.
|
|
67
|
+
|
|
68
|
+
Emit the finding as the sibling-search mandated line
|
|
69
|
+
([`mandated-lines`](../contexts/execution/mandated-lines.md) § 5), which is
|
|
70
|
+
where its shape and the reason it carries a count are specified.
|
|
71
|
+
|
|
72
|
+
**When NOT to fire:** the defect is in code the diff created this turn (there is
|
|
73
|
+
no population to search), or the construct is one the language makes impossible
|
|
74
|
+
to express twice.
|
|
75
|
+
|
|
50
76
|
## Doc-Impact — docs follow code (same change)
|
|
51
77
|
|
|
52
78
|
```
|
|
@@ -45,6 +45,31 @@ NO BLIND TRIAL-AND-ERROR. MAX 2 RETRIES PER APPROACH.
|
|
|
45
45
|
- Do NOT modify code you do not fully understand — read it, trace the flow, then change it.
|
|
46
46
|
- Multiple valid frameworks/patterns coexist (Tailwind + Flux, multiple form libs, competing state stores) → do NOT pick one silently — ask. See [`no blind implementation`](../docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md#2-no-blind-implementation).
|
|
47
47
|
|
|
48
|
+
## The intent line, before a behaviour-changing edit
|
|
49
|
+
|
|
50
|
+
Before an edit that changes behaviour, emit the **intent line**: what the code
|
|
51
|
+
does · what the failing check expects · what the specification says. When the
|
|
52
|
+
three disagree, the disagreement is the finding and the edit does not proceed.
|
|
53
|
+
Shape, the other four mandated lines, and the pre-send sweep:
|
|
54
|
+
[`mandated-lines`](../contexts/execution/mandated-lines.md).
|
|
55
|
+
|
|
56
|
+
## Where the answer lives — and saying so when it lives nowhere
|
|
57
|
+
|
|
58
|
+
Route by **where the answer actually is**: the code, a config, a live probe, a
|
|
59
|
+
doc, the user. When the answer exists only in your own inference — nothing to
|
|
60
|
+
open, nothing to run, nobody to ask — **say that**, in the report, in one clause.
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
AN INFERENCE DRESSED IN PROCESS IS INDISTINGUISHABLE FROM A LOOKUP.
|
|
64
|
+
NAME THE DETOUR. A SILENT DETOUR READS AS A SKIPPED STEP.
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
This rule and its neighbours say *be rigorous* often enough that the costume
|
|
68
|
+
version — narrating a thorough-sounding procedure over a guess — is a live risk
|
|
69
|
+
here specifically. The cost of naming it is one clause; the cost of not naming
|
|
70
|
+
it is that a reader cannot tell a verified fact from a confident one, which is
|
|
71
|
+
the property the whole evidence discipline exists to protect.
|
|
72
|
+
|
|
48
73
|
## Mechanics — workflow, minimum read set, verify-with-real-tools, no blind retries
|
|
49
74
|
|
|
50
75
|
The five-step Understand → Analyze → Plan → Implement → Verify workflow, the minimum read set (symbol, callers, tests, abstractions, data), the memory-consult step, the verification matrix, the output-reduction patterns, the no-blind-retries protocol, and the "open files are context, not intent" clause all live in [`contexts/communication/rules-auto/think-before-action-mechanics.md`](../contexts/communication/rules-auto/think-before-action-mechanics.md). The rule above is the obligation surface; the mechanics file is the lookup material.
|
|
@@ -28,7 +28,7 @@ TO THE FULL FRUGALITY CANON (telegraph-speak, thin-projector).
|
|
|
28
28
|
|---|---|---|---|---|
|
|
29
29
|
| `lean` | No explicit key = lean | Full condensation | May be trimmed | < 500 tokens |
|
|
30
30
|
| `standard` | — | Balanced condensation | Not trimmed if priority ≥ 60 | 500–2000 tokens |
|
|
31
|
-
| `rich` | Must be declared + justified | **Exempt** | **Never trimmed** | 2000–
|
|
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
34
|
whether rich skills may load in full. If `off`, treat them as
|
|
@@ -82,7 +82,7 @@ THE BUDGET LINE IS AN INPUT TO THE DECISION, NEVER THE DECISION ITSELF.
|
|
|
82
82
|
The 15 % rich-skill cap, the lean/standard/rich size targets, and every
|
|
83
83
|
telegraph-speak / thin-projector trim point are cost controls, not
|
|
84
84
|
capability ceilings. When a proposed change is blocked *purely* because
|
|
85
|
-
it would cross one of these lines — a skill needs more than
|
|
85
|
+
it would cross one of these lines — a skill needs more than 3500 tokens
|
|
86
86
|
to stay useful, a rule's condensed form loses a worked example the
|
|
87
87
|
frugality canon would otherwise trim — do not silently reject it.
|
|
88
88
|
Surface the trade-off instead: the estimated token delta, and the
|
|
@@ -107,10 +107,53 @@ These skills are approved `rich` by this roadmap's council:
|
|
|
107
107
|
| `accessibility-auditor` | WCAG criteria are non-negotiable detail; every criterion has a testable condition + failure mode; compression loses the test procedures |
|
|
108
108
|
| `design-system-capture` (Phase 6) | Writes + maintains DESIGN.md + PRODUCT.md; needs full templates + worked examples to generate useful artifacts |
|
|
109
109
|
|
|
110
|
+
## Rich artifacts lead with a non-negotiable band
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
A RICH-CLASS ARTIFACT OPENS WITH THE SECTION THAT OUTRANKS THE REST OF ITS
|
|
114
|
+
OWN DOCUMENT, THEN THE REASONING LAYER.
|
|
115
|
+
A LONG REFERENCE READ PARTIALLY MUST LOSE THE REASONING, NEVER THE OBLIGATION.
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The `rich` exemption buys length, and length buys the risk that a reader stops
|
|
119
|
+
early. Ordering is the mitigation available at authoring time: put the
|
|
120
|
+
load-bearing fraction first, so a partial read loses the part that was
|
|
121
|
+
explanation rather than the part that was binding.
|
|
122
|
+
|
|
123
|
+
This is a **precedence claim inside one document**, not a claim over other
|
|
124
|
+
artifacts — a rich skill's leading band outranks that skill's own later
|
|
125
|
+
sections and nothing else. Cross-artifact precedence is the authority index's
|
|
126
|
+
job.
|
|
127
|
+
|
|
128
|
+
It mitigates partial reading. It does **not** answer whether the artifact should
|
|
129
|
+
be shorter — that is the ceiling, gated below, and the two controls are
|
|
130
|
+
independent: an artifact can sit comfortably under the ceiling and still bury
|
|
131
|
+
its obligation on line 300.
|
|
132
|
+
|
|
133
|
+
## The size band is measured, and only its ceiling is gated
|
|
134
|
+
|
|
135
|
+
The `rich` band is **2,000–3,500 tokens** ([ADR-217](../docs/decisions/ADR-217-rich-class-band-measured-and-enforced.md)).
|
|
136
|
+
It was 2,000–5,000 and enforced by nothing until that record: measured with the
|
|
137
|
+
exact BPE tokenizer, the largest rich artifact in the tree is 3,331 tokens, so
|
|
138
|
+
the old ceiling described no artifact that existed. An unused permission costs
|
|
139
|
+
nothing until someone uses it.
|
|
140
|
+
|
|
141
|
+
`lint_token_budget_discipline.ts` gates the **ceiling** and publishes every rich
|
|
142
|
+
artifact's size on the green path. It does **not** gate the floor, and that is a
|
|
143
|
+
finding rather than an omission: running the check once surfaced a 1,931-token
|
|
144
|
+
skill legitimately holding the class, because `rich` buys exemption from
|
|
145
|
+
condensation — a claim about what compression would *lose*, not about file size.
|
|
146
|
+
The published study supplies a degradation threshold, which is a ceiling.
|
|
147
|
+
Nothing measures a minimum.
|
|
148
|
+
|
|
149
|
+
Measurement is exact where `js-tiktoken` resolves and the character proxy where
|
|
150
|
+
it does not; the gate says which, and a proxy reading within its own error
|
|
151
|
+
margin of the ceiling is reported **unresolved** rather than classified.
|
|
152
|
+
|
|
110
153
|
## Governed by
|
|
111
154
|
|
|
112
155
|
- `tokens.rich_skills` setting in `.agent-settings.yml` (consumer override)
|
|
113
|
-
- `lint_token_budget_discipline.ts` (cap + justification CI check)
|
|
156
|
+
- `lint_token_budget_discipline.ts` (cap + justification + ceiling CI check)
|
|
114
157
|
- the telegraph-speak rule, where enabled (amended to except rich-tagged skills)
|
|
115
158
|
|
|
116
159
|
## See also
|
|
@@ -26,6 +26,19 @@ NEVER CALL THE SAME TOOL >2 TIMES IN A ROW WITH SIMILAR PARAMETERS.
|
|
|
26
26
|
IF YOU CATCH YOURSELF REPEATING → STOP, RETHINK, ASK.
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
## Enumerated file sets are ONE operation, not N repetitions
|
|
30
|
+
|
|
31
|
+
The same-tool ceiling counts *repetition without new information* — the loop where the agent re-runs a tool because it did not learn from the last result. Reading N **declared, enumerated** files is the opposite: each read returns different content and the set was known before the first call. Counting it as N repetitions puts this rule in direct conflict with [`downstream-changes`](downstream-changes.md) ("find **ALL** callers, tests, imports") and with [`source-discovery-gate`](source-discovery-gate.md), which cannot be satisfied in two calls.
|
|
32
|
+
|
|
33
|
+
Exempt — the file set is enumerated **before** the first read and each read is a distinct member:
|
|
34
|
+
|
|
35
|
+
- an override / settings-resolution chain (project → user → global);
|
|
36
|
+
- a downstream-caller sweep after a rename or signature change;
|
|
37
|
+
- the members of a directory listing or grep result being opened in turn;
|
|
38
|
+
- a declared read protocol under [`context-hygiene`](context-hygiene.md).
|
|
39
|
+
|
|
40
|
+
Not exempt, and still the failure this rule exists to catch: re-reading the *same* file hoping for a different answer, re-running a failing command unchanged, or widening a grep by one word at a time instead of thinking. The discriminator is **did the previous call change what I know** — not the tool name.
|
|
41
|
+
|
|
29
42
|
## Fresh Output Over Memory
|
|
30
43
|
|
|
31
44
|
When a tool returns a value (branch name, file path, PR number), use that EXACT value in subsequent API calls. NEVER substitute a value from earlier in the conversation. Context decay causes silent mismatches — fresh output is the only source of truth.
|
|
@@ -46,12 +46,43 @@ EXISTING-UI-AUDIT RUNS FIRST. ALWAYS.
|
|
|
46
46
|
|
|
47
47
|
`null` or `{}` is **not** findings; empty dict is rejected on purpose.
|
|
48
48
|
|
|
49
|
-
## Allow-list — `ui-trivial
|
|
49
|
+
## Allow-list — `ui-trivial`, decidable from the diff alone
|
|
50
50
|
|
|
51
51
|
Skip only when **all** hold:
|
|
52
52
|
|
|
53
|
-
- `directive_set == "ui-trivial"`.
|
|
54
53
|
- ≤ 1 file, ≤ 5 changed lines, no new component, no new state.
|
|
54
|
+
- Inside the work engine, `directive_set == "ui-trivial"` — the dispatcher
|
|
55
|
+
states it directly. Outside it, the same four conditions are read **off the
|
|
56
|
+
diff**, which is observable without any dispatcher state.
|
|
57
|
+
|
|
58
|
+
The `directive_set` check used to be an additional *requirement* rather than
|
|
59
|
+
the dispatcher's way of stating the same fact. That made the escape hatch
|
|
60
|
+
dispatcher-only, and with `state.ui_audit` also dispatcher-only the gate could
|
|
61
|
+
be neither satisfied nor skipped in a plain chat session — the only
|
|
62
|
+
rule-conform action left was "write no UI". A gate whose sole compliant path is
|
|
63
|
+
inaction is not a gate.
|
|
64
|
+
|
|
65
|
+
## Honest scope — what this rule does NOT enforce in a chat session
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
OUTSIDE THE WORK ENGINE, THE AUDIT OBLIGATION IS MODEL-CARRIED.
|
|
69
|
+
NEVER CLAIM THE AUDIT RAN AS IF IT WERE VERIFIED.
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
`state.ui_audit` exists only inside the work-engine dispatcher, so only there
|
|
73
|
+
is "the audit ran" a *checked* fact. A chat session cannot verify it: "I ran
|
|
74
|
+
`existing-ui-audit` first" is self-report, and self-report is not enforcement —
|
|
75
|
+
the same honesty boundary `security-sensitive-stop` and
|
|
76
|
+
`untrusted-input-defense` state for their own obligations. So this rule ships
|
|
77
|
+
`enforced_by: none` outside the dispatcher, deliberately, rather than pretending
|
|
78
|
+
a satisfiable-by-assertion condition is a gate.
|
|
79
|
+
|
|
80
|
+
What that leaves, and it is the useful part: run
|
|
81
|
+
[`existing-ui-audit`](../skills/existing-ui-audit/SKILL.md) before adding a
|
|
82
|
+
component because reuse beats duplication — not because a check will catch you.
|
|
83
|
+
Full enforcement requires the dispatcher (or the `frontend-design` pack once
|
|
84
|
+
pack-scoped rule projection is enabled; that flip is a maintainer decision,
|
|
85
|
+
never an automated one).
|
|
55
86
|
|
|
56
87
|
## Failure modes
|
|
57
88
|
|
|
@@ -37,7 +37,7 @@ sums ("attack the winner, using the losing options' strongest criteria")
|
|
|
37
37
|
1. **Inspect the artifact** — Read the plan, diff, or draft you are about to critique; note its scope, assumptions, and the explicit asks before attacking.
|
|
38
38
|
2. **Attack** — Run Step 1 below as the grumpy senior engineer.
|
|
39
39
|
3. **Defend** — Run Step 2 as the balanced engineer; classify each criticism as must-fix / defer / reject.
|
|
40
|
-
4. **Revise** — Run Step 3 to fold valid fixes back in
|
|
40
|
+
4. **Revise** — Run Step 3 to fold valid fixes back in, then report every criticism with its disposition. Deciding which trade-offs matter is the user's pass, not this step's.
|
|
41
41
|
|
|
42
42
|
### Step 1: Attack (Grumpy Senior Engineer)
|
|
43
43
|
|
|
@@ -64,8 +64,19 @@ Counter the criticism fairly:
|
|
|
64
64
|
- Move deferred concerns to "Open Questions" or "Known Limitations".
|
|
65
65
|
- Present the improved version to the user.
|
|
66
66
|
|
|
67
|
-
**
|
|
68
|
-
|
|
67
|
+
**Debate internally, report completely.** The user sees the improved result
|
|
68
|
+
rather than the blow-by-blow — but every criticism raised reaches the report
|
|
69
|
+
with its disposition (must-fix / deferred / rejected, each with one line of
|
|
70
|
+
reason). Do not decide on the user's behalf which concerns were worth their
|
|
71
|
+
attention.
|
|
72
|
+
|
|
73
|
+
This clause used to read *"surface only the trade-offs that need the user's
|
|
74
|
+
input"*, and that is the pre-filter defect: an instruction to report a subset is
|
|
75
|
+
followed literally — the review finds the defects, then withholds the ones it
|
|
76
|
+
judged unimportant, and the loss is invisible because the withheld set leaves no
|
|
77
|
+
trace. It matters here more than anywhere: `self_review_gate.ts` loads this file
|
|
78
|
+
as the system prompt for the package's own CI self-review, so a suppression
|
|
79
|
+
clause here suppresses findings on every pull request.
|
|
69
80
|
|
|
70
81
|
## Context-specific attack questions
|
|
71
82
|
|
|
@@ -148,7 +159,10 @@ triggers it. See [`rdp-gate`](../../contexts/execution/rdp-gate.md) (L12).
|
|
|
148
159
|
## Output format
|
|
149
160
|
|
|
150
161
|
1. Improved plan/code incorporating adversarial findings
|
|
151
|
-
2.
|
|
162
|
+
2. **Every criticism raised**, each with severity and disposition (must-fix /
|
|
163
|
+
deferred / rejected) and one line of reason. Not "top concerns" — a summary
|
|
164
|
+
that keeps only the highlights is the pre-filter defect wearing an
|
|
165
|
+
editor's hat.
|
|
152
166
|
3. Remaining open risks (if any) with severity rating
|
|
153
167
|
|
|
154
168
|
## Gotcha
|
|
@@ -173,6 +173,55 @@ strengthening evidence.
|
|
|
173
173
|
`skipped` (stale — age > `review_after_days`), surface them to
|
|
174
174
|
the user; do not silently use stale entries as if they were current.
|
|
175
175
|
|
|
176
|
+
## Removal is a disposition — a rule the agent keeps failing gets teeth or gets deleted
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
A RULE THE AGENT CONSISTENTLY FAILS TO FOLLOW GETS STRUCTURAL ENFORCEMENT
|
|
180
|
+
OR DELETION. NEVER A LOUDER RESTATEMENT.
|
|
181
|
+
ASK WHAT CAN BE REMOVED AS DELIBERATELY AS WHAT SHOULD BE ADDED.
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Ratchets in this tree move one way. Counts go up, gates accumulate, and nothing
|
|
185
|
+
retires an artifact — so the default response to non-adherence has been to say
|
|
186
|
+
it again, harder. That is the one response the evidence rules out: an obligation
|
|
187
|
+
that did not change behaviour as prose does not change it as louder prose. The
|
|
188
|
+
fork is **enforcement or deletion**, and both are real options.
|
|
189
|
+
|
|
190
|
+
**Non-adherence is the trigger, not low frequency.** A rule that rarely fires is
|
|
191
|
+
not a rule that fails. A floor is working precisely when nothing crosses it, and
|
|
192
|
+
deleting it because it has been quiet removes the thing that was holding.
|
|
193
|
+
|
|
194
|
+
### The simplify signals
|
|
195
|
+
|
|
196
|
+
Any of these is a reason to open the question. None of them is on its own a
|
|
197
|
+
verdict:
|
|
198
|
+
|
|
199
|
+
- a section that has not been relevant across many sessions;
|
|
200
|
+
- a rule derived from a **single unvalidated observation**;
|
|
201
|
+
- a workflow that is consistently shortcut in practice;
|
|
202
|
+
- sections that are loaded every run and never acted on;
|
|
203
|
+
- two rules that contradict each other;
|
|
204
|
+
- complexity added for a case that has never triggered.
|
|
205
|
+
|
|
206
|
+
Note that *never relevant*, *single unvalidated observation*, and *never acted
|
|
207
|
+
on* are listed separately on purpose. They look alike and they are not: the
|
|
208
|
+
first is about scope, the second about evidence, the third about attention.
|
|
209
|
+
|
|
210
|
+
### Escalation, and its counterpart
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
A THIRD RECURRENCE OF THE SAME VIOLATION CLASS CONVERTS AN OBSERVATION
|
|
214
|
+
INTO A DETERMINISTIC GATE.
|
|
215
|
+
A REVIEW FINDING NEVER SILENTLY BECOMES A HARD GATE.
|
|
216
|
+
ESCALATE AT A STATED THRESHOLD, NEVER SILENTLY.
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Both halves are load-bearing and they come from sources that disagree. The
|
|
220
|
+
threshold stops a recurring defect from being re-observed forever; the
|
|
221
|
+
counterpart stops a single reviewer's opinion from quietly becoming law. Between
|
|
222
|
+
them, the only legitimate path from *noticed* to *enforced* is a stated count
|
|
223
|
+
reached in the open.
|
|
224
|
+
|
|
176
225
|
## Decision-revisit gate — mechanics (migrated from the `decision-revisit-gate` rule)
|
|
177
226
|
|
|
178
227
|
Body of [`decision-revisit-gate`](../../rules/decision-revisit-gate.md)
|
|
@@ -101,7 +101,11 @@ Before finalising:
|
|
|
101
101
|
2. No dimension was penalised for length or word count.
|
|
102
102
|
3. N/A credit was granted only where the schema allows it.
|
|
103
103
|
4. The verdict follows the ratio thresholds above, not intuition.
|
|
104
|
-
5.
|
|
104
|
+
5. The **Dimensions block lists every dimension**, scored, with no omissions —
|
|
105
|
+
that is the complete emission and it is not optional. **Top gaps** is a
|
|
106
|
+
ranked summary layered over it, so it names the highest-weight misses rather
|
|
107
|
+
than repeating the block. Shortening the block itself is the pre-filter
|
|
108
|
+
defect; shortening the summary is what a summary is.
|
|
105
109
|
|
|
106
110
|
## Output format
|
|
107
111
|
|
|
@@ -121,11 +121,24 @@ Issues (if revise/reject):
|
|
|
121
121
|
Trigger: <concrete input/condition>
|
|
122
122
|
Expected: <what should happen>
|
|
123
123
|
🟡 ...
|
|
124
|
+
|
|
125
|
+
Rejected candidates (if the devil's-advocate pass killed any):
|
|
126
|
+
🔴→drop path/to/file.ext:LINE — <the finding> · refuted by: <guard clause
|
|
127
|
+
upstream | framework default | unreachable input | …>
|
|
124
128
|
```
|
|
125
129
|
|
|
126
130
|
Severity: 🔴 crash or incorrect result / 🟡 edge case unhandled but
|
|
127
131
|
graceful / 🟢 defensive-coding suggestion.
|
|
128
132
|
|
|
133
|
+
**A killed 🔴 is demoted, never deleted.** This judge runs a refutation pass on
|
|
134
|
+
every 🔴 and used to leave no trace of what it killed — the one judge with a
|
|
135
|
+
refutation step and no demotion bucket, where `code-review`, `security-audit`,
|
|
136
|
+
`bug-analyzer`, and the adversarial council all pair theirs with one. The
|
|
137
|
+
asymmetry matters because refutation is a judgement: a reviewer who was wrong to
|
|
138
|
+
refute leaves the reader no way to notice. Confidence is what the row carries;
|
|
139
|
+
severity is what it keeps — a 🔴 refuted on a guess is still a 🔴 somebody should
|
|
140
|
+
look at.
|
|
141
|
+
|
|
129
142
|
Required fields (ordered):
|
|
130
143
|
|
|
131
144
|
1. **Judge** and **Model** — skill name and resolved judge model
|
|
@@ -133,6 +146,9 @@ Required fields (ordered):
|
|
|
133
146
|
3. **Verdict** — `apply`, `revise`, or `reject`
|
|
134
147
|
4. **Issues** — every finding cites file:line and concrete trigger;
|
|
135
148
|
omit only when verdict is `apply`
|
|
149
|
+
5. **Rejected candidates** — every finding the refutation pass killed, with what
|
|
150
|
+
refuted it. Omit the section only when the pass killed nothing; never omit it
|
|
151
|
+
because the kills seemed obvious.
|
|
136
152
|
|
|
137
153
|
If a finding needs runtime confirmation, note it as a follow-up for
|
|
138
154
|
the implementer with the concrete probe — backend: `curl` or
|
|
@@ -63,6 +63,15 @@ finding count. Preserve each
|
|
|
63
63
|
judge's own verdict word (do not normalise away `breached` into `reject`); add a
|
|
64
64
|
severity tier (worst/mid/clean) only as a sort key.
|
|
65
65
|
|
|
66
|
+
**A sort key, never a filter.** Severity orders the synthesis; it never decides
|
|
67
|
+
what enters it. Dropping a judge's low-severity finding during synthesis
|
|
68
|
+
reproduces the pre-filter defect one layer up — the finding was found, the
|
|
69
|
+
reviewer reported it, and the aggregator withheld it. Filtering is the
|
|
70
|
+
consumer's pass, after the ledger is whole. Output shape, the separate
|
|
71
|
+
`Confidence` field, and the preserve-an-unverified-S0 rule are specified once in
|
|
72
|
+
[`adversarial-review-protocol`](../../../docs/contracts/adversarial-review-protocol.md)
|
|
73
|
+
§ 3.
|
|
74
|
+
|
|
66
75
|
### 2. Find consensus (highest confidence)
|
|
67
76
|
|
|
68
77
|
A finding flagged by **≥2 judges** (same file:line / same dimension / same
|
|
@@ -85,7 +94,11 @@ contested.
|
|
|
85
94
|
- **Must-fix** — every finding from a worst-tier verdict (`reject` / `incomplete`
|
|
86
95
|
/ `breached`) + every consensus finding at the highest severity.
|
|
87
96
|
- **Should-fix** — mid-tier (`revise` / `partial`) findings.
|
|
88
|
-
- **Advisory** — single-judge low-severity suggestions.
|
|
97
|
+
- **Advisory** — single-judge low-severity suggestions. **Emitted in full,
|
|
98
|
+
never elided.** This is the tier with no downstream consumer, which makes it
|
|
99
|
+
the one where quiet dropping costs nothing visible — and that is exactly why
|
|
100
|
+
it is stated: a finding that reached a judge and not the reader was suppressed
|
|
101
|
+
by the aggregator, whatever the tier was called.
|
|
89
102
|
|
|
90
103
|
Each entry carries **provenance**: which judge(s) raised it. Never merge two
|
|
91
104
|
judges' findings into one unattributed line.
|
|
@@ -203,6 +203,39 @@ See § 3b above for the load-bearing distinction between `load_context:`
|
|
|
203
203
|
(logical, rewritten), `triggers[].path_prefix:` (literal, verbatim),
|
|
204
204
|
and body links (relative `../../docs/...`, rewriter handles depth).
|
|
205
205
|
|
|
206
|
+
## Required: name the primary bias this rule overrides
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
EVERY RULE STATES, IN ONE SENTENCE, THE MODEL'S WRONG DEFAULT IT EXISTS TO
|
|
210
|
+
OVERRIDE. NOT THE HISTORY. NOT THE RATIONALE. THE TENDENCY.
|
|
211
|
+
A RULE THAT CANNOT NAME ONE IS A RULE WITH NO OBSERVED FAILURE BEHIND IT.
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
One sentence, near the top, in the shape *"left alone, the model
|
|
215
|
+
<does the wrong thing>"*:
|
|
216
|
+
|
|
217
|
+
- ✅ "Left alone, the model treats a question as an instruction and starts
|
|
218
|
+
building."
|
|
219
|
+
- ✅ "Left alone, the model reports the happy path it just made pass and calls
|
|
220
|
+
the change finished."
|
|
221
|
+
- ❌ "This rule exists because a session in June went badly." — backstory.
|
|
222
|
+
- ❌ "Correctness matters." — a value, not a tendency.
|
|
223
|
+
- ❌ "Agents sometimes make mistakes." — true of everything, discriminates
|
|
224
|
+
nothing.
|
|
225
|
+
|
|
226
|
+
**Why this field and not a longer rationale.** It is the discriminator the
|
|
227
|
+
mechanism-must-match-an-observed-failure-mode discipline wants at *authoring*
|
|
228
|
+
time: a rule whose bias sentence is a plausible generality is a rule aimed at
|
|
229
|
+
nothing in particular, and that is visible in one line where it is invisible in
|
|
230
|
+
three paragraphs. The field is also the input to the removal question later —
|
|
231
|
+
`decision-review` asks whether the agent still exhibits the named tendency, and
|
|
232
|
+
that question cannot be asked of a rule that never named one.
|
|
233
|
+
|
|
234
|
+
**Retrofit is opportunistic, never a sweep.** Add the sentence when you touch a
|
|
235
|
+
rule for another reason. A batch edit across the rule set trips the
|
|
236
|
+
kernel-prefix byte-stability gate, and that gate is right to fire — the kernel
|
|
237
|
+
prefix is pinned deliberately.
|
|
238
|
+
|
|
206
239
|
## Output format
|
|
207
240
|
|
|
208
241
|
1. Complete rule file at `src/rules/{name}.md`
|