@tiphys/kernel 0.0.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +663 -0
- package/LICENSE +202 -0
- package/assurance-modes.yaml +299 -0
- package/checklists/clean-room.yaml +325 -0
- package/checklists/env-failure-diagnosis.yaml +68 -0
- package/checklists/flake-playbook.yaml +68 -0
- package/checklists/hazard-review.yaml +144 -0
- package/checklists/plan-review.yaml +103 -0
- package/dist/bin/tiphys.d.ts +2 -0
- package/dist/bin/tiphys.js +92 -0
- package/dist/src/adapters/load.d.ts +202 -0
- package/dist/src/adapters/load.js +440 -0
- package/dist/src/brief.d.ts +32 -0
- package/dist/src/brief.js +66 -0
- package/dist/src/checklists.d.ts +169 -0
- package/dist/src/checklists.js +310 -0
- package/dist/src/checks.d.ts +1539 -0
- package/dist/src/checks.js +5025 -0
- package/dist/src/cli.d.ts +9 -0
- package/dist/src/cli.js +68 -0
- package/dist/src/commands/brief.d.ts +92 -0
- package/dist/src/commands/brief.js +343 -0
- package/dist/src/commands/checklist.d.ts +42 -0
- package/dist/src/commands/checklist.js +168 -0
- package/dist/src/commands/cutover.d.ts +35 -0
- package/dist/src/commands/cutover.js +448 -0
- package/dist/src/commands/doctor.d.ts +264 -0
- package/dist/src/commands/doctor.js +1546 -0
- package/dist/src/commands/gates.d.ts +9 -0
- package/dist/src/commands/gates.js +360 -0
- package/dist/src/commands/init.d.ts +30 -0
- package/dist/src/commands/init.js +177 -0
- package/dist/src/commands/lock.d.ts +34 -0
- package/dist/src/commands/lock.js +340 -0
- package/dist/src/commands/mode.d.ts +40 -0
- package/dist/src/commands/mode.js +134 -0
- package/dist/src/commands/next.d.ts +130 -0
- package/dist/src/commands/next.js +597 -0
- package/dist/src/commands/plan.d.ts +20 -0
- package/dist/src/commands/plan.js +105 -0
- package/dist/src/commands/pool.d.ts +1 -0
- package/dist/src/commands/pool.js +139 -0
- package/dist/src/commands/resume.d.ts +1 -0
- package/dist/src/commands/resume.js +88 -0
- package/dist/src/commands/spawn.d.ts +1 -0
- package/dist/src/commands/spawn.js +195 -0
- package/dist/src/commands/status.d.ts +21 -0
- package/dist/src/commands/status.js +122 -0
- package/dist/src/commands/sync.d.ts +47 -0
- package/dist/src/commands/sync.js +341 -0
- package/dist/src/commands/teardown.d.ts +1 -0
- package/dist/src/commands/teardown.js +87 -0
- package/dist/src/commands/tuition.d.ts +21 -0
- package/dist/src/commands/tuition.js +218 -0
- package/dist/src/commands/validate.d.ts +78 -0
- package/dist/src/commands/validate.js +430 -0
- package/dist/src/commands/watch.d.ts +1 -0
- package/dist/src/commands/watch.js +172 -0
- package/dist/src/cutover.d.ts +584 -0
- package/dist/src/cutover.js +1444 -0
- package/dist/src/exclusion.d.ts +389 -0
- package/dist/src/exclusion.js +843 -0
- package/dist/src/exec/env.d.ts +278 -0
- package/dist/src/exec/env.js +334 -0
- package/dist/src/fleet.d.ts +223 -0
- package/dist/src/fleet.js +298 -0
- package/dist/src/gates/adapters/http-json.d.ts +5 -0
- package/dist/src/gates/adapters/http-json.js +283 -0
- package/dist/src/gates/adapters/migrations-command.d.ts +1 -0
- package/dist/src/gates/adapters/migrations-command.js +373 -0
- package/dist/src/gates/citations.d.ts +408 -0
- package/dist/src/gates/citations.js +1169 -0
- package/dist/src/gates/coverage.d.ts +375 -0
- package/dist/src/gates/coverage.js +836 -0
- package/dist/src/gates/credentials.d.ts +233 -0
- package/dist/src/gates/credentials.js +752 -0
- package/dist/src/gates/deploy.d.ts +1 -0
- package/dist/src/gates/deploy.js +33 -0
- package/dist/src/gates/gate-classes.d.ts +56 -0
- package/dist/src/gates/gate-classes.js +633 -0
- package/dist/src/gates/manifest.d.ts +99 -0
- package/dist/src/gates/manifest.js +208 -0
- package/dist/src/gates/merge-preconditions.d.ts +319 -0
- package/dist/src/gates/merge-preconditions.js +932 -0
- package/dist/src/gates/migrations.d.ts +1 -0
- package/dist/src/gates/migrations.js +36 -0
- package/dist/src/gates/pin.d.ts +114 -0
- package/dist/src/gates/pin.js +154 -0
- package/dist/src/gates/red-witness.d.ts +22 -0
- package/dist/src/gates/red-witness.js +482 -0
- package/dist/src/gates/release.d.ts +283 -0
- package/dist/src/gates/release.js +820 -0
- package/dist/src/gates/result.d.ts +116 -0
- package/dist/src/gates/result.js +91 -0
- package/dist/src/gates/run.d.ts +614 -0
- package/dist/src/gates/run.js +1614 -0
- package/dist/src/gates/schemas/citation-config.schema.json +59 -0
- package/dist/src/gates/schemas/coverage-config.schema.json +77 -0
- package/dist/src/gates/schemas/gate-manifest.schema.json +125 -0
- package/dist/src/gates/schemas/gate-result.schema.json +160 -0
- package/dist/src/gates/schemas/phase-declaration.schema.json +87 -0
- package/dist/src/gates/schemas/release-record.schema.json +119 -0
- package/dist/src/gates/schemas/verifier-config.schema.json +101 -0
- package/dist/src/gates/schemas/witness-spec.schema.json +110 -0
- package/dist/src/gates/scope.d.ts +131 -0
- package/dist/src/gates/scope.js +1018 -0
- package/dist/src/gates/suite.d.ts +217 -0
- package/dist/src/gates/suite.js +968 -0
- package/dist/src/gates/validate.d.ts +121 -0
- package/dist/src/gates/validate.js +414 -0
- package/dist/src/hooks.d.ts +84 -0
- package/dist/src/hooks.js +125 -0
- package/dist/src/index.d.ts +31 -0
- package/dist/src/index.js +30 -0
- package/dist/src/liveness.d.ts +321 -0
- package/dist/src/liveness.js +396 -0
- package/dist/src/lock.d.ts +256 -0
- package/dist/src/lock.js +792 -0
- package/dist/src/model-resolution.d.ts +159 -0
- package/dist/src/model-resolution.js +307 -0
- package/dist/src/modes.d.ts +149 -0
- package/dist/src/modes.js +258 -0
- package/dist/src/path-identity.d.ts +34 -0
- package/dist/src/path-identity.js +48 -0
- package/dist/src/plan.d.ts +73 -0
- package/dist/src/plan.js +153 -0
- package/dist/src/pool.d.ts +326 -0
- package/dist/src/pool.js +988 -0
- package/dist/src/roles.d.ts +461 -0
- package/dist/src/roles.js +776 -0
- package/dist/src/spawn.d.ts +482 -0
- package/dist/src/spawn.js +1003 -0
- package/dist/src/status.d.ts +116 -0
- package/dist/src/status.js +148 -0
- package/dist/src/task.d.ts +504 -0
- package/dist/src/task.js +307 -0
- package/dist/src/teardown.d.ts +39 -0
- package/dist/src/teardown.js +422 -0
- package/dist/src/tuition.d.ts +159 -0
- package/dist/src/tuition.js +311 -0
- package/dist/src/validate.d.ts +263 -0
- package/dist/src/validate.js +742 -0
- package/dist/src/version.d.ts +3 -0
- package/dist/src/version.js +38 -0
- package/dist/src/watcher.d.ts +275 -0
- package/dist/src/watcher.js +849 -0
- package/dist/src/witness/run.d.ts +299 -0
- package/dist/src/witness/run.js +1373 -0
- package/dist/src/witness/spec.d.ts +270 -0
- package/dist/src/witness/spec.js +475 -0
- package/dist/tsconfig.src.tsbuildinfo +1 -0
- package/gate-registry.yaml +526 -0
- package/gates.manifest.json +257 -0
- package/package.json +72 -3
- package/role-model-config.yaml +88 -0
- package/roles/README.md +128 -0
- package/roles/_shared-dispatch-contract.md +87 -0
- package/roles/adversarial-plan-reviewer.md +80 -0
- package/roles/clean-room-reviewer.md +140 -0
- package/roles/implementer.md +463 -0
- package/roles/investigator.md +138 -0
- package/roles/plan-writer.md +95 -0
- package/schemas/README.md +82 -0
- package/schemas/assurance-modes.schema.json +264 -0
- package/schemas/charter.schema.json +185 -0
- package/schemas/checklist.schema.json +114 -0
- package/schemas/cutover-state.schema.json +64 -0
- package/schemas/decision-record.schema.json +88 -0
- package/schemas/executor-record.schema.json +36 -0
- package/schemas/final-report.schema.json +90 -0
- package/schemas/finding.schema.json +106 -0
- package/schemas/gate-registry.schema.json +260 -0
- package/schemas/mechanism-index.schema.json +94 -0
- package/schemas/model-resolution.schema.json +362 -0
- package/schemas/plan.schema.json +300 -0
- package/schemas/report.schema.json +579 -0
- package/schemas/role-brief.schema.json +105 -0
- package/schemas/role-model-config.schema.json +90 -0
- package/schemas/status-line.schema.json +40 -0
- package/schemas/tuition.schema.json +191 -0
- package/schemas/verdict.schema.json +295 -0
- package/schemas/work-history.schema.json +183 -0
- package/schemas/write-bypass.schema.json +69 -0
- package/templates/charter.example.yaml +54 -0
- package/templates/decision-record.example.yaml +27 -0
- package/templates/final-report.example.yaml +80 -0
- package/templates/plan.example.yaml +87 -0
- package/templates/report.example.yaml +236 -0
- package/templates/warnings.md +74 -0
- package/templates/work-history.example.yaml +185 -0
- package/tuition/README.md +76 -0
- package/tuition/T-001.yaml +48 -0
- package/tuition/T-002.yaml +51 -0
- package/tuition/T-003.yaml +100 -0
- package/tuition/T-004.yaml +52 -0
- package/tuition/T-005.yaml +72 -0
- package/tuition/T-006.yaml +81 -0
- package/tuition/T-007.yaml +56 -0
- package/tuition/T-008.yaml +111 -0
- package/tuition/T-009.yaml +50 -0
- package/tuition/T-015.yaml +36 -0
- package/tuition/T-016.yaml +36 -0
- package/tuition/T-017.yaml +46 -0
- package/tuition/T-018.yaml +84 -0
- package/tuition/T-021.yaml +40 -0
- package/tuition/T-022.yaml +36 -0
- package/tuition/mechanism-index.yaml +256 -0
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
# THE CANONICAL GATE REGISTRY (kernel plan M3, M3-P2; R-094).
|
|
2
|
+
#
|
|
3
|
+
# This file is the canonical DECLARATION of this repository's gates, and R-094
|
|
4
|
+
# asks for one source that CI and the briefs both read. HOW FAR THAT IS TRUE
|
|
5
|
+
# TODAY, stated in the present tense only where it is:
|
|
6
|
+
#
|
|
7
|
+
# BRIEFS: delivered. The agent-rules gate section in CLAUDE.md is GENERATED
|
|
8
|
+
# from this file by `scripts/render-agent-rules-gates.mjs`. Editing that
|
|
9
|
+
# block by hand makes `node scripts/render-agent-rules-gates.mjs --check`
|
|
10
|
+
# exit nonzero, and the `gates` workflow runs that command as a step on both
|
|
11
|
+
# CI events, so a hand edit fails the build. Edit this file instead.
|
|
12
|
+
#
|
|
13
|
+
# CI: NOT YET. The `gates` workflow calls `scripts/m2-exit-test.sh`, which
|
|
14
|
+
# invokes the runner with `--manifest gates.manifest.json` on both arms.
|
|
15
|
+
# `--registry` occurs nowhere in either file. So a gate declared ONLY here
|
|
16
|
+
# does not run in CI, and `agent-rules-drift` is exactly that case: it runs
|
|
17
|
+
# because the workflow also carries a direct step for it. Closing this needs
|
|
18
|
+
# an edit to `scripts/m2-exit-test.sh`, which is not on M3-P2's declaration
|
|
19
|
+
# and is tracked with the orchestrator. The divergence is not left to be
|
|
20
|
+
# noticed: `test/gate-registry.test.ts` asserts it in BOTH directions, so a
|
|
21
|
+
# NEW script gate declared only here reddens rather than silently not
|
|
22
|
+
# running.
|
|
23
|
+
#
|
|
24
|
+
# PROMOTED, NOT INVENTED. Every `script` entry below is the M2-P1
|
|
25
|
+
# `gates.manifest.json` entry of the same id, carried across with its
|
|
26
|
+
# `command`, `unitLabel`, `applicability`, `parameters` and `precondition`
|
|
27
|
+
# byte-for-byte, plus the three fields this registry adds (`verified-by`,
|
|
28
|
+
# `modes`, `events`). SC-011's precondition semantics travel with the
|
|
29
|
+
# precondition blocks unchanged: a gate whose precondition is unmet reports
|
|
30
|
+
# not-applicable and NEVER green.
|
|
31
|
+
#
|
|
32
|
+
# WHAT IS NOT HERE, stated rather than left to be noticed. Kernel plan M3
|
|
33
|
+
# step 3 names project-specific gates `i18n`, `analytics`, `manifest regen`,
|
|
34
|
+
# `e2e` and `docs grep` as things to keep "declared-but-not-applicable on the
|
|
35
|
+
# kernel exactly as M2-P1 left them". M2-P1 left them NOWHERE: the delivered
|
|
36
|
+
# `gates.manifest.json` on main at 40427b6 declares eleven gates and none of
|
|
37
|
+
# those five is among them. Promoting a gate M2 never shipped would be
|
|
38
|
+
# inventing it, not promoting it, so the two entries that ARE structurally
|
|
39
|
+
# not-applicable on the kernel (`deploy`, `migrations`) are carried across and
|
|
40
|
+
# the other five are recorded as absent here and in
|
|
41
|
+
# delivery/work-history/m3-p2.md rather than fabricated.
|
|
42
|
+
|
|
43
|
+
kind: gate-registry
|
|
44
|
+
version: 1
|
|
45
|
+
|
|
46
|
+
# The ordered local commands every change must pass. Rendered into CLAUDE.md's
|
|
47
|
+
# gate section together with the table below, so that section has no
|
|
48
|
+
# hand-maintained list in it (M3-P2 criterion 6).
|
|
49
|
+
preflight:
|
|
50
|
+
- command: [npm, ci]
|
|
51
|
+
note: install exactly the lockfile, npm only, never pnpm or yarn
|
|
52
|
+
- command: [npm, run, build]
|
|
53
|
+
note: the type gate (tsc -b); emits dist/, which is never committed, and git status must be clean afterwards
|
|
54
|
+
- command: [node, --test]
|
|
55
|
+
note: sources are TypeScript run natively via Node type stripping, so the suite needs no prior build
|
|
56
|
+
|
|
57
|
+
gates:
|
|
58
|
+
- id: manifest-self-check
|
|
59
|
+
command: [node, bin/tiphys.ts, gates, self-check, --manifest, gates.manifest.json]
|
|
60
|
+
unitLabel: schema documents validated
|
|
61
|
+
applicability: required
|
|
62
|
+
verified-by: script
|
|
63
|
+
modes: [full, direct-pr, local-only]
|
|
64
|
+
events: [pull_request, push]
|
|
65
|
+
|
|
66
|
+
- id: coverage
|
|
67
|
+
command: [node, src/gates/coverage.ts]
|
|
68
|
+
unitLabel: finding ids checked
|
|
69
|
+
applicability: required
|
|
70
|
+
verified-by: script
|
|
71
|
+
modes: [full, direct-pr]
|
|
72
|
+
events: [pull_request, push]
|
|
73
|
+
precondition:
|
|
74
|
+
id: coverage-inventory-exists
|
|
75
|
+
kind: file-exists
|
|
76
|
+
path: delivery/requirements/migration-table.md
|
|
77
|
+
|
|
78
|
+
- id: credential-scrub
|
|
79
|
+
command: [node, src/gates/credentials.ts, credential-scrub]
|
|
80
|
+
unitLabel: credential sources probed
|
|
81
|
+
applicability: required
|
|
82
|
+
verified-by: script
|
|
83
|
+
modes: [full, direct-pr, local-only]
|
|
84
|
+
events: [pull_request, push]
|
|
85
|
+
|
|
86
|
+
- id: credential-token
|
|
87
|
+
command: [node, src/gates/credentials.ts, credential-token]
|
|
88
|
+
unitLabel: tokens probed
|
|
89
|
+
applicability: conditional
|
|
90
|
+
verified-by: script
|
|
91
|
+
modes: [full, direct-pr]
|
|
92
|
+
events: [pull_request]
|
|
93
|
+
precondition:
|
|
94
|
+
id: implementer-token-present-owner-action-a-3
|
|
95
|
+
kind: command-exit-zero
|
|
96
|
+
command: [node, -e, "process.exit(process.env.TIPHYS_IMPLEMENTER_TOKEN === undefined ? 1 : 0)"]
|
|
97
|
+
|
|
98
|
+
- id: suite
|
|
99
|
+
command: [node, src/gates/suite.ts, --pin-root, src, --pin-root, bin, --pin-root, test]
|
|
100
|
+
unitLabel: tests reported
|
|
101
|
+
applicability: required
|
|
102
|
+
verified-by: script
|
|
103
|
+
modes: [full, direct-pr, local-only]
|
|
104
|
+
events: [pull_request, push]
|
|
105
|
+
parameters: [base]
|
|
106
|
+
|
|
107
|
+
- id: citations
|
|
108
|
+
command: [node, src/gates/citations.ts]
|
|
109
|
+
unitLabel: citations resolved
|
|
110
|
+
applicability: required
|
|
111
|
+
verified-by: script
|
|
112
|
+
modes: [full, direct-pr]
|
|
113
|
+
events: [pull_request]
|
|
114
|
+
precondition:
|
|
115
|
+
id: citations-diff-touches-documents
|
|
116
|
+
kind: diff-touches
|
|
117
|
+
paths:
|
|
118
|
+
- delivery/plan/
|
|
119
|
+
- delivery/verification/
|
|
120
|
+
- delivery/decisions/
|
|
121
|
+
- delivery/tuition/
|
|
122
|
+
- delivery/requirements/
|
|
123
|
+
- delivery/STATE.md
|
|
124
|
+
|
|
125
|
+
- id: scope
|
|
126
|
+
command: [node, src/gates/scope.ts, --declarations, delivery/plan/phase-declarations]
|
|
127
|
+
unitLabel: changed paths audited
|
|
128
|
+
applicability: required
|
|
129
|
+
verified-by: script
|
|
130
|
+
modes: [full, direct-pr]
|
|
131
|
+
events: [pull_request]
|
|
132
|
+
parameters: [base, head]
|
|
133
|
+
precondition:
|
|
134
|
+
id: scope-branch-is-a-phase-branch
|
|
135
|
+
kind: branch-matches
|
|
136
|
+
pattern: claude/m[0-9]+-p[0-9]+-.*
|
|
137
|
+
|
|
138
|
+
- id: deploy
|
|
139
|
+
command: [node, src/gates/deploy.ts]
|
|
140
|
+
unitLabel: release verifications satisfied
|
|
141
|
+
applicability: conditional
|
|
142
|
+
verified-by: script
|
|
143
|
+
modes: [full]
|
|
144
|
+
events: [pull_request, push]
|
|
145
|
+
precondition:
|
|
146
|
+
id: "deploy-release-verification-declared (an unmet result here is STRUCTURAL in any pre-merge bundle, not local to this repository: release verification runs post-merge against a commit that exists only once the merge has happened; kernel plan M2 section 1.4, investigation observation O-3)"
|
|
147
|
+
kind: file-exists
|
|
148
|
+
path: release-verification.json
|
|
149
|
+
|
|
150
|
+
- id: migrations
|
|
151
|
+
command: [node, src/gates/migrations.ts]
|
|
152
|
+
unitLabel: migrations compared
|
|
153
|
+
applicability: conditional
|
|
154
|
+
verified-by: script
|
|
155
|
+
modes: [full]
|
|
156
|
+
events: [pull_request, push]
|
|
157
|
+
precondition:
|
|
158
|
+
id: "migrations-release-verification-declared (an unmet result here is STRUCTURAL in any pre-merge bundle, not local to this repository: release verification runs post-merge against a commit that exists only once the merge has happened; kernel plan M2 section 1.4, investigation observation O-3)"
|
|
159
|
+
kind: file-exists
|
|
160
|
+
path: release-verification.json
|
|
161
|
+
|
|
162
|
+
- id: clause-map
|
|
163
|
+
command: [node, scripts/check-clause-map.mjs]
|
|
164
|
+
unitLabel: clause-map rows checked
|
|
165
|
+
applicability: required
|
|
166
|
+
verified-by: script
|
|
167
|
+
modes: [full, direct-pr]
|
|
168
|
+
events: [pull_request]
|
|
169
|
+
|
|
170
|
+
- id: red-witness
|
|
171
|
+
command: [node, src/gates/red-witness.ts]
|
|
172
|
+
unitLabel: witnesses evaluated
|
|
173
|
+
applicability: required
|
|
174
|
+
verified-by: script
|
|
175
|
+
modes: [full, direct-pr]
|
|
176
|
+
events: [pull_request]
|
|
177
|
+
parameters: [base, head]
|
|
178
|
+
precondition:
|
|
179
|
+
id: red-witness-diff
|
|
180
|
+
kind: diff-touches
|
|
181
|
+
paths:
|
|
182
|
+
- src/
|
|
183
|
+
- bin/
|
|
184
|
+
- plugin/
|
|
185
|
+
|
|
186
|
+
# NEW IN M3-P2, entry one of three.
|
|
187
|
+
- id: agent-rules-drift
|
|
188
|
+
$comment: >-
|
|
189
|
+
R-094. The check that makes the BRIEFS half of "single source consumed by
|
|
190
|
+
CI and briefs" true rather than asserted: it re-renders CLAUDE.md's gate
|
|
191
|
+
block from this file and fails when the two differ. It is declared here
|
|
192
|
+
because D-M3-34 requires every M3 check to be declared in the registry,
|
|
193
|
+
and its `events` say which arms evaluate it. What actually EXECUTES it in
|
|
194
|
+
CI today is a step in the `gates` workflow, not this entry, because CI
|
|
195
|
+
runs `--manifest gates.manifest.json`; see this file's header. Both arms
|
|
196
|
+
are declared, and the workflow step carries no `if:`, because CLAUDE.md
|
|
197
|
+
drift is a property of `main`, not of a pull request (T-009).
|
|
198
|
+
command: [node, scripts/render-agent-rules-gates.mjs, --check]
|
|
199
|
+
unitLabel: rendered gate rows compared
|
|
200
|
+
applicability: required
|
|
201
|
+
verified-by: script
|
|
202
|
+
modes: [full, direct-pr, local-only]
|
|
203
|
+
events: [pull_request, push]
|
|
204
|
+
|
|
205
|
+
# NEW IN M3-P6 (R-094, D-M3-28, D-M3-34).
|
|
206
|
+
- id: brief-drift
|
|
207
|
+
$comment: >-
|
|
208
|
+
R-094's briefs half, applied to roles/implementer.md the way
|
|
209
|
+
agent-rules-drift applies it to CLAUDE.md: the brief's gate-list section is
|
|
210
|
+
a generated projection of THIS file for the mode its own begin marker
|
|
211
|
+
declares, and this check re-renders and compares. UNLIKE agent-rules-drift,
|
|
212
|
+
it is ALSO in gates.manifest.json, so on a pull request the runner executes
|
|
213
|
+
it as a real gate with a GateResult and M2-C-2's vacuity protection rather
|
|
214
|
+
than as a raw workflow step. WHY `events` IS pull_request ALONE, stated
|
|
215
|
+
exactly because "declared" and "runs" are not the same thing: the push arm
|
|
216
|
+
of scripts/m2-exit-test.sh has a hard-coded `--only` list of six gate ids
|
|
217
|
+
and that script is on no M3 phase's declaration, so a manifest gate outside
|
|
218
|
+
that list cannot run on push, and test/gate-registry.test.ts asserts
|
|
219
|
+
`events` against the harness rather than against a wish. The push arm is
|
|
220
|
+
covered instead by a direct step in .github/workflows/gates.yml carrying no
|
|
221
|
+
`if:`, because brief drift is a property of the default branch and not only
|
|
222
|
+
of a pull request (T-009). Both arms have a witness; they are not the same
|
|
223
|
+
witness, and that is recorded here rather than left to be discovered.
|
|
224
|
+
AND WHICH HALF IS THE TEETH, measured rather than assumed, because the
|
|
225
|
+
sentence above says the runner EXECUTES this as a gate and a reader could
|
|
226
|
+
take that to mean a red one fails the pull request. It does not on its own:
|
|
227
|
+
scripts/m2-exit-test.sh's PR expectation table lists eleven gate ids and
|
|
228
|
+
this is not one of them, and its assertion program compares only gates that
|
|
229
|
+
table names, plus global zero-error and zero-vacuous checks over every row
|
|
230
|
+
with no global zero-red. So an `error` here is caught by the harness and a
|
|
231
|
+
plain `red` is caught by the workflow step, which carries no `if:` and
|
|
232
|
+
therefore fails the job on either event. Adding a table row is an edit to
|
|
233
|
+
that harness, which is on no M3 phase's declaration.
|
|
234
|
+
command: [node, scripts/check-brief-drift.mjs, --check]
|
|
235
|
+
unitLabel: generated brief gate rows compared
|
|
236
|
+
applicability: required
|
|
237
|
+
verified-by: script
|
|
238
|
+
modes: [full, direct-pr, local-only]
|
|
239
|
+
events: [pull_request]
|
|
240
|
+
|
|
241
|
+
# NEW IN M3-P9, entry one of two (D-M3-34, section 2.2a).
|
|
242
|
+
- id: check-agents-references
|
|
243
|
+
$comment: >-
|
|
244
|
+
M3-P9 step 5. Every path `AGENTS.md` references exists AND the ANCHOR it
|
|
245
|
+
names occurs inside that path (criterion 2b), and `AGENTS.md` carries no
|
|
246
|
+
gate id list, no mode table and no model-tier table (criterion 3), because
|
|
247
|
+
section 1.5's anti-duplication rule is what stops the orchestrator brief
|
|
248
|
+
drifting away from the registry it summarizes. WHY BOTH EVENTS: a broken
|
|
249
|
+
reference on `main` is the state that matters, not only one proposed in a
|
|
250
|
+
pull request, which is T-009's rule that where behaviour forks on the CI
|
|
251
|
+
event both arms need a witness. WHAT EXECUTES IT IN CI, stated rather than
|
|
252
|
+
implied: `scripts/m2-exit-test.sh` invokes the runner with `--manifest
|
|
253
|
+
gates.manifest.json` on both arms and that file is on no M3 phase's
|
|
254
|
+
declaration, so a registry-only gate does not run through the runner.
|
|
255
|
+
A step in `.github/workflows/gates.yml` carrying no `if:` is what runs it,
|
|
256
|
+
exactly as for `agent-rules-drift`, and `test/gate-registry.test.ts`
|
|
257
|
+
records the divergence with its reason so the gap is declared rather than
|
|
258
|
+
discovered.
|
|
259
|
+
command: [node, scripts/check-agents-references.mjs]
|
|
260
|
+
unitLabel: references resolved
|
|
261
|
+
applicability: required
|
|
262
|
+
verified-by: script
|
|
263
|
+
modes: [full, direct-pr, local-only]
|
|
264
|
+
events: [pull_request, push]
|
|
265
|
+
|
|
266
|
+
# NEW IN M3-P9, entry two of two (M3R-004, DR-0012, T-001, T-007, D-M3-34).
|
|
267
|
+
- id: check-dual-review
|
|
268
|
+
$comment: >-
|
|
269
|
+
M3-P9 step 3b. The `decorrelated-review` duty made into a command with an
|
|
270
|
+
exit code: two verdicts for one head, distinct `produced-by` model
|
|
271
|
+
families (DR-0012 condition 1), distinct `framing` values (T-001), and
|
|
272
|
+
distinct `review-contract` values (T-007). The comparison itself is the
|
|
273
|
+
Kind B derived check `dual-review-decorrelation` in `src/checks.ts`; this
|
|
274
|
+
script is the runner around it, so deregistering the check is a real
|
|
275
|
+
witness rather than a simulated one (section 2.3 rule 3).
|
|
276
|
+
`events: [pull_request]` ALONE, and the reason is the plan's own: a merged
|
|
277
|
+
head has no pair of verdicts to compare. The PRECONDITION is what keeps
|
|
278
|
+
that from becoming a vacuous green: a gate that cannot reach a verdict
|
|
279
|
+
reports not-applicable with a reason, never green, which is M2-C-3 and
|
|
280
|
+
SC-011 applied to M3's own check. It probes with the script's own
|
|
281
|
+
`--precondition` arm rather than a `file-exists` path, because the
|
|
282
|
+
question is whether any verdict DOCUMENT exists under `delivery/review/`
|
|
283
|
+
and not whether that directory does; this repository has the directory and
|
|
284
|
+
has never had a verdict document in it.
|
|
285
|
+
THE COMMIT UNDER AUDIT IS A PARAMETER, AND ITS ABSENCE WAS THE DR-0047
|
|
286
|
+
SWEEP'S ONE HIGH FINDING (CR-VS-001). Without it the check grouped by the
|
|
287
|
+
head THE VERDICT DOCUMENTS THEMSELVES DECLARE, and nothing compared that
|
|
288
|
+
to the commit the gate was running against or established that it named a
|
|
289
|
+
commit at all. Reproduced: two decorrelated APPROVE verdicts naming
|
|
290
|
+
`deadbeefdeadbeefdeadbeefdeadbeefdeadbeef`, a sha `git cat-file -t`
|
|
291
|
+
reports as not an object, gave `check-dual-review: green`, 2 units, exit
|
|
292
|
+
0, in a repository whose HEAD was a real commit and carried a further
|
|
293
|
+
commit of work no verdict mentioned. So ONE committed approving pair
|
|
294
|
+
turned this gate green for that phase at every later head, indefinitely.
|
|
295
|
+
The runner already had the mechanism: `scope` has declared
|
|
296
|
+
`parameters: [base, head]` since M2 and the runner appends the flags to
|
|
297
|
+
the gate command. This entry simply never declared it. With `--head` the
|
|
298
|
+
audited commit comes from the RUN and the declared head comes from the
|
|
299
|
+
EVIDENCE, and the second is measured against the first instead of
|
|
300
|
+
replacing it. With no `--head` the script falls back to the commit the
|
|
301
|
+
context's own HEAD resolves to, which is what keeps the direct workflow
|
|
302
|
+
step in `.github/workflows/gates.yml` correct.
|
|
303
|
+
command: [node, scripts/check-dual-review.mjs, .]
|
|
304
|
+
unitLabel: review verdicts examined for decorrelation
|
|
305
|
+
applicability: conditional
|
|
306
|
+
verified-by: script
|
|
307
|
+
modes: [full, direct-pr]
|
|
308
|
+
events: [pull_request]
|
|
309
|
+
parameters: [head]
|
|
310
|
+
precondition:
|
|
311
|
+
id: dual-review-verdicts-present
|
|
312
|
+
kind: command-exit-zero
|
|
313
|
+
command: [node, scripts/check-dual-review.mjs, --precondition, .]
|
|
314
|
+
|
|
315
|
+
# NEW IN M3-P10 (EXT-F-09, DR-0013 clause 5, D-M3-34).
|
|
316
|
+
- id: license
|
|
317
|
+
$comment: >-
|
|
318
|
+
M3-P10 step 2. EXT-F-09's five checks as one command with one exit code:
|
|
319
|
+
inventory the TRANSITIVE production dependency set, require license
|
|
320
|
+
metadata on every member, refuse any license off the declared allowlist,
|
|
321
|
+
require THIRD-PARTY-NOTICES whenever copied third-party code is declared
|
|
322
|
+
(plan v1 D-1's license note makes this declaration-driven, because
|
|
323
|
+
protocol reimplementation carries no notice obligation), and require
|
|
324
|
+
LICENSE in the `npm pack` listing. WHY IT IS A GATE AND NOT ONLY A RELEASE
|
|
325
|
+
STEP: what ships is a property of every change, not of the release that
|
|
326
|
+
happens to notice it, and DR-0013 marked a grown production tree the
|
|
327
|
+
costly direction. WHERE IT RUNS, STATED AS WHAT IS TRUE RATHER THAN AS AN
|
|
328
|
+
ABSOLUTE (corrected in M3-P10 fix round 1, clean-room finding HRB-7):
|
|
329
|
+
`.github/workflows/release.yml` runs it as an explicit STEP before
|
|
330
|
+
publishing, which is the enforcement point because it depends on no
|
|
331
|
+
lifecycle hook; `prepublishOnly` runs it on every publish path that runs
|
|
332
|
+
lifecycle scripts, and `--ignore-scripts` skips it, measured on npm
|
|
333
|
+
11.18.0. The earlier wording said no publish path at all could skip it,
|
|
334
|
+
and that was false in a file that SHIPS. BOTH EVENTS, and the
|
|
335
|
+
reason is T-009's: a dependency added on `main` by a merge is exactly the
|
|
336
|
+
state that matters, and an arm with no witness is the arm that breaks.
|
|
337
|
+
WHAT EXECUTES IT IN CI, stated rather than implied: `scripts/m2-exit-test.sh`
|
|
338
|
+
invokes the runner with `--manifest gates.manifest.json` on both arms and
|
|
339
|
+
that file is on no M3 phase's declaration, so a registry-only gate does not
|
|
340
|
+
reach the runner. A step in `.github/workflows/gates.yml` carrying no `if:`
|
|
341
|
+
is what runs it, exactly as for `agent-rules-drift` and
|
|
342
|
+
`check-agents-references`, and `test/gate-registry.test.ts` records the
|
|
343
|
+
divergence with its reason so the gap is declared rather than discovered.
|
|
344
|
+
NOT CONDITIONAL, DELIBERATELY: there is no tree here with no production
|
|
345
|
+
dependencies, so a precondition would be a not-applicable arm that can
|
|
346
|
+
never be reached, and M2-C-2 already refuses a green with zero units.
|
|
347
|
+
command: [node, scripts/license-gate.mjs]
|
|
348
|
+
unitLabel: production packages licensed
|
|
349
|
+
applicability: required
|
|
350
|
+
verified-by: script
|
|
351
|
+
modes: [full, direct-pr, local-only]
|
|
352
|
+
events: [pull_request, push]
|
|
353
|
+
|
|
354
|
+
# NEW IN M4-P14, entry one of two (R-041, DR-0028, DR-0029, M4-P13).
|
|
355
|
+
- id: typecheck
|
|
356
|
+
$comment: >-
|
|
357
|
+
R-041, retargeted by M4-P13 under DR-0028. The kernel ships the gate
|
|
358
|
+
CLASS and no command; the project ships the command. This repository is
|
|
359
|
+
the project, so this is the kernel dogfooding the extension point rather
|
|
360
|
+
than being exempt from it (DR-0029: "the kernel becomes just another
|
|
361
|
+
project under the scheme, with its own registry"). The subject is the one
|
|
362
|
+
M4 has, package.json's build script, which CLAUDE.md already calls the
|
|
363
|
+
type gate. WHY IT IS NOT THE SAME THING AS THE `build` PREFLIGHT STEP:
|
|
364
|
+
preflight is an ordered local command with no record, no units and no
|
|
365
|
+
vacuity protection, so nothing downstream can tell a build that checked
|
|
366
|
+
the whole project from one that checked nothing. This entry produces a
|
|
367
|
+
GateResult whose `units` is the count of distinct paths `tsc --listFiles`
|
|
368
|
+
PRINTED, so a compiler that read no file is error rather than green.
|
|
369
|
+
WHY `--force` IS IN THE COMMAND: without it `tsc -b` is incremental and
|
|
370
|
+
the printed file list depends on the state of `dist/`, which would make
|
|
371
|
+
the unit count a property of the runner's working directory instead of
|
|
372
|
+
the code. `events: [pull_request]` alone, and it is derived rather than
|
|
373
|
+
assigned: `scripts/m2-exit-test.sh` declares the push arm's gate set once
|
|
374
|
+
in MAIN_ONLY_GATES and this id is not in it, so the push arm cannot run
|
|
375
|
+
it and test/gate-registry.test.ts asserts `events` against that harness.
|
|
376
|
+
command: [node, src/gates/gate-classes.ts, typecheck, --project, tsconfig.src.json, --project, tsconfig.test.json, --project, plugin/tsconfig.json]
|
|
377
|
+
unitLabel: source files type-checked
|
|
378
|
+
applicability: required
|
|
379
|
+
verified-by: script
|
|
380
|
+
modes: [full, direct-pr, local-only]
|
|
381
|
+
events: [pull_request]
|
|
382
|
+
|
|
383
|
+
# NEW IN M4-P14, entry two of two (DR-0029 part 2a, M4-P13).
|
|
384
|
+
- id: gate-classes
|
|
385
|
+
$comment: >-
|
|
386
|
+
DR-0029 part 2a made executable. A PHASE declares at least one gate in
|
|
387
|
+
each required class (`correctness`, `scope`, `review`), or declares an
|
|
388
|
+
escape that is DATA: `not-applicable` WITH a recorded reason, or
|
|
389
|
+
`not-yet-establishable` NAMING the phase that will establish it. The
|
|
390
|
+
requirement attaches to the phase and not to the project, because "this
|
|
391
|
+
project must have a correctness gate" is unsatisfiable on day zero while
|
|
392
|
+
"this phase either asserts correctness or declares when it will" is
|
|
393
|
+
satisfiable from the first commit. The property protected, in DR-0029's
|
|
394
|
+
words: you can start from nothing; you can never SILENTLY have nothing.
|
|
395
|
+
THE ESCAPES ARE PRINTED ON THE GREEN ARM, not merely permitted, which is
|
|
396
|
+
the same disclosure trade src/gates/scope.ts makes for a declaration
|
|
397
|
+
addition under M3-P11 change B: a reviewer who does not read the printed
|
|
398
|
+
line gets no protection from it. The PRECONDITION is branch-matches, the
|
|
399
|
+
same one `scope` carries and for the same reason: a phase declaration is
|
|
400
|
+
selected by phase id, and a non-phase branch has none, so the gate
|
|
401
|
+
reports not-applicable with an evaluated precondition rather than a
|
|
402
|
+
vacuous green (SC-011, M2-C-3). `events: [pull_request]` alone because
|
|
403
|
+
the push arm of scripts/m2-exit-test.sh passes no `--phase` at all, so
|
|
404
|
+
there is no declaration for it to select.
|
|
405
|
+
command: [node, src/gates/gate-classes.ts, gate-classes, --declarations, delivery/plan/phase-declarations, --registry, gate-registry.yaml]
|
|
406
|
+
unitLabel: declared gate classes checked
|
|
407
|
+
applicability: required
|
|
408
|
+
verified-by: script
|
|
409
|
+
modes: [full, direct-pr]
|
|
410
|
+
events: [pull_request]
|
|
411
|
+
parameters: [phase]
|
|
412
|
+
precondition:
|
|
413
|
+
id: gate-classes-branch-is-a-phase-branch
|
|
414
|
+
kind: branch-matches
|
|
415
|
+
pattern: claude/m[0-9]+-p[0-9]+-.*
|
|
416
|
+
|
|
417
|
+
# NEW IN M4-P12 (DR-0012, DR-0036, T-009, R-064, R-065a).
|
|
418
|
+
- id: merge-preconditions
|
|
419
|
+
$comment: >-
|
|
420
|
+
M4-P12. The artifact DR-0012's delegated grant has never had: one record
|
|
421
|
+
per condition, each carrying the HEAD SHA it was evaluated against, so
|
|
422
|
+
that "the six conditions held" stops being a sentence somebody wrote and
|
|
423
|
+
becomes a thing a reader can check. It is a PRECONDITION READER and not a
|
|
424
|
+
merge command: M4-D-09 puts the merge capability in the plugin at cutover
|
|
425
|
+
and DR-0036 keeps merge authority with the current process for the whole
|
|
426
|
+
of M4, so the orchestrator reads this record before merging, by hand.
|
|
427
|
+
CONDITIONS 1 AND 2 ARE COMPOSED, NOT REIMPLEMENTED. M4-P10 shipped
|
|
428
|
+
`dual-review-decorrelation` and `verdict-pair-approves` as derived checks
|
|
429
|
+
in src/checks.ts; this gate is a second caller of the same exported
|
|
430
|
+
primitives and runs those checks BY ID, so deregistering either one is
|
|
431
|
+
visible here as an `error` rather than absorbed as a pass.
|
|
432
|
+
`applicability: conditional`, AND THE PRECONDITION IS ANSWERED IN TWO
|
|
433
|
+
PLACES BECAUSE IT IS TWO QUESTIONS. The declared `command-exit-zero` block
|
|
434
|
+
is the SAME probe check-dual-review declares, and it answers the question
|
|
435
|
+
a registry precondition can answer: does this project have any committed
|
|
436
|
+
review verdict at all. The narrower question, whether a verdict names THIS
|
|
437
|
+
head, needs the run's `--head`, and a precondition command is spawned
|
|
438
|
+
without it (src/gates/run.ts:1524 appends the parameter flags to the GATE
|
|
439
|
+
command, not to the precondition's). So the gate answers that half itself
|
|
440
|
+
and emits its own PreconditionRecord with `met: false`, which is SC-011's
|
|
441
|
+
requirement that not-applicable ASSERT an evaluated precondition rather
|
|
442
|
+
than stand for silence. Both arms are not-applicable and each names which
|
|
443
|
+
question was unmet, so a reader is never told only that the gate did not
|
|
444
|
+
run.
|
|
445
|
+
`events: [pull_request]` ALONE, and it is derived rather than assigned:
|
|
446
|
+
scripts/m2-exit-test.sh declares the push arm's gate set once in
|
|
447
|
+
MAIN_ONLY_GATES and this id is not in it, so the push arm cannot run it,
|
|
448
|
+
and test/gate-registry.test.ts asserts `events` against that harness
|
|
449
|
+
rather than against a wish. It is ALSO in gates.manifest.json, because CI
|
|
450
|
+
invokes the runner with `--manifest`: a gate declared only here is
|
|
451
|
+
declared and never executed, which is a gate that cannot go red.
|
|
452
|
+
THE API IS PROBED, NEVER ASSUMED. CLAUDE.md standing warning 6 records
|
|
453
|
+
REST reachability here measured both ways on different days with the
|
|
454
|
+
cause unestablished, so the gate probes first and reports `error` with
|
|
455
|
+
units 0 when it cannot reach the API. Never `not-applicable`, never green:
|
|
456
|
+
M2-C-3, and the hazard this whole entry exists against is a merge
|
|
457
|
+
precondition check that is green because it could not look.
|
|
458
|
+
command: [node, src/gates/merge-preconditions.ts]
|
|
459
|
+
unitLabel: merge preconditions evaluated
|
|
460
|
+
applicability: conditional
|
|
461
|
+
verified-by: script
|
|
462
|
+
modes: [full, direct-pr]
|
|
463
|
+
events: [pull_request]
|
|
464
|
+
parameters: [head, phase]
|
|
465
|
+
precondition:
|
|
466
|
+
id: merge-preconditions-verdicts-present
|
|
467
|
+
kind: command-exit-zero
|
|
468
|
+
command: [node, scripts/check-dual-review.mjs, --precondition, .]
|
|
469
|
+
|
|
470
|
+
# NEW IN M3-P2, entry two of three (R-043, D-11).
|
|
471
|
+
- id: unit-tests-for-changed-service-methods
|
|
472
|
+
$comment: >-
|
|
473
|
+
R-043. Every changed service method has a unit test. D-11 settles that
|
|
474
|
+
this is NOT reliably computable from a diff (mapping changed methods to
|
|
475
|
+
tests produces false positives and negatives on any nontrivial codebase),
|
|
476
|
+
so it is verified by a clean-room checklist probe at L3 rather than by a
|
|
477
|
+
script at L1, and the registry says so in `verified-by` instead of leaving
|
|
478
|
+
a reader to infer it from a missing command. The probe id below is
|
|
479
|
+
M3-P7's to supply. WHAT THE RUNNER DOES WITH THIS ENTRY, stated exactly
|
|
480
|
+
because criterion 3c is about not confusing these two: it is NOT
|
|
481
|
+
executed and its precondition is NOT evaluated. There is no command to
|
|
482
|
+
run, so the runner selects it out before any precondition is reached and
|
|
483
|
+
reports it on stdout and in `summary.declaredByChecklist` as declared
|
|
484
|
+
and not executed. It produces no record, no evidence directory and no
|
|
485
|
+
status, and `not-applicable` is not among the things it can report. The
|
|
486
|
+
`precondition` below is a DECLARATION for M3-P7's checklist, not
|
|
487
|
+
something this runner evaluates.
|
|
488
|
+
unitLabel: changed service methods checked
|
|
489
|
+
applicability: conditional
|
|
490
|
+
verified-by: clean-room-checklist
|
|
491
|
+
probe: unit-tests-for-changed-service-methods
|
|
492
|
+
modes: [full, direct-pr]
|
|
493
|
+
events: [pull_request]
|
|
494
|
+
precondition:
|
|
495
|
+
id: clean-room-checklist-present
|
|
496
|
+
kind: file-exists
|
|
497
|
+
path: checklists/clean-room.yaml
|
|
498
|
+
|
|
499
|
+
# NEW IN M3-P2, entry three of three (R-044, D-11).
|
|
500
|
+
- id: fixtures-for-changed-component-states
|
|
501
|
+
$comment: >-
|
|
502
|
+
R-044. Every changed component state has a story or fixture. Same shape as
|
|
503
|
+
R-043 and settled the same way by D-11: "component state" is not
|
|
504
|
+
machine-enumerable, so the gate is a clean-room checklist probe. Not
|
|
505
|
+
executed and its precondition not evaluated, for the reason spelled out
|
|
506
|
+
on the entry above. Same declared precondition, so M3-P7's checklist is
|
|
507
|
+
what both wait on.
|
|
508
|
+
unitLabel: changed component states checked
|
|
509
|
+
applicability: conditional
|
|
510
|
+
verified-by: clean-room-checklist
|
|
511
|
+
probe: fixtures-for-changed-component-states
|
|
512
|
+
modes: [full, direct-pr]
|
|
513
|
+
events: [pull_request]
|
|
514
|
+
precondition:
|
|
515
|
+
id: clean-room-checklist-present
|
|
516
|
+
kind: file-exists
|
|
517
|
+
path: checklists/clean-room.yaml
|
|
518
|
+
|
|
519
|
+
# Carried across from gates.manifest.json unchanged. M2-P2 rule (e) DERIVES a
|
|
520
|
+
# witness class from this list rather than trusting an implementer to declare
|
|
521
|
+
# one, so shortening it weakens the red-witness gate.
|
|
522
|
+
destructiveCommands:
|
|
523
|
+
- pool destroy
|
|
524
|
+
- teardown
|
|
525
|
+
- src/pool.ts
|
|
526
|
+
- src/teardown.ts
|