@cleocode/contracts 2026.5.111 → 2026.5.113
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/dist/__tests__/cli-meta-suggested-next.test.d.ts +21 -0
- package/dist/__tests__/cli-meta-suggested-next.test.d.ts.map +1 -0
- package/dist/__tests__/cli-meta-suggested-next.test.js +70 -0
- package/dist/__tests__/cli-meta-suggested-next.test.js.map +1 -0
- package/dist/__tests__/evidence-atom-schema.test.d.ts +16 -0
- package/dist/__tests__/evidence-atom-schema.test.d.ts.map +1 -0
- package/dist/__tests__/evidence-atom-schema.test.js +394 -0
- package/dist/__tests__/evidence-atom-schema.test.js.map +1 -0
- package/dist/config/__tests__/manifest.test.d.ts +13 -0
- package/dist/config/__tests__/manifest.test.d.ts.map +1 -0
- package/dist/config/__tests__/manifest.test.js +143 -0
- package/dist/config/__tests__/manifest.test.js.map +1 -0
- package/dist/config/manifest.d.ts +158 -0
- package/dist/config/manifest.d.ts.map +1 -0
- package/dist/config/manifest.js +123 -0
- package/dist/config/manifest.js.map +1 -0
- package/dist/docs/__tests__/provenance.test.d.ts +14 -0
- package/dist/docs/__tests__/provenance.test.d.ts.map +1 -0
- package/dist/docs/__tests__/provenance.test.js +579 -0
- package/dist/docs/__tests__/provenance.test.js.map +1 -0
- package/dist/docs/provenance.d.ts +731 -0
- package/dist/docs/provenance.d.ts.map +1 -0
- package/dist/docs/provenance.js +258 -0
- package/dist/docs/provenance.js.map +1 -0
- package/dist/docs-taxonomy.d.ts +24 -0
- package/dist/docs-taxonomy.d.ts.map +1 -1
- package/dist/docs-taxonomy.js +27 -0
- package/dist/docs-taxonomy.js.map +1 -1
- package/dist/doctor.d.ts +101 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/errors.d.ts +4 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +4 -0
- package/dist/errors.js.map +1 -1
- package/dist/evidence-atom-schema.d.ts +407 -0
- package/dist/evidence-atom-schema.d.ts.map +1 -0
- package/dist/evidence-atom-schema.js +505 -0
- package/dist/evidence-atom-schema.js.map +1 -0
- package/dist/exit-codes.d.ts +37 -0
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +37 -0
- package/dist/exit-codes.js.map +1 -1
- package/dist/index.d.ts +13 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/invariants/__tests__/adr-056-release.test.d.ts +16 -0
- package/dist/invariants/__tests__/adr-056-release.test.d.ts.map +1 -0
- package/dist/invariants/__tests__/adr-056-release.test.js +88 -0
- package/dist/invariants/__tests__/adr-056-release.test.js.map +1 -0
- package/dist/invariants/__tests__/adr-070-orchestration.test.d.ts +22 -0
- package/dist/invariants/__tests__/adr-070-orchestration.test.d.ts.map +1 -0
- package/dist/invariants/__tests__/adr-070-orchestration.test.js +151 -0
- package/dist/invariants/__tests__/adr-070-orchestration.test.js.map +1 -0
- package/dist/invariants/__tests__/registry.test.d.ts +14 -0
- package/dist/invariants/__tests__/registry.test.d.ts.map +1 -0
- package/dist/invariants/__tests__/registry.test.js +113 -0
- package/dist/invariants/__tests__/registry.test.js.map +1 -0
- package/dist/invariants/adr-056-release.d.ts +42 -0
- package/dist/invariants/adr-056-release.d.ts.map +1 -0
- package/dist/invariants/adr-056-release.js +143 -0
- package/dist/invariants/adr-056-release.js.map +1 -0
- package/dist/invariants/adr-070-orchestration.d.ts +73 -0
- package/dist/invariants/adr-070-orchestration.d.ts.map +1 -0
- package/dist/invariants/adr-070-orchestration.js +290 -0
- package/dist/invariants/adr-070-orchestration.js.map +1 -0
- package/dist/invariants/adr-073-saga.d.ts +32 -0
- package/dist/invariants/adr-073-saga.d.ts.map +1 -0
- package/dist/invariants/adr-073-saga.js +155 -0
- package/dist/invariants/adr-073-saga.js.map +1 -0
- package/dist/invariants/index.d.ts +162 -0
- package/dist/invariants/index.d.ts.map +1 -0
- package/dist/invariants/index.js +118 -0
- package/dist/invariants/index.js.map +1 -0
- package/dist/operations/__tests__/input-contract.test.d.ts +20 -0
- package/dist/operations/__tests__/input-contract.test.d.ts.map +1 -0
- package/dist/operations/__tests__/input-contract.test.js +158 -0
- package/dist/operations/__tests__/input-contract.test.js.map +1 -0
- package/dist/operations/docs.d.ts +16 -0
- package/dist/operations/docs.d.ts.map +1 -1
- package/dist/operations/input-contract.d.ts +267 -0
- package/dist/operations/input-contract.d.ts.map +1 -0
- package/dist/operations/input-contract.js +29 -0
- package/dist/operations/input-contract.js.map +1 -0
- package/dist/templates/__tests__/manifest.test.d.ts +18 -0
- package/dist/templates/__tests__/manifest.test.d.ts.map +1 -0
- package/dist/templates/__tests__/manifest.test.js +123 -0
- package/dist/templates/__tests__/manifest.test.js.map +1 -0
- package/dist/templates/manifest.d.ts +186 -0
- package/dist/templates/manifest.d.ts.map +1 -0
- package/dist/templates/manifest.js +165 -0
- package/dist/templates/manifest.js.map +1 -0
- package/package.json +2 -2
- package/src/__tests__/cli-meta-suggested-next.test.ts +76 -0
- package/src/__tests__/evidence-atom-schema.test.ts +499 -0
- package/src/config/__tests__/manifest.test.ts +176 -0
- package/src/config/manifest.ts +218 -0
- package/src/docs/__tests__/__snapshots__/provenance.test.ts.snap +252 -0
- package/src/docs/__tests__/provenance.test.ts +648 -0
- package/src/docs/provenance.ts +601 -0
- package/src/docs-taxonomy.ts +55 -0
- package/src/doctor.ts +111 -0
- package/src/errors.ts +4 -0
- package/src/evidence-atom-schema.ts +628 -0
- package/src/exit-codes.ts +39 -0
- package/src/index.ts +129 -0
- package/src/invariants/__tests__/adr-056-release.test.ts +102 -0
- package/src/invariants/__tests__/adr-070-orchestration.test.ts +186 -0
- package/src/invariants/__tests__/registry.test.ts +136 -0
- package/src/invariants/adr-056-release.ts +154 -0
- package/src/invariants/adr-070-orchestration.ts +317 -0
- package/src/invariants/adr-073-saga.ts +167 -0
- package/src/invariants/index.ts +222 -0
- package/src/operations/__tests__/input-contract.test.ts +188 -0
- package/src/operations/docs.ts +16 -0
- package/src/operations/input-contract.ts +301 -0
- package/src/templates/__tests__/manifest.test.ts +140 -0
- package/src/templates/manifest.ts +208 -0
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-070 ORC-### orchestration invariants registered against the central
|
|
3
|
+
* invariants registry (`./index.ts`).
|
|
4
|
+
*
|
|
5
|
+
* ORC codes govern the three-tier spawn topology — Orchestrator (HITL
|
|
6
|
+
* interface) → Lead (phase coordinator) → Worker (leaf task) — defined by
|
|
7
|
+
* ADR-070 and refined by ADR-083 §2 (Cleo persona + recursion bounds).
|
|
8
|
+
*
|
|
9
|
+
* Severity mapping (see `RegisteredInvariant` JSDoc for tier semantics):
|
|
10
|
+
*
|
|
11
|
+
* - **ORC-012** (thin-agent inversion-of-control) is the only ORC rule with
|
|
12
|
+
* a hard-enforced runtime gate today (`enforceThinAgent` +
|
|
13
|
+
* `ThinAgentViolationError`). It surfaces as
|
|
14
|
+
* `E_THIN_AGENT_VIOLATION` (LAFS error code + exit 68). Tier: `error`.
|
|
15
|
+
* - **ORC-001..ORC-009** are the skill-injection rules shipped through
|
|
16
|
+
* `ct-orchestrator/SKILL.md`. They constrain the Orchestrator's runtime
|
|
17
|
+
* behaviour (no code writes, dependency-ordered spawning, 10 K context
|
|
18
|
+
* budget, etc.) but live as prompt-time invariants rather than dispatch
|
|
19
|
+
* guards. Tier: `warning`, `runtimeGate: null` — the gap is documented
|
|
20
|
+
* explicitly so the R6 doctor audit (T10340) can surface it.
|
|
21
|
+
* - **ORC-010** (Lead-interposition: a Worker spawn for an Epic-child Task
|
|
22
|
+
* requires a preceding Lead spawn) and **ORC-011** (Orchestrator-depth
|
|
23
|
+
* ≤ 3) are filed against ADR-083 §2.4 + §6 but the dispatch-time gate
|
|
24
|
+
* has not yet shipped (tracked T10278 + T10279). They are registered
|
|
25
|
+
* here as `warning` with `runtimeGate: null` so the gap surfaces in the
|
|
26
|
+
* audit pipeline.
|
|
27
|
+
* - **ORC-013** (worktree provisioning per ADR-055 / D009) IS enforced at
|
|
28
|
+
* `createWorktree` time via `assertCanonicalWorktreeLocation` — it
|
|
29
|
+
* carries `severity: 'error'` and a runtime gate. The companion CI gate
|
|
30
|
+
* `lint-worktree-location.mjs` is recorded under `lintRule`.
|
|
31
|
+
* - **ORC-014** (Lead-bypass detection at session end) IS enforced by
|
|
32
|
+
* `endSession` via `LeadBypassDetectedError`. Tier: `error`.
|
|
33
|
+
*
|
|
34
|
+
* @epic T10327 — E-INVARIANT-REGISTRY-SSOT
|
|
35
|
+
* @saga T10326 — SG-SUBSTRATE-RECONCILIATION
|
|
36
|
+
* @task T10336 — R2 (ADR-070 ORC codes)
|
|
37
|
+
* @see ADR-070-three-tier-orchestration.md
|
|
38
|
+
* @see ADR-083-section-2.4 — Cleo persona + recursion bounds
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* Module path that hosts the thin-agent enforcement function.
|
|
42
|
+
*/
|
|
43
|
+
const THIN_AGENT_MODULE = 'packages/core/src/orchestration/thin-agent.ts';
|
|
44
|
+
/**
|
|
45
|
+
* Module path that hosts the session lifecycle entrypoint enforcing
|
|
46
|
+
* Lead-bypass detection at session end.
|
|
47
|
+
*/
|
|
48
|
+
const SESSIONS_MODULE = 'packages/core/src/sessions/index.ts';
|
|
49
|
+
/**
|
|
50
|
+
* Module path that hosts the worktree creation guard (canonical XDG
|
|
51
|
+
* location enforcement per ADR-055 + Council D009).
|
|
52
|
+
*/
|
|
53
|
+
const WORKTREE_CREATE_MODULE = 'packages/worktree/src/worktree-create.ts';
|
|
54
|
+
/**
|
|
55
|
+
* Canonical ct-orchestrator skill that injects ORC-001..ORC-009 into the
|
|
56
|
+
* Orchestrator's prompt at spawn time. Referenced from every prompt-time
|
|
57
|
+
* ORC entry so downstream tooling (R8 docs renderer) can chase the source.
|
|
58
|
+
*/
|
|
59
|
+
const CT_ORCHESTRATOR_SKILL = 'packages/skills/skills/ct-orchestrator/SKILL.md';
|
|
60
|
+
/**
|
|
61
|
+
* Path to the spawn-prompt builder that materialises ORC-006 worker budget
|
|
62
|
+
* constraints into spawn payloads (referenced from ORC-006 below).
|
|
63
|
+
*/
|
|
64
|
+
const SPAWN_PROMPT_MODULE = 'packages/core/src/orchestration/spawn-prompt.ts';
|
|
65
|
+
/**
|
|
66
|
+
* Path to the validate-spawn module that materialises ORC-006 atomic-scope
|
|
67
|
+
* checks via `V_ATOMIC_SCOPE_MISSING` / `V_ATOMIC_SCOPE_TOO_LARGE` codes.
|
|
68
|
+
*/
|
|
69
|
+
const VALIDATE_SPAWN_MODULE = 'packages/core/src/orchestration/validate-spawn.ts';
|
|
70
|
+
/**
|
|
71
|
+
* Skill-validator test that exercises ORC-004 / ORC-005 manifest checks.
|
|
72
|
+
*/
|
|
73
|
+
const SKILL_VALIDATOR_TESTS = 'packages/core/src/skills/orchestrator/__tests__/validator.test.ts';
|
|
74
|
+
/**
|
|
75
|
+
* ADR-070 ORC-### invariants in declaration order.
|
|
76
|
+
*
|
|
77
|
+
* The 14 entries cover:
|
|
78
|
+
* - ORC-001..ORC-009 — ct-orchestrator skill behavioural constraints.
|
|
79
|
+
* - ORC-010..ORC-011 — ADR-083 §2.4 recursion-bound gaps (filed,
|
|
80
|
+
* runtime gate unimplemented — tracked T10278 / T10279).
|
|
81
|
+
* - ORC-012 — thin-agent inversion-of-control (hard-enforced).
|
|
82
|
+
* - ORC-013 — worktree provisioning per ADR-055 / D009 (hard-enforced).
|
|
83
|
+
* - ORC-014 — Lead-bypass detection at session end (hard-enforced).
|
|
84
|
+
*
|
|
85
|
+
* Every `severity: 'warning'` entry with `runtimeGate: null` carries an
|
|
86
|
+
* explicit description of WHY the gate is absent, satisfying the gap-
|
|
87
|
+
* documentation invariant asserted in the unit test below.
|
|
88
|
+
*/
|
|
89
|
+
export const ADR_070_INVARIANTS = Object.freeze([
|
|
90
|
+
{
|
|
91
|
+
adr: 'ADR-070',
|
|
92
|
+
code: 'ORC-001',
|
|
93
|
+
name: 'Orchestrator is the HITL interface',
|
|
94
|
+
description: 'The Orchestrator (Cleo) is the single subagent that talks to the human operator. It plans, decomposes, and delegates — it never produces line-level implementation. Source-of-truth lives in ct-orchestrator/SKILL.md row ORC-001 and is injected into the Orchestrator prompt at spawn time. UNENFORCED at the dispatch layer: this is a prompt-time invariant with no runtime guard today.',
|
|
95
|
+
severity: 'warning',
|
|
96
|
+
runtimeGate: null,
|
|
97
|
+
lintRule: null,
|
|
98
|
+
doctorAudit: null,
|
|
99
|
+
tests: [CT_ORCHESTRATOR_SKILL],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
adr: 'ADR-070',
|
|
103
|
+
code: 'ORC-002',
|
|
104
|
+
name: 'Orchestrator MUST NOT write or edit code',
|
|
105
|
+
description: 'Every line of code is written by a spawned subagent. The Orchestrator delegates implementation work via cleo orchestrate spawn / delegate_task. UNENFORCED at the dispatch layer: this is a prompt-time invariant — there is no runtime gate that blocks the Orchestrator from calling Edit/Write, so the contract is held by the ct-orchestrator skill text.',
|
|
106
|
+
severity: 'warning',
|
|
107
|
+
runtimeGate: null,
|
|
108
|
+
lintRule: null,
|
|
109
|
+
doctorAudit: null,
|
|
110
|
+
tests: [CT_ORCHESTRATOR_SKILL],
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
adr: 'ADR-070',
|
|
114
|
+
code: 'ORC-003',
|
|
115
|
+
name: 'Orchestrator MUST NOT read full source files',
|
|
116
|
+
description: 'Orchestrator reads only pipeline manifests, task envelopes, and rolled-up phase summaries returned by Phase Leads. Workers read code; the Orchestrator reads summaries. UNENFORCED at the dispatch layer — held by the ct-orchestrator skill text and reinforced by ORC-005 budget pressure.',
|
|
117
|
+
severity: 'warning',
|
|
118
|
+
runtimeGate: null,
|
|
119
|
+
lintRule: null,
|
|
120
|
+
doctorAudit: null,
|
|
121
|
+
tests: [CT_ORCHESTRATOR_SKILL],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
adr: 'ADR-070',
|
|
125
|
+
code: 'ORC-004',
|
|
126
|
+
name: 'Dependency-ordered spawning',
|
|
127
|
+
description: 'Spawns within a wave are ordered by task.depends — a Worker MUST NOT be dispatched until its declared dependencies are status=done. Surfaced by validateSpawnReadiness via V_MISSING_DEP / V_UNMET_DEP codes; surfaced by the skill-orchestrator validator via the ORC-004_DEPENDENCY_ORDER warning emitted from packages/core/src/skills/orchestrator/validator.ts. Tier: warning because the validator surfaces ordering issues but does not throw — workers can still proceed if the operator overrides.',
|
|
128
|
+
severity: 'warning',
|
|
129
|
+
runtimeGate: {
|
|
130
|
+
module: VALIDATE_SPAWN_MODULE,
|
|
131
|
+
functionName: 'validateSpawnReadiness',
|
|
132
|
+
},
|
|
133
|
+
lintRule: null,
|
|
134
|
+
doctorAudit: null,
|
|
135
|
+
tests: [
|
|
136
|
+
'packages/core/src/orchestration/__tests__/validate-spawn.test.ts',
|
|
137
|
+
SKILL_VALIDATOR_TESTS,
|
|
138
|
+
],
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
adr: 'ADR-070',
|
|
142
|
+
code: 'ORC-005',
|
|
143
|
+
name: 'Orchestrator context budget ≈ 10 K tokens',
|
|
144
|
+
description: 'The Orchestrator MUST keep its working context under ~10 K tokens; delegate at 80 %. Surfaced by cleo orchestrate context (estimateContext) and by the skill-orchestrator validator (ORC-005_NO_MANIFEST / ORC-005_EMPTY_MANIFEST). UNENFORCED as a hard gate — the budget is advisory, surfaced to the Orchestrator as a warning so the human operator can intervene.',
|
|
145
|
+
severity: 'warning',
|
|
146
|
+
runtimeGate: {
|
|
147
|
+
module: 'packages/core/src/orchestration/context.ts',
|
|
148
|
+
functionName: 'estimateContext',
|
|
149
|
+
},
|
|
150
|
+
lintRule: null,
|
|
151
|
+
doctorAudit: null,
|
|
152
|
+
tests: ['packages/core/src/orchestration/__tests__/'],
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
adr: 'ADR-070',
|
|
156
|
+
code: 'ORC-006',
|
|
157
|
+
name: 'Worker scope ≤ 3 files per spawn',
|
|
158
|
+
description: 'Cross-file reasoning quality degrades beyond ~3 files for a single Worker. Enforced at spawn-time by validateSpawnReadiness — V_ATOMIC_SCOPE_MISSING when task.files is empty, V_ATOMIC_SCOPE_TOO_LARGE when files.length > MAX_WORKER_FILES (currently 3). Spawn-prompt builder injects a Worker Budget Constraints section so the Worker sees the budget inline. Tier: error because the gate refuses to spawn an over-scoped Worker.',
|
|
159
|
+
severity: 'error',
|
|
160
|
+
runtimeGate: {
|
|
161
|
+
module: VALIDATE_SPAWN_MODULE,
|
|
162
|
+
functionName: 'validateSpawnReadiness',
|
|
163
|
+
},
|
|
164
|
+
lintRule: null,
|
|
165
|
+
doctorAudit: null,
|
|
166
|
+
tests: [
|
|
167
|
+
'packages/core/src/orchestration/__tests__/validate-spawn.test.ts',
|
|
168
|
+
'packages/core/src/orchestration/__tests__/spawn-prompt.test.ts',
|
|
169
|
+
],
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
adr: 'ADR-070',
|
|
173
|
+
code: 'ORC-007',
|
|
174
|
+
name: 'All work traced to an Epic',
|
|
175
|
+
description: 'Every Task and Subtask MUST attach to a parent Epic (directly or transitively). No orphan work — orphans are filed against the ADR-066 acceptance-criteria gate and surface via cleo find. UNENFORCED at the dispatch layer; the parent-id requirement is materialised through cleo add validation rather than a single ORC-named guard. R6 doctor audit should walk the task graph to surface orphans.',
|
|
176
|
+
severity: 'warning',
|
|
177
|
+
runtimeGate: null,
|
|
178
|
+
lintRule: null,
|
|
179
|
+
doctorAudit: null,
|
|
180
|
+
tests: [CT_ORCHESTRATOR_SKILL],
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
adr: 'ADR-070',
|
|
184
|
+
code: 'ORC-008',
|
|
185
|
+
name: 'Zero architectural decisions during execution',
|
|
186
|
+
description: 'Architectural choices MUST be pre-decided via RCASD consensus or HITL — never inside a worker session. UNENFORCED at the dispatch layer: this is a behavioural invariant held by the ct-orchestrator skill text plus the ADR-066 acceptance criterion that every task must declare its architecture-relevant decisions before spawn.',
|
|
187
|
+
severity: 'warning',
|
|
188
|
+
runtimeGate: null,
|
|
189
|
+
lintRule: null,
|
|
190
|
+
doctorAudit: null,
|
|
191
|
+
tests: [CT_ORCHESTRATOR_SKILL],
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
adr: 'ADR-070',
|
|
195
|
+
code: 'ORC-009',
|
|
196
|
+
name: 'Manifest-mediated handoffs',
|
|
197
|
+
description: 'Orchestrator reads only the key_findings field of pipeline_manifest rows when reconciling worker output. Subagents read the full task description and supporting files. UNENFORCED at the dispatch layer: the contract is held by the ct-orchestrator skill text and reinforced by ORC-003 + ORC-005 budget pressure.',
|
|
198
|
+
severity: 'warning',
|
|
199
|
+
runtimeGate: null,
|
|
200
|
+
lintRule: null,
|
|
201
|
+
doctorAudit: null,
|
|
202
|
+
tests: [CT_ORCHESTRATOR_SKILL],
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
adr: 'ADR-070',
|
|
206
|
+
code: 'ORC-010',
|
|
207
|
+
name: 'Lead-interposition required for Epic-child Workers',
|
|
208
|
+
description: 'A Worker spawn against a Task whose parent is type=epic MUST be preceded by a Lead spawn for the same Task (ADR-083 §2.4 / §6). The intended runtime gate (composeSpawnPayload throwing E_LEAD_REQUIRED_FOR_EPIC_CHILD) is FILED but UNSHIPPED — tracked under T10278. Registered here as a warning + runtimeGate:null so the gap is visible in the R6 doctor audit.',
|
|
209
|
+
severity: 'warning',
|
|
210
|
+
runtimeGate: null,
|
|
211
|
+
lintRule: null,
|
|
212
|
+
doctorAudit: null,
|
|
213
|
+
tests: [],
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
adr: 'ADR-070',
|
|
217
|
+
code: 'ORC-011',
|
|
218
|
+
name: 'Orchestrator-depth cap at 3',
|
|
219
|
+
description: 'Recursive Orchestrator spawns (Cleo → sub-Orchestrator → sub-Orchestrator → …) MUST stop at depth 3 (ADR-083 §2.2 + §2.4). The intended runtime gate (composeSpawnPayload throwing E_ORCHESTRATOR_DEPTH_EXCEEDED) is FILED but UNSHIPPED — tracked under T10279. Registered here as a warning + runtimeGate:null so the gap is visible in the R6 doctor audit.',
|
|
220
|
+
severity: 'warning',
|
|
221
|
+
runtimeGate: null,
|
|
222
|
+
lintRule: null,
|
|
223
|
+
doctorAudit: null,
|
|
224
|
+
tests: [],
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
adr: 'ADR-070',
|
|
228
|
+
code: 'ORC-012',
|
|
229
|
+
name: 'Thin-agent inversion-of-control',
|
|
230
|
+
description: 'Workers MUST NOT spawn other subagents. The spawn-capable tools (Agent / Task / TaskCreate) are stripped from the Worker tool list at .cant compile time, and any survivor at spawn time triggers ThinAgentViolationError → E_THIN_AGENT_VIOLATION (exit 68). The only ORC rule with a hard-enforced dispatch-time gate today.',
|
|
231
|
+
severity: 'error',
|
|
232
|
+
runtimeGate: {
|
|
233
|
+
module: THIN_AGENT_MODULE,
|
|
234
|
+
functionName: 'enforceThinAgent',
|
|
235
|
+
},
|
|
236
|
+
lintRule: null,
|
|
237
|
+
doctorAudit: null,
|
|
238
|
+
tests: [
|
|
239
|
+
'packages/core/src/orchestration/__tests__/thin-agent.test.ts',
|
|
240
|
+
'packages/cant/src/__tests__/hierarchy.test.ts',
|
|
241
|
+
],
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
adr: 'ADR-070',
|
|
245
|
+
code: 'ORC-013',
|
|
246
|
+
name: 'Worktree provisioning at canonical XDG location',
|
|
247
|
+
description: 'Every agent worktree MUST be created under <cleoHome>/worktrees/<projectHash>/<taskId>/ (ADR-055 + Council D009). createWorktree throws E_WT_LOCATION_FORBIDDEN before any git worktree add call when the computed path falls outside the canonical root. CI gate lint-worktree-location.mjs enforces the same invariant on every PR. The single-most-load-bearing orchestration guard after ORC-012.',
|
|
248
|
+
severity: 'error',
|
|
249
|
+
runtimeGate: {
|
|
250
|
+
module: WORKTREE_CREATE_MODULE,
|
|
251
|
+
functionName: 'assertCanonicalWorktreeLocation',
|
|
252
|
+
},
|
|
253
|
+
lintRule: {
|
|
254
|
+
lintScript: 'scripts/lint-worktree-location.mjs',
|
|
255
|
+
},
|
|
256
|
+
doctorAudit: null,
|
|
257
|
+
tests: ['packages/worktree/src/__tests__/'],
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
adr: 'ADR-070',
|
|
261
|
+
code: 'ORC-014',
|
|
262
|
+
name: 'Lead-bypass detection at session end',
|
|
263
|
+
description: 'A Lead session (CLEO_AGENT_ROLE=lead) that ends with tasks_completed > 0 AND delegate_task_count = 0 is rejected with LeadBypassDetectedError → E_LEAD_BYPASS_DETECTED (exit 107). Leads MUST fan out work to Workers; a Lead that did the work itself defeats the three-tier topology. Override via CLEO_OWNER_OVERRIDE=1 (audited to force-bypass.jsonl).',
|
|
264
|
+
severity: 'error',
|
|
265
|
+
runtimeGate: {
|
|
266
|
+
module: SESSIONS_MODULE,
|
|
267
|
+
functionName: 'endSession',
|
|
268
|
+
},
|
|
269
|
+
lintRule: null,
|
|
270
|
+
doctorAudit: null,
|
|
271
|
+
tests: ['packages/core/src/sessions/__tests__/'],
|
|
272
|
+
},
|
|
273
|
+
]);
|
|
274
|
+
/** Sentinel referenced by the unit test — keep in sync with array length. */
|
|
275
|
+
export const ADR_070_INVARIANT_COUNT = ADR_070_INVARIANTS.length;
|
|
276
|
+
/** Sentinel — minimum entries the central registry must merge from this file. */
|
|
277
|
+
export const ADR_070_MIN_ENTRIES = 14;
|
|
278
|
+
/**
|
|
279
|
+
* Export the prompt-only module reference so other ADR-070 ORC modules can
|
|
280
|
+
* cross-reference the canonical skill location without restating the path.
|
|
281
|
+
* @internal
|
|
282
|
+
*/
|
|
283
|
+
export const ADR_070_PROMPT_SOURCE = CT_ORCHESTRATOR_SKILL;
|
|
284
|
+
/**
|
|
285
|
+
* Re-export for symmetry with the spawn-prompt builder consumers — used by
|
|
286
|
+
* the R8 docs renderer to chase the prompt-injection source for ORC-006.
|
|
287
|
+
* @internal
|
|
288
|
+
*/
|
|
289
|
+
export const ADR_070_SPAWN_PROMPT_MODULE = SPAWN_PROMPT_MODULE;
|
|
290
|
+
//# sourceMappingURL=adr-070-orchestration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adr-070-orchestration.js","sourceRoot":"","sources":["../../src/invariants/adr-070-orchestration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-073 §1.2 invariants I1-I8 registered against the central invariants
|
|
3
|
+
* registry (`./index.ts`).
|
|
4
|
+
*
|
|
5
|
+
* The eight invariants govern the 4-tier task hierarchy (Saga → Epic → Task
|
|
6
|
+
* → Subtask) and the cross-tier rules that keep it healthy. I3, I5, I7 carry
|
|
7
|
+
* runtime guards (the `assertSagaInvariant{I3,I5,I7}` functions in
|
|
8
|
+
* `@cleocode/core` saga module) and surface as `E_SAGA_INVARIANT_VIOLATION_*`
|
|
9
|
+
* LAFS error codes. I1 + I2 are display/storage concerns enforced by DB
|
|
10
|
+
* CHECK constraints (added in W1.B T10329 migration) and ID generation
|
|
11
|
+
* conventions rather than runtime functions. I4, I6, I8 are
|
|
12
|
+
* orchestration/process invariants that lack a unified runtime guard today
|
|
13
|
+
* — they are marked `warning` and explicitly tagged as UNENFORCED
|
|
14
|
+
* (load-bearing) so downstream R6 doctor audits surface them visibly.
|
|
15
|
+
*
|
|
16
|
+
* @epic T10327 — E-INVARIANT-REGISTRY-SSOT
|
|
17
|
+
* @saga T10326 — SG-SUBSTRATE-RECONCILIATION
|
|
18
|
+
* @task T10335 — R1 (registry + ADR-073 I1-I8)
|
|
19
|
+
* @see ADR-073-above-epic-naming.md §1.2
|
|
20
|
+
*/
|
|
21
|
+
import type { RegisteredInvariant } from './index.js';
|
|
22
|
+
/**
|
|
23
|
+
* ADR-073 invariants I1-I8 in declaration order.
|
|
24
|
+
*
|
|
25
|
+
* Severity mapping (see `RegisteredInvariant` JSDoc for tier semantics):
|
|
26
|
+
* - I1, I2 → `info` (display/storage; enforced by DB CHECK + ID convention).
|
|
27
|
+
* - I3, I5, I7 → `error` (LAFS error code + runtime guard mandatory).
|
|
28
|
+
* - I4, I6, I8 → `warning` (orchestration/process; UNENFORCED at runtime
|
|
29
|
+
* today, doctor audit only).
|
|
30
|
+
*/
|
|
31
|
+
export declare const ADR_073_INVARIANTS: readonly RegisteredInvariant[];
|
|
32
|
+
//# sourceMappingURL=adr-073-saga.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adr-073-saga.d.ts","sourceRoot":"","sources":["../../src/invariants/adr-073-saga.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAiBtD;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,mBAAmB,EAuH3D,CAAC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-073 §1.2 invariants I1-I8 registered against the central invariants
|
|
3
|
+
* registry (`./index.ts`).
|
|
4
|
+
*
|
|
5
|
+
* The eight invariants govern the 4-tier task hierarchy (Saga → Epic → Task
|
|
6
|
+
* → Subtask) and the cross-tier rules that keep it healthy. I3, I5, I7 carry
|
|
7
|
+
* runtime guards (the `assertSagaInvariant{I3,I5,I7}` functions in
|
|
8
|
+
* `@cleocode/core` saga module) and surface as `E_SAGA_INVARIANT_VIOLATION_*`
|
|
9
|
+
* LAFS error codes. I1 + I2 are display/storage concerns enforced by DB
|
|
10
|
+
* CHECK constraints (added in W1.B T10329 migration) and ID generation
|
|
11
|
+
* conventions rather than runtime functions. I4, I6, I8 are
|
|
12
|
+
* orchestration/process invariants that lack a unified runtime guard today
|
|
13
|
+
* — they are marked `warning` and explicitly tagged as UNENFORCED
|
|
14
|
+
* (load-bearing) so downstream R6 doctor audits surface them visibly.
|
|
15
|
+
*
|
|
16
|
+
* @epic T10327 — E-INVARIANT-REGISTRY-SSOT
|
|
17
|
+
* @saga T10326 — SG-SUBSTRATE-RECONCILIATION
|
|
18
|
+
* @task T10335 — R1 (registry + ADR-073 I1-I8)
|
|
19
|
+
* @see ADR-073-above-epic-naming.md §1.2
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Module path that hosts the saga runtime-guard exports
|
|
23
|
+
* (`assertSagaInvariantI3`, `assertSagaInvariantI5`, `assertSagaInvariantI7`).
|
|
24
|
+
*
|
|
25
|
+
* Held as a constant so all four entries share the same source-of-truth
|
|
26
|
+
* pointer — touching the module path once propagates to every guard ref.
|
|
27
|
+
*/
|
|
28
|
+
const SAGA_ENFORCEMENT_MODULE = 'packages/core/src/sagas/enforcement.ts';
|
|
29
|
+
/**
|
|
30
|
+
* Path to the canonical enforcement-tests file. Used as the `tests` ref
|
|
31
|
+
* for every I3 / I5 / I7 entry below.
|
|
32
|
+
*/
|
|
33
|
+
const SAGA_ENFORCEMENT_TESTS = 'packages/core/src/sagas/__tests__/enforcement.test.ts';
|
|
34
|
+
/**
|
|
35
|
+
* ADR-073 invariants I1-I8 in declaration order.
|
|
36
|
+
*
|
|
37
|
+
* Severity mapping (see `RegisteredInvariant` JSDoc for tier semantics):
|
|
38
|
+
* - I1, I2 → `info` (display/storage; enforced by DB CHECK + ID convention).
|
|
39
|
+
* - I3, I5, I7 → `error` (LAFS error code + runtime guard mandatory).
|
|
40
|
+
* - I4, I6, I8 → `warning` (orchestration/process; UNENFORCED at runtime
|
|
41
|
+
* today, doctor audit only).
|
|
42
|
+
*/
|
|
43
|
+
export const ADR_073_INVARIANTS = Object.freeze([
|
|
44
|
+
{
|
|
45
|
+
adr: 'ADR-073',
|
|
46
|
+
code: 'I1',
|
|
47
|
+
name: 'Storage uniformity',
|
|
48
|
+
description: 'All task IDs are stored as T#### and the type column is the canonical tier discriminator. There is no separate ID space for Sagas, Epics, Tasks, or Subtasks; label="saga" elevates a type="epic" row to Saga semantics.',
|
|
49
|
+
severity: 'info',
|
|
50
|
+
// I1 is enforced by the DB CHECK constraints introduced in W1.B (T10329)
|
|
51
|
+
// and by TASK_ID_PATTERN in packages/core/src/tasks/id-generator.ts —
|
|
52
|
+
// not by a single runtime function.
|
|
53
|
+
runtimeGate: null,
|
|
54
|
+
lintRule: null,
|
|
55
|
+
doctorAudit: null,
|
|
56
|
+
tests: ['packages/core/src/tasks/__tests__/id-generator.test.ts'],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
adr: 'ADR-073',
|
|
60
|
+
code: 'I2',
|
|
61
|
+
name: 'Conceptual prefixes are display + import only',
|
|
62
|
+
description: "SG-, E-, T- (and Subtask's implicit absence) are documentation, CLI display, and import-mapping conventions only. They MUST NOT be used as DB primary keys — display-only with no runtime enforcement.",
|
|
63
|
+
severity: 'info',
|
|
64
|
+
// I2 is a display convention; the SG- prefix preservation snapshot
|
|
65
|
+
// (T10333) protects the display contract but there is no runtime guard.
|
|
66
|
+
runtimeGate: null,
|
|
67
|
+
lintRule: null,
|
|
68
|
+
doctorAudit: null,
|
|
69
|
+
tests: [],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
adr: 'ADR-073',
|
|
73
|
+
code: 'I3',
|
|
74
|
+
name: 'Tier promotion mandatory when scope outgrows the tier',
|
|
75
|
+
description: 'A Subtask whose change exceeds 2 files or crosses a module boundary MUST be split or promoted to a sibling Task. A Task that requires more than one PR or wave MUST be split. An Epic that spans more than one release MUST be regrouped under a Saga.',
|
|
76
|
+
severity: 'error',
|
|
77
|
+
runtimeGate: {
|
|
78
|
+
module: SAGA_ENFORCEMENT_MODULE,
|
|
79
|
+
functionName: 'assertSagaInvariantI3',
|
|
80
|
+
},
|
|
81
|
+
lintRule: null,
|
|
82
|
+
doctorAudit: null,
|
|
83
|
+
tests: [SAGA_ENFORCEMENT_TESTS],
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
adr: 'ADR-073',
|
|
87
|
+
code: 'I4',
|
|
88
|
+
name: 'Ownership non-overlapping',
|
|
89
|
+
description: 'A single tier maps to a single orchestration role (per ADR-070). Workers MUST NOT spawn other Workers. Phase Leads MUST NOT own multiple Epics simultaneously. The Orchestrator MUST NOT spawn Workers directly when fan-out exceeds the ADR-070 migration threshold.',
|
|
90
|
+
severity: 'warning',
|
|
91
|
+
// I4 is partially covered by ADR-070 spawn guards but the unification
|
|
92
|
+
// with the registry happens in R2 (T10336 — ORC codes). For now this
|
|
93
|
+
// entry stays warning + runtimeGate:null to mark the gap explicitly.
|
|
94
|
+
runtimeGate: null,
|
|
95
|
+
lintRule: null,
|
|
96
|
+
doctorAudit: null,
|
|
97
|
+
tests: [],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
adr: 'ADR-073',
|
|
101
|
+
code: 'I5',
|
|
102
|
+
name: 'Sagas link via groups, not parent',
|
|
103
|
+
description: 'task_relations.type="groups" is the ONLY relation type that links a Saga to its member Epics. The Saga row\'s parent_id MUST be NULL. Enforced at runtime by assertSagaInvariantI5 AND by the DB CHECK constraint from W1.B (T10329) on label="saga" rows.',
|
|
104
|
+
severity: 'error',
|
|
105
|
+
runtimeGate: {
|
|
106
|
+
module: SAGA_ENFORCEMENT_MODULE,
|
|
107
|
+
functionName: 'assertSagaInvariantI5',
|
|
108
|
+
},
|
|
109
|
+
lintRule: null,
|
|
110
|
+
doctorAudit: null,
|
|
111
|
+
tests: [SAGA_ENFORCEMENT_TESTS],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
adr: 'ADR-073',
|
|
115
|
+
code: 'I6',
|
|
116
|
+
name: 'Acceptance criteria required at every tier',
|
|
117
|
+
description: 'Per ADR-066 §"Ownership Matrix" invariant #5, all tasks regardless of type or kind MUST have --acceptance set at creation time. No tier exemption exists. Delegated to the ADR-066 --acceptance requirement on cleo add/add-batch.',
|
|
118
|
+
severity: 'warning',
|
|
119
|
+
// I6 is enforced by ADR-066's CLI requirement, not by a saga runtime
|
|
120
|
+
// function. UNENFORCED in the saga module — left as a warning so R6
|
|
121
|
+
// doctor audit reminds operators of the upstream guard's location.
|
|
122
|
+
runtimeGate: null,
|
|
123
|
+
lintRule: null,
|
|
124
|
+
doctorAudit: null,
|
|
125
|
+
tests: [],
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
adr: 'ADR-073',
|
|
129
|
+
code: 'I7',
|
|
130
|
+
name: 'Maximum parent depth is 3',
|
|
131
|
+
description: 'The parent ladder Subtask → Task → Epic is fixed at depth 3 (hierarchy.maxDepth=3). Sagas do NOT consume depth — they attach via groups relations, not parent edges. Enforced at runtime by assertSagaInvariantI7.',
|
|
132
|
+
severity: 'error',
|
|
133
|
+
runtimeGate: {
|
|
134
|
+
module: SAGA_ENFORCEMENT_MODULE,
|
|
135
|
+
functionName: 'assertSagaInvariantI7',
|
|
136
|
+
},
|
|
137
|
+
lintRule: null,
|
|
138
|
+
doctorAudit: null,
|
|
139
|
+
tests: [SAGA_ENFORCEMENT_TESTS],
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
adr: 'ADR-073',
|
|
143
|
+
code: 'I8',
|
|
144
|
+
name: 'Subtask-to-PR aggregation rule',
|
|
145
|
+
description: "A Task ships as exactly one PR. The PR's commit history is the union of the Task's Subtask commits. A Subtask never produces its own PR; if a unit of work warrants its own PR, it is a Task, not a Subtask. UNENFORCED at runtime today — load-bearing convention enforced via code review and the lifecycle decision table.",
|
|
146
|
+
severity: 'warning',
|
|
147
|
+
// I8 is explicitly "UNENFORCED, load-bearing" — there is no automated
|
|
148
|
+
// gate. R6 doctor audit surfaces this entry so it stays visible.
|
|
149
|
+
runtimeGate: null,
|
|
150
|
+
lintRule: null,
|
|
151
|
+
doctorAudit: null,
|
|
152
|
+
tests: [],
|
|
153
|
+
},
|
|
154
|
+
]);
|
|
155
|
+
//# sourceMappingURL=adr-073-saga.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adr-073-saga.js","sourceRoot":"","sources":["../../src/invariants/adr-073-saga.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central invariants registry — SSoT for system-wide invariants surfaced via
|
|
3
|
+
* the SaGa T10326 SG-SUBSTRATE-RECONCILIATION programme (Epic T10327
|
|
4
|
+
* E-INVARIANT-REGISTRY-SSOT, Task T10335 R1).
|
|
5
|
+
*
|
|
6
|
+
* Every registered invariant carries the metadata needed to:
|
|
7
|
+
* 1. Reference its source ADR (e.g. `ADR-073` §1.2 for I1-I8).
|
|
8
|
+
* 2. Locate the runtime guard that enforces it (when one exists).
|
|
9
|
+
* 3. Bind the CI lint rule that protects it (when one exists).
|
|
10
|
+
* 4. Cross-reference test files that exercise it.
|
|
11
|
+
* 5. Render documentation via the downstream R8 auto-render pipeline.
|
|
12
|
+
*
|
|
13
|
+
* Downstream consumers:
|
|
14
|
+
* - R2 (T10336, SHIPPED): registers ADR-070 ORC-001..ORC-014 codes into
|
|
15
|
+
* this same registry via `./adr-070-orchestration.ts`.
|
|
16
|
+
* - R4 (T10338): CI gate validates that every `severity:'error'` entry has
|
|
17
|
+
* a non-null `runtimeGate` AND a matching error-code in `errors.ts`.
|
|
18
|
+
* - R5 (T10339): refactor `packages/core/src/release/invariants/registry.ts`
|
|
19
|
+
* to consume the central registry instead of carrying its own list.
|
|
20
|
+
* - R6 (T10340): `cleo doctor --audit-invariants` walks the registry to
|
|
21
|
+
* produce a per-invariant audit report.
|
|
22
|
+
* - R8 (T10342): auto-render docs page from the registry.
|
|
23
|
+
*
|
|
24
|
+
* @epic T10327 — E-INVARIANT-REGISTRY-SSOT
|
|
25
|
+
* @saga T10326 — SG-SUBSTRATE-RECONCILIATION
|
|
26
|
+
* @task T10335 — R1: registry + ADR-073 I1-I8
|
|
27
|
+
* @see ADR-073-above-epic-naming.md §1.2
|
|
28
|
+
*/
|
|
29
|
+
export { ADR_056_INVARIANTS } from './adr-056-release.js';
|
|
30
|
+
export { ADR_070_INVARIANTS } from './adr-070-orchestration.js';
|
|
31
|
+
export { ADR_073_INVARIANTS } from './adr-073-saga.js';
|
|
32
|
+
/**
|
|
33
|
+
* Severity tier for a registered invariant.
|
|
34
|
+
*
|
|
35
|
+
* - `'error'` — runtime gate MUST exist; violation surfaces as LAFS error
|
|
36
|
+
* code (cross-checked by R4 CI gate).
|
|
37
|
+
* - `'warning'` — orchestration/process concern; surfaces via doctor audit
|
|
38
|
+
* but does not throw at runtime.
|
|
39
|
+
* - `'info'` — display or storage concern; enforced (if at all) by DB
|
|
40
|
+
* constraints or convention rather than a runtime function.
|
|
41
|
+
*/
|
|
42
|
+
export type InvariantSeverity = 'info' | 'warning' | 'error';
|
|
43
|
+
/**
|
|
44
|
+
* Pointer to a runtime guard function that enforces an invariant.
|
|
45
|
+
*
|
|
46
|
+
* The `module` field is the package-relative import specifier
|
|
47
|
+
* (e.g. `packages/core/src/sagas/enforcement.ts`). The `functionName` is the
|
|
48
|
+
* exported identifier (e.g. `assertSagaInvariantI3`).
|
|
49
|
+
*
|
|
50
|
+
* R4 CI gate uses this triple to assert the guard actually exists and is
|
|
51
|
+
* exported with the expected name. R6 doctor audit uses it to render
|
|
52
|
+
* per-invariant enforcement provenance.
|
|
53
|
+
*/
|
|
54
|
+
export interface InvariantRuntimeGate {
|
|
55
|
+
readonly module: string;
|
|
56
|
+
readonly functionName: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Pointer to a CI lint script that protects an invariant.
|
|
60
|
+
*
|
|
61
|
+
* The path is repo-rooted (e.g. `scripts/lint-saga-label-anti-pattern.mjs`).
|
|
62
|
+
*/
|
|
63
|
+
export interface InvariantLintRule {
|
|
64
|
+
readonly lintScript: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Pointer to a `cleo doctor` audit that surfaces invariant violations.
|
|
68
|
+
*
|
|
69
|
+
* The lintScript field mirrors the CI gate pointer — many invariants share
|
|
70
|
+
* the same script between CI and doctor (e.g. saga-label anti-pattern).
|
|
71
|
+
*/
|
|
72
|
+
export interface InvariantDoctorAudit {
|
|
73
|
+
readonly lintScript: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* A registered invariant — one entry per `(adr, code)` pair.
|
|
77
|
+
*
|
|
78
|
+
* The `adr` + `code` combination forms the registry key
|
|
79
|
+
* (`${adr}.${code}`, e.g. `'ADR-073.I3'`). Lookups via `getInvariant`
|
|
80
|
+
* and per-ADR enumeration via `getInvariantsByAdr` use this convention.
|
|
81
|
+
*
|
|
82
|
+
* @see ADR-073-above-epic-naming.md §1.2 — original I1-I8 source.
|
|
83
|
+
*/
|
|
84
|
+
export interface RegisteredInvariant {
|
|
85
|
+
/** Source ADR identifier, e.g. `'ADR-073'`. */
|
|
86
|
+
readonly adr: string;
|
|
87
|
+
/** Invariant code within the ADR, e.g. `'I3'` or `'ORC-001'`. */
|
|
88
|
+
readonly code: string;
|
|
89
|
+
/** Short human-readable name, e.g. `'Tier promotion mandatory'`. */
|
|
90
|
+
readonly name: string;
|
|
91
|
+
/** Full description (one or two sentences, no markdown). */
|
|
92
|
+
readonly description: string;
|
|
93
|
+
/** Severity tier — drives R4 CI gate strictness. */
|
|
94
|
+
readonly severity: InvariantSeverity;
|
|
95
|
+
/**
|
|
96
|
+
* Runtime guard function, or `null` when the invariant has no
|
|
97
|
+
* runtime-checkable form (display/storage/process concerns).
|
|
98
|
+
*
|
|
99
|
+
* Every `severity:'error'` invariant MUST set a non-null
|
|
100
|
+
* `runtimeGate` — enforced by the registry test suite (T10335 AC5)
|
|
101
|
+
* and by the R4 CI gate (T10338).
|
|
102
|
+
*/
|
|
103
|
+
readonly runtimeGate: InvariantRuntimeGate | null;
|
|
104
|
+
/**
|
|
105
|
+
* Optional CI lint rule reference. Distinct from `runtimeGate` —
|
|
106
|
+
* `runtimeGate` runs in dispatch code, `lintRule` runs in CI.
|
|
107
|
+
*/
|
|
108
|
+
readonly lintRule?: InvariantLintRule | null;
|
|
109
|
+
/**
|
|
110
|
+
* Optional `cleo doctor` audit reference. R6 consumes this field to
|
|
111
|
+
* decide which invariants surface in `cleo doctor --audit-invariants`.
|
|
112
|
+
*/
|
|
113
|
+
readonly doctorAudit?: InvariantDoctorAudit | null;
|
|
114
|
+
/**
|
|
115
|
+
* Paths of test files that exercise the invariant. Used by R8 to render
|
|
116
|
+
* documentation pages with live test cross-references.
|
|
117
|
+
*/
|
|
118
|
+
readonly tests: readonly string[];
|
|
119
|
+
/**
|
|
120
|
+
* Optional flag — set to `true` when the invariant is superseded but
|
|
121
|
+
* preserved for historical/import-mapping reasons. Defaults to `false`.
|
|
122
|
+
*/
|
|
123
|
+
readonly deprecated?: boolean;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Central invariants registry — keyed by `${adr}.${code}`.
|
|
127
|
+
*
|
|
128
|
+
* Treat as read-only at runtime. Mutating this record is a contract
|
|
129
|
+
* violation; downstream consumers (R5 release-registry refactor, R6
|
|
130
|
+
* doctor audit, R8 docs renderer) assume immutability.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```ts
|
|
134
|
+
* import { INVARIANTS_REGISTRY } from '@cleocode/contracts';
|
|
135
|
+
* const i3 = INVARIANTS_REGISTRY['ADR-073.I3'];
|
|
136
|
+
* if (i3?.runtimeGate) {
|
|
137
|
+
* console.log(`Guard: ${i3.runtimeGate.functionName}`);
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export declare const INVARIANTS_REGISTRY: Readonly<Record<string, RegisteredInvariant>>;
|
|
142
|
+
/**
|
|
143
|
+
* Look up a single invariant by its `${adr}.${code}` key.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```ts
|
|
147
|
+
* const i3 = getInvariant('ADR-073.I3');
|
|
148
|
+
* // → RegisteredInvariant for ADR-073 invariant I3
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
export declare function getInvariant(adrCode: string): RegisteredInvariant | undefined;
|
|
152
|
+
/**
|
|
153
|
+
* Return every invariant registered against a given ADR, in declaration order.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```ts
|
|
157
|
+
* const adr073 = getInvariantsByAdr('ADR-073');
|
|
158
|
+
* // → array of I1..I8 entries
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
export declare function getInvariantsByAdr(adr: string): RegisteredInvariant[];
|
|
162
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/invariants/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAQH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AAE7D;;;;;;;;;;GAUG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC,+CAA+C;IAC/C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,oDAAoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAClD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC7C;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnD;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAqCD;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAmB,CAAC;AAElG;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS,CAE7E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,EAAE,CASrE"}
|