@arbiterforge/ca-pi 0.19.0 → 0.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/plugins/ca-pi/CHANGELOG.md +16 -0
  4. package/plugins/ca-pi/SPRINT.md +1 -0
  5. package/plugins/ca-pi/agents/grader.md +5 -4
  6. package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-amd64 +0 -0
  7. package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-arm64 +0 -0
  8. package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-amd64 +0 -0
  9. package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-arm64 +0 -0
  10. package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-amd64.exe +0 -0
  11. package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-arm64.exe +0 -0
  12. package/plugins/ca-pi/helpers/artifacts/release.json +36 -36
  13. package/plugins/ca-pi/hooks/_host.py +1 -1
  14. package/plugins/ca-pi/hooks/hostapi.py +1 -1
  15. package/plugins/ca-pi/includes/artifacts.md +5 -0
  16. package/plugins/ca-pi/includes/smarts/core.md +95 -17
  17. package/plugins/ca-pi/includes/smarts/lenses.md +115 -0
  18. package/plugins/ca-pi/package.json +1 -1
  19. package/plugins/ca-pi/routines/brainstorming/SKILL.md +6 -0
  20. package/plugins/ca-pi/routines/debug/SKILL.md +1 -0
  21. package/plugins/ca-pi/routines/decision-variance/references/analysis.md +5 -2
  22. package/plugins/ca-pi/routines/refactor/SKILL.md +6 -0
  23. package/plugins/ca-pi/routines/subagent-driven-development/SKILL.md +8 -0
  24. package/plugins/ca-pi/routines/writing-plans/SKILL.md +8 -0
  25. package/plugins/ca-pi/skills/ca-debug/SKILL.md +1 -0
  26. package/plugins/ca-pi/skills/ca-feature/SKILL.md +7 -0
  27. package/plugins/ca-pi/skills/ca-fix/SKILL.md +6 -0
  28. package/plugins/ca-pi/skills/ca-refactor/SKILL.md +6 -0
package/README.md CHANGED
@@ -10,7 +10,7 @@ and durable project context. You decide. codeArbiter enforces.
10
10
  <img alt="Claude Code plugin" src="https://img.shields.io/badge/Claude_Code-plugin-d97757">
11
11
  <img alt="Codex plugin" src="https://img.shields.io/badge/OpenAI_Codex-plugin-10a37f">
12
12
  <img alt="Pi Feature Forge preview" src="https://img.shields.io/badge/ca--pi-Feature_Forge_preview-d97757">
13
- <img alt="version 3.0.0" src="https://img.shields.io/badge/version-3.0.0-2b7489">
13
+ <img alt="version 3.1.1" src="https://img.shields.io/badge/version-3.1.1-2b7489">
14
14
  <img alt="core lanes" src="https://img.shields.io/badge/core_lanes-18-555">
15
15
  <img alt="skills" src="https://img.shields.io/badge/skills-22-555">
16
16
  <img alt="agents" src="https://img.shields.io/badge/agents-20-555">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arbiterforge/ca-pi",
3
- "version": "0.19.0",
3
+ "version": "0.20.1",
4
4
  "license": "AGPL-3.0-only",
5
5
  "repository": {
6
6
  "type": "git",
@@ -4,6 +4,22 @@ All notable changes to `ca-pi` are documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.20.1] - 2026-10-18
8
+
9
+ ### Fixed
10
+
11
+ - A spec whose design had only one sane approach recorded its SMARTS rationale with not-applicable filler for every rationale part, because the rationale convention listed all parts unconditionally. The convention now applies the multi-part rationale only when a comparison ran; a single-option choice records exactly one block, its one-line statement and reason. Found by a live `/feature` run.
12
+ - The SMARTS rationale convention and the spec-compliance reviewer no longer describe the rationale as belonging to an "approved" spec, since 3.0.0 retired spec approval.
13
+
14
+ ## [0.20.0] - 2026-10-17
15
+
16
+ ### Added
17
+
18
+ - SMARTS is now the six-lens design-quality rubric for material engineering solution choices, not only architectural variance. Workflows pick a depth (scan, comparison or delegated decision); SMARTS itself grants no approval and is not a command.
19
+ - A fifth verdict, `Unknown`, records missing evidence with its missing observation and whether it is decision-critical. A decision-critical `Unknown` blocks a strong recommendation and the selection of the option that carries it, and never stands in for user approval, a prerequisite or security authority. The engine validates the `smarts-plan-method/0.2.0` record while historical `0.1.0` receipts keep their four-verdict contract.
20
+ - SMARTS runs only where a material choice exists: brainstorming compares approaches when two or more are materially plausible (a single approach gets one line and no table), the `/feature` small lane scans only a material choice, `/fix` compares remediation strategies only after root cause, and refactor compares only distinct strategies. Writing-plans routes undecided design choices back to brainstorming, and verification checks the change against a recorded rationale for material invalidation only.
21
+ - Specs carry a concise SMARTS design rationale (`SEC-SMARTS`), and the per-lens historical detail loads lazily from `includes/smarts/lenses.md`.
22
+
7
23
  ## [0.19.0] - 2026-10-14
8
24
 
9
25
  ### Changed
@@ -48,6 +48,7 @@ The initial request bounds the work; it does **not** grant arbitrary future scop
48
48
  Send the selected plan to `subagent-driven-development` with no artificial per-batch human pause. It reads compact task records, selects actual dependency-clean work, and implements or delegates coherent units. Use TDD where behavior changes benefit from test-first work. Tests, review, and evidence belong to their actual subject and risk; do not require a fixed number of reviewers or rerun them because a receipt ID changed.
49
49
 
50
50
  **Deciding on behalf of the sprint:** use the user's intent and priorities to choose reversible implementation methods. Use SMARTS when a genuinely difficult trade-off warrants it, not as a six-lens tax on every step. Record material decisions in `.codearbiter/sprint-log.md` with reason and any meaningful uncertainty. A changed method, verification runner, or task decomposition within the agreed outcome is ordinary typed plan maintenance with a short reason, not a new user grant. A materially different product outcome is a question for the actual owner.
51
+ Per `<plugin-root>/includes/smarts/core.md`, an `Unknown` cell names its missing observation and whether it is decision-critical; an `Unknown` cannot bypass a hard gate or manufacture authority, and never stands in for user approval, a prerequisite or security authority.
51
52
 
52
53
  For HTML, use receipt-free `task-start`, `task-review` (implementation reported ready), `task-reconcile` (reasoned progress correction), and `accept-scope` (reported implementation `DONE`) as appropriate. These labels **never certify a passing check, independent review, or released artifact**. Preserve applicable test output and state the exact outstanding checks. `eligible` is advisory scheduling; use `verification-status` only when an explicit historical attestation claim is actually needed, never to decide whether ordinary code editing may proceed.
53
54
 
@@ -80,7 +80,7 @@ Constraints:
80
80
  | Testable | ... | ... | ... |
81
81
  | Securable | ... | ... | ... |
82
82
 
83
- (Each cell: starts with verdict word — Strong, Adequate, Weak, or Indifferent — followed by brief justification. No hedging adverbs. Specific evidence required, not vague claims.)
83
+ (Each cell: starts with verdict word — Strong, Adequate, Weak, Indifferent, or Unknown — followed by brief justification. An `Unknown` cell names its `missing_observation` and states whether it is `decision_critical`. No hedging adverbs. Specific evidence required, not vague claims.)
84
84
 
85
85
  ## Lens dominance for this decision
86
86
 
@@ -117,7 +117,8 @@ Before returning, verify:
117
117
  | Check | Status |
118
118
  |---|---|
119
119
  | Every SMARTS cell ≤ 25 words | yes / no — [list violating cells if any] |
120
- | Every cell starts with verdict word (Strong/Adequate/Weak/Indifferent) | yes / no |
120
+ | Every cell starts with verdict word (Strong/Adequate/Weak/Indifferent/Unknown) | yes / no |
121
+ | Every `Unknown` cell names its missing observation and decision-criticality | yes / no |
121
122
  | No hedging adverbs used | yes / no — [list occurrences if any] |
122
123
  | Recommendation strength is strong, moderate, or tied (not "weak") | yes / no |
123
124
  | No vague claims ("industry standard", "widely adopted") | yes / no |
@@ -127,7 +128,7 @@ If any check fails: fix the violation before returning. A non-conformant analysi
127
128
 
128
129
  ## Strength of Recommendation Levels
129
130
 
130
- - **strong** — multiple dominant lenses align cleanly on one option; non-SMARTS considerations confirm.
131
+ - **strong** — multiple dominant lenses align cleanly on one option; non-SMARTS considerations confirm; and no option carries a decision-critical `Unknown`.
131
132
  - **moderate** — dominant lenses align with caveats, or a single lens dominates.
132
133
  - **tied** — the analysis produces no preferred option; user judgment is required.
133
134
 
@@ -140,7 +141,7 @@ The `decision-variance` skill uses strength to decide how forcefully to present
140
141
  Non-negotiable:
141
142
 
142
143
  1. **Length cap:** each SMARTS cell ≤ 25 words.
143
- 2. **Verdict-first:** each cell starts with `Strong`, `Adequate`, `Weak`, or `Indifferent`.
144
+ 2. **Verdict-first:** each cell starts with `Strong`, `Adequate`, `Weak`, `Indifferent`, or `Unknown`. An `Unknown` cell names its `missing_observation` and states whether it is `decision_critical`; a lens that matters but lacks evidence is `Unknown`, never `Indifferent` for missing evidence.
144
145
  3. **Justification follows:** ≤ 20 words after the verdict.
145
146
  4. **No hedging adverbs:** "potentially," "might," "arguably," "perhaps," "generally," "tends to," "could be," "may" are forbidden.
146
147
  5. **Evidence specificity:** vague claims do not count. Cite a specific property of the option, a specific project constraint, or a specific failure mode.
@@ -6,43 +6,43 @@
6
6
  "binaries": {
7
7
  "darwin/amd64": {
8
8
  "file": "ca-artifact-darwin-amd64",
9
- "sha256": "1849b2d8abaa5ef76a4f1682bc75ba2fcf452b55d3c66f7bb6a16b141558438d",
9
+ "sha256": "ca6dc89a106f4b79eb2ab992eb7617c79742f88eb3d5d9b0444102ecf3f23ed3",
10
10
  "native_tested": true
11
11
  },
12
12
  "darwin/arm64": {
13
13
  "file": "ca-artifact-darwin-arm64",
14
- "sha256": "7ee24e5ddd330a2b52336470cd28635b7f1ea16a235fd377058952d5696b0e15",
14
+ "sha256": "04dae5874b003fb5530a460c3d9ce6da8284ca7bbfb886e6b6591d0e2980934d",
15
15
  "native_tested": true
16
16
  },
17
17
  "linux/amd64": {
18
18
  "file": "ca-artifact-linux-amd64",
19
- "sha256": "1d20e9dfdc663c4f3d82f82cb1df861261304acf439f604f7bddc33a79f6af91",
19
+ "sha256": "1b2d858cf64e7774cbc2abf8abe7921c5f9fe147fcee796e70dbe38478272847",
20
20
  "native_tested": true
21
21
  },
22
22
  "linux/arm64": {
23
23
  "file": "ca-artifact-linux-arm64",
24
- "sha256": "94a54eb7e83a4992a4ee78b98b7946d2332e2a007ad7fd4ec14a3e332ad16651",
24
+ "sha256": "37e592fb61297850b17e2cd6c603a203143940b42b04e7a285f081b0d9d848e5",
25
25
  "native_tested": true
26
26
  },
27
27
  "windows/amd64": {
28
28
  "file": "ca-artifact-windows-amd64.exe",
29
- "sha256": "d8f0bafd5f1949d93e87fb3cec7222ad9757087e30f7ea06268f148897f5b5a7",
29
+ "sha256": "4f4b3f4cf0ab7230f9cd577a3310a293007af1126913224c8e6103438aaafc8b",
30
30
  "native_tested": true
31
31
  },
32
32
  "windows/arm64": {
33
33
  "file": "ca-artifact-windows-arm64.exe",
34
- "sha256": "be36ede70afe3dfc57afcd1ff2f5be5b36134ac383998c10145809bd0b80f459",
34
+ "sha256": "855bfbd1c628a0b76cfa5bdf7d6ff392fb55e49dba23efb13e2a7a26d9e5ccb4",
35
35
  "native_tested": true
36
36
  }
37
37
  },
38
38
  "context_qualification": {
39
39
  "darwin/amd64": {
40
- "source_commit": "36685a40ab035074be04bb7204618acbb0a2dfdf",
40
+ "source_commit": "127abda72accc0530746b9f7e91531f21257f9ab",
41
41
  "workflow": ".github/workflows/ci.yml",
42
- "run_id": "38995632892",
43
- "binary_sha256": "1849b2d8abaa5ef76a4f1682bc75ba2fcf452b55d3c66f7bb6a16b141558438d",
44
- "observation_sha256": "4b2b1f09e54d99fe7e7cc0ca177b80c2ac5d47e6428eddd551453a13ac2b272f",
45
- "module_sha256": "91fed16f177e249d082638387a5f6e8d38dcb33604f357e8296b2f0124a4ca2a",
42
+ "run_id": "39166092260",
43
+ "binary_sha256": "ca6dc89a106f4b79eb2ab992eb7617c79742f88eb3d5d9b0444102ecf3f23ed3",
44
+ "observation_sha256": "c1dc9508d095372b7c310a36a9eafe657ae30895d5256c7336cbc5a14b0e9336",
45
+ "module_sha256": "a34f09f52c52145624e87c1d5e3850c822dd1ca54c346c5ad63802f6e5a0d0b3",
46
46
  "native_cases": [
47
47
  "TestContextBoundedRender",
48
48
  "TestContextDocumentContract",
@@ -53,12 +53,12 @@
53
53
  ]
54
54
  },
55
55
  "darwin/arm64": {
56
- "source_commit": "36685a40ab035074be04bb7204618acbb0a2dfdf",
56
+ "source_commit": "127abda72accc0530746b9f7e91531f21257f9ab",
57
57
  "workflow": ".github/workflows/ci.yml",
58
- "run_id": "38995632892",
59
- "binary_sha256": "7ee24e5ddd330a2b52336470cd28635b7f1ea16a235fd377058952d5696b0e15",
60
- "observation_sha256": "3a30a7b8a8d719ac8f261f3c9094bae62a5d9e3db31b565dc401d21486ed48f3",
61
- "module_sha256": "91fed16f177e249d082638387a5f6e8d38dcb33604f357e8296b2f0124a4ca2a",
58
+ "run_id": "39166092260",
59
+ "binary_sha256": "04dae5874b003fb5530a460c3d9ce6da8284ca7bbfb886e6b6591d0e2980934d",
60
+ "observation_sha256": "af9b64da45bc38e2f66545269455496c6bdc780942e314e0e0104b1598ae34e1",
61
+ "module_sha256": "a34f09f52c52145624e87c1d5e3850c822dd1ca54c346c5ad63802f6e5a0d0b3",
62
62
  "native_cases": [
63
63
  "TestContextBoundedRender",
64
64
  "TestContextDocumentContract",
@@ -69,12 +69,12 @@
69
69
  ]
70
70
  },
71
71
  "linux/amd64": {
72
- "source_commit": "36685a40ab035074be04bb7204618acbb0a2dfdf",
72
+ "source_commit": "127abda72accc0530746b9f7e91531f21257f9ab",
73
73
  "workflow": ".github/workflows/ci.yml",
74
- "run_id": "38995632892",
75
- "binary_sha256": "1d20e9dfdc663c4f3d82f82cb1df861261304acf439f604f7bddc33a79f6af91",
76
- "observation_sha256": "d977095e8db3aa5bd71fd2db318292d6c6da3aa716b1253ae7ad0fe95780c475",
77
- "module_sha256": "91fed16f177e249d082638387a5f6e8d38dcb33604f357e8296b2f0124a4ca2a",
74
+ "run_id": "39166092260",
75
+ "binary_sha256": "1b2d858cf64e7774cbc2abf8abe7921c5f9fe147fcee796e70dbe38478272847",
76
+ "observation_sha256": "b85fd2f47de1b531d94627dc91d8fceea7886773205fec61231a02c568541aec",
77
+ "module_sha256": "a34f09f52c52145624e87c1d5e3850c822dd1ca54c346c5ad63802f6e5a0d0b3",
78
78
  "native_cases": [
79
79
  "TestContextBoundedRender",
80
80
  "TestContextDocumentContract",
@@ -85,12 +85,12 @@
85
85
  ]
86
86
  },
87
87
  "linux/arm64": {
88
- "source_commit": "36685a40ab035074be04bb7204618acbb0a2dfdf",
88
+ "source_commit": "127abda72accc0530746b9f7e91531f21257f9ab",
89
89
  "workflow": ".github/workflows/ci.yml",
90
- "run_id": "38995632892",
91
- "binary_sha256": "94a54eb7e83a4992a4ee78b98b7946d2332e2a007ad7fd4ec14a3e332ad16651",
92
- "observation_sha256": "24d3bdce7f5044e3c5dda44b0f2a5ccd37bd0821408aa8f62b5b329aacd8e98b",
93
- "module_sha256": "91fed16f177e249d082638387a5f6e8d38dcb33604f357e8296b2f0124a4ca2a",
90
+ "run_id": "39166092260",
91
+ "binary_sha256": "37e592fb61297850b17e2cd6c603a203143940b42b04e7a285f081b0d9d848e5",
92
+ "observation_sha256": "5c6534f4b9f8ee000acdf53bf5f7b3c608203a965fc6d8a4e1fd4f15c52f2e96",
93
+ "module_sha256": "a34f09f52c52145624e87c1d5e3850c822dd1ca54c346c5ad63802f6e5a0d0b3",
94
94
  "native_cases": [
95
95
  "TestContextBoundedRender",
96
96
  "TestContextDocumentContract",
@@ -101,12 +101,12 @@
101
101
  ]
102
102
  },
103
103
  "windows/amd64": {
104
- "source_commit": "36685a40ab035074be04bb7204618acbb0a2dfdf",
104
+ "source_commit": "127abda72accc0530746b9f7e91531f21257f9ab",
105
105
  "workflow": ".github/workflows/ci.yml",
106
- "run_id": "38995632892",
107
- "binary_sha256": "d8f0bafd5f1949d93e87fb3cec7222ad9757087e30f7ea06268f148897f5b5a7",
108
- "observation_sha256": "eb42182fceca7bdb85924d382a8cf3917fb49b9c2a8a32ccd563a3acab245547",
109
- "module_sha256": "91fed16f177e249d082638387a5f6e8d38dcb33604f357e8296b2f0124a4ca2a",
106
+ "run_id": "39166092260",
107
+ "binary_sha256": "4f4b3f4cf0ab7230f9cd577a3310a293007af1126913224c8e6103438aaafc8b",
108
+ "observation_sha256": "2e973fff4fbc181674affd54e28eb75582e05cae4121a0281a12e86dd27d5843",
109
+ "module_sha256": "a34f09f52c52145624e87c1d5e3850c822dd1ca54c346c5ad63802f6e5a0d0b3",
110
110
  "native_cases": [
111
111
  "TestContextBoundedRender",
112
112
  "TestContextDocumentContract",
@@ -117,12 +117,12 @@
117
117
  ]
118
118
  },
119
119
  "windows/arm64": {
120
- "source_commit": "36685a40ab035074be04bb7204618acbb0a2dfdf",
120
+ "source_commit": "127abda72accc0530746b9f7e91531f21257f9ab",
121
121
  "workflow": ".github/workflows/ci.yml",
122
- "run_id": "38995632892",
123
- "binary_sha256": "be36ede70afe3dfc57afcd1ff2f5be5b36134ac383998c10145809bd0b80f459",
124
- "observation_sha256": "12b1ba42509dd791bebf60df616608e7dbf50359175f90a3cf7a857c3c82cad8",
125
- "module_sha256": "91fed16f177e249d082638387a5f6e8d38dcb33604f357e8296b2f0124a4ca2a",
122
+ "run_id": "39166092260",
123
+ "binary_sha256": "855bfbd1c628a0b76cfa5bdf7d6ff392fb55e49dba23efb13e2a7a26d9e5ccb4",
124
+ "observation_sha256": "076a4e02e76abf1316b923b28fdff97714c0b2708bc8f2028c009c68d98e2991",
125
+ "module_sha256": "a34f09f52c52145624e87c1d5e3850c822dd1ca54c346c5ad63802f6e5a0d0b3",
126
126
  "native_cases": [
127
127
  "TestContextBoundedRender",
128
128
  "TestContextDocumentContract",
@@ -11,7 +11,7 @@ import hostapi # noqa: E402
11
11
  class PiHost(hostapi.Host):
12
12
  name = "pi"
13
13
  adapter_name = "@arbiterforge/ca-pi"
14
- adapter_version = "0.19.0"
14
+ adapter_version = "0.20.1"
15
15
  update_target = "ca-pi"
16
16
  update_tag_prefix = "ca-pi-v"
17
17
  update_command = "pi update npm:@arbiterforge/ca-pi"
@@ -313,7 +313,7 @@ class Host:
313
313
 
314
314
  name = "claude"
315
315
  adapter_name = "ca"
316
- adapter_version = "3.0.0"
316
+ adapter_version = "3.1.1"
317
317
 
318
318
  # Update-notifier descriptor. Each independently versioned host overrides
319
319
  # these three values in its per-plugin _host.py. Keeping the target,
@@ -34,6 +34,11 @@ authorized work. Do not invent criteria, decisions or test results to pass
34
34
  validation. A changed outcome goes to the actual decision owner; in-scope
35
35
  methods and task decomposition can be updated with a reason.
36
36
 
37
+ A spec's SMARTS design rationale is stored in its existing `approach` record, bound
38
+ `decisions` records and one `SEC-SMARTS` section, as defined once in
39
+ `<plugin-root>/includes/smarts/core.md` (Design rationale record); a legacy Markdown spec
40
+ uses its one `## SMARTS design rationale` section instead.
41
+
37
42
  Query an operation-specific `schema` only when its request shape is unknown;
38
43
  reuse known shapes for subsequent calls instead of querying on every read.
39
44
  Do not preload the entire schema. The packaged bridge invokes the verified native
@@ -1,10 +1,23 @@
1
- # SMARTS — lenses, cell rules, strength
1
+ # SMARTS — design-quality rubric
2
2
 
3
- The standardized evaluation for architectural variances. Apply the six lenses evenhandedly to every
4
- option. This is the project's framework; do not substitute another. This `core` file is everything the
5
- scoring path needs (decision-variance, the grader, the decision-challenger, and `/sprint` autonomous
6
- scoring). The append-only **decision-log entry format** lives separately in
7
- [`decision-log-format.md`](decision-log-format.md) — load it only when writing a log line.
3
+ SMARTS is codeArbiter's six-lens design-quality rubric for material engineering solution choices.
4
+ Workflow owners decide when a choice needs a scan, a full comparison, or delegated autonomous
5
+ handling; SMARTS itself does not grant authority. Architectural variance (decision-variance, the
6
+ grader, the decision-challenger) is one consumer of the rubric, not the definition of the framework.
7
+ Apply the six lenses evenhandedly to every option; this is the project's framework, do not substitute
8
+ another. This `core` file is everything a routine evaluation needs; the per-lens detail in [`lenses.md`](lenses.md)
9
+ is loaded only when a case named under the lenses below arises. The append-only **decision-log entry
10
+ format** lives separately in [`decision-log-format.md`](decision-log-format.md) — load it only when
11
+ writing a log line.
12
+
13
+ ## Evaluation depths
14
+
15
+ 1. **Scan** — a lightweight six-lens fitness pass when a choice is material but does not need the full table: name the material strengths, weaknesses, unknowns and decisive lenses; no full table is required in user-visible output.
16
+ 2. **Comparison** — the full option-by-option table, when two or more materially plausible approaches exist, when the user explicitly asks for a full SMARTS read, or when reconciliation or arbitration requires it.
17
+ 3. **Delegated decision** — a requested `/sprint` choosing a reversible in-scope method on the user's behalf and logging its reason in `.codearbiter/sprint-log.md`; no separate method grant is required.
18
+
19
+ All three depths use the semantics in this file; they differ in presentation, persistence and
20
+ decision authority, not in what the acronym means.
8
21
 
9
22
  ## Step 0 — recorded-intent check (before any lens is scored; ADR-0025)
10
23
 
@@ -37,8 +50,27 @@ Three outcomes:
37
50
  Fail-soft: an absent `plans/` or `decisions/` directory is not a gap to surface and never a STOP —
38
51
  record `intent: silent — no decomposition record` and proceed.
39
52
 
53
+ ## Context envelope
54
+
55
+ Before judging a material choice, establish only the context that makes the lenses meaningful:
56
+
57
+ - **decision** — the actual choice being made, stated when the request leaves it implicit.
58
+ - **scope/horizon** — the bounded system and planning horizon, when they change a verdict.
59
+ - **scale expectation** — only when scale could differentiate the options.
60
+ - **failure/availability expectation** — only when failure behavior could differentiate the options.
61
+ - **security/trust boundary** — only when it bears on Securable.
62
+ - **non-SMARTS constraints** — cost, schedule, team skill, vendor or stakeholder constraints, only when they materially affect the recommendation.
63
+
64
+ The envelope is scope-sized and fail-soft. No dimension is required for every choice, and it creates
65
+ no new project or configuration file: existing project context, the active spec, explicit user
66
+ steering and relevant recorded decisions supply the evidence when available.
67
+
40
68
  ## The six lenses
41
69
 
70
+ The summaries below settle most verdicts. Load the per-lens reference
71
+ [`lenses.md`](lenses.md) only when a verdict turns on a consideration these summaries do not
72
+ settle, or when the user asks for a full SMARTS read — never for a routine scan.
73
+
42
74
  - **Scalable** — supports growth in users, data, throughput, geography without an architectural rewrite. Trap: over-engineering for scale that never arrives, or under-engineering for scale that's on the roadmap.
43
75
  - **Maintainable** — can be understood, modified, and extended later (including by agents) without prohibitive effort. Standard patterns over bespoke abstractions; mind the refactoring blast radius and eventual hand-off.
44
76
  - **Available** — reachable and functional when needed, including under partial failure. Watch single points of failure, bundled-dependency failure, recovery time. Do not conflate availability with high availability.
@@ -46,33 +78,79 @@ record `intent: silent — no decomposition record` and proceed.
46
78
  - **Testable** — validated by deterministic, fast tests that cover real failure modes. Unit + integration + contract; mind mockability and test-data isolation. "Tests later" is a Weak verdict.
47
79
  - **Securable** — enables the project's security posture (per `<project-root>/.codearbiter/security-controls.md`) without retrofit. Authentication, authorization, audit, secret management, attack surface, default-deny stance, supply-chain integrity.
48
80
 
81
+ ## Verdicts
82
+
83
+ Every evaluated lens takes exactly one verdict:
84
+
85
+ - **Strong** — performs well for the stated context.
86
+ - **Adequate** — acceptable for the stated context.
87
+ - **Weak** — materially poor for the stated context.
88
+ - **Indifferent** — evidence shows the lens does not materially differentiate the options at the stated context and horizon. If any option marks a lens `Indifferent`, every option marks it `Indifferent`. In a single-option scan there is nothing to differentiate, so Indifferent means the lens is not material to this choice at the stated context; a lens that matters but lacks evidence is `Unknown`, never `Indifferent`.
89
+ - **Unknown** — the evidence needed to judge the lens is missing, contradictory or not yet established. Every Unknown names its missing observation (`missing_observation`) and states whether it is decision-critical (`decision_critical`: true when that observation could change the selected option); no other verdict carries those fields.
90
+
91
+ `Unknown` is not neutral: never treat it as `Indifferent`, `Adequate` or a pass, and never map it to
92
+ one. A recommendation may stand with a non-critical Unknown only when the output names the missing
93
+ observation and why it does not control the decision. A decision-critical Unknown blocks a `strong`
94
+ recommendation, blocks selecting the option that carries it, and is surfaced before any irreversible
95
+ or authority-bearing choice. A non-critical Unknown never shields a dominated option: on the selected
96
+ option it is no better than the other option's verdict on that lens, and strictly worse than a compared
97
+ `Strong`.
98
+
49
99
  ## Cell rules (hard)
50
100
 
51
101
  Each SMARTS cell is a constraint, not a guideline. A non-conformant cell is rejected.
52
102
 
53
103
  1. **Length cap** — at most 25 words per cell.
54
- 2. **Verdict-first** — every cell opens with one verdict word: `Strong` (performs well), `Adequate` (acceptable), `Weak` (poor), `Indifferent` (this lens does not differentiate the options at the current scale).
55
- 3. **Justification follows** — at most 20 words after the verdict.
56
- 4. **No hedging adverbs** — forbidden: potentially, might, arguably, perhaps, generally, tends to, could be, may. If genuinely uncertain, the verdict is `Indifferent`.
104
+ 2. **Verdict-first** — every cell opens with one verdict word: `Strong`, `Adequate`, `Weak`, `Indifferent` or `Unknown`.
105
+ 3. **Justification follows** — at most 20 words after the verdict; an `Unknown` justification names the missing observation and whether it is decision-critical.
106
+ 4. **No hedging adverbs** — forbidden: potentially, might, arguably, perhaps, generally, tends to, could be, may. If genuinely uncertain, the verdict is `Unknown` with its missing observation.
57
107
  5. **Evidence specificity** — "industry standard," "best practice," "widely adopted" are not evidence. Cite a specific property of the option, a specific project constraint, or a specific failure mode.
58
108
 
109
+ ## Conflicting lenses and priority
110
+
111
+ SMARTS stays qualitative: never count `Strong` cells, assign weights, sum or compute percentages to pick a winner.
112
+ Per-lens dominance — one option no worse on every lens and better on at least one — is an ordinal
113
+ comparison, not a score. When lenses conflict, apply preference evidence in this order:
114
+
115
+ 1. explicit current user or approved-spec priority;
116
+ 2. explicit project priority already recorded in project context or an accepted decision;
117
+ 3. relevant prior-decision precedent, labelled as precedent, not authority;
118
+ 4. no assumed priority.
119
+
120
+ Absent explicit priority evidence, a tied comparison stays tied.
121
+
59
122
  ## Strength of recommendation
60
123
 
61
124
  Every recommendation carries exactly one strength label:
62
125
 
63
- - **strong** — multiple dominant lenses align cleanly on one option; non-SMARTS factors confirm.
126
+ - **strong** — dominant lenses align cleanly on one option, non-SMARTS factors confirm, and no option carries a decision-critical Unknown.
64
127
  - **moderate** — dominant lenses align with caveats, or a single lens dominates.
65
128
  - **tied** — no preferred option emerges. A legitimate output: "This is a coin flip under SMARTS — your call."
66
129
 
67
- There is no `weak` level — a slight edge is `moderate`. When lenses conflict with no winner, state it
68
- plainly, surface which lens the user has emphasized in prior decisions as input, and mark `tied`.
69
- The `Precedent:` line under each table (decision-variance Phase 3) is how that emphasis is surfaced
70
- systematically: 1–3 most-similar prior decisions by ID plus the observed lens pattern, or
71
- `Precedent: none on record` when history is thin — never an invented pattern.
130
+ There is no `weak` level — a slight edge is `moderate`. The `Precedent:` line under each table
131
+ (decision-variance Phase 3) surfaces step 3 of the priority order: 1–3 most-similar prior decisions by
132
+ ID plus the observed lens pattern, or `Precedent: none on record` when history is thin — never an
133
+ invented pattern, and never authority on its own.
72
134
 
73
135
  SMARTS does not cover cost, time-to-market, team-skill fit, vendor lock-in, or political
74
- acceptability. When these matter, surface them as **non-SMARTS considerations** alongside the table;
75
- they supplement, never replace, the analysis.
136
+ acceptability. When these matter, surface them as **non-SMARTS considerations** alongside the
137
+ analysis; they supplement, never replace it, and never become a seventh lens.
138
+
139
+ ## Design rationale record
140
+
141
+ A full-lane spec keeps a concise SMARTS design rationale; it is design evidence, not a
142
+ source of execution authority. For a typed HTML spec, write it through the existing mutation
143
+ operations with this convention, with no spec-schema change:
144
+
145
+ - the chosen approach and its trade-off live in the existing `approach` record (`choice`, `tradeoff`);
146
+ - a `decisions` record carries each material decision the SMARTS pass settled, and `approach.binding_decision_refs` cites it;
147
+ - When a comparison ran, one `sections` record with the fixed id `SEC-SMARTS` (title "SMARTS design rationale") holds one block each for: alternatives considered or the single-option statement; decisive lenses; material Weak and Unknown observations, each Unknown with its missing observation and whether it is decision-critical; load-bearing assumptions; non-SMARTS considerations; and priority evidence when one influenced the recommendation.
148
+ - A single-option choice holds exactly one `SEC-SMARTS` block: its one-line statement and reason, with no other part. Do not pad it with not-applicable lens, assumption or constraint entries.
149
+
150
+ Read the rationale back with the existing read operations; never hand-edit or parse rendered HTML.
151
+ A legacy Markdown spec keeps the rationale in one stable `## SMARTS design rationale` section that
152
+ carries the same parts in the same order when a comparison ran, or the single-option statement and
153
+ its reason alone.
76
154
 
77
155
  ## Worked example
78
156
 
@@ -0,0 +1,115 @@
1
+ # SMARTS — lens reference (lazy)
2
+
3
+ Per-lens detail behind the one-line summaries in [`core.md`](core.md). `core.md` owns the role,
4
+ verdicts, cell rules and strength; this file only deepens what each lens asks. Load it only under
5
+ the condition `core.md` states — never for a routine scan the summaries already settle.
6
+
7
+ Each lens lists the question it answers, the considerations that usually decide it, the traps
8
+ that produce a wrong verdict, and the observation that settles an `Unknown` on it (the
9
+ `missing_observation` an Unknown cell names).
10
+
11
+ ## Scalable
12
+
13
+ **Question:** does the option support growth in users, data, throughput or geography without an
14
+ architectural rewrite?
15
+
16
+ **Considerations:**
17
+ - User scale across the stated horizon — prototype, pilot, production.
18
+ - Data volume and its growth rate, including retained history and logs.
19
+ - Throughput shape: bursty versus steady, and the peak the design must absorb.
20
+ - Geographic spread: single region now, multi-region on the roadmap or not.
21
+
22
+ **Traps:** over-engineering for scale that never arrives; under-engineering for scale that is on
23
+ the roadmap; confusing performance (one request is fast) with scalability (many requests stay fast).
24
+
25
+ **Settles an Unknown:** the expected load or data volume at the stated horizon, or a measurement
26
+ of the option at that load.
27
+
28
+ ## Maintainable
29
+
30
+ **Question:** can the system be understood, modified and extended later — including by agents —
31
+ without prohibitive effort?
32
+
33
+ **Considerations:**
34
+ - Comprehensibility for the next contributor, human or agent, without reading internals.
35
+ - Standard patterns versus bespoke abstractions.
36
+ - Documentation the option obliges someone to keep current.
37
+ - Refactoring blast radius when the option changes.
38
+ - Onboarding and hand-off cost to whoever owns the code next.
39
+
40
+ **Traps:** treating maintainability as one engineer's concern; underestimating the cost of a
41
+ bespoke pattern when agents write most of the code; ignoring the eventual hand-off.
42
+
43
+ **Settles an Unknown:** who maintains the code at the stated horizon, and whether the pattern
44
+ already exists in the codebase.
45
+
46
+ ## Available
47
+
48
+ **Question:** is the system reachable and functional when needed, including under partial failure?
49
+
50
+ **Considerations:**
51
+ - Single points of failure the option introduces or removes.
52
+ - Failure of a bundled or external dependency, and what keeps working.
53
+ - Disconnected or degraded operation requirements.
54
+ - Time to recover from the common failure modes.
55
+ - The downtime the caller can actually accept.
56
+
57
+ **Traps:** conflating availability with high availability; designing for high availability the
58
+ project does not require; ignoring partial-availability states.
59
+
60
+ **Settles an Unknown:** the stated downtime tolerance, or how the option behaves when its
61
+ dependency is unreachable.
62
+
63
+ ## Reliable
64
+
65
+ **Question:** does the option produce correct, predictable, durable outcomes?
66
+
67
+ **Considerations:**
68
+ - Atomicity and durability where they matter — the decision log, audit events, receipts.
69
+ - Idempotency of retried operations.
70
+ - State consistency across components.
71
+ - Recovery from failure without corruption.
72
+ - Reproducibility of builds, deployments and recorded evidence.
73
+
74
+ **Traps:** assuming the database or framework handles it without checking; underestimating the
75
+ reliability cost of distribution; ignoring long-tail durability.
76
+
77
+ **Settles an Unknown:** the failure the option must survive, and evidence of its behavior under it.
78
+
79
+ ## Testable
80
+
81
+ **Question:** can the option be validated by deterministic, fast tests that cover meaningful
82
+ failure modes?
83
+
84
+ **Considerations:**
85
+ - Unit testability of the parts the option introduces.
86
+ - Integration and contract testing between components.
87
+ - Test data generation and isolation.
88
+ - Whether the real failure modes can be reproduced in a test, not just the happy path.
89
+ - The boundary between a throwaway spike and a test that must hold.
90
+
91
+ **Traps:** patterns that resist mocking or isolation; ignoring the cost of test infrastructure;
92
+ "tests later" for foundational components.
93
+
94
+ **Settles an Unknown:** whether a deterministic test can reproduce the failure mode the option
95
+ must handle.
96
+
97
+ ## Securable
98
+
99
+ **Question:** does the option enable the project's security posture — as defined in
100
+ `<project-root>/.codearbiter/security-controls.md` — without retrofit?
101
+
102
+ **Considerations:**
103
+ - Authentication boundary: who the actor is.
104
+ - Authorization boundary: what the actor may do.
105
+ - Audit boundary: what is recorded, and whether it can be trusted.
106
+ - Secret handling.
107
+ - Attack surface: every bundled component and exposed input.
108
+ - Default-deny versus default-allow stance.
109
+ - Supply-chain integrity: provenance, licenses, signatures.
110
+
111
+ **Traps:** bolting security on after the architecture is set; confusing compliance with security;
112
+ underestimating the hardening burden of bundled components.
113
+
114
+ **Settles an Unknown:** the trust boundary the option crosses, and the control
115
+ `security-controls.md` requires there.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arbiterforge/ca-pi",
3
- "version": "0.19.0",
3
+ "version": "0.20.1",
4
4
  "private": true,
5
5
  "license": "AGPL-3.0-only",
6
6
  "type": "module",
@@ -45,6 +45,12 @@ State the problem, observable result, intended scope and explicit exclusions. Re
45
45
 
46
46
  Consider genuine trade-offs where they matter, recommend a suitable approach and explain why. Do not manufacture straw alternatives. Reversible implementation methods remain agent-owned within the agreed outcome. Ask for a user ruling on an unresolved, consequential product choice, not on every viable implementation detail.
47
47
 
48
+ **Never manufacture alternatives.** When only one sane approach exists, say so in one line and say why; that path runs no SMARTS comparison and adds no SMARTS table.
49
+
50
+ **SMARTS on a material choice.** Only when two or more materially plausible approaches exist, run a SMARTS comparison per `<plugin-root>/includes/smarts/core.md` inline before recommending one. Bound it to the context-envelope dimensions that could differentiate the approaches, mark missing evidence `Unknown` with its missing observation, and surface a decision-critical `Unknown` before selecting. If every candidate carries one, pause the selection until the missing observation is resolved or the user rules. The comparison dispatches no grader or scout, performs no bulk read of `plans/` or `decisions/`, and loads `<plugin-root>/includes/smarts/lenses.md` only when a verdict turns on a consideration the core summaries do not settle. Name cost, schedule, team-skill, vendor or stakeholder constraints alongside the result; they never become a seventh lens. Apply the core's priority order when lenses conflict; a tie without explicit priority evidence goes to the user. An explicit request for a full SMARTS read changes only the presentation depth — the full option-by-option table — with no new command and no change to decision authority.
51
+
52
+ **Record the rationale.** When the comparison ran, write the decisive lenses, any `Unknown` with its missing observation, the non-SMARTS constraints and the selection reason into the spec's `SEC-SMARTS` section, or the `## SMARTS design rationale` section of a Markdown spec. A single-approach choice records only its one-line statement there.
53
+
48
54
  Review applicable ADRs and explicit exclusions. A real conflicting architecture decision goes to its owner. Mentioning a protected file does not by itself restart the entire feature interview.
49
55
 
50
56
  ## Phase 3 - Make acceptance observable
@@ -353,6 +353,7 @@ reported as an executed pass.
353
353
  - MUST consider mundane environmental, configuration, and dependency mechanisms
354
354
  where plausible, without inventing one to meet a count.
355
355
  - MUST NOT promote INCONCLUSIVE evidence to CONFIRMED or REFUTED without a cited source.
356
+ - MUST NOT apply SMARTS to hypothesis ranking or root-cause confirmation — diagnosis is evidence-led; a remediation strategy choice belongs to `/fix` after root cause.
356
357
  - MUST record capture limits and relevant source/runtime identity; partial
357
358
  observation and stale evidence cannot silently establish a cause.
358
359
  - MUST NOT repeat an unchanged read without a new discriminator or changed context.
@@ -106,8 +106,11 @@ both governing sources and their disagreement; do not invent an artifact/scaffol
106
106
  variance, resolution or scoring inputs where that comparison actually agrees.
107
107
 
108
108
  The SMARTS table follows `<plugin-root>/includes/smarts/core.md` exactly: six lenses, verdict-first cells (Strong /
109
- Adequate / Weak / Indifferent), the length cap, no hedging adverbs, evidence specificity. The
110
- recommendation carries one strength label — strong / moderate / tied.
109
+ Adequate / Weak / Indifferent / Unknown), the length cap, no hedging adverbs, evidence specificity.
110
+ An `Unknown` cell names its `missing_observation` and states whether it is `decision_critical`; a
111
+ lens that matters but lacks evidence is `Unknown`, never `Indifferent` for missing evidence. The
112
+ recommendation carries one strength label — strong / moderate / tied — and is never `strong` while
113
+ any option carries a decision-critical `Unknown`.
111
114
 
112
115
  **Precedent row.** Before writing the tables, scan the existing decision log once: tally which
113
116
  lenses prior resolutions turned on (which lens was decisive, which way ties broke) and note
@@ -84,6 +84,12 @@ Gate: either "No new seams", or failing seam tests with all pre-existing tests s
84
84
 
85
85
  ## Phase 4 — Implementation · gate: BLOCK
86
86
 
87
+ **Strategy choice (conditional).** Only when materially distinct restructuring strategies exist (for
88
+ example, extract-and-delegate versus move-and-rename), and only after the Phase 1 surface table and
89
+ the Phase 2 parity proof are settled, run a SMARTS comparison per
90
+ `<plugin-root>/includes/smarts/core.md` inline to choose between them. The choice never widens the
91
+ surface table or relaxes a parity or coverage gate. One evident strategy gets no SMARTS table.
92
+
87
93
  Apply the restructure with zero behavior change, to the conventions in `coding-standards.md`. Confine every edit to the surface table. Acceptable edits: rename symbols (with consumer updates); extract or inline functions and methods; move symbols between files; replace an internal implementation with an equivalent one; collapse or split modules where the public interface is preserved.
88
94
 
89
95
  Unacceptable inside a refactor: adding a behavior, branch, error path, or side effect; changing the value any public method returns for any pre-existing input; adding a public method beyond a Phase 3 seam; changing observable order of operations (event emission, logging, IO). Classify the resulting staged diff against `commit-gate` classification criteria — a diff that classifies as `feat` is not a refactor; halt and route to `tdd`.
@@ -48,6 +48,14 @@ If implementation reveals a better in-scope method, update task steps, runner, o
48
48
 
49
49
  Compare the implementation to the source criteria: what is required, what changed, what is missing, and what behavior a passing test actually covers. Run the planned applicable test or a narrower verified equivalent through the existing **host-governed execution tool**. Record the command, working directory, outcome, and limitations. A command-level pass is not invented named-test proof. A new failure or a skipped/unknown result cannot be masked by an earlier pass.
50
50
 
51
+ **Design-rationale drift.** When the spec records a SMARTS design rationale (`SEC-SMARTS`, or a
52
+ Markdown spec's `## SMARTS design rationale` section), check the change against it for material
53
+ invalidation only: a load-bearing assumption the change contradicts, a `Weak` or `Unknown` the
54
+ rationale chose to avoid that the change newly introduces, or a materially different approach than
55
+ the one selected. Do not re-run SMARTS or grade the implementation. A mismatch returns the task to
56
+ step 2 with the contradicted rationale cited, or routes the design question back to `brainstorming`;
57
+ never pick a replacement approach inside review.
58
+
51
59
  A failing check is a reason to repair, investigate, or mark verification pending, **not permission to claim it passed** and not a ban on unrelated implementation. Rerun affected checks after a correction. If the same approach fails repeatedly without new information, diagnose differently or record a bounded blocked task and continue unrelated work.
52
60
 
53
61
  Review the combined relevant diff when risk or change size warrants it. Use a specialist reviewer only for an actual security/dependency/migration concern or an explicit policy requirement. Avoid duplicate security reviews and blanket per-task spec/quality fleets. Retain useful findings; revisit affected conclusions only when relevant code, requirements, supporting evidence, or the previously reviewed subject changes. A new receipt ID by itself is not an impact.
@@ -42,6 +42,14 @@ for useful implementation and review, not a compulsory two-to-five-minute limit.
42
42
  A small related change does not need its own author/reviewer lifecycle. Split
43
43
  work when it has separate outcomes, dependencies, or independently useful progress.
44
44
 
45
+ **Design-drift guard.** Decomposition splits decided work; it never designs. If splitting surfaces a
46
+ material solution choice the spec does not decide — two or more materially plausible approaches the
47
+ spec leaves open, or a step that would contradict the spec's recorded SMARTS rationale — STOP and
48
+ never pick, score or SMARTS-evaluate it here. Route the undecided choice back to the owning design
49
+ workflow, `brainstorming` (`<plugin-root>/routines/brainstorming/SKILL.md`), and resume planning only
50
+ once the spec records the decision. A choice the spec already decides, or a trivial local
51
+ implementation detail with no material solution choice, is not drift.
52
+
45
53
  Use real repository commands or an explicitly described observable check. A test
46
54
  file or case that this task will create may not exist yet. An unsupported named
47
55
  result parser is not a reason to reject the plan or invent test outcomes; a
@@ -353,6 +353,7 @@ reported as an executed pass.
353
353
  - MUST consider mundane environmental, configuration, and dependency mechanisms
354
354
  where plausible, without inventing one to meet a count.
355
355
  - MUST NOT promote INCONCLUSIVE evidence to CONFIRMED or REFUTED without a cited source.
356
+ - MUST NOT apply SMARTS to hypothesis ranking or root-cause confirmation — diagnosis is evidence-led; a remediation strategy choice belongs to `/fix` after root cause.
356
357
  - MUST record capture limits and relevant source/runtime identity; partial
357
358
  observation and stale evidence cannot silently establish a cause.
358
359
  - MUST NOT repeat an unchanged read without a new discriminator or changed context.
@@ -67,6 +67,13 @@ judged against `$ARGUMENTS` and a quick look at the code, never assumed:
67
67
  - no new dependency, endpoint, command, or configuration surface;
68
68
  - the behavior change is expressible as 1–3 concrete, individually testable acceptance criteria.
69
69
 
70
+ **Small-lane SMARTS.** Only when the change involves a material solution choice — two or more
71
+ materially plausible ways to build it — run a SMARTS scan per `<plugin-root>/includes/smarts/core.md`,
72
+ inline with no grader or scout, and state its one-line result with the mini-spec. Otherwise state
73
+ `SMARTS: no material solution choice` and continue; that path adds no SMARTS table and no extra
74
+ artifact. If the scan shows that the better approach would violate any small-lane criterion above,
75
+ route to the **full lane**.
76
+
70
77
  **Small lane:** state the mini-spec inline (the 1–3 criteria). Unless the user requested a pause or a real consequential question remains, proceed without a second permission reply. Append one line to `<project-root>/.codearbiter/triage.log`
71
78
  (append-only, `>>`):
72
79
 
@@ -44,6 +44,12 @@ new behavior:
44
44
  current state for the precise reason the bug causes (not an unrelated error).
45
45
  4. **Confirm it's red for the right reason** — the failure message matches the described defect.
46
46
 
47
+ **Remediation strategy (conditional).** Only after step 2 has confirmed the root cause, and only when
48
+ materially distinct remediation strategies exist (for example, a local guard versus a contract
49
+ change), run a SMARTS comparison per `<plugin-root>/includes/smarts/core.md` inline before any fix
50
+ code. A single obvious fix gets no SMARTS table. SMARTS never ranks hypotheses or confirms the cause;
51
+ diagnosis stays evidence-led in `debug`.
52
+
47
53
  Only then does `tdd` proceed: minimal fix to green, then the remaining `tdd` gates. When delegating,
48
54
  select `backend-author`, `frontend-author`, or `infra-author` by where the bug lives. If
49
55
  the defect cannot be pinned by a failing test, STOP and surface the question.
@@ -84,6 +84,12 @@ Gate: either "No new seams", or failing seam tests with all pre-existing tests s
84
84
 
85
85
  ## Phase 4 — Implementation · gate: BLOCK
86
86
 
87
+ **Strategy choice (conditional).** Only when materially distinct restructuring strategies exist (for
88
+ example, extract-and-delegate versus move-and-rename), and only after the Phase 1 surface table and
89
+ the Phase 2 parity proof are settled, run a SMARTS comparison per
90
+ `<plugin-root>/includes/smarts/core.md` inline to choose between them. The choice never widens the
91
+ surface table or relaxes a parity or coverage gate. One evident strategy gets no SMARTS table.
92
+
87
93
  Apply the restructure with zero behavior change, to the conventions in `coding-standards.md`. Confine every edit to the surface table. Acceptable edits: rename symbols (with consumer updates); extract or inline functions and methods; move symbols between files; replace an internal implementation with an equivalent one; collapse or split modules where the public interface is preserved.
88
94
 
89
95
  Unacceptable inside a refactor: adding a behavior, branch, error path, or side effect; changing the value any public method returns for any pre-existing input; adding a public method beyond a Phase 3 seam; changing observable order of operations (event emission, logging, IO). Classify the resulting staged diff against `commit-gate` classification criteria — a diff that classifies as `feat` is not a refactor; halt and route to `tdd`.