@starci/eslint-canon-be 3.4.34 → 3.4.35
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/CHANGELOG.md +4 -0
- package/ambient-id.mjs +4 -5
- package/package.json +1 -1
- package/runtime/engine/yaml.mjs +1 -1
- package/runtime/knowledge/hfs/canon-pins.yaml +4 -4
- package/runtime/knowledge/hfs/rules.yaml +912 -637
- package/runtime/knowledge/hfs/slots.yaml +21 -14
- package/runtime/scripts/hfs/architecture/supabase.mjs +1 -1
- package/runtime/scripts/hfs/manifest-shape.mjs +1 -3
- package/runtime/scripts/hfs/rule-catalog.mjs +7 -10
|
@@ -32,9 +32,9 @@ enforcerKinds:
|
|
|
32
32
|
stylelint: a rule of the @starci/stylelint-canon package
|
|
33
33
|
machine: a check of the architecture machine (scripts/hfs/architecture), which reads the import graph
|
|
34
34
|
hfs: a check of the hfs CLI that reads the repository tree, configuration, contracts or catalogs
|
|
35
|
-
work-validate: a check of scripts/work/validate/work-validate.mjs over a .starciwork tree
|
|
35
|
+
work-validate: "a check of scripts/work/validate/work-validate.mjs over a .starciwork tree; runs only inside the runtime, so no package spec holds it (RUNTIME_ONLY_ENFORCERS in scripts/hfs/rule-catalog.mjs)"
|
|
36
36
|
sonar: a condition of the Sonar quality gate
|
|
37
|
-
runtime: a rule module of the runtime check (scripts/hfs/runtime-check.mjs, scripts/hfs/runtime-rules/*) or an emitter whose findings it judges, over the runtime repository
|
|
37
|
+
runtime: "a rule module of the runtime check (scripts/hfs/runtime-check.mjs, scripts/hfs/runtime-rules/*) or an emitter whose findings it judges, over the runtime repository; runs only inside the runtime, so no package spec holds it and no example app is judged by it (RUNTIME_ONLY_ENFORCERS in scripts/hfs/rule-catalog.mjs; owner ruling no-runtime-specs: the package clean-test and the scaffold e2e are the runtime's tests)"
|
|
38
38
|
rules:
|
|
39
39
|
- id: R01
|
|
40
40
|
code: "HFS_SLOT_UNDECLARED"
|
|
@@ -51,14 +51,18 @@ rules:
|
|
|
51
51
|
editions: [lite, full]
|
|
52
52
|
docs: [docs/architecture.md#r01]
|
|
53
53
|
templateNa: "Slot ownership judges where a path sits in the tree, not what a file holds: the managed templates render files into the slots that own them, and no template exists for a path that no slot, two slots or a forbidden slot own."
|
|
54
|
-
proves:
|
|
55
|
-
- {path: packages/eslint/be/slot-ownership.spec.mjs, editions: [lite, full], codes: [HFS_SLOT_UNDECLARED, HFS_SLOT_AMBIGUOUS, HFS_SLOT_NOT_ENABLED]}
|
|
56
|
-
- {path: packages/eslint/fe/slot-ownership.spec.mjs, editions: [lite, full], codes: [HFS_SLOT_UNDECLARED, HFS_SLOT_AMBIGUOUS, HFS_SLOT_NOT_ENABLED]}
|
|
57
54
|
exemplifiedBy:
|
|
58
55
|
- {path: examples/lite-app/be/src/features/webhooks/calendar/transport/http/calendar.webhook.ts, edition: lite}
|
|
59
56
|
- {path: examples/full-app/be/src/features/webhooks/sepay/transport/http/sepay.webhook.ts, edition: full}
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
- {path: examples/ecommerce-app/be/src/features/webhooks/sepay/transport/http/sepay.webhook.ts, edition: full}
|
|
58
|
+
witness:
|
|
59
|
+
- {path: packages/hfs/src/hfs-repository-tree-layout.spec.mjs, edition: lite, codes: [HFS_ROOT_ENTRY_FORBIDDEN, HFS_ROOT_MARKDOWN_FORBIDDEN, HFS_ROOT_SRC_FORBIDDEN_FE, HFS_SRC_LAYOUT_INVALID, HFS_MODULE_TIER_INVALID, HFS_WORK_IN_FE, HFS_STACKS_IN_SIDE]}
|
|
60
|
+
- {path: packages/hfs/src/hfs-repository-tree-layout.spec.mjs, edition: full, codes: [HFS_ROOT_ENTRY_FORBIDDEN, HFS_ROOT_MARKDOWN_FORBIDDEN, HFS_ROOT_SRC_FORBIDDEN_FE, HFS_SRC_LAYOUT_INVALID, HFS_MODULE_TIER_INVALID, HFS_WORK_IN_FE, HFS_STACKS_IN_SIDE]}
|
|
61
|
+
proves:
|
|
62
|
+
- {path: packages/eslint/be/slot-ownership.spec.mjs, editions: [lite, full], codes: [HFS_SLOT_UNDECLARED, HFS_SLOT_AMBIGUOUS, HFS_SLOT_NOT_ENABLED]}
|
|
63
|
+
- {path: packages/eslint/fe/slot-ownership.spec.mjs, editions: [lite, full], codes: [HFS_SLOT_UNDECLARED, HFS_SLOT_AMBIGUOUS, HFS_SLOT_NOT_ENABLED]}
|
|
64
|
+
- {path: packages/hfs/src/hfs-repository-tree-layout.spec.mjs, editions: [lite, full], codes: [HFS_ROOT_ENTRY_FORBIDDEN, HFS_ROOT_MARKDOWN_FORBIDDEN, HFS_ROOT_SRC_FORBIDDEN_FE, HFS_SRC_LAYOUT_INVALID, HFS_MODULE_TIER_INVALID, HFS_WORK_IN_FE, HFS_STACKS_IN_SIDE]}
|
|
65
|
+
- {path: packages/hfs/src/hfs-slot-ownership.spec.mjs, editions: [lite, full], codes: [HFS_SLOT_UNDECLARED, HFS_SLOT_AMBIGUOUS, HFS_SLOT_NOT_ENABLED, HFS_FORBIDDEN_PRESENT, HFS_TRACKED_MUST_BE_IGNORED]}
|
|
62
66
|
- id: R02
|
|
63
67
|
code: "HFS_SLOT_REQUIRED_MISSING"
|
|
64
68
|
law: "A slot is missing a required file (feature `index.ts`, app `main.ts`, FE `global-error.tsx`), or the root README breaks its standard shape (title, description, standard sections in order, Work pointer, live badges only, no private URL)."
|
|
@@ -70,14 +74,11 @@ rules:
|
|
|
70
74
|
- {kind: machine, id: required-files, at: scripts/hfs/architecture/required-files.mjs}
|
|
71
75
|
- {kind: machine, id: repository-tree-required, at: scripts/hfs/architecture/hfs.mjs}
|
|
72
76
|
- {kind: runtime, id: runtime-required, at: scripts/hfs/runtime-check.mjs}
|
|
73
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
74
77
|
- id: R03
|
|
75
78
|
code: "HFS_UNTRACKED_ROOT_ENTRY"
|
|
76
79
|
editions: [lite, full]
|
|
77
80
|
docs: [docs/legacy-tree-rule-coverage.md#r03]
|
|
78
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
79
81
|
templateNa: "Untracked and empty directories are filesystem states, not scaffolded files."
|
|
80
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
81
82
|
law: "No untracked or ignored entry outside an `ignored` slot."
|
|
82
83
|
kinds: [check, codemod]
|
|
83
84
|
gates: [land, ci, runtime]
|
|
@@ -85,36 +86,49 @@ rules:
|
|
|
85
86
|
enforcers:
|
|
86
87
|
- {kind: hfs, id: untracked-root-entry, at: scripts/hfs/check.mjs}
|
|
87
88
|
- {kind: runtime, id: runtime-untracked, at: scripts/hfs/runtime-check.mjs}
|
|
88
|
-
|
|
89
|
+
proves:
|
|
90
|
+
- {path: packages/hfs/src/hfs-check-tree-slots.spec.mjs, editions: [lite, full], codes: [HFS_UNTRACKED_ROOT_ENTRY, HFS_EMPTY_DIR, HFS_GHOST_TREE]}
|
|
91
|
+
exemplifiedBy:
|
|
92
|
+
- {path: packages/hfs/src/hfs-check-tree-slots.spec.mjs, editions: [lite, full], codes: [HFS_UNTRACKED_ROOT_ENTRY, HFS_EMPTY_DIR, HFS_GHOST_TREE]}
|
|
93
|
+
witness:
|
|
94
|
+
- {path: packages/hfs/src/hfs-check-tree-slots.spec.mjs, editions: [lite, full], codes: [HFS_UNTRACKED_ROOT_ENTRY, HFS_EMPTY_DIR, HFS_GHOST_TREE]}
|
|
89
95
|
- id: R04
|
|
90
96
|
code: "HFS_GITIGNORE_BLOCK_DRIFT"
|
|
91
97
|
editions: [lite, full]
|
|
92
98
|
docs: [docs/legacy-managed-rule-coverage.md#r04]
|
|
93
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
94
|
-
exemplifiedBy:
|
|
95
|
-
- {path: packages/hfs/templates/app/gitignore-lite, edition: lite}
|
|
96
|
-
- {path: packages/hfs/templates/app/gitignore, edition: full}
|
|
97
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
98
99
|
law: "The managed `.gitignore` block equals its render."
|
|
99
100
|
kinds: [check, codemod]
|
|
100
101
|
gates: [land, ci]
|
|
101
102
|
failureCodes: ["HFS_GITIGNORE_BLOCK_DRIFT"]
|
|
102
103
|
enforcers:
|
|
103
104
|
- {kind: hfs, id: gitignore-block-drift, at: packages/hfs/sync/managed.mjs}
|
|
105
|
+
proves:
|
|
106
|
+
- {path: packages/hfs/src/hfs-gitignore-block-drift.spec.mjs, editions: [lite, full]}
|
|
107
|
+
exemplifiedBy:
|
|
108
|
+
- {path: packages/hfs/templates/app/gitignore-lite, edition: lite}
|
|
109
|
+
- {path: packages/hfs/templates/app/gitignore, edition: full}
|
|
110
|
+
- {path: packages/hfs/src/hfs-gitignore-block-drift.spec.mjs, editions: [lite, full]}
|
|
111
|
+
witness:
|
|
112
|
+
- {path: packages/hfs/src/hfs-gitignore-block-drift.spec.mjs, edition: lite, codes: [HFS_GITIGNORE_BLOCK_DRIFT]}
|
|
113
|
+
- {path: packages/hfs/src/hfs-gitignore-block-drift.spec.mjs, edition: full, codes: [HFS_GITIGNORE_BLOCK_DRIFT]}
|
|
104
114
|
- id: R05
|
|
105
115
|
code: "HFS_MANAGED_FILE_DRIFT"
|
|
106
116
|
editions: [lite, full]
|
|
107
117
|
docs: [docs/legacy-managed-rule-coverage.md#r05]
|
|
108
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
109
|
-
exemplifiedBy:
|
|
110
|
-
- {path: packages/hfs/templates/app/hooks/husky/pre-push, editions: [lite, full]}
|
|
111
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
112
118
|
law: "A managed file equals its template render."
|
|
113
119
|
kinds: [check, codemod]
|
|
114
120
|
gates: [land, ci]
|
|
115
121
|
failureCodes: ["HFS_MANAGED_FILE_DRIFT"]
|
|
116
122
|
enforcers:
|
|
117
123
|
- {kind: hfs, id: managed-file-drift, at: packages/hfs/sync/managed.mjs}
|
|
124
|
+
proves:
|
|
125
|
+
- {path: packages/hfs/src/hfs-managed-file-drift.spec.mjs, editions: [lite, full]}
|
|
126
|
+
exemplifiedBy:
|
|
127
|
+
- {path: packages/hfs/templates/app/hooks/husky/pre-push, editions: [lite, full]}
|
|
128
|
+
- {path: packages/hfs/src/hfs-managed-file-drift.spec.mjs, editions: [lite, full]}
|
|
129
|
+
witness:
|
|
130
|
+
- {path: packages/hfs/src/hfs-managed-file-drift.spec.mjs, edition: lite, codes: [HFS_MANAGED_FILE_DRIFT]}
|
|
131
|
+
- {path: packages/hfs/src/hfs-managed-file-drift.spec.mjs, edition: full, codes: [HFS_MANAGED_FILE_DRIFT]}
|
|
118
132
|
- id: R06
|
|
119
133
|
code: "HFS_PLAINTEXT_SECRET"
|
|
120
134
|
law: "Secrets exist only as `.starcistacks/<env>/secrets/<slug>.enc`."
|
|
@@ -127,9 +141,11 @@ rules:
|
|
|
127
141
|
editions: [lite, full]
|
|
128
142
|
docs: [docs/legacy-managed-rule-coverage.md#r06-plaintext-secrets]
|
|
129
143
|
templateNa: "Encrypted secrets are supplied by the app secret command; plaintext secret files are forbidden and are never scaffolded."
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
144
|
+
proves: [packages/hfs/src/hfs-plaintext-secret.spec.mjs]
|
|
145
|
+
exemplifiedBy:
|
|
146
|
+
- {path: packages/hfs/src/hfs-plaintext-secret.spec.mjs, editions: [lite, full]}
|
|
147
|
+
witness:
|
|
148
|
+
- {path: packages/hfs/src/hfs-plaintext-secret.spec.mjs, editions: [lite, full], codes: [HFS_PLAINTEXT_SECRET]}
|
|
133
149
|
- id: R07
|
|
134
150
|
code: "HFS_AGENT_DATA_TRACKED"
|
|
135
151
|
law: "`.starciwork` holds product records only."
|
|
@@ -138,7 +154,6 @@ rules:
|
|
|
138
154
|
failureCodes: ["HFS_AGENT_DATA_TRACKED"]
|
|
139
155
|
enforcers:
|
|
140
156
|
- {kind: work-validate, id: agent-data-tracked, at: scripts/work/validate/check-example-work.mjs}
|
|
141
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
142
157
|
- id: R09
|
|
143
158
|
code: "HFS_IDENTITY_CUSTODY"
|
|
144
159
|
law: "An identity points its secret at `secrets/identity-<slug>.enc`; UAT chooses by role."
|
|
@@ -148,16 +163,10 @@ rules:
|
|
|
148
163
|
enforcers:
|
|
149
164
|
- {kind: work-validate, id: sealed-custody-location, at: scripts/work/validate/check-work-artifacts.mjs}
|
|
150
165
|
- {kind: work-validate, id: identity-custody-role, at: scripts/work/validate/check-example-work.mjs}
|
|
151
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
152
166
|
- id: R10
|
|
153
167
|
code: "HFS_STACKS_SHAPE"
|
|
154
168
|
editions: [lite, full]
|
|
155
169
|
docs: [docs/legacy-tree-rule-coverage.md#r10]
|
|
156
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
157
|
-
exemplifiedBy:
|
|
158
|
-
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
159
|
-
- {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
|
|
160
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
161
170
|
law: "`.starcistacks` has the edition-aware standard shape and the host Sonar owner; Swarm stacks have digest-pinned images, healthchecks, rollout, rollback and restart policies, versioned external secrets, ingress-only published ports and declared schedulers for replicated jobs. Recurring work is app-owned; host crontab installation is forbidden. Lite declares Supabase as managed backing and runs no duplicate backing-service component."
|
|
162
171
|
kinds: [check, codemod]
|
|
163
172
|
gates: [settle, land, ci]
|
|
@@ -168,42 +177,53 @@ rules:
|
|
|
168
177
|
- {kind: hfs, id: stacks-evidence-runtime, at: scripts/hfs/stacks-gate.mjs}
|
|
169
178
|
- {kind: hfs, id: starcistacks-runtime, at: scripts/hfs/starcistacks-runtime.mjs}
|
|
170
179
|
- {kind: hfs, id: starcistacks-runtime-gate, at: scripts/gates/starcistacks.mjs}
|
|
180
|
+
exemplifiedBy:
|
|
181
|
+
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
182
|
+
- {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
|
|
183
|
+
- {path: packages/hfs/src/hfs-stacks-shape.spec.mjs, editions: [lite, full]}
|
|
184
|
+
witness:
|
|
185
|
+
- {path: packages/hfs/src/hfs-stacks-shape.spec.mjs, editions: [lite, full]}
|
|
186
|
+
proves:
|
|
187
|
+
- {path: packages/hfs/src/hfs-stacks-shape.spec.mjs, editions: [lite, full]}
|
|
188
|
+
- {path: packages/hfs/src/hfs-stacks-runtime-shape.spec.mjs, editions: [lite, full]}
|
|
171
189
|
- id: R11
|
|
172
190
|
code: "HFS_SONAR_CONFIG"
|
|
173
191
|
editions: [lite, full]
|
|
174
192
|
docs: [docs/legacy-managed-rule-coverage.md#r11]
|
|
175
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
176
|
-
exemplifiedBy:
|
|
177
|
-
- {path: packages/hfs/templates/app/quality-config/sonar-project.properties, editions: [lite, full]}
|
|
178
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
179
193
|
law: "Sonar config is generated, with no host URL, importing the be lcov with the logic of be/src/modules (the coverage scope derived from the slot manifest) as the only coverage scope."
|
|
180
194
|
kinds: [check, codemod]
|
|
181
195
|
gates: [land, ci]
|
|
182
196
|
failureCodes: ["HFS_SONAR_CONFIG"]
|
|
183
197
|
enforcers:
|
|
184
198
|
- {kind: hfs, id: sonar-config, at: packages/hfs/sync/managed.mjs}
|
|
199
|
+
proves:
|
|
200
|
+
- {path: packages/hfs/src/hfs-sonar-config.spec.mjs, editions: [lite, full]}
|
|
201
|
+
exemplifiedBy:
|
|
202
|
+
- {path: packages/hfs/templates/app/quality-config/sonar-project.properties, editions: [lite, full]}
|
|
203
|
+
- {path: packages/hfs/src/hfs-sonar-config.spec.mjs, editions: [lite, full]}
|
|
204
|
+
witness:
|
|
205
|
+
- {path: packages/hfs/src/hfs-sonar-config.spec.mjs, edition: lite, codes: [HFS_SONAR_CONFIG]}
|
|
206
|
+
- {path: packages/hfs/src/hfs-sonar-config.spec.mjs, edition: full, codes: [HFS_SONAR_CONFIG]}
|
|
185
207
|
- id: R12
|
|
186
208
|
code: "HFS_E2E_IN_AUTOMATIC_GATE"
|
|
187
209
|
editions: [lite, full]
|
|
188
210
|
docs: [docs/legacy-custody-e2e-coverage.md#r12-automatic-test-execution]
|
|
189
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
190
|
-
exemplifiedBy:
|
|
191
|
-
- {path: packages/hfs/templates/app/hooks/husky/pre-push, editions: [lite, full]}
|
|
192
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
193
211
|
law: "e2e never joins husky, coverage or automatic CI."
|
|
194
212
|
kinds: [check]
|
|
195
213
|
gates: [land, ci]
|
|
196
214
|
failureCodes: ["HFS_E2E_IN_AUTOMATIC_GATE"]
|
|
197
215
|
enforcers:
|
|
198
216
|
- {kind: machine, id: e2e-in-automatic-gate, at: scripts/hfs/architecture/hfs.mjs}
|
|
217
|
+
proves:
|
|
218
|
+
- {path: packages/hfs/src/hfs-e2e-automatic-gate.spec.mjs, editions: [lite, full]}
|
|
219
|
+
exemplifiedBy:
|
|
220
|
+
- {path: packages/hfs/templates/app/hooks/husky/pre-push, editions: [lite, full]}
|
|
221
|
+
- {path: packages/hfs/src/hfs-e2e-automatic-gate.spec.mjs, editions: [lite, full]}
|
|
222
|
+
witness:
|
|
223
|
+
- {path: packages/hfs/src/hfs-e2e-automatic-gate.spec.mjs, editions: [lite, full]}
|
|
199
224
|
- id: R13
|
|
200
225
|
editions: [lite, full]
|
|
201
226
|
docs: [docs/hfs-legacy-tooling.md#ci-and-hooks]
|
|
202
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
203
|
-
exemplifiedBy:
|
|
204
|
-
- {path: packages/hfs/templates/app/ci-workflows-lite, edition: lite}
|
|
205
|
-
- {path: packages/hfs/templates/app/ci-workflows, edition: full}
|
|
206
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
207
227
|
code: "HFS_CI_MISSING_CANON"
|
|
208
228
|
law: "CI runs the pinned `starci app lint` (`npm run lint`), a clone never redirects `core.hooksPath` away from husky, and the folder a set `core.hooksPath` names holds the installed hooks in every checkout (husky's dispatcher in `.husky/_`), so no commit lands without the pre-commit gate."
|
|
209
229
|
kinds: [check, codemod]
|
|
@@ -212,44 +232,62 @@ rules:
|
|
|
212
232
|
enforcers:
|
|
213
233
|
- {kind: machine, id: hooks-path-not-redirected, at: scripts/hfs/architecture/hfs.mjs}
|
|
214
234
|
- {kind: hfs, id: ci-missing-canon, at: scripts/hfs/rules/pipeline.mjs}
|
|
235
|
+
proves: [packages/hfs/src/hfs-pipeline-example.spec.mjs, packages/hfs/src/hfs-hooks-path-redirected.spec.mjs]
|
|
236
|
+
exemplifiedBy:
|
|
237
|
+
- {path: packages/hfs/templates/app/ci-workflows-lite, edition: lite}
|
|
238
|
+
- {path: packages/hfs/templates/app/ci-workflows, edition: full}
|
|
239
|
+
- {path: packages/hfs/src/hfs-pipeline-example.spec.mjs, editions: [lite, full]}
|
|
240
|
+
- {path: packages/hfs/src/hfs-hooks-path-redirected.spec.mjs, editions: [lite, full]}
|
|
241
|
+
witness:
|
|
242
|
+
- {path: packages/hfs/src/hfs-pipeline-example.spec.mjs, editions: [lite, full], codes: [HFS_CI_MISSING_CANON]}
|
|
243
|
+
- {path: packages/hfs/src/hfs-hooks-path-redirected.spec.mjs, editions: [lite, full], codes: [HFS_HOOKS_PATH_REDIRECTED]}
|
|
215
244
|
- id: R14
|
|
216
245
|
code: "HFS_DEP_VERSION_SKEW"
|
|
217
246
|
law: "One version per dependency in the workspace, a root `overrides` pin included, and npm is the only package manager."
|
|
218
247
|
editions: [lite, full]
|
|
219
248
|
docs: [docs/hfs-legacy-tooling.md#dependency-consistency]
|
|
220
249
|
templateNa: "Dependency versions, root overrides and the npm packageManager field are generated programmatically by pinnedSection and packageManifest in packages/hfs/scaffold/app.mjs rather than rendered from a managed dependency template."
|
|
221
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
222
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
223
250
|
kinds: [check, codemod]
|
|
224
251
|
gates: [land, ci]
|
|
225
252
|
failureCodes: ["HFS_DEP_VERSION_SKEW", "HFS_PACKAGE_MANAGER_MIXED"]
|
|
226
253
|
enforcers:
|
|
227
254
|
- {kind: hfs, id: dep-version-skew, at: scripts/hfs/rules/deps.mjs}
|
|
228
255
|
- {kind: machine, id: package-manager, at: scripts/hfs/architecture/hfs.mjs}
|
|
229
|
-
|
|
256
|
+
proves:
|
|
257
|
+
- {path: packages/hfs/src/hfs-dep-version-skew-coverage.spec.mjs, editions: [lite, full], codes: [HFS_DEP_VERSION_SKEW]}
|
|
258
|
+
- {path: packages/hfs/src/hfs-package-manager-mixed.spec.mjs, editions: [lite, full], codes: [HFS_PACKAGE_MANAGER_MIXED]}
|
|
259
|
+
exemplifiedBy:
|
|
260
|
+
- {path: packages/hfs/src/hfs-dep-version-skew-coverage.spec.mjs, editions: [lite, full], codes: [HFS_DEP_VERSION_SKEW]}
|
|
261
|
+
- {path: packages/hfs/src/hfs-package-manager-mixed.spec.mjs, editions: [lite, full], codes: [HFS_PACKAGE_MANAGER_MIXED]}
|
|
262
|
+
witness:
|
|
263
|
+
- {path: packages/hfs/src/hfs-dep-version-skew-coverage.spec.mjs, edition: lite, codes: [HFS_DEP_VERSION_SKEW]}
|
|
264
|
+
- {path: packages/hfs/src/hfs-package-manager-mixed.spec.mjs, edition: lite, codes: [HFS_PACKAGE_MANAGER_MIXED]}
|
|
265
|
+
- {path: packages/hfs/src/hfs-dep-version-skew-coverage.spec.mjs, edition: full, codes: [HFS_DEP_VERSION_SKEW]}
|
|
266
|
+
- {path: packages/hfs/src/hfs-package-manager-mixed.spec.mjs, edition: full, codes: [HFS_PACKAGE_MANAGER_MIXED]}
|
|
230
267
|
- id: R15
|
|
231
268
|
code: "HFS_CANON_PIN_DRIFT"
|
|
232
269
|
law: "Canon packages and frameworks match `canon-pins.yaml`."
|
|
233
270
|
editions: [lite, full]
|
|
234
271
|
docs: [docs/hfs-legacy-tooling.md#canon-package-pins]
|
|
235
272
|
templateNa: "Dependency versions are generated programmatically by pinnedSection and packageManifest in packages/hfs/scaffold/app.mjs rather than rendered from a managed dependency template."
|
|
236
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
237
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
238
273
|
kinds: [check, codemod]
|
|
239
274
|
gates: [land, ci]
|
|
240
275
|
failureCodes: ["HFS_CANON_PIN_DRIFT"]
|
|
241
276
|
enforcers:
|
|
242
277
|
- {kind: hfs, id: canon-pin-drift, at: scripts/hfs/check.mjs}
|
|
243
|
-
|
|
278
|
+
proves:
|
|
279
|
+
- {path: packages/hfs/src/hfs-canon-pin-drift-checker.spec.mjs, editions: [lite, full]}
|
|
280
|
+
- {path: packages/hfs/src/hfs-canon-pin-drift.spec.mjs, editions: [lite, full]}
|
|
281
|
+
exemplifiedBy:
|
|
282
|
+
- {path: packages/hfs/src/hfs-canon-pin-drift-checker.spec.mjs, edition: lite, codes: [HFS_CANON_PIN_DRIFT]}
|
|
283
|
+
- {path: packages/hfs/src/hfs-canon-pin-drift-checker.spec.mjs, edition: full, codes: [HFS_CANON_PIN_DRIFT]}
|
|
284
|
+
witness:
|
|
285
|
+
- {path: packages/hfs/src/hfs-canon-pin-drift-checker.spec.mjs, edition: lite, codes: [HFS_CANON_PIN_DRIFT]}
|
|
286
|
+
- {path: packages/hfs/src/hfs-canon-pin-drift-checker.spec.mjs, edition: full, codes: [HFS_CANON_PIN_DRIFT]}
|
|
244
287
|
- id: R16
|
|
245
288
|
code: "HFS_TOOL_CONFIG_LOCAL"
|
|
246
289
|
editions: ["lite", "full"]
|
|
247
290
|
docs: ["docs/managed-tooling-coverage.md#local-tool-configuration"]
|
|
248
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
249
|
-
exemplifiedBy:
|
|
250
|
-
- {path: "packages/hfs/templates/be/tool-config/eslint.config.mjs", editions: ["lite", "full"]}
|
|
251
|
-
- {path: "packages/hfs/templates/fe/tool-config/eslint.config.mjs", editions: ["lite", "full"]}
|
|
252
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
253
291
|
law: "Configs only call the factories; no local rules."
|
|
254
292
|
kinds: [check, codemod]
|
|
255
293
|
gates: [land, ci]
|
|
@@ -257,22 +295,36 @@ rules:
|
|
|
257
295
|
enforcers:
|
|
258
296
|
- {kind: hfs, id: tool-config-local, at: packages/hfs/sync/managed.mjs}
|
|
259
297
|
- {kind: hfs, id: tool-config-forbidden, at: scripts/hfs/check.mjs}
|
|
298
|
+
proves:
|
|
299
|
+
- {path: packages/hfs/src/hfs-tool-config-local.spec.mjs, editions: [lite, full]}
|
|
300
|
+
- {path: packages/hfs/src/hfs-tool-config-forbidden.spec.mjs, editions: [lite, full]}
|
|
301
|
+
exemplifiedBy:
|
|
302
|
+
- {path: "packages/hfs/templates/be/tool-config/eslint.config.mjs", editions: ["lite", "full"]}
|
|
303
|
+
- {path: "packages/hfs/templates/fe/tool-config/eslint.config.mjs", editions: ["lite", "full"]}
|
|
304
|
+
- {path: packages/hfs/src/hfs-tool-config-local.spec.mjs, editions: [lite, full]}
|
|
305
|
+
- {path: packages/hfs/src/hfs-tool-config-forbidden.spec.mjs, editions: [lite, full]}
|
|
306
|
+
witness:
|
|
307
|
+
- {path: packages/hfs/src/hfs-tool-config-local.spec.mjs, editions: [lite, full], codes: [HFS_TOOL_CONFIG_LOCAL]}
|
|
308
|
+
- {path: packages/hfs/src/hfs-tool-config-forbidden.spec.mjs, editions: [lite, full], codes: [HFS_TOOL_CONFIG_LOCAL]}
|
|
260
309
|
- id: R17
|
|
261
310
|
code: "HFS_RULE_OFF_WITHOUT_REPLACEMENT"
|
|
262
311
|
editions: ["lite", "full"]
|
|
263
312
|
docs: ["docs/managed-tooling-coverage.md#rendered-lint-configurations"]
|
|
264
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
265
|
-
exemplifiedBy:
|
|
266
|
-
- {path: "packages/hfs/templates/be/tool-config/eslint.config.mjs", editions: ["lite", "full"]}
|
|
267
|
-
- {path: "packages/hfs/templates/fe/tool-config/eslint.config.mjs", editions: ["lite", "full"]}
|
|
268
|
-
- {path: "packages/hfs/templates/fe/tool-config/stylelint.config.mjs", editions: ["lite", "full"]}
|
|
269
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
270
313
|
law: "The ESLint configuration (and a front end's stylelint configuration) is the rendered one-liner, so no rule is off, warned or redefined in a repository."
|
|
271
314
|
kinds: [check]
|
|
272
315
|
gates: [land, ci]
|
|
273
316
|
failureCodes: ["HFS_RULE_OFF_WITHOUT_REPLACEMENT"]
|
|
274
317
|
enforcers:
|
|
275
318
|
- {kind: hfs, id: rule-off-without-replacement, at: packages/hfs/sync/managed.mjs}
|
|
319
|
+
proves:
|
|
320
|
+
- {path: packages/hfs/src/hfs-rule-off-without-replacement.spec.mjs, editions: [lite, full]}
|
|
321
|
+
exemplifiedBy:
|
|
322
|
+
- {path: "packages/hfs/templates/be/tool-config/eslint.config.mjs", editions: ["lite", "full"]}
|
|
323
|
+
- {path: "packages/hfs/templates/fe/tool-config/eslint.config.mjs", editions: ["lite", "full"]}
|
|
324
|
+
- {path: "packages/hfs/templates/fe/tool-config/stylelint.config.mjs", editions: ["lite", "full"]}
|
|
325
|
+
- {path: packages/hfs/src/hfs-rule-off-without-replacement.spec.mjs, editions: [lite, full]}
|
|
326
|
+
witness:
|
|
327
|
+
- {path: packages/hfs/src/hfs-rule-off-without-replacement.spec.mjs, editions: [lite, full], codes: [HFS_RULE_OFF_WITHOUT_REPLACEMENT]}
|
|
276
328
|
- id: R18
|
|
277
329
|
code: "HFS_INLINE_SUPPRESSION"
|
|
278
330
|
law: "No inline suppression of any kind."
|
|
@@ -287,17 +339,20 @@ rules:
|
|
|
287
339
|
code: "HFS_FORMAT"
|
|
288
340
|
editions: ["lite", "full"]
|
|
289
341
|
docs: ["docs/managed-tooling-coverage.md#canonical-formatting"]
|
|
290
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
291
|
-
exemplifiedBy:
|
|
292
|
-
- {path: "packages/hfs/templates/app/tool-config-lite/prettierrc", edition: "lite"}
|
|
293
|
-
- {path: "packages/hfs/templates/app/tool-config/prettierrc", edition: "full"}
|
|
294
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
295
342
|
law: "Prettier is the only formatter."
|
|
296
343
|
kinds: [codemod]
|
|
297
344
|
gates: [land, ci]
|
|
298
345
|
failureCodes: ["HFS_FORMAT"]
|
|
299
346
|
enforcers:
|
|
300
347
|
- {kind: hfs, id: format, at: packages/hfs/sync/format.mjs}
|
|
348
|
+
proves:
|
|
349
|
+
- {path: packages/hfs/src/hfs-format.spec.mjs, editions: [lite, full]}
|
|
350
|
+
exemplifiedBy:
|
|
351
|
+
- {path: "packages/hfs/templates/app/tool-config-lite/prettierrc", edition: "lite"}
|
|
352
|
+
- {path: "packages/hfs/templates/app/tool-config/prettierrc", edition: "full"}
|
|
353
|
+
- {path: packages/hfs/src/hfs-format.spec.mjs, editions: [lite, full]}
|
|
354
|
+
witness:
|
|
355
|
+
- {path: packages/hfs/src/hfs-format.spec.mjs, editions: [lite, full], codes: [HFS_FORMAT]}
|
|
301
356
|
- id: R20
|
|
302
357
|
code: "HFS_SIZE_GROWTH"
|
|
303
358
|
law: "Over-budget files do not grow; new files are inside budget."
|
|
@@ -309,7 +364,6 @@ rules:
|
|
|
309
364
|
- {kind: eslint-fe, id: file-size-growth}
|
|
310
365
|
- {kind: sonar, id: cognitive-complexity, at: knowledge/sonar-gate.yaml}
|
|
311
366
|
- {kind: runtime, id: runtime-size, at: scripts/hfs/runtime-rules/size.mjs}
|
|
312
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
313
367
|
- id: R21
|
|
314
368
|
code: "HFS_DUPLICATE_CODE"
|
|
315
369
|
law: "No duplicated blocks or twice-defined helpers."
|
|
@@ -327,11 +381,6 @@ rules:
|
|
|
327
381
|
code: "HFS_TS_STRICT"
|
|
328
382
|
editions: ["lite", "full"]
|
|
329
383
|
docs: ["docs/hfs-typescript-strict.md#r22-typescript"]
|
|
330
|
-
exemplifiedBy:
|
|
331
|
-
- {path: "packages/hfs/templates/be/tool-config/tsconfig.json", editions: ["lite", "full"]}
|
|
332
|
-
- {path: "packages/hfs/templates/fe/tool-config/tsconfig.json", editions: ["lite", "full"]}
|
|
333
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
334
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
335
384
|
law: "tsconfig extends `@starci/tsconfig` and lowers no flag; no assertion, `!` or `any` in product source."
|
|
336
385
|
kinds: [codemod, design, lint]
|
|
337
386
|
gates: [pre-commit, settle, land, ci]
|
|
@@ -342,46 +391,58 @@ rules:
|
|
|
342
391
|
- {kind: eslint-fe, id: no-explicit-any}
|
|
343
392
|
- {kind: hfs, id: ts-strict, at: packages/hfs/sync/ts-strict.mjs}
|
|
344
393
|
- {kind: eslint-fe, id: no-double-cast}
|
|
394
|
+
proves:
|
|
395
|
+
- {path: packages/hfs/src/hfs-ts-strict.spec.mjs, editions: [lite, full], codes: [HFS_TS_STRICT]}
|
|
396
|
+
- {path: packages/hfs/src/hfs-ts-strict-rule-tester.spec.mjs, editions: [lite, full], codes: [FE_TYPE_ESCAPE]}
|
|
397
|
+
exemplifiedBy:
|
|
398
|
+
- {path: "packages/hfs/templates/be/tool-config/tsconfig.json", editions: ["lite", "full"]}
|
|
399
|
+
- {path: "packages/hfs/templates/fe/tool-config/tsconfig.json", editions: ["lite", "full"]}
|
|
400
|
+
- {path: packages/hfs/src/hfs-ts-strict.spec.mjs, editions: [lite, full], codes: [HFS_TS_STRICT]}
|
|
401
|
+
- {path: packages/hfs/src/hfs-ts-strict-rule-tester.spec.mjs, editions: [lite, full], codes: [FE_TYPE_ESCAPE]}
|
|
402
|
+
witness:
|
|
403
|
+
- {path: packages/hfs/src/hfs-ts-strict.spec.mjs, editions: [lite, full], codes: [HFS_TS_STRICT]}
|
|
404
|
+
- {path: packages/hfs/src/hfs-ts-strict-rule-tester.spec.mjs, editions: [lite, full], codes: [FE_TYPE_ESCAPE]}
|
|
345
405
|
- id: R23
|
|
346
406
|
code: "HFS_CONTRACT_SNAPSHOT_DRIFT"
|
|
347
407
|
editions: ["lite", "full"]
|
|
348
408
|
docs: ["docs/hfs-contract-snapshots.md#committed-contract-snapshots"]
|
|
349
409
|
templateNa: "Contract snapshots are generated from each app's composed schema and operation table, not from a scaffolded contract artifact."
|
|
350
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
351
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
352
410
|
law: "The be side commits its contract snapshot and it equals the emit; the fe side reads it in place (be/contracts/)."
|
|
353
411
|
kinds: [check]
|
|
354
412
|
gates: [land, ci]
|
|
355
413
|
failureCodes: ["HFS_CONTRACT_SNAPSHOT_DRIFT"]
|
|
356
414
|
enforcers:
|
|
357
415
|
- {kind: hfs, id: contract-snapshot-drift, at: scripts/hfs/rules/contract.mjs}
|
|
358
|
-
|
|
416
|
+
proves:
|
|
417
|
+
- {path: packages/hfs/src/hfs-contract-snapshot-drift-direct.spec.mjs, editions: [lite, full], codes: [HFS_CONTRACT_SNAPSHOT_DRIFT]}
|
|
418
|
+
exemplifiedBy:
|
|
419
|
+
- {path: packages/hfs/src/hfs-contract-snapshot-drift-direct.spec.mjs, editions: [lite, full], codes: [HFS_CONTRACT_SNAPSHOT_DRIFT]}
|
|
420
|
+
witness:
|
|
421
|
+
- {path: packages/hfs/src/hfs-contract-snapshot-drift-direct.spec.mjs, edition: lite, codes: [HFS_CONTRACT_SNAPSHOT_DRIFT]}
|
|
422
|
+
- {path: packages/hfs/src/hfs-contract-snapshot-drift-direct.spec.mjs, edition: full, codes: [HFS_CONTRACT_SNAPSHOT_DRIFT]}
|
|
359
423
|
- id: R24
|
|
360
424
|
code: "HFS_ARCH_CONFIG_UNREAD"
|
|
361
425
|
editions: ["lite", "full"]
|
|
362
426
|
docs: ["docs/hfs-analysis-coverage.md#analysed-production-source"]
|
|
363
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
364
|
-
exemplifiedBy:
|
|
365
|
-
- {path: "packages/hfs/templates/be/skeleton-lite/apps/api/src/main.ts", edition: "lite"}
|
|
366
|
-
- {path: "packages/hfs/templates/be/skeleton/apps/__app__/src/main.ts", edition: "full"}
|
|
367
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
368
427
|
law: "The machine reads `hfs.json`; zero files analysed is red."
|
|
369
428
|
kinds: [check]
|
|
370
429
|
gates: [land, ci]
|
|
371
430
|
failureCodes: ["HFS_ARCH_CONFIG_UNREAD"]
|
|
372
431
|
enforcers:
|
|
373
432
|
- {kind: machine, id: arch-config-unread, at: scripts/hfs/architecture/config-unread.mjs}
|
|
433
|
+
proves:
|
|
434
|
+
- {path: packages/hfs/src/hfs-arch-config-unread.spec.mjs, editions: [lite, full], codes: [HFS_ARCH_CONFIG_UNREAD]}
|
|
435
|
+
exemplifiedBy:
|
|
436
|
+
- {path: "packages/hfs/templates/be/skeleton-lite/apps/api/src/main.ts", edition: "lite"}
|
|
437
|
+
- {path: "packages/hfs/templates/be/skeleton/apps/__app__/src/main.ts", edition: "full"}
|
|
438
|
+
- {path: packages/hfs/src/hfs-arch-config-unread.spec.mjs, editions: [lite, full], codes: [HFS_ARCH_CONFIG_UNREAD]}
|
|
439
|
+
witness:
|
|
440
|
+
- {path: packages/hfs/src/hfs-arch-config-unread.spec.mjs, edition: lite, codes: [HFS_ARCH_CONFIG_UNREAD]}
|
|
441
|
+
- {path: packages/hfs/src/hfs-arch-config-unread.spec.mjs, edition: full, codes: [HFS_ARCH_CONFIG_UNREAD]}
|
|
374
442
|
- id: R25
|
|
375
443
|
code: "HFS_UNUSED_EXPORT"
|
|
376
444
|
editions: ["lite", "full"]
|
|
377
445
|
docs: ["docs/hfs-export-liveness.md#export-and-file-liveness"]
|
|
378
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
379
|
-
exemplifiedBy:
|
|
380
|
-
- {path: "packages/hfs/templates/be/skeleton-lite/apps/api/src/main.ts", edition: "lite"}
|
|
381
|
-
- {path: "packages/hfs/templates/be/skeleton/apps/__app__/src/main.ts", edition: "full"}
|
|
382
|
-
- {path: "packages/hfs/templates/fe/skeleton-lite/apps/web/src/app/[locale]/page.tsx", edition: "lite"}
|
|
383
|
-
- {path: "packages/hfs/templates/fe/skeleton/apps/app/src/app/[locale]/page.tsx", edition: "full"}
|
|
384
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
385
446
|
law: "No public export without a consumer; no source file nothing reaches."
|
|
386
447
|
kinds: [lint, codemod]
|
|
387
448
|
gates: [settle, land, ci]
|
|
@@ -389,6 +450,17 @@ rules:
|
|
|
389
450
|
enforcers:
|
|
390
451
|
- {kind: eslint-be, id: dead-exports}
|
|
391
452
|
- {kind: eslint-fe, id: dead-exports}
|
|
453
|
+
proves:
|
|
454
|
+
- {path: packages/hfs/src/hfs-unused-export.spec.mjs, editions: [lite, full], codes: [HFS_UNUSED_EXPORT, HFS_UNUSED_FILE]}
|
|
455
|
+
exemplifiedBy:
|
|
456
|
+
- {path: "packages/hfs/templates/be/skeleton-lite/apps/api/src/main.ts", edition: "lite"}
|
|
457
|
+
- {path: "packages/hfs/templates/be/skeleton/apps/__app__/src/main.ts", edition: "full"}
|
|
458
|
+
- {path: "packages/hfs/templates/fe/skeleton-lite/apps/web/src/app/[locale]/page.tsx", edition: "lite"}
|
|
459
|
+
- {path: "packages/hfs/templates/fe/skeleton/apps/app/src/app/[locale]/page.tsx", edition: "full"}
|
|
460
|
+
- {path: packages/hfs/src/hfs-unused-export.spec.mjs, editions: [lite, full], codes: [HFS_UNUSED_EXPORT, HFS_UNUSED_FILE]}
|
|
461
|
+
witness:
|
|
462
|
+
- {path: packages/hfs/src/hfs-unused-export.spec.mjs, edition: lite, codes: [HFS_UNUSED_EXPORT, HFS_UNUSED_FILE]}
|
|
463
|
+
- {path: packages/hfs/src/hfs-unused-export.spec.mjs, edition: full, codes: [HFS_UNUSED_EXPORT, HFS_UNUSED_FILE]}
|
|
392
464
|
- id: R26
|
|
393
465
|
code: "BE_TIER_DIRECTION"
|
|
394
466
|
editions: [lite, full]
|
|
@@ -413,12 +485,6 @@ rules:
|
|
|
413
485
|
code: "ARCH_OWNER_CYCLE"
|
|
414
486
|
editions: [lite, full]
|
|
415
487
|
docs: [docs/a16-r26-r28.md#r27]
|
|
416
|
-
proves:
|
|
417
|
-
- {path: packages/eslint/be/legacy-owner-graph.a16.spec.mjs, editions: [lite, full]}
|
|
418
|
-
exemplifiedBy:
|
|
419
|
-
- {path: packages/eslint/be/legacy-owner-graph.a16.spec.mjs, editions: [lite, full]}
|
|
420
|
-
witness:
|
|
421
|
-
- {path: packages/eslint/be/legacy-owner-graph.a16.spec.mjs, editions: [lite, full]}
|
|
422
488
|
templateNa: "Owner cycles concern relations between separately generated owners, including the runtime; no cyclic or acyclic graph scaffold is generated."
|
|
423
489
|
law: "No owner cycles, type-only included."
|
|
424
490
|
kinds: [lint, design]
|
|
@@ -428,7 +494,12 @@ rules:
|
|
|
428
494
|
- {kind: eslint-be, id: owner-cycle}
|
|
429
495
|
- {kind: eslint-fe, id: owner-cycle}
|
|
430
496
|
- {kind: runtime, id: runtime-cycles, at: scripts/hfs/runtime-rules/tier-direction.mjs}
|
|
431
|
-
|
|
497
|
+
proves:
|
|
498
|
+
- {path: packages/eslint/be/legacy-owner-graph.a16.spec.mjs, editions: [lite, full]}
|
|
499
|
+
exemplifiedBy:
|
|
500
|
+
- {path: packages/eslint/be/legacy-owner-graph.a16.spec.mjs, editions: [lite, full]}
|
|
501
|
+
witness:
|
|
502
|
+
- {path: packages/eslint/be/legacy-owner-graph.a16.spec.mjs, editions: [lite, full]}
|
|
432
503
|
- id: R28
|
|
433
504
|
code: "BE_FEATURE_IMPORTS_FEATURE"
|
|
434
505
|
editions: [lite, full]
|
|
@@ -451,10 +522,6 @@ rules:
|
|
|
451
522
|
law: "Feature root is `index.ts`, module, `application/`, `transport/<protocol>/`; `application/` never imports `transport/` or a protocol framework."
|
|
452
523
|
editions: [lite, full]
|
|
453
524
|
docs: [docs/a16-r29-r31.md#r29-feature-shape]
|
|
454
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
455
|
-
exemplifiedBy:
|
|
456
|
-
- {path: packages/hfs/templates/be/patterns/api/feature.module.ts.tpl, editions: [lite, full]}
|
|
457
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
458
525
|
kinds: [check, codemod, design, lint]
|
|
459
526
|
gates: [settle, land, ci]
|
|
460
527
|
failureCodes: ["BE_FEATURE_SHAPE", "BE_FEATURE_LAYOUT_INVALID", "BE_APPLICATION_IMPORTS_TRANSPORT", "BE_APPLICATION_TRANSPORT_FRAMEWORK"]
|
|
@@ -462,6 +529,14 @@ rules:
|
|
|
462
529
|
- {kind: machine, id: feature-shape, at: scripts/hfs/architecture/feature-shape.mjs}
|
|
463
530
|
- {kind: eslint-be, id: feature-layout}
|
|
464
531
|
- {kind: eslint-be, id: application-never-imports-transport}
|
|
532
|
+
proves:
|
|
533
|
+
- {path: packages/hfs/src/a16-r29-r31.spec.mjs, editions: [lite, full]}
|
|
534
|
+
exemplifiedBy:
|
|
535
|
+
- {path: packages/hfs/templates/be/patterns/api/feature.module.ts.tpl, editions: [lite, full]}
|
|
536
|
+
- {path: packages/hfs/src/a16-r29-r31.spec.mjs, editions: [lite, full]}
|
|
537
|
+
witness:
|
|
538
|
+
- {path: packages/hfs/src/a16-r29-r31.spec.mjs, edition: lite}
|
|
539
|
+
- {path: packages/hfs/src/a16-r29-r31.spec.mjs, edition: full}
|
|
465
540
|
- id: R30
|
|
466
541
|
code: "BE_PUBLIC_SURFACE"
|
|
467
542
|
law: "Every owner has one `index.ts`; cross-owner imports use it, same-owner imports are relative and never go through it; it holds only named `export { }` lines, no `export *`, no alias re-export (`export { X as Y }`, `export const Y = X`, `export type Y = X`, `export interface Y extends X {}`: one declaration has one name), within the owner slot's `indexExports` budget (60 for domain and feature owners, 80 for `be.integrations` provider entries); cross-package imports use the package name and a declared export."
|
|
@@ -841,11 +916,6 @@ rules:
|
|
|
841
916
|
code: "BE_TEST_TOPOLOGY"
|
|
842
917
|
editions: [lite, full]
|
|
843
918
|
docs: [docs/quality-bar.md#r47-test-topology]
|
|
844
|
-
proves:
|
|
845
|
-
- {path: packages/eslint/be/r47-topology-coverage.spec.mjs, editions: [lite, full], codes: ["BE_TEST_TOPOLOGY"]}
|
|
846
|
-
exemplifiedBy:
|
|
847
|
-
- {path: packages/hfs/templates/be/inbox/service.spec.ts.tpl, editions: [lite, full]}
|
|
848
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
849
919
|
law: "One jest config, projects `unit`, `integration`, `e2e` and `contract`, live by folder, `diagnostics: false`; unit specs are `<name>.<role>.spec.ts` beside the file they test: required for the roles of `ruleParams.be.unitRoles` (`<name>.service.spec.ts` beside a `<name>.service.ts`, `<name>.cli.spec.ts` beside a cli command `<name>.cli.ts` of `src/features/cli`), optional for any other logic role (`ruleParams.be.logicRoles`) inside a slot whose `coverage` is required, except that the commit adding a measured logic file stages its `<name>.<role>.spec.ts` beside it (owner 2026-10-20, judged by `starci app hygiene` in the pre-commit hook), and nowhere else but beside a webhook or realtime door that has no service of its own (`<provider>.webhook.spec.ts`, `<channel>.gateway.spec.ts`, `<x>.subscription.spec.ts`) (every unit-tested subject has exactly one; any other `*.spec.ts` outside `be/src/tests/{world,integration,e2e,contract}` is a finding, including specs in apps), and the unit project collects coverage from the logic roles of the measured roots only (the scope derived from the slot manifest, R204) with a per-file threshold of 100 on lines, branches, functions and statements (`test` runs `--coverage`; `importHelpers` and `tslib`); `be/src/tests/world/` is the ONLY test infrastructure: `global-setup.ts` starts the app's own stack (`.starcistacks/<env>`, named by `stack` in `test-world.config.ts`, the declaration of the test-world library in its one named form `export const { useTestWorld, useSandbox } = defineTestWorld({...})` (a default export is not read): every service it declares runs REAL, behind toxiproxy, images and versions read from the stack at run time, never spelled in test source) or attaches to a warm one that answers, and runs the migrations once over the cli app's connections (the runner of the cli migrate command); `global-teardown.ts` stops only what its setup started; `use-test-world.ts` exports `useTestWorld({ apps } | { modules })` (`world.apps.<name>.api`, `world.db.<connection>`, `world.infra.<service>` with `latency(ms)`, `cut()` and `restore()` on the real service, `world.fake.<provider>`, `world.waitFor`) and `fakes/<provider>/` holds the network-edge fakes (`failNext`, `replayWebhook`, `delay`, payload fixtures) of external SaaS the team does not operate ONLY: a fake of a service the stack declares is refused, except stateless compute that needs special hardware or an external model (GPU inference, a self-hosted embedding model), whose `stacks` entry in `test-world.config.ts` declares `{ fakedBy: <fake>, reason }` with a non-empty `reason` (a stateful service, or one with a persistent volume, is never accepted); it alone owns containers, DataSource, migrations and `process.env`; nothing under `be/src/tests` overrides a provider or DI token; `be/src/tests/integration/<capability>/*.integration-spec.ts` (`{ modules }`, with the real peer apps its client calls beside them as `apps`; real infrastructure, no HTTP door of ours), `be/src/tests/e2e/<area>/*.e2e-spec.ts` (`{ apps }`) and `be/src/tests/contract/<provider>/*.contract-spec.ts` (provider sandboxes, skipped without sandbox config, run only by `test:contract`, never by `test` or `test:e2e`) agree folder with suffix; an integration or e2e spec passes `useTestWorld` one object literal with plain keys (no variable, spread or computed key) and calls it; the contract layer has no skip either: a contract spec writes `sandbox.describe(...)` from the test-world library's `useSandbox(...)`, and when the sandbox config is absent that describe registers one failing test naming the missing keys (the body never runs), and every `fakes/<provider>/` that serves payload fixtures (`payloads/*.json`) has a `contract/<provider>/*.contract-spec.ts` that references those fixtures and asserts `shapeOf(real)` equals `shapeOf(fixture)` (the helper `shapeOf` is named by `ruleParams.be.contractShape` of the slot manifest; fakes the test-world library provides are guarded by the library); no `.test.ts`, `int-spec` or `harness-spec`, no `live/` and no `be/src/tests/e2e/world`."
|
|
850
920
|
kinds: [check, codemod, lint]
|
|
851
921
|
gates: [land, ci]
|
|
@@ -860,7 +930,15 @@ rules:
|
|
|
860
930
|
- {kind: eslint-be, id: tests-infra-only-in-world}
|
|
861
931
|
- {kind: eslint-be, id: tests-no-override}
|
|
862
932
|
- {kind: eslint-be, id: test-world-shape}
|
|
863
|
-
|
|
933
|
+
exemplifiedBy:
|
|
934
|
+
- {path: packages/hfs/templates/be/inbox/service.spec.ts.tpl, editions: [lite, full]}
|
|
935
|
+
- {path: packages/hfs/src/r47-test-topology-coverage.spec.mjs, editions: [lite, full], codes: [BE_TEST_TOPOLOGY, BE_CONTRACT_UNGUARDED]}
|
|
936
|
+
witness:
|
|
937
|
+
- {path: packages/hfs/src/r47-test-topology-coverage.spec.mjs, edition: lite, codes: [BE_TEST_TOPOLOGY, BE_CONTRACT_UNGUARDED]}
|
|
938
|
+
- {path: packages/hfs/src/r47-test-topology-coverage.spec.mjs, edition: full, codes: [BE_TEST_TOPOLOGY, BE_CONTRACT_UNGUARDED]}
|
|
939
|
+
proves:
|
|
940
|
+
- {path: packages/eslint/be/r47-topology-coverage.spec.mjs, editions: [lite, full], codes: ["BE_TEST_TOPOLOGY"]}
|
|
941
|
+
- {path: packages/hfs/src/r47-test-topology-coverage.spec.mjs, editions: [lite, full], codes: [BE_TEST_TOPOLOGY, BE_CONTRACT_UNGUARDED, BE_UNIT_SPEC_NOT_STAGED]}
|
|
864
942
|
- id: R48
|
|
865
943
|
code: "BE_SPEC_QUALITY"
|
|
866
944
|
editions: [lite, full]
|
|
@@ -978,10 +1056,6 @@ rules:
|
|
|
978
1056
|
code: "FE_WIRE_GENERATED"
|
|
979
1057
|
editions: [lite, full]
|
|
980
1058
|
docs: [docs/code-pattern-enforcement.md#r52]
|
|
981
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
982
|
-
exemplifiedBy:
|
|
983
|
-
- {path: packages/hfs/templates/fe/table/graphql/query.types.ts.tpl, editions: [lite, full]}
|
|
984
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
985
1059
|
law: "Wire types are generated by graphql-codegen from `be/contracts/<app>/schema.graphql`, read in place and never copied, into `modules/api/graphql/__generated__`; an operation's request and response types re-export the generated ones and are never typed by hand."
|
|
986
1060
|
kinds: [lint, check, design]
|
|
987
1061
|
gates: [settle, land, ci]
|
|
@@ -989,15 +1063,18 @@ rules:
|
|
|
989
1063
|
enforcers:
|
|
990
1064
|
- {kind: eslint-fe, id: no-hand-typed-wire}
|
|
991
1065
|
- {kind: hfs, id: wire-generated, at: scripts/hfs/rules/frontend-tree.mjs}
|
|
1066
|
+
proves:
|
|
1067
|
+
- {path: packages/hfs/src/r52-wire-generated.spec.mjs, editions: [lite, full], codes: [FE_WIRE_GENERATED]}
|
|
1068
|
+
exemplifiedBy:
|
|
1069
|
+
- {path: packages/hfs/templates/fe/table/graphql/query.types.ts.tpl, editions: [lite, full]}
|
|
1070
|
+
- {path: packages/hfs/src/r52-wire-generated.spec.mjs, editions: [lite, full], codes: [FE_WIRE_GENERATED]}
|
|
1071
|
+
witness:
|
|
1072
|
+
- {path: packages/hfs/src/r52-wire-generated.spec.mjs, edition: lite, codes: [FE_WIRE_GENERATED]}
|
|
1073
|
+
- {path: packages/hfs/src/r52-wire-generated.spec.mjs, edition: full, codes: [FE_WIRE_GENERATED]}
|
|
992
1074
|
- id: R53
|
|
993
1075
|
code: "FE_ERROR_BOUNDARY_MISSING"
|
|
994
1076
|
editions: [lite, full]
|
|
995
1077
|
docs: [docs/code-pattern-enforcement.md#r53]
|
|
996
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
997
|
-
exemplifiedBy:
|
|
998
|
-
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/app/global-error.tsx, edition: lite}
|
|
999
|
-
- {path: packages/hfs/templates/fe/skeleton/apps/app/src/app/global-error.tsx, edition: full}
|
|
1000
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
1001
1078
|
law: "Global, locale error, not-found and loading boundaries exist."
|
|
1002
1079
|
kinds: [check, codemod, lint]
|
|
1003
1080
|
gates: [settle, land, ci]
|
|
@@ -1005,6 +1082,15 @@ rules:
|
|
|
1005
1082
|
enforcers:
|
|
1006
1083
|
- {kind: eslint-fe, id: no-null-suspense-fallback}
|
|
1007
1084
|
- {kind: machine, id: error-boundary-missing, at: scripts/hfs/architecture/required-files.mjs}
|
|
1085
|
+
proves:
|
|
1086
|
+
- {path: packages/hfs/src/r53-error-boundaries.spec.mjs, editions: [lite, full], codes: [FE_ERROR_BOUNDARY_MISSING, FE_SUSPENSE_NULL_FALLBACK]}
|
|
1087
|
+
exemplifiedBy:
|
|
1088
|
+
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/app/global-error.tsx, edition: lite}
|
|
1089
|
+
- {path: packages/hfs/templates/fe/skeleton/apps/app/src/app/global-error.tsx, edition: full}
|
|
1090
|
+
- {path: packages/hfs/src/r53-error-boundaries.spec.mjs, editions: [lite, full], codes: [FE_ERROR_BOUNDARY_MISSING, FE_SUSPENSE_NULL_FALLBACK]}
|
|
1091
|
+
witness:
|
|
1092
|
+
- {path: packages/hfs/src/r53-error-boundaries.spec.mjs, edition: lite, codes: [FE_ERROR_BOUNDARY_MISSING, FE_SUSPENSE_NULL_FALLBACK]}
|
|
1093
|
+
- {path: packages/hfs/src/r53-error-boundaries.spec.mjs, edition: full, codes: [FE_ERROR_BOUNDARY_MISSING, FE_SUSPENSE_NULL_FALLBACK]}
|
|
1008
1094
|
- id: R54
|
|
1009
1095
|
code: "FE_ROUTE_FILES_THIN"
|
|
1010
1096
|
law: "Route files mount one owner; Next conventions (`proxy.ts`, metadata)."
|
|
@@ -1122,14 +1208,6 @@ rules:
|
|
|
1122
1208
|
code: "FE_I18N_PLACEMENT"
|
|
1123
1209
|
editions: [lite, full]
|
|
1124
1210
|
docs: [docs/architecture.md#r59]
|
|
1125
|
-
proves:
|
|
1126
|
-
- {path: packages/eslint/fe/i18n-placement-coverage.spec.mjs, editions: [lite, full]}
|
|
1127
|
-
exemplifiedBy:
|
|
1128
|
-
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/modules/i18n, edition: lite}
|
|
1129
|
-
- {path: packages/hfs/templates/fe/skeleton/packages/__project__-i18n/src, edition: full}
|
|
1130
|
-
- {path: packages/eslint/fe/i18n-placement-coverage.spec.mjs, editions: [lite, full]}
|
|
1131
|
-
witness:
|
|
1132
|
-
- {path: packages/eslint/fe/i18n-placement-coverage.spec.mjs, editions: [lite, full]}
|
|
1133
1211
|
law: "`next-intl` with `[locale]`; the next-intl stack is written once per front end: `fe/packages/<family>-i18n` (`createAppI18n`) called by each app's `modules/i18n/index.ts`, or the only app's `modules/i18n/`."
|
|
1134
1212
|
kinds: [check, codemod, lint]
|
|
1135
1213
|
gates: [settle, land, ci]
|
|
@@ -1142,24 +1220,35 @@ rules:
|
|
|
1142
1220
|
- {kind: eslint-fe, id: no-native-anchor}
|
|
1143
1221
|
- {kind: eslint-fe, id: use-intl-formatter}
|
|
1144
1222
|
- {kind: hfs, id: i18n-placement, at: scripts/hfs/rules/frontend-tree.mjs}
|
|
1145
|
-
|
|
1146
|
-
|
|
1223
|
+
proves:
|
|
1224
|
+
- {path: packages/eslint/fe/i18n-placement-coverage.spec.mjs, editions: [lite, full]}
|
|
1225
|
+
- {path: packages/hfs/src/hfs-i18n-placement-coverage.spec.mjs, editions: [lite, full], codes: [FE_I18N_PLACEMENT]}
|
|
1226
|
+
exemplifiedBy:
|
|
1227
|
+
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/modules/i18n, edition: lite}
|
|
1228
|
+
- {path: packages/hfs/templates/fe/skeleton/packages/__project__-i18n/src, edition: full}
|
|
1229
|
+
- {path: packages/eslint/fe/i18n-placement-coverage.spec.mjs, editions: [lite, full]}
|
|
1230
|
+
- {path: packages/hfs/src/hfs-i18n-placement-coverage.spec.mjs, editions: [lite, full], codes: [FE_I18N_PLACEMENT]}
|
|
1231
|
+
witness:
|
|
1232
|
+
- {path: packages/eslint/fe/i18n-placement-coverage.spec.mjs, editions: [lite, full]}
|
|
1233
|
+
- {path: packages/hfs/src/hfs-i18n-placement-coverage.spec.mjs, editions: [lite, full], codes: [FE_I18N_PLACEMENT]}
|
|
1147
1234
|
- id: R60
|
|
1148
1235
|
code: "FE_I18N_CATALOG"
|
|
1149
1236
|
editions: [lite, full]
|
|
1150
1237
|
docs: [docs/architecture.md#r60]
|
|
1151
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
1152
|
-
exemplifiedBy:
|
|
1153
|
-
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/modules/i18n/messages, edition: lite}
|
|
1154
|
-
- {path: packages/hfs/templates/fe/skeleton/apps/app/src/modules/i18n/messages, edition: full}
|
|
1155
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
1156
1238
|
law: "Same keys in every catalog, `pick` for clients."
|
|
1157
1239
|
kinds: [check]
|
|
1158
1240
|
gates: [land, ci]
|
|
1159
1241
|
failureCodes: ["FE_I18N_CATALOG"]
|
|
1160
1242
|
enforcers:
|
|
1161
1243
|
- {kind: hfs, id: i18n-catalog, at: scripts/hfs/rules/frontend-tree.mjs}
|
|
1162
|
-
|
|
1244
|
+
proves:
|
|
1245
|
+
- {path: packages/hfs/src/hfs-i18n-catalog-coverage.spec.mjs, editions: [lite, full]}
|
|
1246
|
+
exemplifiedBy:
|
|
1247
|
+
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/modules/i18n/messages, edition: lite}
|
|
1248
|
+
- {path: packages/hfs/templates/fe/skeleton/apps/app/src/modules/i18n/messages, edition: full}
|
|
1249
|
+
- {path: packages/hfs/src/hfs-i18n-catalog-coverage.spec.mjs, editions: [lite, full]}
|
|
1250
|
+
witness:
|
|
1251
|
+
- {path: packages/hfs/src/hfs-i18n-catalog-coverage.spec.mjs, editions: [lite, full]}
|
|
1163
1252
|
- id: R61
|
|
1164
1253
|
code: "FE_STYLE_TOKEN_ONLY"
|
|
1165
1254
|
law: "Token-only CSS; colour only in `brand.css`; every `@source` resolves (sub-check `FE_STYLE_SOURCE_UNRESOLVED`). Status colours follow HeroUI soft pairs: every status tone has `--<tone>-soft` and `--<tone>-soft-foreground` in light and dark, the soft foreground reaches 3:1 on its tint and on `--background`, body text 4.5:1, a solid tone is never text below 4.5:1, and text and icons take the soft foreground, never the solid tone."
|
|
@@ -1215,15 +1304,19 @@ rules:
|
|
|
1215
1304
|
editions: [lite, full]
|
|
1216
1305
|
docs: [docs/architecture.md#r63]
|
|
1217
1306
|
templateNa: "Shared package manifests are authored by the app; the frontend scaffold creates app workspaces rather than shared package owners."
|
|
1218
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
1219
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
1220
1307
|
law: "Packages build to `dist` with explicit exports and no dead unit."
|
|
1221
1308
|
kinds: [check, design]
|
|
1222
1309
|
gates: [land, ci]
|
|
1223
1310
|
failureCodes: ["FE_PACKAGE_SHAPE"]
|
|
1224
1311
|
enforcers:
|
|
1225
1312
|
- {kind: machine, id: package-shape, at: scripts/hfs/architecture/package-shape.mjs}
|
|
1226
|
-
|
|
1313
|
+
proves:
|
|
1314
|
+
- {path: packages/hfs/src/architecture-package-shape-coverage.spec.mjs, editions: [lite, full]}
|
|
1315
|
+
exemplifiedBy:
|
|
1316
|
+
- {path: packages/hfs/src/architecture-package-shape-coverage.spec.mjs, editions: [lite, full]}
|
|
1317
|
+
witness:
|
|
1318
|
+
- {path: packages/hfs/src/architecture-package-shape-coverage.spec.mjs, edition: lite, codes: [FE_PACKAGE_SHAPE]}
|
|
1319
|
+
- {path: packages/hfs/src/architecture-package-shape-coverage.spec.mjs, edition: full, codes: [FE_PACKAGE_SHAPE]}
|
|
1227
1320
|
- id: R64
|
|
1228
1321
|
code: "FE_APP_ISOLATION"
|
|
1229
1322
|
law: "Apps never import apps; ui-screen declares `app`."
|
|
@@ -1685,10 +1778,15 @@ rules:
|
|
|
1685
1778
|
- {kind: eslint-be, id: public-contract-form}
|
|
1686
1779
|
editions: ["lite","full"]
|
|
1687
1780
|
docs: ["docs/be-shape-coverage.md#r89"]
|
|
1688
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
1689
|
-
exemplifiedBy: [{"path":"packages/hfs/templates/be/patterns/api/graphql.input.ts.tpl","editions":["lite","full"]}]
|
|
1690
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
1691
1781
|
gates: ["pre-commit","settle","land","ci"]
|
|
1782
|
+
proves:
|
|
1783
|
+
- {path: packages/hfs/src/be-r89-source-form-coverage.spec.mjs, editions: [lite, full]}
|
|
1784
|
+
exemplifiedBy:
|
|
1785
|
+
- {path: packages/hfs/templates/be/patterns/api/graphql.input.ts.tpl, editions: [lite, full]}
|
|
1786
|
+
- {path: packages/hfs/src/be-r89-source-form-coverage.spec.mjs, editions: [lite, full]}
|
|
1787
|
+
witness:
|
|
1788
|
+
- {path: packages/hfs/src/be-r89-source-form-coverage.spec.mjs, edition: lite, codes: [BE_SOURCE_FORM, BE_PUBLIC_CONTRACT_FORM]}
|
|
1789
|
+
- {path: packages/hfs/src/be-r89-source-form-coverage.spec.mjs, edition: full, codes: [BE_SOURCE_FORM, BE_PUBLIC_CONTRACT_FORM]}
|
|
1692
1790
|
- id: R90
|
|
1693
1791
|
code: "BE_INFRA_OWNER"
|
|
1694
1792
|
law: "Each raw infrastructure library (HTTP, cache, queue, scheduler, logger, date, config, events) is imported or referenced only by its one owning platform or integration capability, and the `HttpClient` port of `platform/http` is called only by an `integrations` capability."
|
|
@@ -1790,14 +1888,16 @@ rules:
|
|
|
1790
1888
|
- {kind: machine, id: grammar, at: scripts/hfs/architecture/frontend-grammar.mjs}
|
|
1791
1889
|
editions: [lite, full]
|
|
1792
1890
|
docs: ["docs/code-pattern-enforcement.md#r93-vendor-and-grammar-ownership"]
|
|
1891
|
+
templateNa: "Vendor boundary violations and installed Grammar package contracts are checked against consumer ownership; no managed template scaffolds a vendor install or a forbidden import."
|
|
1793
1892
|
proves:
|
|
1794
1893
|
- packages/eslint/fe/r93-vendor-coverage.spec.mjs
|
|
1795
|
-
|
|
1894
|
+
- packages/hfs/src/r93-grammar-ownership.spec.mjs
|
|
1796
1895
|
exemplifiedBy:
|
|
1797
1896
|
- {path: packages/eslint/fe/r93-vendor-coverage.spec.mjs, editions: [lite, full]}
|
|
1897
|
+
- {path: packages/hfs/src/r93-grammar-ownership.spec.mjs, editions: [lite, full]}
|
|
1798
1898
|
witness:
|
|
1799
1899
|
- {path: packages/eslint/fe/r93-vendor-coverage.spec.mjs, editions: [lite, full], codes: [FE_VENDOR_BOUNDARY]}
|
|
1800
|
-
|
|
1900
|
+
- {path: packages/hfs/src/r93-grammar-ownership.spec.mjs, editions: [lite, full], codes: [ARCH_GRAMMAR_CONTRACT_INVALID, ARCH_GRAMMAR_EXPORT_BYPASS]}
|
|
1801
1901
|
- id: R94
|
|
1802
1902
|
code: "FE_SLOT_FILE_ROLE"
|
|
1803
1903
|
law: "A front-end file is owned by a slot and named by it: a slot that owns a directory (route, feature, components, hooks, api module) holds only the files its `allows` list names, and holds them inside a folder of its own."
|
|
@@ -1808,9 +1908,13 @@ rules:
|
|
|
1808
1908
|
- {kind: machine, id: fe-slot-allows, at: scripts/hfs/architecture/fe-slot-allows.mjs}
|
|
1809
1909
|
editions: ["lite","full"]
|
|
1810
1910
|
docs: ["docs/hfs-authored-file-boundaries.md#r94-slot-file-roles"]
|
|
1811
|
-
|
|
1812
|
-
exemplifiedBy:
|
|
1813
|
-
|
|
1911
|
+
proves: [packages/hfs/src/r94-r96-r97-coverage.spec.mjs]
|
|
1912
|
+
exemplifiedBy:
|
|
1913
|
+
- {path: "packages/hfs/templates/fe/skeleton-lite/apps/web/src/app/[locale]/page.tsx", edition: lite}
|
|
1914
|
+
- {path: "packages/hfs/templates/fe/skeleton/apps/app/src/app/[locale]/page.tsx", edition: full}
|
|
1915
|
+
- {path: packages/hfs/src/r94-r96-r97-coverage.spec.mjs, editions: [lite, full], codes: [FE_SLOT_FILE_ROLE]}
|
|
1916
|
+
witness:
|
|
1917
|
+
- {path: packages/hfs/src/r94-r96-r97-coverage.spec.mjs, editions: [lite, full], codes: [FE_SLOT_FILE_ROLE]}
|
|
1814
1918
|
- id: R95
|
|
1815
1919
|
code: "BE_OPERATION_CONTRACT"
|
|
1816
1920
|
law: "A versioned operation is declared once in the app's typed operation table (`OperationContract<Input, Output, RefusalCode>` registered by `defineOperations`): its input and output are closed types (never `any`, `unknown` or `Record<string, unknown>`), its refusal codes a closed union of string literals, and the route that serves the table takes `OperationRequest<Table>` and answers `Promise<OperationReply<Table>>` of that one table."
|
|
@@ -1837,9 +1941,11 @@ rules:
|
|
|
1837
1941
|
editions: ["lite","full"]
|
|
1838
1942
|
docs: ["docs/hfs-authored-file-boundaries.md#r96-document-language"]
|
|
1839
1943
|
templateNa: "Language validation judges authored document content rather than a scaffolded file role; edition-specific spec fixtures exercise English documents and localized data."
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1944
|
+
proves: [packages/hfs/src/r94-r96-r97-coverage.spec.mjs]
|
|
1945
|
+
exemplifiedBy:
|
|
1946
|
+
- {path: packages/hfs/src/r94-r96-r97-coverage.spec.mjs, editions: [lite, full], codes: [HFS_DOC_NOT_ENGLISH]}
|
|
1947
|
+
witness:
|
|
1948
|
+
- {path: packages/hfs/src/r94-r96-r97-coverage.spec.mjs, editions: [lite, full], codes: [HFS_DOC_NOT_ENGLISH]}
|
|
1843
1949
|
- id: R97
|
|
1844
1950
|
code: "FE_NO_TESTS"
|
|
1845
1951
|
law: "The front end (`fe/`) has no tests by standard: no `*.spec.*`, `*.test.*` or `*-spec.*` file, no `e2e/`, `__tests__/`, `__mocks__/` or `test-support/` directory, no vitest, Playwright, jest or Cypress configuration or setup file, no test script, and no test-runner, test-environment, testing-library or axe dependency in any `package.json`; there is no exception, `scripts/` included."
|
|
@@ -1850,10 +1956,12 @@ rules:
|
|
|
1850
1956
|
editions: ["lite","full"]
|
|
1851
1957
|
docs: ["docs/hfs-authored-file-boundaries.md#r97-front-end-test-exclusion"]
|
|
1852
1958
|
templateNa: "Front-end test files and test tooling are forbidden and are therefore not scaffolded; spec fixtures show permitted production files and manifests without test tooling."
|
|
1853
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
1854
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
1855
1959
|
gates: ["settle","land","ci"]
|
|
1856
|
-
|
|
1960
|
+
proves: [packages/hfs/src/r94-r96-r97-coverage.spec.mjs]
|
|
1961
|
+
exemplifiedBy:
|
|
1962
|
+
- {path: packages/hfs/src/r94-r96-r97-coverage.spec.mjs, editions: [lite, full], codes: [FE_NO_TESTS]}
|
|
1963
|
+
witness:
|
|
1964
|
+
- {path: packages/hfs/src/r94-r96-r97-coverage.spec.mjs, editions: [lite, full], codes: [FE_NO_TESTS]}
|
|
1857
1965
|
- id: R98
|
|
1858
1966
|
code: "BE_TEST_BUILDER_HOME"
|
|
1859
1967
|
law: "A test data builder lives only in `be/src/tests/fixtures/builders/<area>.builder.ts` (slot `be.tests.fixtures.builders`, its SQL text in `<area>.sql.ts` beside it): a `*.repository.ts`, `*.factory.ts` or `*.fixture.ts` under `be/src/tests` and a `*.builder.ts` elsewhere are BE_SOURCE_FORM findings, and any other module of the test tree that exports a function creating persisted rows through an EntityManager, DataSource or QueryRunner is a builder in the wrong place."
|
|
@@ -1923,28 +2031,29 @@ rules:
|
|
|
1923
2031
|
code: "BE_SPEC_PLACEMENT"
|
|
1924
2032
|
editions: [lite, full]
|
|
1925
2033
|
docs: [docs/legacy-repo-rule-coverage.md#r102]
|
|
2034
|
+
law: "A back-end spec or test file lives in one of the four test layers and nowhere else: a unit spec of a unit-tested role (`ruleParams.be.unitRoles`: `<name>.service.spec.ts` beside its service, `<name>.cli.spec.ts` beside its cli command), or an integration, e2e or contract spec under `be/src/tests/{integration,e2e,contract}`; a `*.spec.*`, `*.test.*` or `*-spec.*` file anywhere else, `scripts/` and `tools/` included, is a finding."
|
|
2035
|
+
kinds: [check, lint]
|
|
2036
|
+
gates: [land, ci]
|
|
2037
|
+
failureCodes: ["BE_SPEC_PLACEMENT"]
|
|
2038
|
+
enforcers:
|
|
2039
|
+
- {kind: hfs, id: spec-placement, at: scripts/hfs/rules/spec-placement.mjs}
|
|
2040
|
+
- {kind: eslint-be, id: spec-placement}
|
|
1926
2041
|
proves:
|
|
1927
2042
|
- {path: packages/eslint/be/spec-placement-coverage.spec.mjs, editions: [lite, full], codes: [BE_SPEC_PLACEMENT]}
|
|
2043
|
+
- {path: packages/hfs/src/hfs-spec-placement-coverage.spec.mjs, editions: [lite, full], codes: [BE_SPEC_PLACEMENT]}
|
|
1928
2044
|
exemplifiedBy:
|
|
1929
2045
|
- {path: packages/hfs/templates/be/patterns/cli/group.cli.spec.ts.tpl, editions: [lite, full]}
|
|
1930
2046
|
- {path: packages/eslint/be/spec-placement-coverage.spec.mjs, editions: [lite, full], codes: [BE_SPEC_PLACEMENT]}
|
|
2047
|
+
- {path: packages/hfs/src/hfs-spec-placement-coverage.spec.mjs, editions: [lite, full], codes: [BE_SPEC_PLACEMENT]}
|
|
1931
2048
|
witness:
|
|
1932
2049
|
- {path: packages/eslint/be/spec-placement-coverage.spec.mjs, edition: lite, codes: [BE_SPEC_PLACEMENT]}
|
|
1933
2050
|
- {path: packages/eslint/be/spec-placement-coverage.spec.mjs, edition: full, codes: [BE_SPEC_PLACEMENT]}
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
gates: [land, ci]
|
|
1937
|
-
failureCodes: ["BE_SPEC_PLACEMENT"]
|
|
1938
|
-
enforcers:
|
|
1939
|
-
- {kind: hfs, id: spec-placement, at: scripts/hfs/rules/spec-placement.mjs}
|
|
1940
|
-
- {kind: eslint-be, id: spec-placement}
|
|
1941
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; the package specs named in proves keep proving the lint enforcers, the runtime-code enforcers lost their deleted runtime spec"
|
|
2051
|
+
- {path: packages/hfs/src/hfs-spec-placement-coverage.spec.mjs, edition: lite, codes: [BE_SPEC_PLACEMENT]}
|
|
2052
|
+
- {path: packages/hfs/src/hfs-spec-placement-coverage.spec.mjs, edition: full, codes: [BE_SPEC_PLACEMENT]}
|
|
1942
2053
|
- id: R103
|
|
1943
2054
|
code: "HFS_REPO_LOCAL_CHECK"
|
|
1944
2055
|
editions: [lite, full]
|
|
1945
2056
|
docs: [docs/legacy-repo-rule-coverage.md#r103]
|
|
1946
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
1947
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
1948
2057
|
templateNa: "Repository-local checks and lint plugins are forbidden artifacts and have no managed scaffold."
|
|
1949
2058
|
law: "A repository keeps no check, lint rule or lint plugin of its own: no `check-*` file in `scripts/` or `tools/`, no `eslint-local-rules*` or local eslint plugin, no script that runs one; every check lives in the `.claude` runtime and the canons."
|
|
1950
2059
|
kinds: [check]
|
|
@@ -1952,13 +2061,17 @@ rules:
|
|
|
1952
2061
|
failureCodes: ["HFS_REPO_LOCAL_CHECK"]
|
|
1953
2062
|
enforcers:
|
|
1954
2063
|
- {kind: hfs, id: repo-local-check, at: scripts/hfs/rules/repo-local-checks.mjs}
|
|
1955
|
-
|
|
2064
|
+
proves:
|
|
2065
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, editions: [lite, full], codes: [HFS_REPO_LOCAL_CHECK]}
|
|
2066
|
+
exemplifiedBy:
|
|
2067
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, editions: [lite, full], codes: [HFS_REPO_LOCAL_CHECK]}
|
|
2068
|
+
witness:
|
|
2069
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, edition: lite, codes: [HFS_REPO_LOCAL_CHECK]}
|
|
2070
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, edition: full, codes: [HFS_REPO_LOCAL_CHECK]}
|
|
1956
2071
|
- id: R104
|
|
1957
2072
|
code: "HFS_LINT_SUPPRESSION_FILE"
|
|
1958
2073
|
editions: [lite, full]
|
|
1959
2074
|
docs: [docs/legacy-repo-rule-coverage.md#r104]
|
|
1960
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
1961
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
1962
2075
|
templateNa: "Lint-suppression files and options are prohibited, so no suppression artifact is scaffolded."
|
|
1963
2076
|
law: "A repository keeps no lint-suppression file, script or option: no `eslint.suppressions*`, no `lint:suppressions` script, no eslint `--suppress-all` or `--suppressions-location` flag and no suppressions configuration passed to eslint; a finding is fixed in the code."
|
|
1964
2077
|
kinds: [check]
|
|
@@ -1966,21 +2079,31 @@ rules:
|
|
|
1966
2079
|
failureCodes: ["HFS_LINT_SUPPRESSION_FILE"]
|
|
1967
2080
|
enforcers:
|
|
1968
2081
|
- {kind: hfs, id: lint-suppression, at: scripts/hfs/rules/lint-suppression.mjs}
|
|
1969
|
-
|
|
2082
|
+
proves:
|
|
2083
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, editions: [lite, full], codes: [HFS_LINT_SUPPRESSION_FILE]}
|
|
2084
|
+
exemplifiedBy:
|
|
2085
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, editions: [lite, full], codes: [HFS_LINT_SUPPRESSION_FILE]}
|
|
2086
|
+
witness:
|
|
2087
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, edition: lite, codes: [HFS_LINT_SUPPRESSION_FILE]}
|
|
2088
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, edition: full, codes: [HFS_LINT_SUPPRESSION_FILE]}
|
|
1970
2089
|
- id: R105
|
|
1971
2090
|
code: "HFS_PROOF_COMMAND_FILE_MISSING"
|
|
1972
2091
|
editions: [lite, full]
|
|
1973
2092
|
docs: [docs/legacy-repo-rule-coverage.md#r105]
|
|
1974
2093
|
templateNa: "Proof plans name project-specific files in authored Work records; managed app scaffolds do not supply those commands or their target scripts."
|
|
1975
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
1976
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
1977
2094
|
law: "A proof command of a `.starciwork` record (`requiresProof.<kind>.command`) is runnable as written: every repository file it names exists."
|
|
1978
2095
|
kinds: [check]
|
|
1979
2096
|
gates: [land, ci]
|
|
1980
2097
|
failureCodes: ["HFS_PROOF_COMMAND_FILE_MISSING"]
|
|
1981
2098
|
enforcers:
|
|
1982
2099
|
- {kind: hfs, id: proof-command-files, at: scripts/hfs/rules/proof-commands.mjs}
|
|
1983
|
-
|
|
2100
|
+
proves:
|
|
2101
|
+
- {path: packages/hfs/src/hfs-proof-command-file-missing.spec.mjs, editions: [lite, full]}
|
|
2102
|
+
exemplifiedBy:
|
|
2103
|
+
- {path: packages/hfs/src/hfs-proof-command-file-missing.spec.mjs, editions: [lite, full]}
|
|
2104
|
+
witness:
|
|
2105
|
+
- {path: packages/hfs/src/hfs-proof-command-file-missing.spec.mjs, edition: lite, codes: [HFS_PROOF_COMMAND_FILE_MISSING]}
|
|
2106
|
+
- {path: packages/hfs/src/hfs-proof-command-file-missing.spec.mjs, edition: full, codes: [HFS_PROOF_COMMAND_FILE_MISSING]}
|
|
1984
2107
|
- id: R106
|
|
1985
2108
|
code: "FE_I18N_KEYS"
|
|
1986
2109
|
law: "The catalogs of a front-end app and its source agree both ways: a literal key read through `next-intl` (`useTranslations`, `getTranslations`, `t`, `t.rich`, `t.raw`, `t.markup`) exists in every locale, and a catalog key that no string of the app's or the shared packages' source can be reading is deleted."
|
|
@@ -2079,8 +2202,6 @@ rules:
|
|
|
2079
2202
|
code: "HFS_PEER_INTEGRATION_MISSING"
|
|
2080
2203
|
editions: [lite, full]
|
|
2081
2204
|
docs: [docs/legacy-contract-rule-coverage.md#r111]
|
|
2082
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2083
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2084
2205
|
templateNa: "Optional integration dependency pairs and their runtime peers are application-specific package.json dependencies, not a managed scaffold surface."
|
|
2085
2206
|
law: "An app declares the runtime peer every driver integration it uses needs: when the app root package.json depends on every package of a pair of knowledge/hfs/peer-integrations.yaml (at the named major), it declares the pair's `requires` in its dependencies (`@nestjs/apollo` on `@nestjs/platform-express` 11, Express 5, needs `@as-integrations/express5`)."
|
|
2086
2207
|
kinds: [check]
|
|
@@ -2088,14 +2209,17 @@ rules:
|
|
|
2088
2209
|
failureCodes: ["HFS_PEER_INTEGRATION_MISSING"]
|
|
2089
2210
|
enforcers:
|
|
2090
2211
|
- {kind: hfs, id: peer-integrations, at: scripts/hfs/rules/peer-integrations.mjs}
|
|
2091
|
-
|
|
2212
|
+
proves:
|
|
2213
|
+
- {path: packages/hfs/src/hfs-peer-integrations-coverage.spec.mjs, editions: [lite, full]}
|
|
2214
|
+
exemplifiedBy:
|
|
2215
|
+
- {path: packages/hfs/src/hfs-peer-integrations-coverage.spec.mjs, editions: [lite, full]}
|
|
2216
|
+
witness:
|
|
2217
|
+
- {path: packages/hfs/src/hfs-peer-integrations-coverage.spec.mjs, editions: [lite, full], codes: [HFS_PEER_INTEGRATION_MISSING]}
|
|
2092
2218
|
- id: R112
|
|
2093
2219
|
code: "BE_INTEGRATION_SPEC_MISSING"
|
|
2094
2220
|
editionWhy: "ruling:R212/case-3 keeps lite outside the full test world; ruling:lite-production-swarm amends hosting and ruling:lite-contract-specs permits contract specs while preserving that e2e boundary. R284 owns lite's integration proof lane; this rule judges provider module, error-code and outage proofs through the full world."
|
|
2095
2221
|
docs: [docs/quality-bar.md#r112]
|
|
2096
2222
|
templateNa: "Provider-specific module registration, refusal mapping and outage scenarios must be authored for each integration; the app scaffold has no provider-specific integration proof to generate."
|
|
2097
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2098
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2099
2223
|
law: "Every integration of a back end (`src/modules/integrations/<provider>/` holding `<provider>.config.ts`) has at least one `src/tests/integration/<provider>/*.integration-spec.ts` that, read as a syntax tree, calls `useTestWorld({ modules })` with a factory registering the integration's own module (`<Provider>Module.register`, imported from the integration folder; an inline array, a local const or an exported const of another file), references the ErrorCode enum the integration exports, and drives an outage through the world (`world.infra.<service>.cut|latency|during|connection`, `world.fake.<name>.failNext`, `world.apps.<peer>.during`, `world.interruptDatabase`); the finding sits on the integration folder."
|
|
2100
2224
|
kinds: [check]
|
|
2101
2225
|
gates: [land, ci]
|
|
@@ -2103,21 +2227,29 @@ rules:
|
|
|
2103
2227
|
editions: [full]
|
|
2104
2228
|
enforcers:
|
|
2105
2229
|
- {kind: hfs, id: integration-specs, at: scripts/hfs/rules/integration-specs.mjs}
|
|
2106
|
-
|
|
2230
|
+
proves:
|
|
2231
|
+
- {path: packages/hfs/src/hfs-repo-scripts-rules.spec.mjs, editions: [full], codes: [BE_INTEGRATION_SPEC_MISSING]}
|
|
2232
|
+
exemplifiedBy:
|
|
2233
|
+
- {path: packages/hfs/src/hfs-repo-scripts-rules.spec.mjs, editions: [full], codes: [BE_INTEGRATION_SPEC_MISSING]}
|
|
2234
|
+
witness:
|
|
2235
|
+
- {path: packages/hfs/src/hfs-repo-scripts-rules.spec.mjs, editions: [full], codes: [BE_INTEGRATION_SPEC_MISSING]}
|
|
2107
2236
|
- id: R113
|
|
2108
2237
|
code: "FE_GRAPHQL_CONTRACT"
|
|
2109
2238
|
editions: [lite, full]
|
|
2110
2239
|
docs: [docs/legacy-contract-rule-coverage.md#r113]
|
|
2111
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2112
|
-
exemplifiedBy:
|
|
2113
|
-
- {path: packages/hfs/templates/fe/table/graphql/query.ts.tpl, editions: [lite, full]}
|
|
2114
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2115
2240
|
law: "Every GraphQL operation a front end keeps in a `.graphql` file under `fe/` is one its back end serves: it is judged against the contract snapshot (`be/contracts/<service>/schema.graphql`) whose root type declares its first root field, and every selected field, argument and input field must be declared there, every required argument and required input field given, every variable passed with the argument's named type, every leaf selected without and every object with a selection, and every declared variable used; a root field no contract declares is a finding too."
|
|
2116
2241
|
kinds: [check]
|
|
2117
2242
|
gates: [land, ci]
|
|
2118
2243
|
failureCodes: ["FE_GRAPHQL_CONTRACT"]
|
|
2119
2244
|
enforcers:
|
|
2120
2245
|
- {kind: hfs, id: fe-contract-documents, at: scripts/hfs/rules/fe-contract-documents.mjs}
|
|
2246
|
+
proves:
|
|
2247
|
+
- {path: packages/hfs/src/hfs-fe-contract-documents-coverage.spec.mjs, editions: [lite, full]}
|
|
2248
|
+
exemplifiedBy:
|
|
2249
|
+
- {path: packages/hfs/templates/fe/table/graphql/query.ts.tpl, editions: [lite, full]}
|
|
2250
|
+
- {path: packages/hfs/src/hfs-fe-contract-documents-coverage.spec.mjs, editions: [lite, full]}
|
|
2251
|
+
witness:
|
|
2252
|
+
- {path: packages/hfs/src/hfs-fe-contract-documents-coverage.spec.mjs, editions: [lite, full], codes: [FE_GRAPHQL_CONTRACT]}
|
|
2121
2253
|
- id: R114
|
|
2122
2254
|
code: "RT_EXTERNAL_OWNER"
|
|
2123
2255
|
law: "In the runtime repository a process, the network, SQLite or an external binary is reached only by its owner in ruleParams.runtime.infraOwners of knowledge/hfs/runtime-slots.yaml: an owned module specifier, global or spawned program word is used only by the files of scripts/api/<system> or engine/db that the map names."
|
|
@@ -2130,9 +2262,6 @@ rules:
|
|
|
2130
2262
|
editions: [lite, full]
|
|
2131
2263
|
docs: [docs/legacy-runtime-shape.md#external-owner]
|
|
2132
2264
|
templateNa: "Runtime repository source ownership and layout are not scaffolded by managed application templates."
|
|
2133
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2134
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2135
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
2136
2265
|
- id: R115
|
|
2137
2266
|
code: "RT_TIER_DIRECTION"
|
|
2138
2267
|
law: "Every relative import between two runtime owners goes from a tier to a tier its mayImport lists in tiers.runtime of knowledge/hfs/runtime-slots.yaml; owner cycles are ARCH_OWNER_CYCLE."
|
|
@@ -2145,9 +2274,6 @@ rules:
|
|
|
2145
2274
|
editions: [lite, full]
|
|
2146
2275
|
docs: [docs/legacy-runtime-shape.md#tier-direction]
|
|
2147
2276
|
templateNa: "Runtime repository source ownership and layout are not scaffolded by managed application templates."
|
|
2148
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2149
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2150
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
2151
2277
|
- id: R116
|
|
2152
2278
|
code: "RT_BASE_IMPURE"
|
|
2153
2279
|
law: "The runtime base tier (the engine foundation and scripts/lib) never writes the filesystem and reads process.env only in a declared seam of ruleParams.runtime.baseEnvSeams."
|
|
@@ -2160,9 +2286,6 @@ rules:
|
|
|
2160
2286
|
editions: [lite, full]
|
|
2161
2287
|
docs: [docs/legacy-runtime-shape.md#base-purity]
|
|
2162
2288
|
templateNa: "Runtime repository source ownership and layout are not scaffolded by managed application templates."
|
|
2163
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2164
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2165
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
2166
2289
|
- id: R117
|
|
2167
2290
|
code: "RT_API_SHAPE"
|
|
2168
2291
|
law: "A call file of scripts/api/<system>/ exports exactly one function named in camelCase after the file; only the files of its own system import its lib.mjs; no api system imports another; a system with a calls contract has a call file only for a call id the contract declares."
|
|
@@ -2175,9 +2298,6 @@ rules:
|
|
|
2175
2298
|
editions: [lite, full]
|
|
2176
2299
|
docs: [docs/legacy-runtime-shape.md#api-shape]
|
|
2177
2300
|
templateNa: "Runtime repository source ownership and layout are not scaffolded by managed application templates."
|
|
2178
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2179
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2180
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
2181
2301
|
- id: R118
|
|
2182
2302
|
code: "RT_SPEC_PLACEMENT"
|
|
2183
2303
|
law: "No runtime tests in .claude (owner ruling no-runtime-specs, 2026-10-17): a spec or test file is allowed only beside its package source as <name>.spec.* (never .test.), under examples/, or as a declared file of the scaffold e2e (slot runtime.e2e); any other tracked spec, tests/** included, is refused."
|
|
@@ -2190,9 +2310,6 @@ rules:
|
|
|
2190
2310
|
editions: [lite, full]
|
|
2191
2311
|
docs: [docs/legacy-runtime-shape.md#spec-placement]
|
|
2192
2312
|
templateNa: "Runtime repository source ownership and layout are not scaffolded by managed application templates."
|
|
2193
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2194
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2195
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
2196
2313
|
- id: R119
|
|
2197
2314
|
code: "RT_SOURCE_NAME"
|
|
2198
2315
|
law: "A runtime source file is named <kebab-name>.mjs, never a one-off of ruleParams.runtime.oneOffNames (_*, tmp-*, fix-*, *-backfill, migrate-*, *-old, *.bak*), and its basename is unique inside its tier except lib.mjs and index.mjs."
|
|
@@ -2205,15 +2322,10 @@ rules:
|
|
|
2205
2322
|
editions: [lite, full]
|
|
2206
2323
|
docs: [docs/legacy-runtime-shape.md#source-name]
|
|
2207
2324
|
templateNa: "Runtime repository source ownership and layout are not scaffolded by managed application templates."
|
|
2208
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2209
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2210
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
2211
2325
|
- id: R121
|
|
2212
2326
|
editions: [lite, full]
|
|
2213
2327
|
docs: [docs/legacy-runtime-state.md#generated-runtime-output]
|
|
2214
2328
|
templateNa: "Generated runtime copies and the tracked runtime repository are not application scaffold surfaces."
|
|
2215
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2216
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2217
2329
|
code: "RT_GENERATED_DRIFT"
|
|
2218
2330
|
law: "A generated root of ruleParams.runtime.generated is git-ignored output of its declared generatedBy: the repo's check regenerates every root, the runtime copies (packages/hfs/runtime, packages/eslint/be/runtime, packages/eslint/fe/runtime) are judged equal to what scripts/hfs/sync-runtime.mjs writes from the single source, and no git-tracked path lies under a generated root."
|
|
2219
2331
|
scope: runtime
|
|
@@ -2223,7 +2335,6 @@ rules:
|
|
|
2223
2335
|
enforcers:
|
|
2224
2336
|
- {kind: runtime, id: generated-drift, at: scripts/hfs/sync-runtime.mjs}
|
|
2225
2337
|
- {kind: runtime, id: generated-untracked, at: scripts/hfs/runtime-rules/generated-untracked.mjs}
|
|
2226
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
2227
2338
|
- id: R122
|
|
2228
2339
|
code: "RT_CITED_PATH_MISSING"
|
|
2229
2340
|
law: "A runtime path cited by live prose or contracts (modules, docs, skills, knowledge, CONTEXT.md, README.md, CONTRIBUTING.md, init, the ui docs) exists; history (a changelog, a benchmark file) is not read."
|
|
@@ -2236,9 +2347,6 @@ rules:
|
|
|
2236
2347
|
editions: [lite, full]
|
|
2237
2348
|
docs: [docs/legacy-runtime-state.md#cited-runtime-paths]
|
|
2238
2349
|
templateNa: "Runtime repository integrity is authored in the runtime manifest and source tree; application scaffolds do not contain this surface."
|
|
2239
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2240
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2241
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
2242
2350
|
- id: R124
|
|
2243
2351
|
code: "RT_PINNED_PATH_MOVED"
|
|
2244
2352
|
law: "A pinned path of ruleParams.runtime.pinned (persisted outside git) exists."
|
|
@@ -2251,9 +2359,6 @@ rules:
|
|
|
2251
2359
|
editions: [lite, full]
|
|
2252
2360
|
docs: [docs/legacy-runtime-state.md#pinned-runtime-paths]
|
|
2253
2361
|
templateNa: "Runtime repository integrity is authored in the runtime manifest and source tree; application scaffolds do not contain this surface."
|
|
2254
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2255
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2256
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
2257
2362
|
- id: R125
|
|
2258
2363
|
code: "RT_NODE_MODULES_LINK"
|
|
2259
2364
|
law: "No runtime source creates a junction or a symlink for a node_modules folder, through node:fs (symlink, symlinkSync, directly or through a local wrapper) or a spawned link command (mklink /J or /D, New-Item -ItemType Junction or SymbolicLink, ln -s): every checkout installs its own dependencies with a real npm ci from the cache."
|
|
@@ -2266,9 +2371,6 @@ rules:
|
|
|
2266
2371
|
editions: [lite, full]
|
|
2267
2372
|
docs: [docs/legacy-runtime-state.md#dependency-directories]
|
|
2268
2373
|
templateNa: "Runtime repository integrity is authored in the runtime manifest and source tree; application scaffolds do not contain this surface."
|
|
2269
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2270
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2271
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
2272
2374
|
- id: R126
|
|
2273
2375
|
code: "RT_CONTROL_CHARACTER"
|
|
2274
2376
|
law: "Tracked text source of the runtime (*.mjs, *.cjs, *.js, *.ts, *.tsx, *.yaml, *.yml, *.md, *.json outside the generated copies) holds no raw control character (U+0000 to U+001F except tab, LF and CR, and U+007F); the character is written as its escape."
|
|
@@ -2281,9 +2383,6 @@ rules:
|
|
|
2281
2383
|
editions: [lite, full]
|
|
2282
2384
|
docs: [docs/legacy-runtime-paths.md#r126]
|
|
2283
2385
|
templateNa: "Runtime tracked-source hygiene is checked in the runtime repository; application scaffolds do not generate this surface."
|
|
2284
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2285
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2286
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
2287
2386
|
- id: R127
|
|
2288
2387
|
code: "RT_ABSOLUTE_PATH"
|
|
2289
2388
|
law: "No tracked file of the runtime holds a hard-coded absolute host path: a drive-letter path, a user-profile path (/Users/<name>/, /home/<name>/) or an expanded AppData path. Paths resolve from the runtime root, os.tmpdir(), the config or a state-root helper, and a spec builds every path and prompt fixture from its temp dir; %LOCALAPPDATA% as an unexpanded name is clean. In source the rule reads string and template literals and comments through the syntax tree (a URL and a generic drive-pattern regular expression are not paths); in yaml, json and md it reads line text."
|
|
@@ -2296,9 +2395,6 @@ rules:
|
|
|
2296
2395
|
editions: [lite, full]
|
|
2297
2396
|
docs: [docs/legacy-runtime-paths.md#r127]
|
|
2298
2397
|
templateNa: "Runtime tracked-source hygiene is checked in the runtime repository; application scaffolds do not generate this surface."
|
|
2299
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2300
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2301
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
2302
2398
|
- id: R141
|
|
2303
2399
|
code: "BE_COOKIE_ATTRIBUTES"
|
|
2304
2400
|
law: "A cookie a back-end door writes through the response of Express or Fastify (`cookie`, `setCookie`) states `httpOnly: true`, `secure: true` and `sameSite` `lax` or `strict` in options typed with those literals, and `Set-Cookie` is never written as a header (`setHeader`, `append`, `header`); the call is recognised by where its signature is declared, never by the receiver's name."
|
|
@@ -2319,8 +2415,7 @@ rules:
|
|
|
2319
2415
|
- {path: packages/eslint/be/cookies-coverage.spec.mjs, edition: full, codes: ["BE_COOKIE_ATTRIBUTES"]}
|
|
2320
2416
|
- id: R142
|
|
2321
2417
|
code: "BE_AMBIENT_ID"
|
|
2322
|
-
law: "`randomUUID` of Node's crypto (named, namespace or global), the `v1`, `v4`, `v6` and `v7` generators of `uuid`, `nanoid` and `ulid` are used only inside `platform/ids`, specs
|
|
2323
|
-
amendedBy: [owner:ambient-id-test-world-exemption]
|
|
2418
|
+
law: "`randomUUID` of Node's crypto (named, namespace or global), the `v1`, `v4`, `v6` and `v7` generators of `uuid`, `nanoid` and `ulid` are used only inside `platform/ids`, specs and the test world included; code asks the injected `Ids` port (`ids.next()`) and specs use `fakeIds()`."
|
|
2324
2419
|
kinds: [lint, codemod]
|
|
2325
2420
|
gates: [pre-commit, settle, land, ci]
|
|
2326
2421
|
failureCodes: ["BE_AMBIENT_ID"]
|
|
@@ -2328,7 +2423,7 @@ rules:
|
|
|
2328
2423
|
- {kind: eslint-be, id: no-ambient-id}
|
|
2329
2424
|
editions: [lite, full]
|
|
2330
2425
|
docs: [docs/quality-bar.md#r142]
|
|
2331
|
-
templateNa: "Ambient identifier sources are a negative lint constraint; the spec exercises owned
|
|
2426
|
+
templateNa: "Ambient identifier sources are a negative lint constraint; the spec exercises owned and injected identifiers rather than a scaffolded surface."
|
|
2332
2427
|
proves: [packages/eslint/be/ambient-id.spec.mjs]
|
|
2333
2428
|
exemplifiedBy:
|
|
2334
2429
|
- {path: packages/eslint/be/ambient-id.spec.mjs, editions: [lite, full], codes: [BE_AMBIENT_ID]}
|
|
@@ -2345,10 +2440,14 @@ rules:
|
|
|
2345
2440
|
- {kind: hfs, id: monorepo, at: scripts/hfs/rules/monorepo.mjs}
|
|
2346
2441
|
editions: [lite, full]
|
|
2347
2442
|
docs: [docs/legacy-monorepo-rules.md#r143-root-workspace-manifest]
|
|
2348
|
-
|
|
2443
|
+
proves:
|
|
2444
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_WORKSPACES]}
|
|
2349
2445
|
exemplifiedBy:
|
|
2350
2446
|
- {path: packages/hfs/templates/app/task-graph/turbo.json, editions: [lite, full]}
|
|
2351
|
-
|
|
2447
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_WORKSPACES]}
|
|
2448
|
+
witness:
|
|
2449
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, edition: lite, codes: [HFS_MONO_WORKSPACES]}
|
|
2450
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, edition: full, codes: [HFS_MONO_WORKSPACES]}
|
|
2352
2451
|
- id: R144
|
|
2353
2452
|
code: "HFS_MONO_FE_WORKSPACE"
|
|
2354
2453
|
law: "Every fe app `fe/apps/<app>` is an npm workspace: its `package.json` is named `@<project>/<app>`, is private, declares its own runtime dependencies and has exactly the scripts `build: next build`, `dev: next dev`, `lint: starci app lint --workspace .`, `start: next start` and `typecheck: tsc --noEmit`; every fe package `fe/packages/<pkg>` is private with `build`, `typecheck` and the same workspace `lint` script."
|
|
@@ -2359,52 +2458,68 @@ rules:
|
|
|
2359
2458
|
- {kind: hfs, id: monorepo, at: scripts/hfs/rules/monorepo.mjs}
|
|
2360
2459
|
editions: [lite, full]
|
|
2361
2460
|
docs: [docs/legacy-monorepo-rules.md#r144-front-end-workspace-manifests]
|
|
2362
|
-
|
|
2461
|
+
proves:
|
|
2462
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_FE_WORKSPACE]}
|
|
2363
2463
|
exemplifiedBy:
|
|
2364
2464
|
- {path: packages/hfs/templates/fe/app/package.json.tpl, editions: [lite, full]}
|
|
2365
|
-
|
|
2465
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_FE_WORKSPACE]}
|
|
2466
|
+
witness:
|
|
2467
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, edition: lite, codes: [HFS_MONO_FE_WORKSPACE]}
|
|
2468
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, edition: full, codes: [HFS_MONO_FE_WORKSPACE]}
|
|
2366
2469
|
- id: R145
|
|
2367
2470
|
code: "HFS_MONO_NEST_PROJECTS"
|
|
2368
2471
|
editions: [lite, full]
|
|
2369
2472
|
docs: [docs/legacy-monorepo-rules.md#r145-nest-monorepo-projects]
|
|
2370
2473
|
templateNa: "be/nest-cli.json is generated programmatically by nestCli(app) in packages/hfs/scaffold/app.mjs, rather than from a managed template file."
|
|
2371
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2372
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2373
2474
|
law: "The back end is a Nest monorepo of `be/apps/<app>`, even with one service: `be/nest-cli.json` is `\"monorepo\": true`, its default project (`root`, `sourceRoot`) is an api app, and its `projects` are exactly the be apps hfs.json declares, each `{\"type\": \"application\", \"root\": \"apps/<app>\", \"sourceRoot\": \"apps/<app>/src\"}`."
|
|
2374
2475
|
kinds: [check]
|
|
2375
2476
|
gates: [settle, land, ci]
|
|
2376
2477
|
failureCodes: ["HFS_MONO_NEST_PROJECTS"]
|
|
2377
2478
|
enforcers:
|
|
2378
2479
|
- {kind: hfs, id: monorepo, at: scripts/hfs/rules/monorepo.mjs}
|
|
2379
|
-
|
|
2480
|
+
proves:
|
|
2481
|
+
- {path: packages/hfs/src/hfs-mono-nest-projects-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_NEST_PROJECTS]}
|
|
2482
|
+
exemplifiedBy:
|
|
2483
|
+
- {path: packages/hfs/src/hfs-mono-nest-projects-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_NEST_PROJECTS]}
|
|
2484
|
+
witness:
|
|
2485
|
+
- {path: packages/hfs/src/hfs-mono-nest-projects-coverage.spec.mjs, edition: lite, codes: [HFS_MONO_NEST_PROJECTS]}
|
|
2486
|
+
- {path: packages/hfs/src/hfs-mono-nest-projects-coverage.spec.mjs, edition: full, codes: [HFS_MONO_NEST_PROJECTS]}
|
|
2380
2487
|
- id: R146
|
|
2381
2488
|
code: "HFS_MONO_WORKSPACE_DEP"
|
|
2382
2489
|
editions: [lite, full]
|
|
2383
2490
|
docs: [docs/architecture.md#workspace-dependency-declarations]
|
|
2384
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2385
2491
|
templateNa: "Sibling workspace dependencies depend on the product's imports; no scaffold can declare that product-specific dependency graph."
|
|
2386
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2387
2492
|
law: "An fe workspace declares every package its files import (read with TypeScript's import pre-processor, its tsconfig path aliases excluded) in its own `package.json`, a sibling workspace package at `\"*\"`; the app root `package.json` never declares a workspace package."
|
|
2388
2493
|
kinds: [check]
|
|
2389
2494
|
gates: [settle, land, ci]
|
|
2390
2495
|
failureCodes: ["HFS_MONO_WORKSPACE_DEP"]
|
|
2391
2496
|
enforcers:
|
|
2392
2497
|
- {kind: hfs, id: monorepo, at: scripts/hfs/rules/monorepo.mjs}
|
|
2393
|
-
|
|
2498
|
+
proves:
|
|
2499
|
+
- {path: packages/hfs/src/r146-workspace-version-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_WORKSPACE_DEP]}
|
|
2500
|
+
exemplifiedBy:
|
|
2501
|
+
- {path: packages/hfs/src/r146-workspace-version-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_WORKSPACE_DEP]}
|
|
2502
|
+
witness:
|
|
2503
|
+
- {path: packages/hfs/src/r146-workspace-version-coverage.spec.mjs, edition: lite, codes: [HFS_MONO_WORKSPACE_DEP]}
|
|
2504
|
+
- {path: packages/hfs/src/r146-workspace-version-coverage.spec.mjs, edition: full, codes: [HFS_MONO_WORKSPACE_DEP]}
|
|
2394
2505
|
- id: R147
|
|
2395
2506
|
code: "BE_CLI_REQUIRED"
|
|
2396
2507
|
editions: [lite, full]
|
|
2397
2508
|
docs: [docs/backend-cli.md#back-end-cli-rules]
|
|
2398
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2399
|
-
exemplifiedBy:
|
|
2400
|
-
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
2401
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2402
2509
|
law: "Every one-off action of a back end lives in ONE app, `be/apps/cli` (kind cli, named cli): a back end that declares a connection (its migrations run as `cli migrate run`) or tracks a command under `src/features/cli/` declares exactly that app, and tracks its image `be/apps/cli/Dockerfile` (one image, run as `cli <group> <command>`)."
|
|
2403
2510
|
kinds: [check]
|
|
2404
2511
|
gates: [settle, land, ci]
|
|
2405
2512
|
failureCodes: ["BE_CLI_REQUIRED"]
|
|
2406
2513
|
enforcers:
|
|
2407
2514
|
- {kind: hfs, id: cli, at: scripts/hfs/rules/cli.mjs}
|
|
2515
|
+
proves:
|
|
2516
|
+
- {path: packages/hfs/src/hfs-cli-coverage.spec.mjs, editions: [lite, full], codes: [BE_CLI_REQUIRED]}
|
|
2517
|
+
exemplifiedBy:
|
|
2518
|
+
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
2519
|
+
- {path: packages/hfs/src/hfs-cli-coverage.spec.mjs, editions: [lite, full], codes: [BE_CLI_REQUIRED]}
|
|
2520
|
+
witness:
|
|
2521
|
+
- {path: packages/hfs/src/hfs-cli-coverage.spec.mjs, edition: lite, codes: [BE_CLI_REQUIRED]}
|
|
2522
|
+
- {path: packages/hfs/src/hfs-cli-coverage.spec.mjs, edition: full, codes: [BE_CLI_REQUIRED]}
|
|
2408
2523
|
- id: R148
|
|
2409
2524
|
code: "BE_CLI_BOOTSTRAP"
|
|
2410
2525
|
editions: [lite, full]
|
|
@@ -2466,21 +2581,25 @@ rules:
|
|
|
2466
2581
|
code: "BE_EVENT_CLASS_CONTRACT"
|
|
2467
2582
|
editions: [lite, full]
|
|
2468
2583
|
docs: [docs/code-pattern-enforcement.md#backend-event-bus-rules]
|
|
2469
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2470
|
-
exemplifiedBy:
|
|
2471
|
-
- {path: packages/hfs/templates/be/inbox/delivery-recorded.event.ts.tpl, editions: [lite, full]}
|
|
2472
|
-
- {path: packages/hfs/templates/be/inbox/events.json.tpl, editions: [lite, full]}
|
|
2473
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2474
2584
|
law: "Every typed event class `be/src/modules/events/<service>/<event>.event.ts` (one class with literal `static readonly eventName` and `version`, in a file named after its event: dots become dashes) equals an entry of the vendored contract `be/contracts/<service>/events.json` at the same name and version, and every entry of a vendored contract has its class; a class the contract does not list, a version mismatch, a contract entry with no class or a misnamed file is a finding (pattern event-bus)."
|
|
2475
2585
|
kinds: [check, codemod]
|
|
2476
2586
|
gates: [settle, land, ci]
|
|
2477
2587
|
failureCodes: ["BE_EVENT_CLASS_CONTRACT"]
|
|
2478
2588
|
enforcers:
|
|
2479
2589
|
- {kind: hfs, id: event-class-contract, at: scripts/hfs/rules/event-bus.mjs}
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2590
|
+
proves:
|
|
2591
|
+
- {path: packages/hfs/src/hfs-event-class-coverage.spec.mjs, editions: [lite, full]}
|
|
2592
|
+
exemplifiedBy:
|
|
2593
|
+
- {path: packages/hfs/templates/be/inbox/delivery-recorded.event.ts.tpl, editions: [lite, full]}
|
|
2594
|
+
- {path: packages/hfs/templates/be/inbox/events.json.tpl, editions: [lite, full]}
|
|
2595
|
+
- {path: packages/hfs/src/hfs-event-class-coverage.spec.mjs, editions: [lite, full]}
|
|
2596
|
+
witness:
|
|
2597
|
+
- {path: packages/hfs/src/hfs-event-class-coverage.spec.mjs, edition: lite, codes: [BE_EVENT_CLASS_CONTRACT]}
|
|
2598
|
+
- {path: packages/hfs/src/hfs-event-class-coverage.spec.mjs, edition: full, codes: [BE_EVENT_CLASS_CONTRACT]}
|
|
2599
|
+
- id: R152
|
|
2600
|
+
code: "BE_OUTBOX_WRITE_TX"
|
|
2601
|
+
editions: [lite, full]
|
|
2602
|
+
docs: [docs/code-pattern-enforcement.md#backend-event-bus-rules]
|
|
2484
2603
|
proves:
|
|
2485
2604
|
- {path: packages/eslint/be/event-bus-coverage.spec.mjs, editions: [lite, full], codes: [BE_OUTBOX_WRITE_TX]}
|
|
2486
2605
|
exemplifiedBy:
|
|
@@ -2543,16 +2662,20 @@ rules:
|
|
|
2543
2662
|
editionWhy: "each enforcer judges the edition it emits for (pattern-spec-missing returns no findings for lite, lite-proof-lane is lite's emitter), so the split adds lite's emitter and drops no finding; ruling:R212/case-2 (with the Work boundary amended by ruling:R212/case-4) gives lite its integration proof lane while full retains e2e or integration proofs."
|
|
2544
2663
|
docs: [docs/quality-bar.md#r155]
|
|
2545
2664
|
templateNa: "Pattern scenarios depend on application behavior and providers; no universal runnable scenario proof is scaffolded."
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2665
|
+
proves:
|
|
2666
|
+
- {path: packages/hfs/src/hfs-pattern-spec-missing.spec.mjs, editions: [full], codes: [BE_PATTERN_SPEC_MISSING]}
|
|
2667
|
+
- {path: packages/hfs/src/hfs-lite-proof-lane.spec.mjs, editions: [lite], codes: [BE_PATTERN_SPEC_MISSING]}
|
|
2668
|
+
exemplifiedBy:
|
|
2669
|
+
- {path: packages/hfs/src/hfs-pattern-spec-missing.spec.mjs, editions: [full], codes: [BE_PATTERN_SPEC_MISSING]}
|
|
2670
|
+
- {path: packages/hfs/src/hfs-lite-proof-lane.spec.mjs, editions: [lite], codes: [BE_PATTERN_SPEC_MISSING]}
|
|
2671
|
+
witness:
|
|
2672
|
+
- {path: packages/hfs/src/hfs-pattern-spec-missing.spec.mjs, edition: full, codes: [BE_PATTERN_SPEC_MISSING]}
|
|
2673
|
+
- {path: packages/hfs/src/hfs-lite-proof-lane.spec.mjs, edition: lite, codes: [BE_PATTERN_SPEC_MISSING]}
|
|
2549
2674
|
- id: R156
|
|
2550
2675
|
code: "BE_KIND_ISOLATION"
|
|
2551
2676
|
editions: [lite, full]
|
|
2552
2677
|
docs: [docs/code-pattern-enforcement.md#r156-kind-isolation]
|
|
2553
2678
|
templateNa: "Cross-kind imports are a negative architecture constraint; the spec supplies actual owner graphs in both editions."
|
|
2554
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2555
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2556
2679
|
law: "No trigger kind imports another: a feature whose owner slot names one `trigger` (api, webhooks, realtime, saga, reactors, jobs, cli) never imports (static, dynamic, re-export or type-only) a feature of another kind; each kind imports only `modules/*` and only be/apps/* compose features. The kinds meet through the event bus: a domain service publishes `eventBus.publish(event, tx)` and the other kind consumes it. The importing and imported owners are read from the slot view (slot field `trigger`), never from a folder name; the finding replaces BE_FEATURE_IMPORTS_FEATURE when both features name different kinds."
|
|
2557
2680
|
kinds: [lint, design]
|
|
2558
2681
|
gates: [settle, land, ci]
|
|
@@ -2560,7 +2683,11 @@ rules:
|
|
|
2560
2683
|
enforcers:
|
|
2561
2684
|
- {kind: eslint-be, id: kind-isolation}
|
|
2562
2685
|
- {kind: machine, id: tiers, at: scripts/hfs/architecture/tiers.mjs}
|
|
2563
|
-
|
|
2686
|
+
proves: [packages/hfs/src/architecture-kind-isolation-coverage.spec.mjs]
|
|
2687
|
+
exemplifiedBy:
|
|
2688
|
+
- {path: packages/hfs/src/architecture-kind-isolation-coverage.spec.mjs, editions: [lite, full], codes: [BE_KIND_ISOLATION]}
|
|
2689
|
+
witness:
|
|
2690
|
+
- {path: packages/hfs/src/architecture-kind-isolation-coverage.spec.mjs, editions: [lite, full], codes: [BE_KIND_ISOLATION]}
|
|
2564
2691
|
- id: R157
|
|
2565
2692
|
code: "BE_JOB_WRITE_OUTSIDE_OWNER"
|
|
2566
2693
|
editions: [lite, full]
|
|
@@ -2676,68 +2803,81 @@ rules:
|
|
|
2676
2803
|
code: "HFS_SERVICE_PLACEMENT"
|
|
2677
2804
|
editions: [lite, full]
|
|
2678
2805
|
docs: [docs/microservices.md#r163]
|
|
2679
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2680
|
-
exemplifiedBy:
|
|
2681
|
-
- {path: packages/hfs/templates/be/skeleton-lite/apps/api/Dockerfile, edition: lite}
|
|
2682
|
-
- {path: packages/hfs/templates/be/image/api/Dockerfile, edition: full}
|
|
2683
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2684
2806
|
law: "A back-end service lives only at `be/apps/<service>/`: a folder with a `Dockerfile` of its own, or with a `package.json` other than the app root's and those of the fe workspaces (`fe/apps/<app>`, `fe/packages/<pkg>`), outside `be/apps/<service>/` (and outside a front end's `fe/apps/<app>/Dockerfile`) is a second service root and a finding; a service is a Nest app of the one repository that shares the `be/src` libraries and the one package.json, and its image is built from its own Dockerfile."
|
|
2685
2807
|
kinds: [check]
|
|
2686
2808
|
gates: [land, ci]
|
|
2687
2809
|
failureCodes: ["HFS_SERVICE_PLACEMENT"]
|
|
2688
2810
|
enforcers:
|
|
2689
2811
|
- {kind: hfs, id: services-placement, at: scripts/hfs/rules/services.mjs}
|
|
2812
|
+
proves:
|
|
2813
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
2814
|
+
exemplifiedBy:
|
|
2815
|
+
- {path: packages/hfs/templates/be/skeleton-lite/apps/api/Dockerfile, edition: lite}
|
|
2816
|
+
- {path: packages/hfs/templates/be/image/api/Dockerfile, edition: full}
|
|
2817
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
2818
|
+
witness:
|
|
2819
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_SERVICE_PLACEMENT]}
|
|
2820
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, edition: full, codes: [HFS_SERVICE_PLACEMENT]}
|
|
2690
2821
|
- id: R164
|
|
2691
2822
|
code: "HFS_IMAGE_UNPINNED"
|
|
2692
2823
|
editions: [lite, full]
|
|
2693
2824
|
docs: [docs/microservices.md#r164]
|
|
2694
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2695
|
-
exemplifiedBy:
|
|
2696
|
-
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
2697
|
-
- {path: packages/hfs/templates/app/upgrade-full/.starcistacks/application-stacks.yaml, edition: full}
|
|
2698
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2699
2825
|
law: "In a product with more than one service (two or more be apps of kind api or worker) every component `image` of `.starcistacks/application-stacks.yaml` is pinned: a digest (`@sha256:<64 hex>`) or an exact version tag (`x.y.z`, optionally with a suffix); no tag, `latest`, a branch word or a major or minor-only tag is a finding. An own service image is `<repo>/<service>:<x.y.z>`, built from `be/apps/<service>/Dockerfile`; a service the product does not own stays a pinned third-party image."
|
|
2700
2826
|
kinds: [check]
|
|
2701
2827
|
gates: [land, ci]
|
|
2702
2828
|
failureCodes: ["HFS_IMAGE_UNPINNED"]
|
|
2703
2829
|
enforcers:
|
|
2704
2830
|
- {kind: hfs, id: services-image-pins, at: scripts/hfs/rules/services.mjs}
|
|
2831
|
+
proves:
|
|
2832
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
2833
|
+
exemplifiedBy:
|
|
2834
|
+
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
2835
|
+
- {path: packages/hfs/templates/app/upgrade-full/.starcistacks/application-stacks.yaml, edition: full}
|
|
2836
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
2837
|
+
witness:
|
|
2838
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_IMAGE_UNPINNED]}
|
|
2839
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, edition: full, codes: [HFS_IMAGE_UNPINNED]}
|
|
2705
2840
|
- id: R165
|
|
2706
2841
|
code: "HFS_SERVICE_STACK_DECLARATION"
|
|
2707
2842
|
editions: [lite, full]
|
|
2708
2843
|
docs: [docs/microservices.md#r165]
|
|
2709
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2710
|
-
exemplifiedBy:
|
|
2711
|
-
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
2712
|
-
- {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
|
|
2713
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2714
2844
|
law: "Every api or worker app `be/apps/<service>` of a product with more than one service is a `role: service` component in `.starcistacks/application-stacks.yaml`: the component of the same name, or one whose `environments.<env>.deploy.images.<component>.app` names the app."
|
|
2715
2845
|
kinds: [check]
|
|
2716
2846
|
gates: [land, ci]
|
|
2717
2847
|
failureCodes: ["HFS_SERVICE_STACK_DECLARATION"]
|
|
2718
2848
|
enforcers:
|
|
2719
2849
|
- {kind: hfs, id: services-stack-declaration, at: scripts/hfs/rules/services.mjs}
|
|
2850
|
+
proves:
|
|
2851
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
2852
|
+
exemplifiedBy:
|
|
2853
|
+
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
2854
|
+
- {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
|
|
2855
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
2856
|
+
witness:
|
|
2857
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_SERVICE_STACK_DECLARATION]}
|
|
2858
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, edition: full, codes: [HFS_SERVICE_STACK_DECLARATION]}
|
|
2720
2859
|
- id: R166
|
|
2721
2860
|
code: "HFS_EVENT_CONTRACT"
|
|
2722
2861
|
editions: [lite, full]
|
|
2723
2862
|
docs: [docs/microservices.md#r166]
|
|
2724
2863
|
templateNa: "Provider EVENTS and consumer CONSUMES tables are product-specific contracts; the app scaffold has no literal service event table to generate."
|
|
2725
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2726
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2727
2864
|
law: "The async contract between services is vendored under `be/contracts/<service>/events.json` (`starci/event-contract@1`, emitted by `starci app emit` from the literal `EVENTS` table of `be/apps/<service>/src/events.ts`, never written by hand) and equals that table; an event that undoes the step of another declares `compensates: \"<event>\"` and the named event must exist in a contract; a consumer declares what it reads in the literal `CONSUMES` table of `be/apps/<app>/src/consumes.ts` (service, event, version), every entry must exist in the provider's vendored snapshot at the same version, and a missing or stale snapshot, an unknown event or a version mismatch is a finding."
|
|
2728
2865
|
kinds: [check, codemod]
|
|
2729
2866
|
gates: [land, ci]
|
|
2730
2867
|
failureCodes: ["HFS_EVENT_CONTRACT"]
|
|
2731
2868
|
enforcers:
|
|
2732
2869
|
- {kind: hfs, id: services-event-contract, at: scripts/hfs/rules/services.mjs}
|
|
2733
|
-
|
|
2870
|
+
proves:
|
|
2871
|
+
- {path: packages/hfs/src/hfs-event-table-contract.spec.mjs, editions: [lite, full]}
|
|
2872
|
+
exemplifiedBy:
|
|
2873
|
+
- {path: packages/hfs/src/hfs-event-table-contract.spec.mjs, editions: [lite, full]}
|
|
2874
|
+
witness:
|
|
2875
|
+
- {path: packages/hfs/src/hfs-event-table-contract.spec.mjs, editions: [lite, full], codes: [HFS_EVENT_CONTRACT]}
|
|
2734
2876
|
- id: R167
|
|
2735
2877
|
code: "BE_ASYNC_SPEC_MISSING"
|
|
2736
2878
|
editionWhy: "ruling:lite-contract-specs preserves the full-only e2e boundary. R284 owns lite's integration proof lane; this rule requires consumed-event scenarios through the full test world."
|
|
2737
2879
|
docs: [docs/microservices.md#r167]
|
|
2738
2880
|
templateNa: "Consumed-event and compensation scenarios depend on the product's event contracts and effects; the app scaffold has no product-specific asynchronous e2e scenario to generate."
|
|
2739
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2740
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2741
2881
|
law: "Every event an app consumes (an entry of its `consumes.ts`) is named by an e2e spec, a file `be/src/tests/e2e/<area>/*.e2e-spec.ts` that boots the apps through `useTestWorld` (it publishes the event, reads the effect back and redelivers it); when the contract of the event declares `compensates: \"<event>\"` it is a saga step, and a spec naming it also names the compensated event, so the spec drives the whole flow: the step, the failure, then the compensated state."
|
|
2742
2882
|
kinds: [check]
|
|
2743
2883
|
gates: [land, ci]
|
|
@@ -2745,7 +2885,12 @@ rules:
|
|
|
2745
2885
|
editions: [full]
|
|
2746
2886
|
enforcers:
|
|
2747
2887
|
- {kind: hfs, id: services-async-specs, at: scripts/hfs/rules/services.mjs}
|
|
2748
|
-
|
|
2888
|
+
proves:
|
|
2889
|
+
- {path: packages/hfs/src/hfs-microservice-rules.spec.mjs, edition: full}
|
|
2890
|
+
exemplifiedBy:
|
|
2891
|
+
- {path: packages/hfs/src/hfs-microservice-rules.spec.mjs, edition: full}
|
|
2892
|
+
witness:
|
|
2893
|
+
- {path: packages/hfs/src/hfs-microservice-rules.spec.mjs, edition: full}
|
|
2749
2894
|
- id: R168
|
|
2750
2895
|
code: "BE_SERVICE_ISOLATION"
|
|
2751
2896
|
editions: [lite, full]
|
|
@@ -2768,69 +2913,82 @@ rules:
|
|
|
2768
2913
|
code: "BE_SAGA_STEP_COMPENSATION"
|
|
2769
2914
|
editions: [lite, full]
|
|
2770
2915
|
docs: [docs/microservices.md#r169]
|
|
2771
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2772
|
-
exemplifiedBy:
|
|
2773
|
-
- {path: packages/hfs/templates/be/patterns/saga/saga.service.ts.tpl, editions: [lite, full]}
|
|
2774
|
-
- {path: packages/hfs/templates/be/patterns/saga/saga.step.ts.tpl, editions: [lite, full]}
|
|
2775
|
-
- {path: packages/hfs/templates/be/patterns/saga/saga.compensation.ts.tpl, editions: [lite, full]}
|
|
2776
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2777
2916
|
law: "In a product that declares the `saga` pattern (`patterns: [\"saga\"]` in hfs.json sides.be) a saga is the folder `be/src/features/saga/<saga>/` (`<saga>.saga.ts` the orchestrator, `steps/<step>.step.ts`, `compensations/<step>.compensation.ts`): every step has a compensation of the same name and every compensation a step, the orchestrator imports every step and every compensation of its folder, and a folder of steps or compensations has an orchestrator; the folders themselves are slots enabled only by the declared pattern, so an undeclared saga is `HFS_SLOT_NOT_ENABLED`."
|
|
2778
2917
|
kinds: [check]
|
|
2779
2918
|
gates: [land, ci]
|
|
2780
2919
|
failureCodes: ["BE_SAGA_STEP_COMPENSATION"]
|
|
2781
2920
|
enforcers:
|
|
2782
2921
|
- {kind: hfs, id: saga-step-compensation, at: scripts/hfs/rules/saga.mjs}
|
|
2922
|
+
proves:
|
|
2923
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, editions: [lite, full], codes: [BE_SAGA_STEP_COMPENSATION]}
|
|
2924
|
+
exemplifiedBy:
|
|
2925
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.service.ts.tpl, editions: [lite, full]}
|
|
2926
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.step.ts.tpl, editions: [lite, full]}
|
|
2927
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.compensation.ts.tpl, editions: [lite, full]}
|
|
2928
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, editions: [lite, full], codes: [BE_SAGA_STEP_COMPENSATION]}
|
|
2929
|
+
witness:
|
|
2930
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, edition: lite, codes: [BE_SAGA_STEP_COMPENSATION]}
|
|
2931
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, edition: full, codes: [BE_SAGA_STEP_COMPENSATION]}
|
|
2783
2932
|
- id: R170
|
|
2784
2933
|
code: "BE_SAGA_STATE_VERSIONED"
|
|
2785
2934
|
editions: [lite, full]
|
|
2786
2935
|
docs: [docs/microservices.md#r170]
|
|
2787
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2788
|
-
exemplifiedBy:
|
|
2789
|
-
- {path: packages/hfs/templates/be/patterns/saga/saga.service.ts.tpl, editions: [lite, full]}
|
|
2790
|
-
- {path: packages/hfs/templates/be/patterns/saga/saga.state.ts.tpl, editions: [lite, full]}
|
|
2791
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2792
2936
|
law: "Every saga orchestrator has `<saga>.saga-state.ts` beside it, whose exported state type declares `status` and `version: number`, and imports the fenced store of `platform/saga`: the persisted state of a run moves only through the store, every transition naming the version it read, so a zombie delivery cannot move a run twice."
|
|
2793
2937
|
kinds: [check]
|
|
2794
2938
|
gates: [land, ci]
|
|
2795
2939
|
failureCodes: ["BE_SAGA_STATE_VERSIONED"]
|
|
2796
2940
|
enforcers:
|
|
2797
2941
|
- {kind: hfs, id: saga-state-versioned, at: scripts/hfs/rules/saga.mjs}
|
|
2942
|
+
proves:
|
|
2943
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, editions: [lite, full], codes: [BE_SAGA_STATE_VERSIONED]}
|
|
2944
|
+
exemplifiedBy:
|
|
2945
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.service.ts.tpl, editions: [lite, full]}
|
|
2946
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.state.ts.tpl, editions: [lite, full]}
|
|
2947
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, editions: [lite, full], codes: [BE_SAGA_STATE_VERSIONED]}
|
|
2948
|
+
witness:
|
|
2949
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, edition: lite, codes: [BE_SAGA_STATE_VERSIONED]}
|
|
2950
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, edition: full, codes: [BE_SAGA_STATE_VERSIONED]}
|
|
2798
2951
|
- id: R171
|
|
2799
2952
|
code: "BE_SAGA_EVENT_CONTRACT"
|
|
2800
2953
|
editions: [lite, full]
|
|
2801
2954
|
docs: [docs/microservices.md#r171]
|
|
2802
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2803
|
-
exemplifiedBy:
|
|
2804
|
-
- {path: packages/hfs/templates/be/patterns/saga/saga.step.ts.tpl, editions: [lite, full]}
|
|
2805
|
-
- {path: packages/hfs/templates/be/patterns/saga/saga.compensation.ts.tpl, editions: [lite, full]}
|
|
2806
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2807
2955
|
law: "A saga step and a saga compensation each name their event (`readonly event = \"<name>\"`), both events are declared in a vendored contract (`be/contracts/<service>/events.json`), and the contract of the compensation's event declares `compensates: \"<event of the step of the same name>\"`."
|
|
2808
2956
|
kinds: [check]
|
|
2809
2957
|
gates: [land, ci]
|
|
2810
2958
|
failureCodes: ["BE_SAGA_EVENT_CONTRACT"]
|
|
2811
2959
|
enforcers:
|
|
2812
2960
|
- {kind: hfs, id: saga-event-contract, at: scripts/hfs/rules/saga.mjs}
|
|
2961
|
+
proves:
|
|
2962
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, editions: [lite, full], codes: [BE_SAGA_EVENT_CONTRACT]}
|
|
2963
|
+
exemplifiedBy:
|
|
2964
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.step.ts.tpl, editions: [lite, full]}
|
|
2965
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.compensation.ts.tpl, editions: [lite, full]}
|
|
2966
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, editions: [lite, full], codes: [BE_SAGA_EVENT_CONTRACT]}
|
|
2967
|
+
witness:
|
|
2968
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, edition: lite, codes: [BE_SAGA_EVENT_CONTRACT]}
|
|
2969
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, edition: full, codes: [BE_SAGA_EVENT_CONTRACT]}
|
|
2813
2970
|
- id: R172
|
|
2814
2971
|
code: "BE_SAGA_CONSUMER_DEDUPE"
|
|
2815
2972
|
editions: [lite, full]
|
|
2816
2973
|
docs: [docs/microservices.md#r172]
|
|
2817
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2818
|
-
exemplifiedBy:
|
|
2819
|
-
- {path: packages/hfs/templates/be/patterns/saga/saga.done.consumer.ts.tpl, editions: [lite, full]}
|
|
2820
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2821
2974
|
law: "A consumer of a saga (`be/src/features/saga/<saga>/transport/message/<event>.consumer.ts`) passes the id of the delivery on (`message.eventId`) to the command it dispatches: the saga takes every event through the inbox (R80), so the consumer must hand it the dedupe key."
|
|
2822
2975
|
kinds: [check]
|
|
2823
2976
|
gates: [land, ci]
|
|
2824
2977
|
failureCodes: ["BE_SAGA_CONSUMER_DEDUPE"]
|
|
2825
2978
|
enforcers:
|
|
2826
2979
|
- {kind: hfs, id: saga-consumer-dedupe, at: scripts/hfs/rules/saga.mjs}
|
|
2980
|
+
proves:
|
|
2981
|
+
- {path: packages/hfs/src/hfs-saga-consumer-dedupe.spec.mjs, editions: [lite, full]}
|
|
2982
|
+
exemplifiedBy:
|
|
2983
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.done.consumer.ts.tpl, editions: [lite, full]}
|
|
2984
|
+
- {path: packages/hfs/src/hfs-saga-consumer-dedupe.spec.mjs, editions: [lite, full]}
|
|
2985
|
+
witness:
|
|
2986
|
+
- {path: packages/hfs/src/hfs-saga-consumer-dedupe.spec.mjs, editions: [lite, full], codes: [BE_SAGA_CONSUMER_DEDUPE]}
|
|
2827
2987
|
- id: R173
|
|
2828
2988
|
code: "BE_SAGA_E2E_MISSING"
|
|
2829
2989
|
editionWhy: "ruling:lite-contract-specs preserves the full-only e2e boundary. R284 owns lite's integration proof lane; this rule requires compensation fault scenarios through the full test world."
|
|
2830
2990
|
docs: [docs/microservices.md#r173]
|
|
2831
2991
|
templateNa: "Compensation events and injected-fault scenarios depend on the product's saga; the app scaffold has no product-specific compensation e2e scenario to generate."
|
|
2832
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2833
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2834
2992
|
law: "Every compensation path of a saga has an e2e spec (`be/src/tests/e2e/<area>/*.e2e-spec.ts` through `useTestWorld`) that names the event of the compensation and injects a failure through the world (an outage of an infra service or an app with `during`, `cut` or `latency`, a fake's `failNext`, `interruptDatabase`): the compensation is proven under a fault, not only on the happy flow."
|
|
2835
2993
|
kinds: [check]
|
|
2836
2994
|
gates: [land, ci]
|
|
@@ -2838,7 +2996,12 @@ rules:
|
|
|
2838
2996
|
editions: [full]
|
|
2839
2997
|
enforcers:
|
|
2840
2998
|
- {kind: hfs, id: saga-e2e, at: scripts/hfs/rules/saga.mjs}
|
|
2841
|
-
|
|
2999
|
+
proves:
|
|
3000
|
+
- {path: packages/hfs/src/hfs-saga-rules.spec.mjs, edition: full}
|
|
3001
|
+
exemplifiedBy:
|
|
3002
|
+
- {path: packages/hfs/src/hfs-saga-rules.spec.mjs, edition: full}
|
|
3003
|
+
witness:
|
|
3004
|
+
- {path: packages/hfs/src/hfs-saga-rules.spec.mjs, edition: full}
|
|
2842
3005
|
- id: R174
|
|
2843
3006
|
code: "BE_CONTEXT_OWNER"
|
|
2844
3007
|
editions: [lite, full]
|
|
@@ -2899,8 +3062,6 @@ rules:
|
|
|
2899
3062
|
code: "BE_CONTRACT_BREAKING"
|
|
2900
3063
|
editions: [lite, full]
|
|
2901
3064
|
docs: [docs/microservices.md#r177]
|
|
2902
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2903
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2904
3065
|
templateNa: "Published event-contract pins are service-owned release snapshots, not scaffolded files."
|
|
2905
3066
|
law: "An event contract evolves only additively: `be/contracts/<service>/events.json` against its pinned previous copy `events.pin.json` keeps every event, stream, version, payload field and type, adds only optional fields, and a breaking change is a new `<event>.v2` key."
|
|
2906
3067
|
kinds: [check]
|
|
@@ -2908,7 +3069,13 @@ rules:
|
|
|
2908
3069
|
failureCodes: ["BE_CONTRACT_BREAKING"]
|
|
2909
3070
|
enforcers:
|
|
2910
3071
|
- {kind: hfs, id: contract-compat, at: scripts/hfs/rules/contract-compat.mjs}
|
|
2911
|
-
|
|
3072
|
+
proves:
|
|
3073
|
+
- {path: packages/hfs/src/hfs-contract-compat-coverage.spec.mjs, editions: [lite, full], codes: [BE_CONTRACT_BREAKING]}
|
|
3074
|
+
exemplifiedBy:
|
|
3075
|
+
- {path: packages/hfs/src/hfs-contract-compat-coverage.spec.mjs, editions: [lite, full], codes: [BE_CONTRACT_BREAKING]}
|
|
3076
|
+
witness:
|
|
3077
|
+
- {path: packages/hfs/src/hfs-contract-compat-coverage.spec.mjs, edition: lite, codes: [BE_CONTRACT_BREAKING]}
|
|
3078
|
+
- {path: packages/hfs/src/hfs-contract-compat-coverage.spec.mjs, edition: full, codes: [BE_CONTRACT_BREAKING]}
|
|
2912
3079
|
- id: R178
|
|
2913
3080
|
code: "BE_CONTEXT_PLATFORM_TABLES"
|
|
2914
3081
|
editions: [lite, full]
|
|
@@ -2931,30 +3098,38 @@ rules:
|
|
|
2931
3098
|
code: "BE_KIND_DECLARATION"
|
|
2932
3099
|
editions: [lite, full]
|
|
2933
3100
|
docs: [docs/microservices.md#r179]
|
|
2934
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2935
|
-
exemplifiedBy:
|
|
2936
|
-
- {path: packages/hfs/templates/be/patterns/jobs/job.processor.ts.tpl, editions: [lite, full]}
|
|
2937
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2938
3101
|
law: "`hfs.json` `sides.be.kinds` lists exactly the trigger kinds (api, webhooks, realtime, saga, reactors, jobs, cli) the back end uses: a kind in use that is not declared, a declared kind with no feature, a declared kind whose patterns (`ruleParams.be.kindPatterns`, e.g. jobs needs fenced-job and queue) are missing from `sides.be.patterns`, and a declared kind whose platform capabilities (the tier-platform slots naming those patterns) are not tracked are each a finding. A kind is declared only when it is used; `starci app add <noun> <name>` creates the first member, the platform capabilities it needs and the registration."
|
|
2939
3102
|
kinds: [check]
|
|
2940
3103
|
gates: [settle, land, ci]
|
|
2941
3104
|
failureCodes: ["BE_KIND_DECLARATION"]
|
|
2942
3105
|
enforcers:
|
|
2943
3106
|
- {kind: hfs, id: kind-declaration, at: scripts/hfs/rules/kinds.mjs}
|
|
3107
|
+
proves:
|
|
3108
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, editions: [lite, full], codes: [BE_KIND_DECLARATION]}
|
|
3109
|
+
exemplifiedBy:
|
|
3110
|
+
- {path: packages/hfs/templates/be/patterns/jobs/job.processor.ts.tpl, editions: [lite, full]}
|
|
3111
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, editions: [lite, full], codes: [BE_KIND_DECLARATION]}
|
|
3112
|
+
witness:
|
|
3113
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, edition: lite, codes: [BE_KIND_DECLARATION]}
|
|
3114
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, edition: full, codes: [BE_KIND_DECLARATION]}
|
|
2944
3115
|
- id: R180
|
|
2945
3116
|
code: "BE_KIND_EMPTY"
|
|
2946
3117
|
editions: [lite, full]
|
|
2947
3118
|
docs: [docs/microservices.md#r180]
|
|
2948
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
2949
|
-
exemplifiedBy:
|
|
2950
|
-
- {path: packages/hfs/templates/be/patterns/jobs/job.processor.ts.tpl, editions: [lite, full]}
|
|
2951
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
2952
3119
|
law: "A kind folder `be/src/features/<kind>/` holds only instance folders `<kind>/<name>/`, and each instance holds TypeScript source: a file directly in the kind folder (a feature named like a kind, a `.gitkeep`) and an instance with no TypeScript file are findings; an empty kind folder is never kept."
|
|
2953
3120
|
kinds: [check]
|
|
2954
3121
|
gates: [settle, land, ci]
|
|
2955
3122
|
failureCodes: ["BE_KIND_EMPTY"]
|
|
2956
3123
|
enforcers:
|
|
2957
3124
|
- {kind: hfs, id: kind-empty, at: scripts/hfs/rules/kinds.mjs}
|
|
3125
|
+
proves:
|
|
3126
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, editions: [lite, full], codes: [BE_KIND_EMPTY]}
|
|
3127
|
+
exemplifiedBy:
|
|
3128
|
+
- {path: packages/hfs/templates/be/patterns/jobs/job.processor.ts.tpl, editions: [lite, full]}
|
|
3129
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, editions: [lite, full], codes: [BE_KIND_EMPTY]}
|
|
3130
|
+
witness:
|
|
3131
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, edition: lite, codes: [BE_KIND_EMPTY]}
|
|
3132
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, edition: full, codes: [BE_KIND_EMPTY]}
|
|
2958
3133
|
- id: R181
|
|
2959
3134
|
code: "BE_SQL_RETURNING_SHAPE"
|
|
2960
3135
|
editions: [lite, full]
|
|
@@ -3067,77 +3242,92 @@ rules:
|
|
|
3067
3242
|
code: "HFS_DOCKER_BUILD_CONTEXT"
|
|
3068
3243
|
editions: [lite, full]
|
|
3069
3244
|
docs: [docs/application-stacks.md#r187]
|
|
3070
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3071
|
-
exemplifiedBy:
|
|
3072
|
-
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3073
|
-
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3074
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3075
3245
|
law: "Every app image is built from the app root: the header comment of an app's Dockerfile states `starci docker build <app>` for its own path, and no COPY or ADD source leaves the build context (a `..` segment or an absolute path)."
|
|
3076
3246
|
kinds: [check]
|
|
3077
3247
|
gates: [settle, land, ci]
|
|
3078
3248
|
failureCodes: ["HFS_DOCKER_BUILD_CONTEXT"]
|
|
3079
3249
|
enforcers:
|
|
3080
3250
|
- {kind: hfs, id: docker, at: scripts/hfs/rules/docker.mjs}
|
|
3251
|
+
proves: [packages/hfs/src/docker-legacy-coverage.spec.mjs]
|
|
3252
|
+
exemplifiedBy:
|
|
3253
|
+
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3254
|
+
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3255
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
3256
|
+
witness:
|
|
3257
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_DOCKER_BUILD_CONTEXT]}
|
|
3258
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: full, codes: [HFS_DOCKER_BUILD_CONTEXT]}
|
|
3081
3259
|
- id: R188
|
|
3082
3260
|
code: "HFS_DOCKER_STAGES"
|
|
3083
3261
|
editions: [lite, full]
|
|
3084
3262
|
docs: [docs/application-stacks.md#r188]
|
|
3085
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3086
|
-
exemplifiedBy:
|
|
3087
|
-
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3088
|
-
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3089
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3090
3263
|
law: "An app Dockerfile is multi-stage: a stage named `build` and a last stage named `runtime`; the runtime stage ends as `USER node` and runs no build (`npm run build*`, tsc, next, turbo, nest); every install is `npm ci`, never `npm install`; a back-end runtime runs `npm ci --omit=dev --ignore-scripts` and a front-end runtime installs nothing."
|
|
3091
3264
|
kinds: [check]
|
|
3092
3265
|
gates: [settle, land, ci]
|
|
3093
3266
|
failureCodes: ["HFS_DOCKER_STAGES"]
|
|
3094
3267
|
enforcers:
|
|
3095
3268
|
- {kind: hfs, id: docker, at: scripts/hfs/rules/docker.mjs}
|
|
3269
|
+
proves: [packages/hfs/src/docker-legacy-coverage.spec.mjs]
|
|
3270
|
+
exemplifiedBy:
|
|
3271
|
+
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3272
|
+
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3273
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
3274
|
+
witness:
|
|
3275
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_DOCKER_STAGES]}
|
|
3276
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: full, codes: [HFS_DOCKER_STAGES]}
|
|
3096
3277
|
- id: R189
|
|
3097
3278
|
code: "HFS_DOCKER_ENTRY"
|
|
3098
3279
|
editions: [lite, full]
|
|
3099
3280
|
docs: [docs/application-stacks.md#r189]
|
|
3100
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3101
|
-
exemplifiedBy:
|
|
3102
|
-
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3103
|
-
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3104
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3105
3281
|
law: "The runtime stage starts the app's own built entry in exec form (be `node be/dist/apps/<app>/src/main.js`, fe `node` on the standalone `server.js` of the app); an api or Next app sets `ENV PORT` and EXPOSEs the same port and carries a HEALTHCHECK, a worker carries a process HEALTHCHECK and exposes nothing, a cli app says `HEALTHCHECK NONE` and exposes nothing; a Next app's build stage runs `turbo run build --filter=@<project>/<app>` and its `next.config.ts` sets `output: \"standalone\"`."
|
|
3106
3282
|
kinds: [check]
|
|
3107
3283
|
gates: [settle, land, ci]
|
|
3108
3284
|
failureCodes: ["HFS_DOCKER_ENTRY"]
|
|
3109
3285
|
enforcers:
|
|
3110
3286
|
- {kind: hfs, id: docker, at: scripts/hfs/rules/docker.mjs}
|
|
3287
|
+
proves: [packages/hfs/src/docker-legacy-coverage.spec.mjs]
|
|
3288
|
+
exemplifiedBy:
|
|
3289
|
+
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3290
|
+
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3291
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
3292
|
+
witness:
|
|
3293
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_DOCKER_ENTRY]}
|
|
3294
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: full, codes: [HFS_DOCKER_ENTRY]}
|
|
3111
3295
|
- id: R190
|
|
3112
3296
|
code: "HFS_DOCKER_BASE_PIN"
|
|
3113
3297
|
editions: [lite, full]
|
|
3114
3298
|
docs: [docs/application-stacks.md#r190]
|
|
3115
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3116
|
-
exemplifiedBy:
|
|
3117
|
-
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3118
|
-
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3119
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3120
3299
|
law: "Every FROM of an app Dockerfile is a prior stage, the one node base image of the canon (an exact node version on an exact alpine release, `NODE_IMAGE` in scripts/hfs/rules/docker.mjs), or an image pinned by `@sha256` digest; never a moving tag, never an unresolved build argument."
|
|
3121
3300
|
kinds: [check]
|
|
3122
3301
|
gates: [settle, land, ci]
|
|
3123
3302
|
failureCodes: ["HFS_DOCKER_BASE_PIN"]
|
|
3124
3303
|
enforcers:
|
|
3125
3304
|
- {kind: hfs, id: docker, at: scripts/hfs/rules/docker.mjs}
|
|
3305
|
+
proves: [packages/hfs/src/docker-legacy-coverage.spec.mjs]
|
|
3306
|
+
exemplifiedBy:
|
|
3307
|
+
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3308
|
+
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3309
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
3310
|
+
witness:
|
|
3311
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_DOCKER_BASE_PIN]}
|
|
3312
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: full, codes: [HFS_DOCKER_BASE_PIN]}
|
|
3126
3313
|
- id: R191
|
|
3127
3314
|
code: "HFS_DOCKER_SECRETS"
|
|
3128
3315
|
editions: [lite, full]
|
|
3129
3316
|
docs: [docs/application-stacks.md#r191]
|
|
3130
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3131
|
-
exemplifiedBy:
|
|
3132
|
-
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3133
|
-
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3134
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3135
3317
|
law: "No secret enters an image: no COPY or ADD of an `.env*` file (except `.env.example`) or of a path under `.starcistacks`, `.secrets`, `.volume`, a key, certificate or kubeconfig; no ADD of a URL; no ARG or ENV whose name is a credential (PASSWORD, SECRET, TOKEN, KEY, CREDENTIAL, PRIVATE), `NEXT_PUBLIC_*` excepted because it is published by design."
|
|
3136
3318
|
kinds: [check]
|
|
3137
3319
|
gates: [settle, land, ci]
|
|
3138
3320
|
failureCodes: ["HFS_DOCKER_SECRETS"]
|
|
3139
3321
|
enforcers:
|
|
3140
3322
|
- {kind: hfs, id: docker, at: scripts/hfs/rules/docker.mjs}
|
|
3323
|
+
proves: [packages/hfs/src/docker-legacy-coverage.spec.mjs]
|
|
3324
|
+
exemplifiedBy:
|
|
3325
|
+
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3326
|
+
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3327
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
3328
|
+
witness:
|
|
3329
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_DOCKER_SECRETS]}
|
|
3330
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: full, codes: [HFS_DOCKER_SECRETS]}
|
|
3141
3331
|
- id: R192
|
|
3142
3332
|
code: "RT_FACT_FALSE"
|
|
3143
3333
|
law: "Every claim of knowledge/hfs/facts.yaml holds against knowledge/hfs/slots.yaml (the one source of the product shape), and no prose of knowledge/**, docs/** or a README states the opposite of a fact (for example that an fe app lacks its own package.json, which fe.app.next requires); prose quotes a fact id or a slot id and never restates the claim."
|
|
@@ -3145,14 +3335,11 @@ rules:
|
|
|
3145
3335
|
editions: [lite, full]
|
|
3146
3336
|
docs: [docs/knowledge-yaml.md#runtime-knowledge-evidence]
|
|
3147
3337
|
templateNa: "Runtime facts are authored knowledge checks; app scaffolds do not contain this runtime surface."
|
|
3148
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3149
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3150
3338
|
kinds: [check]
|
|
3151
3339
|
gates: [runtime]
|
|
3152
3340
|
failureCodes: ["RT_FACT_FALSE"]
|
|
3153
3341
|
enforcers:
|
|
3154
3342
|
- {kind: runtime, id: facts, at: scripts/hfs/runtime-rules/facts.mjs}
|
|
3155
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3156
3343
|
- id: R193
|
|
3157
3344
|
code: "RT_RULE_ID_UNKNOWN"
|
|
3158
3345
|
law: "Every rule id (R<digits>) that tracked knowledge, docs, code or data names is a rule of this catalog, and rule ids are unique and well-formed (a gap between two ids is fine), and every rule of the catalog is named by the `hfsRules:` of at least one knowledge/patterns topic or carries `scope: runtime` (RT_RULE_UNCITED). History paths (changelogs, benchmark findings, .starciwork records), specs and generated copies are not read."
|
|
@@ -3160,14 +3347,11 @@ rules:
|
|
|
3160
3347
|
editions: [lite, full]
|
|
3161
3348
|
docs: [docs/knowledge-yaml.md#runtime-knowledge-evidence]
|
|
3162
3349
|
templateNa: "Rule references and pattern citations belong to authored runtime knowledge, not scaffolded app files."
|
|
3163
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3164
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3165
3350
|
kinds: [check]
|
|
3166
3351
|
gates: [runtime]
|
|
3167
3352
|
failureCodes: ["RT_RULE_ID_UNKNOWN", "RT_RULE_UNCITED"]
|
|
3168
3353
|
enforcers:
|
|
3169
3354
|
- {kind: runtime, id: rule-ids, at: scripts/hfs/runtime-rules/rule-ids.mjs}
|
|
3170
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3171
3355
|
- id: R194
|
|
3172
3356
|
code: "RT_GENERATED_BLOCK_STALE"
|
|
3173
3357
|
law: "The app map (section 4), the back-end source tree (5.1), the tier matrix (5.2), the front-end source tree (6.1) and the rule catalog (12) of knowledge/hfs/README.md are generated blocks, rendered by scripts/hfs/readme-blocks.mjs from knowledge/hfs/slots.yaml and rules.yaml between hfs:generated markers and equal to the render byte for byte; the README never restates them by hand. Likewise the `verification.automated` list of a pattern rule is the failure codes of the rules its `hfsRules` names, the `slot` of a `files:` entry is the slot that owns its path, and the `code` of a why-map entry is the code of the catalog rule that lists the lint rule: scripts/hfs/derived-fields.mjs writes them and they equal the derivation byte for byte."
|
|
@@ -3175,21 +3359,16 @@ rules:
|
|
|
3175
3359
|
editions: [lite, full]
|
|
3176
3360
|
docs: [docs/knowledge-yaml.md#runtime-knowledge-evidence]
|
|
3177
3361
|
templateNa: "Generated runtime knowledge and its derivations are maintained from the catalogs, not app scaffolds."
|
|
3178
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3179
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3180
3362
|
kinds: [check]
|
|
3181
3363
|
gates: [runtime]
|
|
3182
3364
|
failureCodes: ["RT_GENERATED_BLOCK_STALE"]
|
|
3183
3365
|
enforcers:
|
|
3184
3366
|
- {kind: runtime, id: generated-block, at: scripts/hfs/runtime-rules/generated-block.mjs}
|
|
3185
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3186
3367
|
- id: R195
|
|
3187
3368
|
code: "RT_PROSE_PATH_NO_SLOT"
|
|
3188
3369
|
editions: [lite, full]
|
|
3189
3370
|
docs: [docs/knowledge-yaml.md#r195]
|
|
3190
3371
|
templateNa: "This rule judges authored runtime prose against slot catalogs and shipped example declarations; app templates do not scaffold this runtime surface."
|
|
3191
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3192
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3193
3372
|
law: "Every product path the knowledge, the docs and the READMEs name (a be/ or fe/ path, whole or with placeholders, globs and braces) is owned by a slot of knowledge/hfs/slots.yaml or is a folder above one; a path no slot owns is prose that invented a place or kept one a slot no longer has. App names are free: a literal app name is one a shipped examples/*/hfs.json declares, a placeholder stands for any; a ** glob and a topic file of the knowledge are not paths."
|
|
3194
3373
|
scope: runtime
|
|
3195
3374
|
kinds: [check]
|
|
@@ -3197,7 +3376,6 @@ rules:
|
|
|
3197
3376
|
failureCodes: ["RT_PROSE_PATH_NO_SLOT"]
|
|
3198
3377
|
enforcers:
|
|
3199
3378
|
- {kind: runtime, id: prose-path, at: scripts/hfs/runtime-rules/prose-path.mjs}
|
|
3200
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3201
3379
|
- id: R196
|
|
3202
3380
|
code: "RT_PROSE_RESTATES_SLOTS"
|
|
3203
3381
|
law: "Knowledge, docs and READMEs never restate knowledge/hfs/slots.yaml: no fenced block or line names three or more product paths a slot owns, and no sentence lists three or more of the root or side file names the slots declare; a slot is referenced by its id, and the only allowed copy is a generated block between hfs:generated markers. The slot and rule catalogs, the example READMEs and the templates are sources or snapshots, not prose."
|
|
@@ -3205,21 +3383,16 @@ rules:
|
|
|
3205
3383
|
editions: [lite, full]
|
|
3206
3384
|
docs: [docs/knowledge-yaml.md#runtime-knowledge-evidence]
|
|
3207
3385
|
templateNa: "This checker judges prose about the runtime slot catalogs; app templates are snapshots rather than this authored prose."
|
|
3208
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3209
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3210
3386
|
kinds: [check]
|
|
3211
3387
|
gates: [runtime]
|
|
3212
3388
|
failureCodes: ["RT_PROSE_RESTATES_SLOTS"]
|
|
3213
3389
|
enforcers:
|
|
3214
3390
|
- {kind: runtime, id: prose-restates, at: scripts/hfs/runtime-rules/prose-restates.mjs}
|
|
3215
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3216
3391
|
- id: R198
|
|
3217
3392
|
code: "RT_CLI_CATALOG_DRIFT"
|
|
3218
3393
|
editions: [lite, full]
|
|
3219
3394
|
docs: [docs/installation.md#r198-cli-catalog-drift]
|
|
3220
3395
|
templateNa: "The host CLI catalog generator is runtime source governance, not an app scaffold surface."
|
|
3221
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3222
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3223
3396
|
law: "Every generated output of the unified CLI catalog (packages/cli/src/catalog.generated.mjs, docs/cli.md, packages/cli/completions/*) equals what scripts/cli/gen-catalog.mjs writes from modules/cli/commands."
|
|
3224
3397
|
scope: runtime
|
|
3225
3398
|
kinds: [check]
|
|
@@ -3227,14 +3400,11 @@ rules:
|
|
|
3227
3400
|
failureCodes: ["RT_CLI_CATALOG_DRIFT"]
|
|
3228
3401
|
enforcers:
|
|
3229
3402
|
- {kind: runtime, id: cli-catalog-drift, at: scripts/cli/gen-catalog.mjs}
|
|
3230
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3231
3403
|
- id: R199
|
|
3232
3404
|
code: "RT_CLI_VERB_PARITY"
|
|
3233
3405
|
editions: [lite, full]
|
|
3234
3406
|
docs: [docs/installation.md#cli-catalog-parity]
|
|
3235
3407
|
templateNa: "CLI catalog and implementation parity is runtime source governance, not an app scaffold surface."
|
|
3236
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3237
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3238
3408
|
law: "The CLI catalog of modules/cli/commands and the implementation agree: every catalog verb has a handler and a doc, every kernel verb module and cli.mjs dispatch case has a catalog file, and every --flag a verb module names (usage, required, api-boolean-flags.txt) is a catalog flag."
|
|
3239
3409
|
scope: runtime
|
|
3240
3410
|
kinds: [check]
|
|
@@ -3242,15 +3412,10 @@ rules:
|
|
|
3242
3412
|
failureCodes: ["RT_CLI_VERB_PARITY"]
|
|
3243
3413
|
enforcers:
|
|
3244
3414
|
- {kind: runtime, id: cli-parity, at: scripts/checks/check-cli-parity.mjs}
|
|
3245
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3246
3415
|
- id: R200
|
|
3247
3416
|
code: "RT_CLI_APP_ONLY_TEMPLATES"
|
|
3248
3417
|
editions: [lite, full]
|
|
3249
3418
|
docs: [docs/installation.md#managed-app-command-boundary]
|
|
3250
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3251
|
-
exemplifiedBy:
|
|
3252
|
-
- {path: packages/hfs/templates/app/hooks/husky/pre-commit, editions: [lite, full]}
|
|
3253
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3254
3419
|
law: "Managed app templates and their generated runtime copies invoke product actions only through `starci app <verb>`; any other starci group is forbidden there."
|
|
3255
3420
|
scope: runtime
|
|
3256
3421
|
kinds: [check]
|
|
@@ -3258,13 +3423,13 @@ rules:
|
|
|
3258
3423
|
failureCodes: ["RT_CLI_APP_ONLY_TEMPLATES"]
|
|
3259
3424
|
enforcers:
|
|
3260
3425
|
- {kind: runtime, id: cli-app-only-templates, at: scripts/hfs/runtime-rules/app-cli-templates.mjs}
|
|
3426
|
+
exemplifiedBy:
|
|
3427
|
+
- {path: packages/hfs/templates/app/hooks/husky/pre-commit, editions: [lite, full]}
|
|
3261
3428
|
- id: R201
|
|
3262
3429
|
code: "CLI_ONLY_ENTRY"
|
|
3263
3430
|
editions: [lite, full]
|
|
3264
3431
|
docs: [docs/installation.md#catalog-entry-boundary]
|
|
3265
3432
|
templateNa: "The runtime tracked-action scanner governs catalog entry use; its implementation is not scaffolded into apps."
|
|
3266
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3267
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3268
3433
|
law: "Every action enters runtime code through `starci <group> <verb>`: tracked prompts, docs, skills, knowledge files, configs, CI files, hooks and scheduled-task registrations do not bypass the catalog through direct runtime scripts or package-script wrappers; the dispatcher and the specs' own spawn helpers are the declared exceptions."
|
|
3269
3434
|
scope: runtime
|
|
3270
3435
|
kinds: [check]
|
|
@@ -3272,16 +3437,10 @@ rules:
|
|
|
3272
3437
|
failureCodes: ["CLI_ONLY_ENTRY"]
|
|
3273
3438
|
enforcers:
|
|
3274
3439
|
- {kind: runtime, id: cli-only-entry, at: scripts/checks/check-cli-only-entry.mjs}
|
|
3275
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3276
3440
|
- id: R202
|
|
3277
3441
|
code: "CI_UPLOAD_NOT_SILENT"
|
|
3278
3442
|
editions: [lite, full]
|
|
3279
3443
|
docs: [docs/releasing.md#r202]
|
|
3280
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3281
|
-
exemplifiedBy:
|
|
3282
|
-
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
3283
|
-
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
3284
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3285
3444
|
law: "A coverage upload of a CI workflow never skips or fails silently: every step that uses codecov/codecov-action, in a root workflow, an example workflow or a template workflow of packages/hfs, authenticates by OIDC (`use_oidc: true`, with `permissions: id-token: write` on the job or the workflow), sets `fail_ci_if_error: true`, has no `continue-on-error`, and has no `if` that reads a secret or CODECOV_TOKEN, so a missing token can never turn the upload into a skipped step. Every step that uses SonarSource/* has no `if` that reads a secret or SONAR_TOKEN (a missing token fails the job), and no step or job of a workflow sets `continue-on-error`."
|
|
3286
3445
|
scope: runtime
|
|
3287
3446
|
kinds: [check]
|
|
@@ -3289,6 +3448,9 @@ rules:
|
|
|
3289
3448
|
failureCodes: ["CI_UPLOAD_NOT_SILENT"]
|
|
3290
3449
|
enforcers:
|
|
3291
3450
|
- {kind: runtime, id: ci-upload, at: scripts/hfs/runtime-rules/ci-upload.mjs}
|
|
3451
|
+
exemplifiedBy:
|
|
3452
|
+
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
3453
|
+
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
3292
3454
|
- id: R203
|
|
3293
3455
|
code: "BE_FEATURE_THIN"
|
|
3294
3456
|
editions: [lite, full]
|
|
@@ -3311,23 +3473,25 @@ rules:
|
|
|
3311
3473
|
code: "HFS_COVERAGE_SCOPE_DRIFT"
|
|
3312
3474
|
editions: [lite, full]
|
|
3313
3475
|
docs: [docs/quality-bar.md#r204-coverage-scope]
|
|
3314
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3315
|
-
exemplifiedBy:
|
|
3316
|
-
- {path: packages/hfs/templates/app/quality-config/codecov.yml, editions: [lite, full]}
|
|
3317
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3318
3476
|
law: "What a back end measures at 100 per file is derived once from the slot manifest (the `coverage: required|none` field of every be slot and ruleParams.be.logicRoles, scripts/hfs/coverage-scope.mjs), and the three files that state it are its render: be/jest.config.js (thresholds), the `sonar.coverage.exclusions` line of sonar-project.properties, and codecov.yml (paths and one component per service app plus platform, each at 100). A difference is drift; the scope is never edited by hand."
|
|
3319
3477
|
kinds: [check, codemod]
|
|
3320
3478
|
gates: [land, ci]
|
|
3321
3479
|
failureCodes: ["HFS_COVERAGE_SCOPE_DRIFT"]
|
|
3322
3480
|
enforcers:
|
|
3323
3481
|
- {kind: hfs, id: coverage-scope-drift, at: packages/hfs/sync/managed.mjs}
|
|
3482
|
+
proves:
|
|
3483
|
+
- {path: packages/hfs/src/coverage-scope-evidence.spec.mjs, editions: [lite, full]}
|
|
3484
|
+
exemplifiedBy:
|
|
3485
|
+
- {path: packages/hfs/templates/app/quality-config/codecov.yml, editions: [lite, full]}
|
|
3486
|
+
- {path: packages/hfs/src/coverage-scope-evidence.spec.mjs, editions: [lite, full]}
|
|
3487
|
+
witness:
|
|
3488
|
+
- {path: packages/hfs/src/coverage-scope-evidence.spec.mjs, edition: lite, codes: [HFS_COVERAGE_SCOPE_DRIFT]}
|
|
3489
|
+
- {path: packages/hfs/src/coverage-scope-evidence.spec.mjs, edition: full, codes: [HFS_COVERAGE_SCOPE_DRIFT]}
|
|
3324
3490
|
- id: R205
|
|
3325
3491
|
code: "RT_DOC_NO_OWNER"
|
|
3326
3492
|
editions: [lite, full]
|
|
3327
3493
|
docs: [docs/architecture.md#r205]
|
|
3328
3494
|
templateNa: "Runtime documentation ownership is checked in the authored runtime repository; application scaffolds do not generate runtime docs/*.md."
|
|
3329
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3330
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3331
3495
|
law: "Every tracked docs/*.md declares exactly one ownership header on its first line — \"Owner: <knowledge/ or modules/ path that exists>\" when the document explains a machine-owned source, \"Task: <one task>\" for a how-to — no two documents carry the same task, and two documents whose titles share two or more topic words while at least 30% of the shorter one's sentences appear in the other are one document merged, not two."
|
|
3332
3496
|
scope: runtime
|
|
3333
3497
|
kinds: [check]
|
|
@@ -3335,15 +3499,10 @@ rules:
|
|
|
3335
3499
|
failureCodes: ["RT_DOC_NO_OWNER"]
|
|
3336
3500
|
enforcers:
|
|
3337
3501
|
- {kind: runtime, id: doc-owner, at: scripts/checks/check-doc-owner.mjs}
|
|
3338
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3339
3502
|
- id: R206
|
|
3340
3503
|
code: "RT_EXAMPLE_COUPLING"
|
|
3341
3504
|
editions: [lite, full]
|
|
3342
3505
|
docs: [docs/architecture.md#r206]
|
|
3343
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3344
|
-
exemplifiedBy:
|
|
3345
|
-
- {path: packages/hfs/templates/app/hooks/husky/pre-commit, editions: [lite, full]}
|
|
3346
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3347
3506
|
law: "Runtime source never couples to a product or its example: no tracked file under scripts/, engine/, packages/, ui/src or ui/api - and no managed template under packages/hfs/templates/ - spells a literal examples/<name>, one of the product names this runtime shipped against (the closed PRODUCT_NAMES list of scripts/lib/example-refs.mjs), an inc-<hash> a product name prefixes, or a host drive path. Specs, tests, the generated runtime copies, changelogs and .starciwork records are out of scope; a read the runtime genuinely makes at run time is declared once in scripts/lib/example-refs.mjs and every consumer names that constant."
|
|
3348
3507
|
scope: runtime
|
|
3349
3508
|
kinds: [check]
|
|
@@ -3351,6 +3510,8 @@ rules:
|
|
|
3351
3510
|
failureCodes: ["RT_EXAMPLE_COUPLING", "RT_PRODUCT_NAME_IN_SOURCE", "RT_HOST_PATH_IN_TEMPLATE"]
|
|
3352
3511
|
enforcers:
|
|
3353
3512
|
- {kind: runtime, id: example-coupling, at: scripts/checks/check-example-coupling.mjs}
|
|
3513
|
+
exemplifiedBy:
|
|
3514
|
+
- {path: packages/hfs/templates/app/hooks/husky/pre-commit, editions: [lite, full]}
|
|
3354
3515
|
- id: R208
|
|
3355
3516
|
code: "RT_PORT_RESTATED"
|
|
3356
3517
|
law: "Every port literal of the runtime is spelled once, by its owner, and every other file references the owner: the harness UI ports live in modules/models/runtimes.yaml statusApp.port/devPort read through ui/ports.mjs, the local SonarQube host in scripts/gates/sonar-local.mjs DEFAULT_HOST. No in-scope file that is not the owner spells an owned literal in a port position (a scheme://host:NNNN or host:NNNN authority, a *port*/PORT assignment, a listen(NNNN) call), and an unowned literal in a port position of two or more runtime source files gets one owning exported constant the rest reference. Specs, tests, node_modules, the generated runtime copies, changelogs, .starciwork and the product stack declarations (.starcistacks, starcistacks-services - a product owns the ports of the services it runs) are out of scope."
|
|
@@ -3363,9 +3524,6 @@ rules:
|
|
|
3363
3524
|
editions: [lite, full]
|
|
3364
3525
|
docs: [docs/source-process.md#r208]
|
|
3365
3526
|
templateNa: "Runtime port ownership is repository infrastructure; app scaffolds do not contain its owner files or readers."
|
|
3366
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3367
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3368
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3369
3527
|
- id: R209
|
|
3370
3528
|
code: "RT_CONFIG_DEFAULT_TWICE"
|
|
3371
3529
|
law: "Every documented configuration default is stated once, by its owner, and read through it: a camelCase leaf or lowercase key of config.example.yaml, or a value an owner declares - scripts/machine/home.mjs DEFAULTS (supervisor workers, the land gate, frozenMinutes, pollIntervalMs), engine/config.mjs (connector, ask, UAT, spec and allocation defaults, and DEFAULT_OWNER_LANGUAGE which scripts/machine/home.mjs re-exports), engine/orca-config.mjs (worker depth), scripts/reconciler/state.mjs (the controller mode) - is never restated as a literal fallback (?? or ||, a parameter default, or a language ternary) in any other runtime source file; the reader calls the owner accessor (supervisorSettings(), configuredMode(), ownerLanguage(), ...). Specs, tests, the generated runtime copies, stories and the HFS templates are out of scope, and a bare identifier or a computed value is a read, not a restatement."
|
|
@@ -3378,9 +3536,6 @@ rules:
|
|
|
3378
3536
|
editions: [lite, full]
|
|
3379
3537
|
docs: [docs/source-process.md#r209]
|
|
3380
3538
|
templateNa: "Runtime configuration defaults belong to harness owners and readers; HFS product templates are outside this check's scope."
|
|
3381
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3382
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3383
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3384
3539
|
- id: R210
|
|
3385
3540
|
code: "RT_VERSION_RESTATED"
|
|
3386
3541
|
law: "knowledge/hfs/canon-pins.yaml spells the version of every @starci package and every canon-pinned dependency once; a package.json is the declared install site and a lockfile its resolution. Anywhere else a semver literal equal to a pin - or a name@x.y.z specifier naming one - restates it, except on the declared binding keys a refresher owns and rewrites in place (canon.version of the code-pattern bindings held by check-canon-pins.mjs, provenance.version and identity.version of the grammar snapshots rewritten by scripts/work/ui/grammar-knowledge.mjs). Package manifests, lockfiles, changelogs, specs, tests, the generated runtime copies and .starciwork are out of scope; a restatement is fixed by naming the pin, never the literal."
|
|
@@ -3393,9 +3548,6 @@ rules:
|
|
|
3393
3548
|
editions: [lite, full]
|
|
3394
3549
|
docs: [docs/source-process.md#r210]
|
|
3395
3550
|
templateNa: "This runtime check scans tracked references to the canon pin catalog; product package install declarations are excluded and no app scaffold owns this runtime surface."
|
|
3396
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3397
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3398
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3399
3551
|
- id: R211
|
|
3400
3552
|
code: "RT_SLOT_ID_SHAPE"
|
|
3401
3553
|
law: "A slot id follows the grammar its manifest declares, read from the manifest not from a list: dot-separated lowercase kebab segments, a first segment of naming.prefixes in knowledge/hfs/slots.yaml (profiles in knowledge/hfs/runtime-slots.yaml), <side>.app.<kind> naming a kind of appKinds.<side>, and every deeper id extending a declared id - an explicit parent field, or a family at least two slots share; a lone deep orphan invents a family. The role-suffix vocabulary holds no synonym pairs: a profile's suffixes never share a word with bannedSuffixes, no naming.refusedPairs pair is live in suffixes on both sides, and naming.sameConceptPairs is the one declared exception (step + saga-step), live on both sides or dropped; naming.glossary binds the five incoming-thing names (consumer, subscription, webhook, processor, handler) to their distinct kinds."
|
|
@@ -3408,17 +3560,12 @@ rules:
|
|
|
3408
3560
|
editions: [lite, full]
|
|
3409
3561
|
docs: [docs/source-process.md#r211]
|
|
3410
3562
|
templateNa: "The authored app and runtime slot manifests are canon catalogs, not files scaffolded into apps."
|
|
3411
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3412
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3413
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3414
3563
|
- id: R212
|
|
3415
3564
|
editions: [lite, full]
|
|
3416
3565
|
codeEditions: {HFS_EDITION_FORBIDDEN_PRESENT: [lite], HFS_STARCIWORK_LITE_FORBIDDEN: [lite]}
|
|
3417
3566
|
editionWhy: "R212/case-3 and R212/case-4 (owner:lite-production-swarm) preserve full Work and limit the lite infrastructure and Work surfaces."
|
|
3418
3567
|
docs: [docs/lite-edition.md#edition-validation]
|
|
3419
3568
|
templateNa: "The hfs.json edition declaration is generated programmatically by packages/hfs/scaffold/app.mjs; no managed declaration template exists. Forbidden paths are rejected rather than scaffolded."
|
|
3420
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3421
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3422
3569
|
code: "HFS_EDITION_INVALID"
|
|
3423
3570
|
law: "hfs.json names an edition the manifest knows (full, or lite; absent means full). Lite follows the 2026-10-13 ruling: the same monorepo, code structure, slots, patterns and back-end unit specs, with only backing infrastructure swapped for managed Supabase (Postgres, Auth, Storage, Supabase Queues/pgmq for queue and event bus, Postgres locks, pg_cron); the api and sidecars run on docker-swarm on a VPS. The realtime pattern uses the same socket.io gateway inside the be api process (one instance, no Redis adapter), and both editions share knowledge/hfs/fe-stack.yaml. Lite requires application-stacks.yaml and permits environment metadata, runbooks, infra/swarm and encrypted-secret custody, while refusing infra/compose, infra/k8s, infra/terraform and components duplicating Supabase backing services (runtime/{config,env}, seeds and the sealed secrets of its environments are allowed). Contract specs and `test:contract` are allowed (owner 2026-10-14); it has no e2e spec, `test:e2e`, `test:stack` or `test:browser` script, e2e workflow, browser journey, Work catalog, shell, features, resources, UAT or br records, test container, toxiproxy, browser-runner, BullMQ, Kafka, Redis or graphql-ws dependency, or supabase/functions. Its .starciwork is optional and admits only .gitignore, workspace.yaml and brand/**; workspace.yaml is optional and carries project identity and repo roles for the Work tools."
|
|
3424
3571
|
kinds: [check]
|
|
@@ -3450,60 +3597,86 @@ rules:
|
|
|
3450
3597
|
source: owner
|
|
3451
3598
|
quote: "In a lite app, .starciwork keeps only the brand records."
|
|
3452
3599
|
ruling: "Amended by the owner on 2026-10-14: under lite, .starciwork is optional when the app has no brand records and admits only .gitignore, workspace.yaml and brand/** in the existing brand tooling layout, including drawing records, references and assets. workspace.yaml is optional and keeps the project id and repo roles so Work root detection and render-proof role mapping can tie brand records to the front end. index.yaml, shell/, features/, _resources/, uat and br remain forbidden. Lite readers read workspace.yaml normally and skip the full-edition catalog, shell and feature metadata; lite scaffolding creates .gitignore and workspace.yaml, with brand/ only when present. Full edition is unchanged."
|
|
3453
|
-
|
|
3454
|
-
|
|
3600
|
+
proves: [packages/hfs/src/hfs-edition-invalid.spec.mjs, packages/hfs/src/hfs-edition-forbidden-present.spec.mjs, packages/hfs/src/hfs-starciwork-lite-forbidden.spec.mjs]
|
|
3601
|
+
exemplifiedBy:
|
|
3602
|
+
- {path: packages/hfs/src/hfs-edition-invalid.spec.mjs, editions: [lite, full]}
|
|
3603
|
+
- {path: packages/hfs/src/hfs-edition-forbidden-present.spec.mjs, edition: lite}
|
|
3604
|
+
- {path: packages/hfs/src/hfs-starciwork-lite-forbidden.spec.mjs, edition: lite}
|
|
3605
|
+
witness:
|
|
3606
|
+
- {path: packages/hfs/src/hfs-edition-invalid.spec.mjs, editions: [lite, full], codes: [HFS_EDITION_INVALID]}
|
|
3607
|
+
- {path: packages/hfs/src/hfs-edition-forbidden-present.spec.mjs, edition: lite, codes: [HFS_EDITION_FORBIDDEN_PRESENT]}
|
|
3608
|
+
- {path: packages/hfs/src/hfs-starciwork-lite-forbidden.spec.mjs, edition: lite, codes: [HFS_STARCIWORK_LITE_FORBIDDEN]}
|
|
3455
3609
|
- id: R213
|
|
3456
3610
|
code: "DB_MIGRATION_SHAPE"
|
|
3457
3611
|
editions: [lite, full]
|
|
3458
3612
|
docs: [docs/architecture.md#r213]
|
|
3459
3613
|
templateNa: "Full apps opt into Supabase without a managed Supabase migration scaffold; their migration sequence and Git history are product-authored."
|
|
3460
|
-
exemplifiedBy:
|
|
3461
|
-
- {path: packages/hfs/templates/app/skeleton-lite/supabase/migrations/__timestamp___baseline.sql, edition: lite}
|
|
3462
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3463
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3464
3614
|
law: "A migration is `supabase/migrations/<ts14>_<kebab>.sql`; the stamp is a valid UTC instant, active stamps are unique, and a new migration sorts strictly after the committed active migrations in HEAD. Repository history includes the archive: moving an active migration to the archive retires it from ordering, so a replacement baseline may predate archived stamps and later migrations append after the baseline. Wall-clock time, commit time and remote-branch stamps do not set the ordering boundary. A migration already on the base is immutable (a diff or an unarchived removal is a finding); a file that does not parse as PostgreSQL is a shape failure."
|
|
3465
3615
|
kinds: [check]
|
|
3466
3616
|
gates: [settle, land, ci]
|
|
3467
3617
|
failureCodes: ["DB_MIGRATION_SHAPE"]
|
|
3468
3618
|
enforcers:
|
|
3469
3619
|
- {kind: hfs, id: db-migration-shape, at: scripts/hfs/rules/database.mjs}
|
|
3620
|
+
proves:
|
|
3621
|
+
- {path: packages/hfs/src/db-migration-shape.spec.mjs, editions: [lite, full]}
|
|
3622
|
+
exemplifiedBy:
|
|
3623
|
+
- {path: packages/hfs/templates/app/skeleton-lite/supabase/migrations/__timestamp___baseline.sql, edition: lite}
|
|
3624
|
+
- {path: packages/hfs/src/db-migration-shape.spec.mjs, editions: [lite, full]}
|
|
3625
|
+
witness:
|
|
3626
|
+
- {path: packages/hfs/src/db-migration-shape.spec.mjs, editions: [lite, full], codes: [DB_MIGRATION_SHAPE]}
|
|
3470
3627
|
- id: R214
|
|
3471
3628
|
code: "DB_RLS_REQUIRED"
|
|
3472
3629
|
editions: [lite, full]
|
|
3473
3630
|
docs: [docs/lite-edition.md#r214]
|
|
3474
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3475
|
-
exemplifiedBy:
|
|
3476
|
-
- {path: packages/hfs/templates/be/table/migration.sql.tpl, editions: [lite, full]}
|
|
3477
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3478
3631
|
law: "Row level security is code a parser can read: every `create table` (or `create table as`) in an exposed schema (`public` plus the config.toml `[api] schemas`) is followed, in the same migration, by `alter table <t> enable row level security` (and `force` for a table hfs.json `supabase.forceRls` declares); no `DO` block or function runs dynamic SQL that builds DDL or grants; a write or `for all` policy never uses `(true)`, `to anon`/`to public` is legal only on a `for select` policy named `*_public_read`, every policy is named `<table>_<role>_<action>`, and `service_role` is never granted."
|
|
3479
3632
|
kinds: [check, codemod]
|
|
3480
3633
|
gates: [settle, land, ci]
|
|
3481
3634
|
failureCodes: ["DB_RLS_REQUIRED", "DB_DYNAMIC_DDL", "DB_POLICY_SHAPE"]
|
|
3482
3635
|
enforcers:
|
|
3483
3636
|
- {kind: hfs, id: db-rls, at: scripts/hfs/rules/database.mjs}
|
|
3637
|
+
proves:
|
|
3638
|
+
- {path: packages/hfs/src/db-rls-required.spec.mjs, editions: [lite, full], codes: [DB_RLS_REQUIRED]}
|
|
3639
|
+
- {path: packages/hfs/src/db-dynamic-ddl.spec.mjs, editions: [lite, full], codes: [DB_DYNAMIC_DDL]}
|
|
3640
|
+
- {path: packages/hfs/src/db-policy-shape.spec.mjs, editions: [lite, full], codes: [DB_POLICY_SHAPE]}
|
|
3641
|
+
exemplifiedBy:
|
|
3642
|
+
- {path: packages/hfs/templates/be/table/migration.sql.tpl, editions: [lite, full]}
|
|
3643
|
+
- {path: packages/hfs/src/db-rls-required.spec.mjs, editions: [lite, full]}
|
|
3644
|
+
- {path: packages/hfs/src/db-dynamic-ddl.spec.mjs, editions: [lite, full]}
|
|
3645
|
+
- {path: packages/hfs/src/db-policy-shape.spec.mjs, editions: [lite, full]}
|
|
3646
|
+
witness:
|
|
3647
|
+
- {path: packages/hfs/src/db-rls-required.spec.mjs, edition: lite, codes: [DB_RLS_REQUIRED]}
|
|
3648
|
+
- {path: packages/hfs/src/db-dynamic-ddl.spec.mjs, edition: lite, codes: [DB_DYNAMIC_DDL]}
|
|
3649
|
+
- {path: packages/hfs/src/db-policy-shape.spec.mjs, edition: lite, codes: [DB_POLICY_SHAPE]}
|
|
3650
|
+
- {path: packages/hfs/src/db-rls-required.spec.mjs, edition: full, codes: [DB_RLS_REQUIRED]}
|
|
3651
|
+
- {path: packages/hfs/src/db-dynamic-ddl.spec.mjs, edition: full, codes: [DB_DYNAMIC_DDL]}
|
|
3652
|
+
- {path: packages/hfs/src/db-policy-shape.spec.mjs, edition: full, codes: [DB_POLICY_SHAPE]}
|
|
3484
3653
|
- id: R215
|
|
3485
3654
|
code: "DB_DEFINER_SAFE"
|
|
3486
3655
|
editions: [lite, full]
|
|
3487
3656
|
docs: [docs/lite-edition.md#r215]
|
|
3488
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3489
3657
|
templateNa: "Security-definer functions and storage buckets are app-owned SQL objects; neither edition scaffolds them."
|
|
3490
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3491
3658
|
law: "Privileged database objects are declared safely: a `security definer` function pins `search_path` (never `from current`), lives outside the exposed schemas or is `revoke execute ... from public` in the same migration, declares a return type and interpolates parameters into dynamic SQL only through `format('%I/%L')`; a bucket inserted into `storage.buckets` declares `public = false` (true only for an id ending `_public`), `file_size_limit` and `allowed_mime_types`, and has a `storage.objects` policy naming its `bucket_id` in the same migration."
|
|
3492
3659
|
kinds: [check]
|
|
3493
3660
|
gates: [settle, land, ci]
|
|
3494
3661
|
failureCodes: ["DB_DEFINER_SAFE", "DB_STORAGE_POLICY"]
|
|
3495
3662
|
enforcers:
|
|
3496
3663
|
- {kind: hfs, id: db-privileged-objects, at: scripts/hfs/rules/database.mjs}
|
|
3497
|
-
|
|
3664
|
+
proves:
|
|
3665
|
+
- {path: packages/hfs/src/db-definer-safe.spec.mjs, editions: [lite, full], codes: [DB_DEFINER_SAFE]}
|
|
3666
|
+
- {path: packages/hfs/src/db-storage-policy.spec.mjs, editions: [lite, full], codes: [DB_STORAGE_POLICY]}
|
|
3667
|
+
exemplifiedBy:
|
|
3668
|
+
- {path: packages/hfs/src/db-definer-safe.spec.mjs, editions: [lite, full]}
|
|
3669
|
+
- {path: packages/hfs/src/db-storage-policy.spec.mjs, editions: [lite, full]}
|
|
3670
|
+
witness:
|
|
3671
|
+
- {path: packages/hfs/src/db-definer-safe.spec.mjs, edition: lite, codes: [DB_DEFINER_SAFE]}
|
|
3672
|
+
- {path: packages/hfs/src/db-storage-policy.spec.mjs, edition: lite, codes: [DB_STORAGE_POLICY]}
|
|
3673
|
+
- {path: packages/hfs/src/db-definer-safe.spec.mjs, edition: full, codes: [DB_DEFINER_SAFE]}
|
|
3674
|
+
- {path: packages/hfs/src/db-storage-policy.spec.mjs, edition: full, codes: [DB_STORAGE_POLICY]}
|
|
3498
3675
|
- id: R216
|
|
3499
3676
|
code: "DB_CONFIG_POLICY"
|
|
3500
3677
|
editions: [lite, full]
|
|
3501
3678
|
docs: [docs/lite-edition.md#r216]
|
|
3502
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3503
|
-
exemplifiedBy:
|
|
3504
|
-
- {path: packages/hfs/templates/app/skeleton-lite/supabase/config.toml, edition: lite}
|
|
3505
3679
|
templateNa: "Database types are generated from each app migration set, not static templates; full-edition Supabase configuration is app-owned."
|
|
3506
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3507
3680
|
law: "The database configuration and its types are checked facts: `supabase/config.toml` carries no literal value under a credential key (the value is `env(NAME)`), `auth.jwt_expiry` is at most 3600, and signup, site url and redirect urls equal the Supabase block of hfs.json where it declares them; `supabase/types/database.types.ts` is committed and equals the text `contract:emit` regenerates from the migrations. Type emission refuses HFS_EMIT_DB_TYPES_STALE unless the complete applied migration version set equals the SQL filename stamps; lint and check report drift without writing types."
|
|
3508
3681
|
kinds: [check]
|
|
3509
3682
|
gates: [land, ci]
|
|
@@ -3511,15 +3684,25 @@ rules:
|
|
|
3511
3684
|
enforcers:
|
|
3512
3685
|
- {kind: hfs, id: db-config-types, at: scripts/hfs/rules/database.mjs}
|
|
3513
3686
|
- {kind: hfs, id: db-types-emit, at: packages/hfs/emit/db-types.mjs}
|
|
3687
|
+
proves:
|
|
3688
|
+
- {path: packages/hfs/src/db-types-returned-collector.spec.mjs, editions: [lite, full], codes: [DB_TYPES_DRIFT]}
|
|
3689
|
+
- {path: packages/hfs/src/db-config-policy.spec.mjs, editions: [lite, full], codes: [DB_CONFIG_POLICY]}
|
|
3690
|
+
- {path: packages/hfs/src/db-types-emit-stale.spec.mjs, editions: [lite, full], codes: [HFS_EMIT_DB_TYPES_STALE]}
|
|
3691
|
+
exemplifiedBy:
|
|
3692
|
+
- {path: packages/hfs/templates/app/skeleton-lite/supabase/config.toml, edition: lite}
|
|
3693
|
+
- {path: packages/hfs/src/db-types-returned-collector.spec.mjs, editions: [lite, full]}
|
|
3694
|
+
- {path: packages/hfs/src/db-config-policy.spec.mjs, editions: [lite, full]}
|
|
3695
|
+
- {path: packages/hfs/src/db-types-emit-stale.spec.mjs, editions: [lite, full], codes: [HFS_EMIT_DB_TYPES_STALE]}
|
|
3696
|
+
witness:
|
|
3697
|
+
- {path: packages/hfs/src/db-types-returned-collector.spec.mjs, edition: lite, codes: [DB_TYPES_DRIFT]}
|
|
3698
|
+
- {path: packages/hfs/src/db-types-returned-collector.spec.mjs, edition: full, codes: [DB_TYPES_DRIFT]}
|
|
3699
|
+
- {path: packages/hfs/src/db-config-policy.spec.mjs, edition: lite, codes: [DB_CONFIG_POLICY]}
|
|
3700
|
+
- {path: packages/hfs/src/db-config-policy.spec.mjs, edition: full, codes: [DB_CONFIG_POLICY]}
|
|
3701
|
+
- {path: packages/hfs/src/db-types-emit-stale.spec.mjs, editions: [lite, full], codes: [HFS_EMIT_DB_TYPES_STALE]}
|
|
3514
3702
|
- id: R217
|
|
3515
3703
|
code: "FE_SUPABASE_CLIENT_OWNER"
|
|
3516
3704
|
editions: [lite, full]
|
|
3517
3705
|
docs: [docs/lite-edition.md#r217]
|
|
3518
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3519
|
-
exemplifiedBy:
|
|
3520
|
-
- {path: packages/hfs/templates/fe/auth/supabase-client.ts.tpl, editions: [lite, full]}
|
|
3521
|
-
- {path: packages/hfs/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.client.ts, edition: lite}
|
|
3522
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3523
3706
|
law: "Supabase has one door per side: on the front end `@supabase/supabase-js` and `@supabase/ssr` are imported only by `fe.modules.auth` and only their auth API is called (sign-in, sign-out, session, access token; never `.from`, `.rpc`, `.storage` or `.channel`, so the front end reads and writes no data through Supabase), and on the back end only `be.integrations.supabase` imports them, every back-end client carrying the committed `Database` type; the front end holds no credential: `fe/` names no service-role or `*_SECRET`, `*_PRIVATE`, `*_TOKEN`, `*_PASSWORD` value (public configuration is read once by `modules/config`)."
|
|
3524
3707
|
kinds: [check, design]
|
|
3525
3708
|
gates: [settle, land, ci]
|
|
@@ -3527,52 +3710,74 @@ rules:
|
|
|
3527
3710
|
enforcers:
|
|
3528
3711
|
- {kind: machine, id: supabase-client-owner, at: scripts/hfs/architecture/supabase.mjs}
|
|
3529
3712
|
- {kind: machine, id: supabase-service-role, at: scripts/hfs/architecture/supabase.mjs}
|
|
3713
|
+
proves:
|
|
3714
|
+
- {path: packages/hfs/src/fe-supabase-client-owner.spec.mjs, editions: [lite, full], codes: [FE_SUPABASE_CLIENT_OWNER]}
|
|
3715
|
+
- {path: packages/hfs/src/r217-backend-client-owner.spec.mjs, editions: [lite, full], codes: [BE_SUPABASE_CLIENT_OWNER]}
|
|
3716
|
+
- {path: packages/hfs/src/fe-service-role-forbidden.spec.mjs, editions: [lite, full], codes: [FE_SERVICE_ROLE_FORBIDDEN]}
|
|
3717
|
+
exemplifiedBy:
|
|
3718
|
+
- {path: packages/hfs/templates/fe/auth/supabase-client.ts.tpl, editions: [lite, full]}
|
|
3719
|
+
- {path: packages/hfs/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.client.ts, edition: lite}
|
|
3720
|
+
- {path: packages/hfs/src/fe-supabase-client-owner.spec.mjs, editions: [lite, full]}
|
|
3721
|
+
- {path: packages/hfs/src/r217-backend-client-owner.spec.mjs, editions: [lite, full]}
|
|
3722
|
+
- {path: packages/hfs/src/fe-service-role-forbidden.spec.mjs, editions: [lite, full]}
|
|
3723
|
+
witness:
|
|
3724
|
+
- {path: packages/hfs/src/fe-supabase-client-owner.spec.mjs, edition: lite, codes: [FE_SUPABASE_CLIENT_OWNER]}
|
|
3725
|
+
- {path: packages/hfs/src/r217-backend-client-owner.spec.mjs, edition: lite, codes: [BE_SUPABASE_CLIENT_OWNER]}
|
|
3726
|
+
- {path: packages/hfs/src/fe-service-role-forbidden.spec.mjs, edition: lite, codes: [FE_SERVICE_ROLE_FORBIDDEN]}
|
|
3727
|
+
- {path: packages/hfs/src/fe-supabase-client-owner.spec.mjs, edition: full, codes: [FE_SUPABASE_CLIENT_OWNER]}
|
|
3728
|
+
- {path: packages/hfs/src/r217-backend-client-owner.spec.mjs, edition: full, codes: [BE_SUPABASE_CLIENT_OWNER]}
|
|
3729
|
+
- {path: packages/hfs/src/fe-service-role-forbidden.spec.mjs, edition: full, codes: [FE_SERVICE_ROLE_FORBIDDEN]}
|
|
3530
3730
|
- id: R219
|
|
3531
3731
|
code: "BE_SUPABASE_JWT_VERIFIED"
|
|
3532
3732
|
editions: [lite, full]
|
|
3533
3733
|
docs: [docs/lite-edition.md#r219]
|
|
3534
3734
|
templateNa: "Full-edition Supabase verification is an optional integration with no managed verifier scaffold; lite has the referenced integration template."
|
|
3535
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3536
|
-
exemplifiedBy:
|
|
3537
|
-
- {path: packages/hfs/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.jwks.ts, edition: lite}
|
|
3538
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3539
3735
|
law: "The principal is verified, never trusted: a back-end principal comes only from a Supabase access token verified against the project JWKS (signature, issuer, audience, expiry, pinned algorithm), never decoded unverified and never from the request body."
|
|
3540
3736
|
kinds: [check, design]
|
|
3541
3737
|
gates: [settle, land, ci]
|
|
3542
3738
|
failureCodes: ["BE_SUPABASE_JWT_VERIFIED"]
|
|
3543
3739
|
enforcers:
|
|
3544
3740
|
- {kind: machine, id: supabase-principal, at: scripts/hfs/architecture/supabase.mjs}
|
|
3741
|
+
proves:
|
|
3742
|
+
- {path: packages/hfs/src/be-supabase-jwt-verified.spec.mjs, editions: [lite, full]}
|
|
3743
|
+
exemplifiedBy:
|
|
3744
|
+
- {path: packages/hfs/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.jwks.ts, edition: lite}
|
|
3745
|
+
- {path: packages/hfs/src/be-supabase-jwt-verified.spec.mjs, editions: [lite, full]}
|
|
3746
|
+
witness:
|
|
3747
|
+
- {path: packages/hfs/src/be-supabase-jwt-verified.spec.mjs, edition: lite, codes: [BE_SUPABASE_JWT_VERIFIED]}
|
|
3748
|
+
- {path: packages/hfs/src/be-supabase-jwt-verified.spec.mjs, edition: full, codes: [BE_SUPABASE_JWT_VERIFIED]}
|
|
3545
3749
|
- id: R220
|
|
3546
3750
|
code: "HFS_LITE_SECRET_CUSTODY"
|
|
3547
3751
|
editions: [lite]
|
|
3548
3752
|
editionWhy: "ruling:lite-backing-services assigns Supabase backing to lite; R220 adds lite's reduced custody tree and Supabase/FE literal scan, while R06 governs plaintext secret material in both editions."
|
|
3549
3753
|
docs: [docs/host-secrets.md#application-secret-rules]
|
|
3550
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3551
|
-
exemplifiedBy:
|
|
3552
|
-
- {path: packages/hfs/templates/app/skeleton-lite/.sops.yaml, edition: lite}
|
|
3553
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3554
3754
|
law: "A lite app holds no secret material in the tree: root `.env*`, `secrets.env`, `.secrets/` and an `.enc` file outside `.starcistacks/<env>/secrets` are forbidden, and `fe/` and `supabase/` hold no Supabase token, JWT or connection string with a password; the one custody is the sealed `.starcistacks/<env>/secrets/<slug>.enc`."
|
|
3555
3755
|
kinds: [check]
|
|
3556
3756
|
gates: [settle, land, ci]
|
|
3557
3757
|
failureCodes: ["HFS_LITE_SECRET_CUSTODY"]
|
|
3558
3758
|
enforcers:
|
|
3559
3759
|
- {kind: hfs, id: lite-secret-custody, at: scripts/hfs/rules/supabase-secrets.mjs}
|
|
3760
|
+
proves:
|
|
3761
|
+
- {path: packages/hfs/src/hfs-supabase-secrets.spec.mjs, edition: lite}
|
|
3762
|
+
exemplifiedBy:
|
|
3763
|
+
- {path: packages/hfs/templates/app/skeleton-lite/.sops.yaml, edition: lite}
|
|
3764
|
+
- {path: packages/hfs/src/hfs-supabase-secrets.spec.mjs, edition: lite}
|
|
3765
|
+
witness:
|
|
3766
|
+
- {path: packages/hfs/src/hfs-supabase-secrets.spec.mjs, edition: lite}
|
|
3560
3767
|
- id: R221
|
|
3561
3768
|
code: "CI_TRIGGERS_RELEASE_ONLY"
|
|
3562
3769
|
law: "The only workflow triggers are a push of release tags, a push of release candidate branches `release/candidate-*`, a person dispatching it and, in the runtime's own workflows (`.github/workflows/` at the root), a push to `main`: every tracked workflow declares an `on` that holds only `push` filtered to `tags: ['v*']` and/or `branches` naming only `release/candidate-*` (and, in the runtime's own workflows, `main`; no paths or ignore filter beside them) and `workflow_dispatch`. Every `ci.yml`, and the runtime's `examples.yml`, must name `release/candidate-*`: `starci release cut` and `starci app release push` push the exact release sha there and move main and the tag only when that run is green (owner ruling candidate-ci, 2026-10-18). A push to any other branch, a pull_request, a schedule, a workflow_call or any other event refuses the workflow."
|
|
3563
3770
|
scope: runtime
|
|
3564
3771
|
editions: [lite, full]
|
|
3565
3772
|
docs: [docs/git-governance.md#r221]
|
|
3566
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3567
|
-
exemplifiedBy:
|
|
3568
|
-
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
3569
|
-
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
3570
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3571
3773
|
kinds: [check]
|
|
3572
3774
|
gates: [runtime]
|
|
3573
3775
|
failureCodes: ["CI_TRIGGERS_RELEASE_ONLY"]
|
|
3574
3776
|
enforcers:
|
|
3575
3777
|
- {kind: runtime, id: git-triggers, at: scripts/hfs/runtime-rules/git-triggers.mjs}
|
|
3778
|
+
exemplifiedBy:
|
|
3779
|
+
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
3780
|
+
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
3576
3781
|
- id: R222
|
|
3577
3782
|
code: "RELEASE_NOTES"
|
|
3578
3783
|
law: "A release tag `v<version>` on HEAD has its CHANGELOG.md section `## [<version>]` with no TODO, PENDING or TBD left in it and no `in preparation` mark: the tag message and the GitHub Release are that section, so a tag is never cut over an unfinished or missing section."
|
|
@@ -3580,14 +3785,11 @@ rules:
|
|
|
3580
3785
|
editions: [lite, full]
|
|
3581
3786
|
docs: [docs/git-governance.md#r222]
|
|
3582
3787
|
templateNa: "Release tags at HEAD and their finished changelog sections are authored release evidence, not app scaffold output."
|
|
3583
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3584
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3585
3788
|
kinds: [check]
|
|
3586
3789
|
gates: [runtime]
|
|
3587
3790
|
failureCodes: ["RELEASE_NOTES"]
|
|
3588
3791
|
enforcers:
|
|
3589
3792
|
- {kind: runtime, id: release-notes, at: scripts/hfs/runtime-rules/release-notes.mjs}
|
|
3590
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3591
3793
|
- id: R223
|
|
3592
3794
|
code: "RIGHTS_ROLE_DENIED"
|
|
3593
3795
|
law: "By the caller's role, the command guard refuses git push, git tag, raw git commit/add/rm/mv, raw git synchronization writes, npm publish, a whole-suite run outside the release cut and unit.verify/e2e.verify, npm ci without the host lock, a release cut, and raw side-effecting tools; modules/kernel/command-policy.yaml is the one rule table read by both the PreToolUse guard and the PATH shim."
|
|
@@ -3597,7 +3799,6 @@ rules:
|
|
|
3597
3799
|
failureCodes: ["RIGHTS_ROLE_DENIED", "RIGHTS_GIT_PUSH", "RIGHTS_GIT_TAG", "RIGHTS_GIT_COMMIT", "RIGHTS_GIT_SYNC", "RIGHTS_NPM_PUBLISH", "RIGHTS_NPM_CI_UNLOCKED", "RIGHTS_SUITE_RUN", "RIGHTS_RELEASE_CUT", "RIGHTS_RAW_TOOL"]
|
|
3598
3800
|
enforcers:
|
|
3599
3801
|
- {kind: runtime, id: role-rights, at: scripts/hfs/runtime-rules/rights-policy.mjs}
|
|
3600
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3601
3802
|
- id: R224
|
|
3602
3803
|
code: "RIGHTS_PROTECTED_ZONE"
|
|
3603
3804
|
law: "The protected zone declared once in modules/kernel/protected-zone.yaml is edited only by the owner path; a supervisor self-upgrade files an owner proposal, and an op never writes the .claude runtime checkout."
|
|
@@ -3607,7 +3808,6 @@ rules:
|
|
|
3607
3808
|
failureCodes: ["RIGHTS_PROTECTED_ZONE", "RIGHTS_OP_RUNTIME_WRITE"]
|
|
3608
3809
|
enforcers:
|
|
3609
3810
|
- {kind: runtime, id: protected-zone, at: scripts/hfs/runtime-rules/rights-policy.mjs}
|
|
3610
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3611
3811
|
- id: R225
|
|
3612
3812
|
code: "RT_HOOK_SHAPE"
|
|
3613
3813
|
law: "The app hook templates keep the gate model: pre-commit is L0 only (no typecheck, no test run); pre-push checks the release gate (the starci-release L4 record, refs/backup/, v[0-9] tags; the runtime's own hook is scripts/guards/release-push-gate.mjs, which judges main and v* tags against the release definition and lets every other ref through) and runs no npm test, jest, typecheck or lint."
|
|
@@ -3617,14 +3817,11 @@ rules:
|
|
|
3617
3817
|
failureCodes: ["RT_HOOK_SHAPE", "RIGHTS_PUSH_NOT_RELEASE"]
|
|
3618
3818
|
enforcers:
|
|
3619
3819
|
- {kind: runtime, id: hook-shape, at: scripts/hfs/runtime-rules/hook-shape.mjs}
|
|
3620
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3621
3820
|
- id: R227
|
|
3622
3821
|
code: "RT_SYNTAX_INVALID"
|
|
3623
3822
|
editions: [lite, full]
|
|
3624
3823
|
docs: [docs/source-process.md#r227]
|
|
3625
3824
|
templateNa: "The runtime syntax check judges tracked authored JavaScript, not a scaffolded application surface."
|
|
3626
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3627
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3628
3825
|
law: "Every git-tracked .mjs, .cjs and .js file parses as JavaScript, including tests and package sources; node_modules, generated roots of ruleParams.runtime.generated and vendored build output are outside the authored-source scope. The runtime folder's Node-exact syntax pass remains in place, while this batched in-process pass extends coverage to the whole tracked repository and reports every parser diagnostic at its file and line."
|
|
3629
3826
|
scope: runtime
|
|
3630
3827
|
kinds: [check]
|
|
@@ -3632,7 +3829,6 @@ rules:
|
|
|
3632
3829
|
failureCodes: ["RT_SYNTAX_INVALID"]
|
|
3633
3830
|
enforcers:
|
|
3634
3831
|
- {kind: runtime, id: syntax, at: scripts/hfs/runtime-rules/syntax.mjs}
|
|
3635
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3636
3832
|
- id: R228
|
|
3637
3833
|
code: "RT_IDENTIFIER_UNDECLARED"
|
|
3638
3834
|
law: "Every identifier a runtime ES module (scripts/, engine/ without the vendored yaml bundle, ui/api/, packages/cli/bin and src) reads or writes resolves, by scope analysis over its TypeScript syntax tree, to a declaration, import, parameter or Node global of an enclosing scope. A re-export (export {x} from './y.mjs') binds x in no local scope; require, module, exports and __dirname are not globals of a module; browser globals resolve only inside a function that a module hands to page.evaluate, here or through an import. A name a refactor left behind is refused before the line that reads it runs."
|
|
@@ -3645,9 +3841,6 @@ rules:
|
|
|
3645
3841
|
editions: [lite, full]
|
|
3646
3842
|
docs: [docs/source-process.md#r228]
|
|
3647
3843
|
templateNa: "This check scans authored runtime ES modules; app scaffolds do not contain these harness modules."
|
|
3648
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3649
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3650
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3651
3844
|
- id: R229
|
|
3652
3845
|
code: "RT_REMOVED_VOCABULARY"
|
|
3653
3846
|
law: "No text an agent or the owner reads teaches a spelling the runtime refuses. The refused names - config keys, routing-bias fields, verbs, flags, codes and vocabulary - are the one list modules/kernel/removed-vocabulary.yaml, each with its replacement and the release that removed it; the config and routing-bias refusals read the same list. Every tracked file of skills/, docs/, README.md, CONTEXT.md, CONTRIBUTING.md, modules/ and knowledge/ (Markdown and yaml) is scanned line by line, and a line that spells a listed name is a finding naming file:line, the name and its replacement unless the file is the list, CHANGELOG.md, or the line or block carries the [removed-list] marker (a marker alone on a comment line covers the lines up to the next blank one). Removing or renaming a key, flag, verb, field or code adds its entry to the list in the same commit."
|
|
@@ -3660,9 +3853,6 @@ rules:
|
|
|
3660
3853
|
editions: [lite, full]
|
|
3661
3854
|
docs: [docs/source-process.md#r229]
|
|
3662
3855
|
templateNa: "The removed-name catalog and authored runtime instructions are maintained repository surfaces, not app scaffold output."
|
|
3663
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3664
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3665
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3666
3856
|
- id: R230
|
|
3667
3857
|
code: "RT_PROSE_COMMAND_UNKNOWN"
|
|
3668
3858
|
law: "A command an instruction shows exists as written. Every `starci <group> <verb>` in a backticked span, fenced code line or yaml example item of skills/, docs/, README.md, CONTEXT.md, CONTRIBUTING.md and modules/ names a verb of the CLI catalog (modules/cli/commands) in a catalogued group, and every --flag on it is a flag of that verb or a global flag; the text after a lone -- belongs to another program and a [removed-list] marked line is exempt. The catalog is generated into the valid set, never typed twice."
|
|
@@ -3670,14 +3860,11 @@ rules:
|
|
|
3670
3860
|
editions: [lite, full]
|
|
3671
3861
|
docs: [docs/debugging.md#r230-instruction-commands]
|
|
3672
3862
|
templateNa: "Runtime instruction and contract self-checks judge authored runtime surfaces; application scaffolds do not contain this surface."
|
|
3673
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3674
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3675
3863
|
kinds: [check]
|
|
3676
3864
|
gates: [runtime]
|
|
3677
3865
|
failureCodes: ["RT_PROSE_COMMAND_UNKNOWN"]
|
|
3678
3866
|
enforcers:
|
|
3679
3867
|
- {kind: runtime, id: prose-commands, at: scripts/checks/check-prose-commands.mjs}
|
|
3680
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3681
3868
|
- id: R231
|
|
3682
3869
|
code: "RT_DOCUMENTED_DEFAULT_DRIFT"
|
|
3683
3870
|
law: "A default a document states equals the value the code reads. A document states a default by citing its key - default <value> = `<key>` - where the key is a config.yaml path (resolved through the validator's settings reader, so an absent block yields its code default) or <yaml file under modules/>:<dotted path>; the check resolves the key and compares, and a key that resolves to nothing is a finding. docs/, README.md, CONTEXT.md, config.example.yaml and modules/ prose and yaml are scanned; a bare number stated as a default without its key is not judged, so the owner of a default is cited, never retyped."
|
|
@@ -3685,14 +3872,11 @@ rules:
|
|
|
3685
3872
|
editions: [lite, full]
|
|
3686
3873
|
docs: [docs/debugging.md#r231-documented-defaults]
|
|
3687
3874
|
templateNa: "Runtime instruction and contract self-checks judge authored runtime surfaces; application scaffolds do not contain this surface."
|
|
3688
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3689
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3690
3875
|
kinds: [check]
|
|
3691
3876
|
gates: [runtime]
|
|
3692
3877
|
failureCodes: ["RT_DOCUMENTED_DEFAULT_DRIFT"]
|
|
3693
3878
|
enforcers:
|
|
3694
3879
|
- {kind: runtime, id: documented-defaults, at: scripts/checks/check-documented-defaults.mjs}
|
|
3695
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3696
3880
|
- id: R232
|
|
3697
3881
|
code: "RT_ROLES_CONTRACT_DRIFT"
|
|
3698
3882
|
law: "A role is described once. modules/kernel/roles.yaml holds, per role, its scope, what it does, what it must clean up, what it never does, whom it reports to and who oversees it; a Markdown surface of the role carries the block generated from it, a yaml or script surface cites modules/kernel/roles.yaml#<role>, and no surface teaches a spelling the role's contradicts list names."
|
|
@@ -3700,14 +3884,11 @@ rules:
|
|
|
3700
3884
|
editions: [lite, full]
|
|
3701
3885
|
docs: [docs/debugging.md#r232-generated-role-contracts]
|
|
3702
3886
|
templateNa: "Runtime instruction and contract self-checks judge authored runtime surfaces; application scaffolds do not contain this surface."
|
|
3703
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3704
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3705
3887
|
kinds: [check]
|
|
3706
3888
|
gates: [runtime]
|
|
3707
3889
|
failureCodes: ["RT_ROLES_CONTRACT_DRIFT"]
|
|
3708
3890
|
enforcers:
|
|
3709
3891
|
- {kind: runtime, id: roles-contract, at: scripts/checks/check-roles-contract.mjs}
|
|
3710
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3711
3892
|
- id: R233
|
|
3712
3893
|
code: "RT_EDGE_CASE_REGISTRY"
|
|
3713
3894
|
law: "Every edge case met is a declared entry of modules/reconciler/edge-cases.yaml with its family, its real occurrence and a status of covered or open; a covered entry names the rule that handles it and that file exists, a named spec is a package spec or the scaffold e2e that exists (never a runtime test, owner ruling no-runtime-specs), and an open entry says why."
|
|
@@ -3715,21 +3896,16 @@ rules:
|
|
|
3715
3896
|
editions: [lite, full]
|
|
3716
3897
|
docs: [docs/debugging.md#r233-edge-case-evidence]
|
|
3717
3898
|
templateNa: "Runtime instruction and contract self-checks judge authored runtime surfaces; application scaffolds do not contain this surface."
|
|
3718
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3719
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3720
3899
|
kinds: [check]
|
|
3721
3900
|
gates: [runtime]
|
|
3722
3901
|
failureCodes: ["RT_EDGE_CASE_REGISTRY"]
|
|
3723
3902
|
enforcers:
|
|
3724
3903
|
- {kind: runtime, id: edge-case-registry, at: scripts/checks/check-edge-case-registry.mjs}
|
|
3725
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3726
3904
|
- id: R234
|
|
3727
3905
|
code: "RT_SECRET_TRACKED"
|
|
3728
3906
|
editions: [lite, full]
|
|
3729
3907
|
docs: [docs/application-stacks.md#where-a-secret-may-live]
|
|
3730
3908
|
templateNa: "The public runtime repository secret policy judges Git-tracked custody paths; application scaffolds do not contain runtime host secrets."
|
|
3731
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3732
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3733
3909
|
law: "The runtime repository is public and tracks no secret material, not even ciphertext: no tracked *.enc member and no tracked secret.env or .env file, except the paths ruleParams.runtime.heldSecrets names with their reason (a list that only shrinks). Every secret the host needs lives in the one untracked .claude/secret.env, read only through engine/secrets.mjs, its names listed in the tracked secret.env.example; a product repository keeps its own custody in its own repository. Two Sonar servers, no overlap: SonarCloud serves everything that lives in the runtime repository (the runtime and the example apps, token SONAR_TOKEN), the self-hosted ext/sonar serves product repositories only."
|
|
3734
3910
|
scope: runtime
|
|
3735
3911
|
kinds: [check]
|
|
@@ -3737,7 +3913,6 @@ rules:
|
|
|
3737
3913
|
failureCodes: ["RT_SECRET_TRACKED"]
|
|
3738
3914
|
enforcers:
|
|
3739
3915
|
- {kind: runtime, id: secret-tracked, at: scripts/hfs/runtime-rules/secret-tracked.mjs}
|
|
3740
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3741
3916
|
- id: R235
|
|
3742
3917
|
code: "SCAN_SMELL"
|
|
3743
3918
|
editions: [lite, full]
|
|
@@ -3782,8 +3957,6 @@ rules:
|
|
|
3782
3957
|
editions: [lite, full]
|
|
3783
3958
|
docs: [docs/debugging.md#r236]
|
|
3784
3959
|
templateNa: "Runtime release history is judged against the committed gates of the last release; product scaffolding has no runtime release history to generate."
|
|
3785
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3786
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3787
3960
|
law: "A change that loosens a gate or check is always red: a check removed from a gate file's list, a floor lowered or a ceiling raised there, an allowlist entry added, a spec deleted or weakened or skipped together with product code (modules/kernel/gate-loosening.yaml). It never lands and never passes the check; there is no approval route, the owner's included (owner:loosening-always-red), and the fix is to restore the gate. An entry that only moves with a git rename of the paths it names is no loosening."
|
|
3788
3961
|
scope: runtime
|
|
3789
3962
|
kinds: [check]
|
|
@@ -3791,14 +3964,11 @@ rules:
|
|
|
3791
3964
|
failureCodes: ["RT_GATE_LOOSENING"]
|
|
3792
3965
|
enforcers:
|
|
3793
3966
|
- {kind: runtime, id: gate-loosening, at: scripts/checks/check-gate-loosening.mjs}
|
|
3794
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3795
3967
|
- id: R237
|
|
3796
3968
|
code: "RT_REVISION_SCOPE"
|
|
3797
3969
|
editions: [lite, full]
|
|
3798
3970
|
docs: [docs/debugging.md#r237]
|
|
3799
3971
|
templateNa: "The runtime revision-scope table and derived engine import graph are runtime authoring surfaces, not generated application files."
|
|
3800
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3801
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3802
3972
|
law: "What a change of the runtime tree asks of each role is declared once, in modules/kernel/revision-scope.yaml: every tracked path matches a row, the engine-loaded files are derived from the import graph of the engine's entries and never hand-listed, the files each seat's launch prompt is built from are the files its generator reads, and a wording-only declaration holds only for an edit that keeps the file's structure."
|
|
3803
3973
|
scope: runtime
|
|
3804
3974
|
kinds: [check]
|
|
@@ -3806,7 +3976,6 @@ rules:
|
|
|
3806
3976
|
failureCodes: ["RT_REVISION_SCOPE"]
|
|
3807
3977
|
enforcers:
|
|
3808
3978
|
- {kind: runtime, id: revision-scope, at: scripts/checks/check-revision-scope.mjs}
|
|
3809
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3810
3979
|
- id: R238
|
|
3811
3980
|
code: "RT_EVENT_SPILL_BYPASS"
|
|
3812
3981
|
law: "A ledger event payload that grows with its input (a file list, a manifest, a digest, a report, a critique, a menu) goes to the blob store through the one path of appendEvent: engine/db/event-compact.mjs eventPayloadRecord keeps a bounded inline view of at most 16 KiB and the whole payload behind events.payload_sha, and readers resolve it through engine/db/event-payload.mjs. No runtime source file other than engine/db/ledger.mjs and engine/db/event-compact.mjs passes a payloadSha to a write, catches the payload-too-large refusal to spill by hand, or inserts into the events table directly. Specs, tests, node_modules, the generated runtime copies and packages are out of scope."
|
|
@@ -3814,14 +3983,11 @@ rules:
|
|
|
3814
3983
|
editions: [lite, full]
|
|
3815
3984
|
docs: [docs/ledger-db.md#the-storage-convention-owner-ruling-2026-10-09]
|
|
3816
3985
|
templateNa: "These runtime checker inputs are maintained in the runtime repository, not scaffolded in a product app."
|
|
3817
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3818
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3819
3986
|
kinds: [check]
|
|
3820
3987
|
gates: [runtime]
|
|
3821
3988
|
failureCodes: ["RT_EVENT_SPILL_BYPASS"]
|
|
3822
3989
|
enforcers:
|
|
3823
3990
|
- {kind: runtime, id: event-spill, at: scripts/checks/check-event-spill.mjs}
|
|
3824
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3825
3991
|
- id: R239
|
|
3826
3992
|
code: "RT_STORAGE_UNDECLARED"
|
|
3827
3993
|
law: "Content lives as a file in the content-addressed blob store under the runtime state dir (<runtime root>/.runtime/artifacts, engine/db/blob.mjs) and a database row holds only the reference (the sha) plus the small scalars it is queried by (owner ruling 2026-10-09). Always content, whatever its size: a report, a critique or verdict, a prompt or dispatch contract, a read manifest, a list of files, a log or command output, a menu or digest snapshot, an image or render, a diff. What may stay inline: ids, states, timestamps, counts, short codes and one-line reasons up to 256 bytes; any other free text up to 1024 bytes; a payload of any size is class spill (appendEvent and supEvent keep the whole payload behind the sha and a small inline form). Every text column of the product ledger and of machine.sqlite is declared in modules/schemas/storage-convention.yaml with its class (scalar, bounded, reference, spill, migrate), so a new table or column cannot appear without one; a column that holds content inline today is class migrate with its measured size, and the migration to a reference is a proposed runtime step, idempotent and journalled, never a hand rewrite of a live store."
|
|
@@ -3829,14 +3995,11 @@ rules:
|
|
|
3829
3995
|
editions: [lite, full]
|
|
3830
3996
|
docs: [docs/ledger-db.md#the-storage-convention-owner-ruling-2026-10-09]
|
|
3831
3997
|
templateNa: "These runtime checker inputs are maintained in the runtime repository, not scaffolded in a product app."
|
|
3832
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3833
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3834
3998
|
kinds: [check]
|
|
3835
3999
|
gates: [runtime]
|
|
3836
4000
|
failureCodes: ["RT_STORAGE_UNDECLARED"]
|
|
3837
4001
|
enforcers:
|
|
3838
4002
|
- {kind: runtime, id: storage-convention, at: scripts/checks/check-storage-convention.mjs}
|
|
3839
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3840
4003
|
- id: R240
|
|
3841
4004
|
code: "RT_ROOT_ADHOC"
|
|
3842
4005
|
law: "Which directory a component reads or writes is decided in one module, scripts/lib/roots.mjs: the runtime tree, its state directory, the temp root, the invocation directory, the Work directory name, the order in which two trees that can hold the same record are tried (the tree the work happens in first, then the product's main checkout: workDirHolding, workRecordPath) and the order a tool is looked up (the tree the work happens in, then the project, the runtime's own install last: toolSearchDirs). A runtime source file does not resolve a root by itself: it neither spells process.cwd() nor the Work directory name as a literal outside that module more often than the tree the check landed on held it: a file keeps the count it had and only loses it as it is converted, and a new file starts at none. Four times in two days a component read or wrote the wrong tree because it resolved the directory itself."
|
|
@@ -3844,14 +4007,11 @@ rules:
|
|
|
3844
4007
|
editions: [lite, full]
|
|
3845
4008
|
docs: [docs/architecture.md#r240]
|
|
3846
4009
|
templateNa: "These runtime checker inputs are maintained in the runtime repository, not scaffolded in a product app."
|
|
3847
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3848
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3849
4010
|
kinds: [check]
|
|
3850
4011
|
gates: [runtime]
|
|
3851
4012
|
failureCodes: ["RT_ROOT_ADHOC"]
|
|
3852
4013
|
enforcers:
|
|
3853
4014
|
- {kind: runtime, id: root-adhoc, at: scripts/checks/check-root-adhoc.mjs}
|
|
3854
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3855
4015
|
- id: R241
|
|
3856
4016
|
code: "RT_HELD_UNSURFACED"
|
|
3857
4017
|
law: "A failure code the catalogue gives to the Supervisor or the owner as a runtime fault is a state that role must be able to learn of; a stop that nobody is told of stands for hours until someone reads source. Each such entry of modules/kernel/failure-codes.yaml names the house mechanism that reaches its owner (surfacedBy: decision-item, sla-clock, incident, digest, notifier, caller or open) with surfacedAs (the item kind, clock code, incident kind, digest problem line or urgent class) and surfacedAt (the file that does it), and the check proves the mechanism exists and is wired in that file: the kind is a Decision Item kind and the file opens items naming it, the code is an SLA code with an owner and the file sets its clock, the problem line is a departure of the operating standard, a caller is a verb the owning role ran itself and never a reconciler file (a loop is no owner). An entry nothing reaches is surfacedBy open and names an open edge-case registry entry with the exact reason; it is never exempted silently."
|
|
@@ -3859,14 +4019,11 @@ rules:
|
|
|
3859
4019
|
editions: [lite, full]
|
|
3860
4020
|
docs: [docs/debugging.md#r241]
|
|
3861
4021
|
templateNa: "These runtime checker inputs are maintained in the runtime repository, not scaffolded in a product app."
|
|
3862
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3863
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3864
4022
|
kinds: [check]
|
|
3865
4023
|
gates: [runtime]
|
|
3866
4024
|
failureCodes: ["RT_HELD_UNSURFACED"]
|
|
3867
4025
|
enforcers:
|
|
3868
4026
|
- {kind: runtime, id: held-surfacing, at: scripts/checks/check-held-surfacing.mjs}
|
|
3869
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3870
4027
|
- id: R242
|
|
3871
4028
|
code: "RT_OP_JUDGE_UNDECLARED"
|
|
3872
4029
|
law: "Every op declares who judges its product (principle P2: the maker never judges its own work). The contract of each op (modules/ops/ops/<op>.yaml) carries the required field `judge`, a list of at least one entry, each with a one-line why: machine (independent measures the runtime owns or re-runs at settle, named from modules/kernel/op-judges.yaml, and the contract proofs they rely on; a test file the same attempt wrote is never one by itself), critic (the independent Critic and its rubric, declared exactly for the op kinds that modules/kernel/critic.yaml coverage marks covered), owner (only where modules/kernel/op-judges.yaml ownerGates holds an owner gate) and next-leg (a registered reviewing leg whose contract is to review this product). Nobody cannot be declared. The registry and the contracts are checked against the runtime's own tables (op-gate and sonar-gate enforcedOps, opProofs, proof media, the Critic coverage), so the declarations and what the runtime does cannot drift apart. Surfaced in the full status text of a leg and in the op prompt."
|
|
@@ -3874,24 +4031,15 @@ rules:
|
|
|
3874
4031
|
editions: [lite, full]
|
|
3875
4032
|
docs: [docs/ops.md#r242]
|
|
3876
4033
|
templateNa: "These runtime checker inputs are maintained in the runtime repository, not scaffolded in a product app."
|
|
3877
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3878
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3879
4034
|
kinds: [check]
|
|
3880
4035
|
gates: [runtime]
|
|
3881
4036
|
failureCodes: ["RT_OP_JUDGE_UNDECLARED"]
|
|
3882
4037
|
enforcers:
|
|
3883
4038
|
- {kind: runtime, id: op-judge, at: scripts/checks/check-op-judge.mjs}
|
|
3884
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3885
4039
|
- id: R243
|
|
3886
4040
|
code: "FE_SERVER_ACTION_FORBIDDEN"
|
|
3887
4041
|
editions: [lite, full]
|
|
3888
4042
|
docs: [docs/code-pattern-enforcement.md#r243]
|
|
3889
|
-
proves:
|
|
3890
|
-
- {path: packages/eslint/fe/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_SERVER_ACTION_FORBIDDEN]}
|
|
3891
|
-
exemplifiedBy:
|
|
3892
|
-
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/app/health/live/route.ts, edition: lite}
|
|
3893
|
-
- {path: packages/hfs/templates/fe/skeleton/apps/app/src/app/health/live/route.ts, edition: full}
|
|
3894
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3895
4043
|
law: "The front end serves no API, in every app and edition (R212 case-2 (owner:lite-production-swarm), with the Work boundary amended by ruling:R212/case-4): no file under `fe/` carries a `\"use server\"` directive (module or function level), and the only route handlers are `app/health/live/route.ts` and the auth callback of the `fe.route.callback` slot; reads and writes reach the back end through `modules/api` and the SWR hooks, and a webhook, cron, public API or third-party callback is a back-end feature."
|
|
3896
4044
|
kinds: [check, lint]
|
|
3897
4045
|
gates: [pre-commit, settle, land, ci]
|
|
@@ -3899,17 +4047,19 @@ rules:
|
|
|
3899
4047
|
enforcers:
|
|
3900
4048
|
- {kind: machine, id: server-action-forbidden, at: scripts/hfs/architecture/server-action.mjs}
|
|
3901
4049
|
- {kind: eslint-fe, id: no-server-action}
|
|
3902
|
-
|
|
4050
|
+
proves:
|
|
4051
|
+
- {path: packages/eslint/fe/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_SERVER_ACTION_FORBIDDEN]}
|
|
4052
|
+
- {path: packages/hfs/src/frontend-boundary-coverage.spec.mjs, editions: [lite, full]}
|
|
4053
|
+
exemplifiedBy:
|
|
4054
|
+
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/app/health/live/route.ts, edition: lite}
|
|
4055
|
+
- {path: packages/hfs/templates/fe/skeleton/apps/app/src/app/health/live/route.ts, edition: full}
|
|
4056
|
+
- {path: packages/hfs/src/frontend-boundary-coverage.spec.mjs, editions: [lite, full]}
|
|
4057
|
+
witness:
|
|
4058
|
+
- {path: packages/hfs/src/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_SERVER_ACTION_FORBIDDEN, FE_ROUTE_HANDLER_FORBIDDEN]}
|
|
3903
4059
|
- id: R244
|
|
3904
4060
|
code: "FE_STACK_FORBIDDEN"
|
|
3905
4061
|
editions: [lite, full]
|
|
3906
4062
|
docs: [docs/code-pattern-enforcement.md#r244]
|
|
3907
|
-
proves:
|
|
3908
|
-
- {path: packages/eslint/fe/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_STACK_FORBIDDEN]}
|
|
3909
|
-
exemplifiedBy:
|
|
3910
|
-
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/proxy.ts, edition: lite}
|
|
3911
|
-
- {path: packages/hfs/templates/fe/skeleton/apps/app/src/proxy.ts, edition: full}
|
|
3912
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3913
4063
|
law: "A front end uses the one canonical library of each concern of knowledge/hfs/fe-stack.yaml: no front-end package.json (an app or a `fe/packages/*` package) depends on, and no source file under `fe/` imports, a package that the catalog lists under a concern's `forbids`; a missing concern is added to the catalog (with its pin in canon-pins.yaml), never installed beside it."
|
|
3914
4064
|
kinds: [check, lint]
|
|
3915
4065
|
gates: [pre-commit, settle, land, ci]
|
|
@@ -3917,7 +4067,15 @@ rules:
|
|
|
3917
4067
|
enforcers:
|
|
3918
4068
|
- {kind: hfs, id: fe-stack, at: scripts/hfs/rules/fe-stack.mjs}
|
|
3919
4069
|
- {kind: eslint-fe, id: fe-stack-import}
|
|
3920
|
-
|
|
4070
|
+
proves:
|
|
4071
|
+
- {path: packages/eslint/fe/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_STACK_FORBIDDEN]}
|
|
4072
|
+
- {path: packages/hfs/src/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_STACK_FORBIDDEN]}
|
|
4073
|
+
exemplifiedBy:
|
|
4074
|
+
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/proxy.ts, edition: lite}
|
|
4075
|
+
- {path: packages/hfs/templates/fe/skeleton/apps/app/src/proxy.ts, edition: full}
|
|
4076
|
+
- {path: packages/hfs/src/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_STACK_FORBIDDEN]}
|
|
4077
|
+
witness:
|
|
4078
|
+
- {path: packages/hfs/src/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_STACK_FORBIDDEN]}
|
|
3921
4079
|
- id: R245
|
|
3922
4080
|
code: "BE_APP_OPTIONS_COMPOSITION"
|
|
3923
4081
|
amendedBy: R289
|
|
@@ -3962,74 +4120,71 @@ rules:
|
|
|
3962
4120
|
editions: [lite, full]
|
|
3963
4121
|
docs: [docs/quality-bar.md#coverage-matrix]
|
|
3964
4122
|
templateNa: "The runtime coverage checker judges authored catalogs and proof metadata; app scaffolds do not contain this runtime surface."
|
|
3965
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3966
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3967
4123
|
kinds: [check]
|
|
3968
4124
|
gates: [runtime]
|
|
3969
4125
|
failureCodes: ["RT_COVERAGE_MATRIX", "RT_COVERAGE_NO_ENFORCER", "RT_COVERAGE_NO_SPEC", "RT_COVERAGE_NO_WITNESS", "RT_COVERAGE_NO_DOC", "RT_COVERAGE_NO_TEMPLATE", "RT_COVERAGE_NO_EXAMPLE", "RT_COVERAGE_EDITION_ASYMMETRY", "RT_COVERAGE_SCHEMA_NO_RECORD", "RT_COVERAGE_GATE_LIE", "RT_COVERAGE_SUPERSEDED_CITE", "RT_COVERAGE_SURFACE_UNMAPPED", "RT_COVERAGE_REQUIREMENT_UNLEDGERED", "RT_COVERAGE_PROOF_VACUOUS", "RT_COVERAGE_CODE_UNROUTED"]
|
|
3970
4126
|
enforcers:
|
|
3971
4127
|
- {kind: runtime, id: hfs-coverage, at: scripts/checks/check-hfs-coverage.mjs}
|
|
3972
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
3973
4128
|
- id: R248
|
|
3974
4129
|
code: "ENV_REQUIRED_UNSET"
|
|
3975
4130
|
editions: [lite, full]
|
|
3976
4131
|
docs: [docs/host-secrets.md#r248]
|
|
3977
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3978
|
-
exemplifiedBy:
|
|
3979
|
-
- {path: packages/hfs/templates/be/skeleton-lite/apps/api/src/api.env.ts, edition: lite}
|
|
3980
|
-
- {path: packages/hfs/templates/be/skeleton/apps/__app__/src/__app__.env.ts, edition: full}
|
|
3981
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3982
4132
|
law: "The environment keys a back end reads through its typed `EnvSource` (`<app>.env.ts` and the capability `*.config.ts` parse helpers, resolved by a static TypeScript walk that substitutes the literal arguments of a reader's call sites into a template key such as `${prefix}_WEBHOOK_SECRET`), the key names sealed in `.starcistacks/<env>/secrets/*.enc` and the keys the stack declares or passes (`KEYS.md`, `environment:`/`env:` entries, `runtimeSecrets`, `vars[].name`) are one set, compared by name only in both editions: a required read is sealed or declared (ENV_REQUIRED_UNSET), a sealed key is read or has a declared consumer (ENV_SEALED_UNREAD), one key lives in one member (ENV_DUPLICATE), no `NEXT_PUBLIC_*` key is sealed (ENV_PUBLIC_SEALED) and every `*.env.example` key is read (ENV_EXAMPLE_DRIFT)."
|
|
3983
4133
|
kinds: [check]
|
|
3984
4134
|
gates: [settle, land, ci]
|
|
3985
4135
|
failureCodes: ["ENV_REQUIRED_UNSET", "ENV_SEALED_UNREAD", "ENV_DUPLICATE", "ENV_PUBLIC_SEALED", "ENV_EXAMPLE_DRIFT"]
|
|
3986
4136
|
enforcers:
|
|
3987
4137
|
- {kind: hfs, id: env-parity, at: scripts/hfs/rules/env-parity.mjs}
|
|
3988
|
-
|
|
4138
|
+
proves:
|
|
4139
|
+
- {path: packages/hfs/src/hfs-env-parity.spec.mjs, editions: [lite, full]}
|
|
4140
|
+
exemplifiedBy:
|
|
4141
|
+
- {path: packages/hfs/templates/be/skeleton-lite/apps/api/src/api.env.ts, edition: lite}
|
|
4142
|
+
- {path: packages/hfs/templates/be/skeleton/apps/__app__/src/__app__.env.ts, edition: full}
|
|
4143
|
+
- {path: packages/hfs/src/hfs-env-parity.spec.mjs, editions: [lite, full]}
|
|
4144
|
+
witness:
|
|
4145
|
+
- {path: packages/hfs/src/hfs-env-parity.spec.mjs, editions: [lite, full]}
|
|
3989
4146
|
- id: R249
|
|
3990
4147
|
code: "ENV_VALUE_SHAPE"
|
|
3991
4148
|
editions: [lite, full]
|
|
3992
4149
|
docs: [docs/host-secrets.md#r249]
|
|
3993
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
3994
|
-
exemplifiedBy:
|
|
3995
|
-
- {path: packages/hfs/templates/be/skeleton-lite/apps/api/src/api.env.ts, edition: lite}
|
|
3996
|
-
- {path: packages/hfs/templates/be/skeleton/apps/__app__/src/__app__.env.ts, edition: full}
|
|
3997
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
3998
4150
|
law: "A stored environment value parses as the type its `EnvSource` reader declares (an integer, `true`/`false`, an absolute URL, a duration `250`/`30s`/`5m`/`2h`, a member of the declared enum, a nonempty string or secret): `starci app secret verify <env>` decrypts every member in memory and reports each key and its violated shape, never a value, and a concrete (non-placeholder) value of a `*.env.example` parses the same way."
|
|
3999
4151
|
kinds: [check]
|
|
4000
4152
|
gates: [settle, land, ci]
|
|
4001
4153
|
failureCodes: ["ENV_VALUE_SHAPE"]
|
|
4002
4154
|
enforcers:
|
|
4003
4155
|
- {kind: hfs, id: env-value-shape, at: scripts/hfs/rules/env-value-shape.mjs}
|
|
4004
|
-
|
|
4005
|
-
|
|
4156
|
+
proves:
|
|
4157
|
+
- {path: packages/hfs/src/hfs-env-parity.spec.mjs, editions: [lite, full]}
|
|
4158
|
+
exemplifiedBy:
|
|
4159
|
+
- {path: packages/hfs/templates/be/skeleton-lite/apps/api/src/api.env.ts, edition: lite}
|
|
4160
|
+
- {path: packages/hfs/templates/be/skeleton/apps/__app__/src/__app__.env.ts, edition: full}
|
|
4161
|
+
- {path: packages/hfs/src/hfs-env-parity.spec.mjs, editions: [lite, full]}
|
|
4162
|
+
witness:
|
|
4163
|
+
- {path: packages/hfs/src/hfs-env-parity.spec.mjs, editions: [lite, full]}
|
|
4006
4164
|
- id: R250
|
|
4007
4165
|
code: "HFS_HOST_CRON"
|
|
4008
4166
|
editions: [lite, full]
|
|
4009
4167
|
docs:
|
|
4010
4168
|
- {path: docs/application-stacks.md#r250-deploy-scan, editions: [lite, full]}
|
|
4011
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
4012
|
-
exemplifiedBy:
|
|
4013
|
-
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
4014
|
-
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4015
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
4016
4169
|
law: "In lite and full apps, scheduled work belongs to the back-end scheduler, pgmq/pg_cron or a declared replicated-job. Deployment files, scripts, workflows, compose files and Dockerfiles install no host crontab, cron.d entry, systemd timer, @reboot job or at job; a workflow does not schedule app work. Docker compose up, down and pull run only against an explicitly dev environment. Deploy shell scripts delegate to docker, starci or the app CLI, and contain no node -e, psql, inline SQL or downloaded shell logic."
|
|
4017
4170
|
kinds: [check]
|
|
4018
4171
|
gates: [settle, land, ci]
|
|
4019
4172
|
failureCodes: ["HFS_HOST_CRON", "HFS_DEPLOY_NO_LOGIC", "HFS_DEPLOY_COMPOSE_ON_VPS", "HFS_DEPLOY_SCHEDULER"]
|
|
4020
4173
|
enforcers:
|
|
4021
4174
|
- {kind: hfs, id: deploy-scan, at: scripts/hfs/rules/deploy-scan.mjs}
|
|
4022
|
-
|
|
4175
|
+
proves:
|
|
4176
|
+
- {path: packages/hfs/src/hfs-deploy-scan.spec.mjs, editions: [lite, full]}
|
|
4177
|
+
exemplifiedBy:
|
|
4178
|
+
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
4179
|
+
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4180
|
+
- {path: packages/hfs/src/hfs-deploy-scan.spec.mjs, editions: [lite, full]}
|
|
4181
|
+
witness:
|
|
4182
|
+
- {path: packages/hfs/src/hfs-deploy-scan.spec.mjs, editions: [lite, full]}
|
|
4023
4183
|
- id: R251
|
|
4024
4184
|
code: "HFS_DEPLOY_WORKFLOW"
|
|
4025
4185
|
editions: [lite, full]
|
|
4026
4186
|
docs:
|
|
4027
4187
|
- {path: docs/application-stacks.md#r251-deploy-workflow, editions: [lite, full]}
|
|
4028
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
4029
|
-
exemplifiedBy:
|
|
4030
|
-
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml, edition: lite}
|
|
4031
|
-
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4032
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
4033
4188
|
law: "In lite and full apps, deployment jobs declare a protected environment, explicit permissions and concurrency, materialize sealed secrets through SOPS_AGE_KEY or starci app secret materialize, and reference only the age key and transport SSH key/known_hosts secrets. They never embed a dotenv blob or write a dotenv file. Every remote workflow action uses a 40-hex commit SHA (local actions are allowed and container actions require a full sha256 digest); supply-chain reports each unpinned uses reference at its source line, including disabled jobs and steps; installed tools are checksum or digest verified, or supplied by a pinned action. App workflows start only on release tags [v*], the release candidate branches release/candidate-* (required in ci.yml: starci app release push waits for that run, owner ruling candidate-ci 2026-10-18) or workflow_dispatch, never on another branch push."
|
|
4034
4189
|
kinds: [check]
|
|
4035
4190
|
gates: [settle, land, ci]
|
|
@@ -4037,34 +4192,37 @@ rules:
|
|
|
4037
4192
|
enforcers:
|
|
4038
4193
|
- {kind: hfs, id: deploy-workflow, at: scripts/hfs/rules/deploy-workflow.mjs}
|
|
4039
4194
|
- {kind: hfs, id: supply-chain, at: scripts/hfs/rules/supply-chain.mjs}
|
|
4040
|
-
|
|
4195
|
+
proves:
|
|
4196
|
+
- {path: packages/hfs/src/hfs-deploy-workflow.spec.mjs, editions: [lite, full]}
|
|
4197
|
+
exemplifiedBy:
|
|
4198
|
+
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml, edition: lite}
|
|
4199
|
+
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4200
|
+
- {path: packages/hfs/src/hfs-deploy-workflow.spec.mjs, editions: [lite, full]}
|
|
4201
|
+
witness:
|
|
4202
|
+
- {path: packages/hfs/src/hfs-deploy-workflow.spec.mjs, editions: [lite, full]}
|
|
4041
4203
|
- id: R252
|
|
4042
4204
|
code: "HFS_SCRIPT_PLAINTEXT_LOAD"
|
|
4043
4205
|
editions: [lite, full]
|
|
4044
4206
|
docs:
|
|
4045
4207
|
- {path: docs/application-stacks.md#r252-script-hygiene, editions: [lite, full]}
|
|
4046
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
4047
|
-
exemplifiedBy:
|
|
4048
|
-
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml, edition: lite}
|
|
4049
|
-
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4050
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
4051
4208
|
law: "In lite and full apps, executable scripts and workflow commands never load plaintext secrets.env, secret.env, .env secret files or a home-directory credential file, enable shell xtrace or request --reveal. Service-role references belong only to the back-end Supabase integration; deployment scripts and source outside that integration never use the service role. Scanners inspect source references and report paths without reading secret files or printing their values."
|
|
4052
4209
|
kinds: [check]
|
|
4053
4210
|
gates: [settle, land, ci]
|
|
4054
4211
|
failureCodes: ["HFS_SCRIPT_PLAINTEXT_LOAD", "HFS_SCRIPT_XTRACE", "HFS_SERVICE_ROLE_SCOPE"]
|
|
4055
4212
|
enforcers:
|
|
4056
4213
|
- {kind: hfs, id: script-hygiene, at: scripts/hfs/rules/script-hygiene.mjs}
|
|
4057
|
-
|
|
4214
|
+
proves:
|
|
4215
|
+
- {path: packages/hfs/src/hfs-script-hygiene.spec.mjs, editions: [lite, full]}
|
|
4216
|
+
exemplifiedBy:
|
|
4217
|
+
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml, edition: lite}
|
|
4218
|
+
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4219
|
+
- {path: packages/hfs/src/hfs-script-hygiene.spec.mjs, editions: [lite, full]}
|
|
4220
|
+
witness:
|
|
4221
|
+
- {path: packages/hfs/src/hfs-script-hygiene.spec.mjs, editions: [lite, full]}
|
|
4058
4222
|
- id: R253
|
|
4059
4223
|
code: "HFS_AGE_KEY_CUSTODY"
|
|
4060
4224
|
editions: [lite, full]
|
|
4061
4225
|
docs: [docs/host-secrets.md#application-secret-rules]
|
|
4062
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
4063
|
-
exemplifiedBy:
|
|
4064
|
-
- {path: packages/hfs/templates/be/skeleton/src/modules/platform/config/env-source.config.ts, editions: [lite, full]}
|
|
4065
|
-
- {path: packages/hfs/templates/be/skeleton/src/modules/platform/http-security/origin.guard.ts, editions: [lite, full]}
|
|
4066
|
-
- {path: packages/hfs/templates/be/skeleton/src/modules/platform/http-security/webhook-signature.service.ts, editions: [lite, full]}
|
|
4067
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
4068
4226
|
law: "The age identity that seals and opens an app's `.starcistacks/<env>/secrets/*.enc` is host-local custody only: it lives in the untracked `.claude/secret.env` (as `SOPS_AGE_KEY`, which wins over the legacy `keys.txt` and is handed to sops through the `SOPS_AGE_KEY` child environment, never as an argument and never printed) or in the sops config dir's `keys.txt`; a tracked `.claude/secret.env`, `keys.txt` or `*.agekey` is the identity committed. The three files the secret custody depends on - `src/modules/platform/config/env-source.config.ts`, `src/modules/platform/http-security/origin.guard.ts` and `src/modules/platform/http-security/webhook-signature.service.ts` - are hash-sensitive canon, not files to edit: their bytes equal the `be/skeleton` template they were scaffolded from, judged by sha256."
|
|
4069
4227
|
kinds: [check]
|
|
4070
4228
|
gates: [settle, land, ci]
|
|
@@ -4072,45 +4230,57 @@ rules:
|
|
|
4072
4230
|
enforcers:
|
|
4073
4231
|
- {kind: hfs, id: secret-age-key-custody, at: scripts/hfs/rules/secrets.mjs}
|
|
4074
4232
|
- {kind: hfs, id: canon-copy-drift, at: scripts/hfs/rules/canon-copy-drift.mjs}
|
|
4075
|
-
|
|
4233
|
+
proves:
|
|
4234
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [lite, full]}
|
|
4235
|
+
exemplifiedBy:
|
|
4236
|
+
- {path: packages/hfs/templates/be/skeleton/src/modules/platform/config/env-source.config.ts, editions: [lite, full]}
|
|
4237
|
+
- {path: packages/hfs/templates/be/skeleton/src/modules/platform/http-security/origin.guard.ts, editions: [lite, full]}
|
|
4238
|
+
- {path: packages/hfs/templates/be/skeleton/src/modules/platform/http-security/webhook-signature.service.ts, editions: [lite, full]}
|
|
4239
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [lite, full]}
|
|
4240
|
+
witness:
|
|
4241
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [lite, full]}
|
|
4076
4242
|
- id: R254
|
|
4077
4243
|
code: "DB_BE_ONLY_ACCESS"
|
|
4078
4244
|
editions: [lite]
|
|
4079
4245
|
editionWhy: "owner:lite-backing-services makes Supabase lite's database backing; these SQL access requirements apply to that backing."
|
|
4080
4246
|
docs: [docs/microservices.md#r254]
|
|
4081
4247
|
templateNa: "Browser grants, policies and publication membership belong to product-authored Supabase migrations, rather than a scaffolded SQL surface."
|
|
4082
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
4083
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
4084
4248
|
law: "In lite and full, browser data access stays closed on exposed schemas: authenticated receives neither table or sequence privileges nor data policies, and anon reads only through a select policy named *_public_read. A table listed in hfs.json supabase.directAccess is an explicit exception. A table joins supabase_realtime only when that direct access is declared. The front end uses Supabase for Auth and reaches product data through the back end."
|
|
4085
4249
|
kinds: [check]
|
|
4086
4250
|
gates: [settle, land, ci]
|
|
4087
4251
|
failureCodes: ["DB_BE_ONLY_ACCESS", "DB_REALTIME_UNLISTED"]
|
|
4088
4252
|
enforcers:
|
|
4089
4253
|
- {kind: hfs, id: db-be-only-access, at: scripts/hfs/rules/database-access.mjs}
|
|
4090
|
-
|
|
4254
|
+
proves:
|
|
4255
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_BE_ONLY_ACCESS, DB_REALTIME_UNLISTED]}
|
|
4256
|
+
exemplifiedBy:
|
|
4257
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_BE_ONLY_ACCESS, DB_REALTIME_UNLISTED]}
|
|
4258
|
+
witness:
|
|
4259
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_BE_ONLY_ACCESS, DB_REALTIME_UNLISTED]}
|
|
4091
4260
|
- id: R255
|
|
4092
4261
|
code: "DB_APP_ROLE"
|
|
4093
4262
|
editions: [lite]
|
|
4094
4263
|
editionWhy: "owner:lite-backing-services makes Supabase lite's database backing; application-role and forced-RLS requirements apply to that backing."
|
|
4095
4264
|
docs: [docs/microservices.md#r255]
|
|
4096
4265
|
templateNa: "Application roles and table ownership are product-authored Supabase migration content, rather than a scaffolded SQL surface."
|
|
4097
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
4098
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
4099
4266
|
law: "The declared back-end database role (hfs.json supabase.appRole, app_be by default) has only the privileges it needs: role declarations refuse superuser and bypassrls, require noinherit and nobypassrls, and never grant all schema or table privileges. Tables owned by that role enable and force row level security by default; a forceRls exemption identifies the table and carries a nonempty reason. This applies to every edition that declares Supabase."
|
|
4100
4267
|
kinds: [check]
|
|
4101
4268
|
gates: [settle, land, ci]
|
|
4102
4269
|
failureCodes: ["DB_APP_ROLE", "DB_FORCE_RLS_DEFAULT"]
|
|
4103
4270
|
enforcers:
|
|
4104
4271
|
- {kind: hfs, id: db-app-role, at: scripts/hfs/rules/database-access.mjs}
|
|
4105
|
-
|
|
4272
|
+
proves:
|
|
4273
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_APP_ROLE, DB_FORCE_RLS_DEFAULT]}
|
|
4274
|
+
exemplifiedBy:
|
|
4275
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_APP_ROLE, DB_FORCE_RLS_DEFAULT]}
|
|
4276
|
+
witness:
|
|
4277
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_APP_ROLE, DB_FORCE_RLS_DEFAULT]}
|
|
4106
4278
|
- id: R256
|
|
4107
4279
|
code: "DB_POLICY_TAUTOLOGY"
|
|
4108
4280
|
editions: [lite]
|
|
4109
4281
|
editionWhy: "owner:lite-backing-services makes Supabase lite's database backing; access-policy, view, definer and storage SQL requirements apply to that backing."
|
|
4110
4282
|
docs: [docs/microservices.md#r256]
|
|
4111
4283
|
templateNa: "Access policies, views, definers and storage policies belong to product-authored Supabase migrations, rather than a scaffolded SQL surface."
|
|
4112
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
4113
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
4114
4284
|
law: "Exposed database objects keep their access boundaries in lite and full. Policies refuse tautological true, is-not-null and self-equality predicates; policies for browser roles prove a principal predicate. An exposed view or materialized view uses security_invoker or the migration set ends with access revoked from anon and authenticated. Disabling RLS or moving a table into an exposed schema preserves the R214 RLS obligation. A security definer declaration, including alter function, preserves R215 safety checks and the migration set ends with execute revoked from authenticated when exposed, in addition to R215's public and anon revocation. A storage.objects policy scopes an ownership prefix to the principal unless its bucket id ends _public."
|
|
4115
4285
|
kinds: [check]
|
|
4116
4286
|
gates: [settle, land, ci]
|
|
@@ -4118,46 +4288,57 @@ rules:
|
|
|
4118
4288
|
enforcers:
|
|
4119
4289
|
- {kind: hfs, id: db-policy-hardening, at: scripts/hfs/rules/database-access.mjs}
|
|
4120
4290
|
- {kind: hfs, id: db-definer-revoke, at: scripts/hfs/rules/database-plpgsql.mjs}
|
|
4121
|
-
|
|
4122
|
-
|
|
4291
|
+
proves:
|
|
4292
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_POLICY_TAUTOLOGY, DB_VIEW_UNSAFE, DB_STORAGE_PREFIX]}
|
|
4293
|
+
- {path: packages/hfs/src/hfs-database-rules.spec.mjs, edition: lite, codes: [DB_DEFINER_REVOKE]}
|
|
4294
|
+
exemplifiedBy:
|
|
4295
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_POLICY_TAUTOLOGY, DB_VIEW_UNSAFE, DB_STORAGE_PREFIX]}
|
|
4296
|
+
- {path: packages/hfs/src/hfs-database-rules.spec.mjs, edition: lite, codes: [DB_DEFINER_REVOKE]}
|
|
4297
|
+
witness:
|
|
4298
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_POLICY_TAUTOLOGY, DB_VIEW_UNSAFE, DB_STORAGE_PREFIX]}
|
|
4299
|
+
- {path: packages/hfs/src/hfs-database-rules.spec.mjs, edition: lite, codes: [DB_DEFINER_REVOKE]}
|
|
4123
4300
|
- id: R257
|
|
4124
4301
|
code: "DB_BASELINE_SHAPE"
|
|
4125
4302
|
editions: [lite]
|
|
4126
4303
|
editionWhy: "owner:lite-backing-services makes Supabase lite's database backing; baseline and archive requirements apply to its migration history."
|
|
4127
4304
|
docs: [docs/microservices.md#r257]
|
|
4128
4305
|
templateNa: "A baseline is derived from a product's existing Supabase migration history and cannot be supplied by a scaffold template."
|
|
4129
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
4130
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
4131
4306
|
law: "An archived migration chain has exactly one active baseline marked -- starci:baseline <archived-last-stamp>, with a later valid stamp or an explicit restamp. Archived files only need the digits-stamp_name.sql shape, whatever the stamp value (they are immutable history and never applied); the baseline and active migrations keep the real-instant stamp check. Archive contents are immutable against repository history; an active migration enters the archive unchanged only in the same diff that adds the replacement baseline. The app db baseline, restamp and plan verbs are read-only unless --apply is explicit."
|
|
4132
4307
|
kinds: [check]
|
|
4133
4308
|
gates: [settle, land, ci]
|
|
4134
4309
|
failureCodes: ["DB_BASELINE_SHAPE", "DB_ARCHIVE_MUTATED"]
|
|
4135
4310
|
enforcers:
|
|
4136
4311
|
- {kind: hfs, id: db-baseline-shape, at: scripts/hfs/rules/database-baseline.mjs}
|
|
4137
|
-
|
|
4312
|
+
proves:
|
|
4313
|
+
- {path: packages/hfs/src/hfs-database-baseline.spec.mjs, edition: lite, codes: [DB_BASELINE_SHAPE, DB_ARCHIVE_MUTATED]}
|
|
4314
|
+
exemplifiedBy:
|
|
4315
|
+
- {path: packages/hfs/src/hfs-database-baseline.spec.mjs, edition: lite, codes: [DB_BASELINE_SHAPE, DB_ARCHIVE_MUTATED]}
|
|
4316
|
+
witness:
|
|
4317
|
+
- {path: packages/hfs/src/hfs-database-baseline.spec.mjs, edition: lite, codes: [DB_BASELINE_SHAPE, DB_ARCHIVE_MUTATED]}
|
|
4138
4318
|
- id: R258
|
|
4139
4319
|
code: "DB_PGMQ_DECLARED"
|
|
4140
4320
|
editions: [lite]
|
|
4141
4321
|
editionWhy: "owner:lite-backing-services makes Supabase lite's database backing; pgmq and pg_cron ownership requirements apply to that backing."
|
|
4142
4322
|
docs: [docs/microservices.md#r258]
|
|
4143
4323
|
templateNa: "Queue declarations and enqueue-only cron commands depend on product-owned work and are authored in its Supabase migrations."
|
|
4144
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
4145
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
4146
4324
|
law: "DB_QUEUE_CRON: every pgmq queue constant has an active migration creating the queue and every created queue has a constant. Queue objects are granted only to the application role. A uniquely named pg_cron job belongs to a migration and only enqueues to an existing queue directly or through one enqueue-only *_tick function; it executes no business DML or HTTP request and shares no tick with an app scheduler. Removing a tick unschedules its job."
|
|
4147
4325
|
kinds: [check]
|
|
4148
4326
|
gates: [settle, land, ci]
|
|
4149
4327
|
failureCodes: ["DB_PGMQ_DECLARED", "DB_CRON_OWNED"]
|
|
4150
4328
|
enforcers:
|
|
4151
4329
|
- {kind: hfs, id: db-queue-cron, at: scripts/hfs/rules/database-queues.mjs}
|
|
4152
|
-
|
|
4330
|
+
proves:
|
|
4331
|
+
- {path: packages/hfs/src/hfs-database-queues.spec.mjs, edition: lite, codes: [DB_PGMQ_DECLARED, DB_CRON_OWNED]}
|
|
4332
|
+
exemplifiedBy:
|
|
4333
|
+
- {path: packages/hfs/src/hfs-database-queues.spec.mjs, edition: lite, codes: [DB_PGMQ_DECLARED, DB_CRON_OWNED]}
|
|
4334
|
+
witness:
|
|
4335
|
+
- {path: packages/hfs/src/hfs-database-queues.spec.mjs, edition: lite, codes: [DB_PGMQ_DECLARED, DB_CRON_OWNED]}
|
|
4153
4336
|
- id: R259
|
|
4154
4337
|
code: "DB_EXTENSION_ALLOWED"
|
|
4155
4338
|
editions: [lite]
|
|
4156
4339
|
editionWhy: "owner:lite-backing-services makes Supabase lite's database backing; database configuration, extension, migration and seed requirements apply to that backing."
|
|
4157
4340
|
docs: [docs/microservices.md#r259]
|
|
4158
4341
|
templateNa: "Extension use, contract migrations, vault operations and seed literals are product-authored Supabase content, rather than a scaffolded SQL surface."
|
|
4159
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
4160
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
4161
4342
|
law: "DB_CONFIG_EXT: extensions belong to the database allowlist, vault writes and migration role passwords are refused, pgmq schemas are never exposed through the API, and lite API access is closed except for explicit public-read policies. R216 DB_CONFIG_POLICY also checks API schema allowlisting, existing seed paths, anonymous sign-ins, disabled edge runtime, bounded storage uploads and the database major-version pin. Destructive DDL belongs only to *_contract_* migrations whose targets are no longer referenced by back-end SQL or entities. Seeds contain no real email or phone literals."
|
|
4162
4343
|
kinds: [check]
|
|
4163
4344
|
gates: [settle, land, ci]
|
|
@@ -4165,8 +4346,12 @@ rules:
|
|
|
4165
4346
|
enforcers:
|
|
4166
4347
|
- {kind: hfs, id: db-config-ext, at: scripts/hfs/rules/database-config.mjs}
|
|
4167
4348
|
- {kind: hfs, id: db-migration-destructive, at: scripts/hfs/rules/database-migrations.mjs}
|
|
4168
|
-
|
|
4169
|
-
|
|
4349
|
+
proves:
|
|
4350
|
+
- {path: packages/hfs/src/hfs-database-config.spec.mjs, editions: [lite], codes: [DB_EXTENSION_ALLOWED, DB_API_EXPOSED, DB_MIGRATION_DESTRUCTIVE, HFS_SEED_PII, DB_VAULT_WRITE]}
|
|
4351
|
+
exemplifiedBy:
|
|
4352
|
+
- {path: packages/hfs/src/hfs-database-config.spec.mjs, editions: [lite], codes: [DB_EXTENSION_ALLOWED, DB_API_EXPOSED, DB_MIGRATION_DESTRUCTIVE, HFS_SEED_PII, DB_VAULT_WRITE]}
|
|
4353
|
+
witness:
|
|
4354
|
+
- {path: packages/hfs/src/hfs-database-config.spec.mjs, editions: [lite], codes: [DB_EXTENSION_ALLOWED, DB_API_EXPOSED, DB_MIGRATION_DESTRUCTIVE, HFS_SEED_PII, DB_VAULT_WRITE]}
|
|
4170
4355
|
- id: R260
|
|
4171
4356
|
code: "BE_JWT_ALG_PINNED"
|
|
4172
4357
|
law: "A back-end JWT verifier pins a nonempty literal subset of ES256, RS256 and EdDSA and obtains its issuer from configuration. A Supabase principal is built only after verification and rejection of every role other than authenticated, in lite and full."
|
|
@@ -4180,15 +4365,16 @@ rules:
|
|
|
4180
4365
|
templateNa: "Full identity providers are product-owned integrations with no scaffolded JWT verifier; the lite Supabase verifier is templated and both editions are exercised by the verifier specs."
|
|
4181
4366
|
docs:
|
|
4182
4367
|
- "docs/microservices.md#r260"
|
|
4368
|
+
proves:
|
|
4369
|
+
- "packages/eslint/be/jwt-alg.spec.mjs"
|
|
4370
|
+
- packages/hfs/src/architecture-jwt-policy.spec.mjs
|
|
4183
4371
|
exemplifiedBy:
|
|
4184
4372
|
- {"path":"packages/hfs/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.jwks.ts","edition":"lite"}
|
|
4185
4373
|
- {"path":"examples/lite-app/be/src/modules/integrations/supabase/supabase.jwks.ts","edition":"lite"}
|
|
4186
4374
|
- {"path":"packages/eslint/be/jwt-alg.spec.mjs","edition":"full","codes":["BE_JWT_ALG_PINNED"]}
|
|
4187
|
-
proves:
|
|
4188
|
-
- "packages/eslint/be/jwt-alg.spec.mjs"
|
|
4189
4375
|
witness:
|
|
4190
4376
|
- {"path":"packages/eslint/be/jwt-alg.spec.mjs","editions":["lite","full"],"codes":["BE_JWT_ALG_PINNED"]}
|
|
4191
|
-
|
|
4377
|
+
- {path: packages/hfs/src/architecture-jwt-policy.spec.mjs, editions: [lite, full], codes: [BE_JWT_ALG_PINNED]}
|
|
4192
4378
|
- id: R261
|
|
4193
4379
|
code: "BE_CORS_ALLOWLIST"
|
|
4194
4380
|
law: "Every back-end API declares an exact browser origin allowlist, applies the platform/http-security response middleware, disables x-powered-by and states a nonnegative integer trust proxy hop count. Wildcard or missing CORS and blanket proxy trust are refused in lite and full."
|
|
@@ -4225,17 +4411,19 @@ rules:
|
|
|
4225
4411
|
editions: ["lite","full"]
|
|
4226
4412
|
docs:
|
|
4227
4413
|
- "docs/microservices.md#r262"
|
|
4414
|
+
proves:
|
|
4415
|
+
- {"path":"packages/eslint/be/health-ready.spec.mjs","editions":["lite","full"],"codes":["BE_READY_REAL","BE_HEALTH_SIGNALS"]}
|
|
4416
|
+
- {path: packages/hfs/src/be-docker-health.spec.mjs, editions: [lite, full], codes: [HFS_DOCKER_HEALTHCHECK_FAKE]}
|
|
4228
4417
|
exemplifiedBy:
|
|
4229
4418
|
- {"path":"packages/hfs/templates/be/skeleton/src/features/api/system-health/transport/http/ready.controller.ts","editions":["lite","full"]}
|
|
4230
4419
|
- {"path":"packages/hfs/templates/be/skeleton/src/modules/platform/http-security/readiness.service.ts","editions":["lite","full"]}
|
|
4231
4420
|
- {"path":"packages/hfs/templates/be/image/api/Dockerfile","editions":["lite","full"]}
|
|
4232
4421
|
- {"path":"packages/eslint/be/health-ready.spec.mjs","editions":["lite","full"],"codes":["BE_READY_REAL","BE_HEALTH_SIGNALS"]}
|
|
4233
|
-
|
|
4234
|
-
- {"path":"packages/eslint/be/health-ready.spec.mjs","editions":["lite","full"],"codes":["BE_READY_REAL","BE_HEALTH_SIGNALS"]}
|
|
4422
|
+
- {path: packages/hfs/src/be-docker-health.spec.mjs, editions: [lite, full], codes: [HFS_DOCKER_HEALTHCHECK_FAKE]}
|
|
4235
4423
|
witness:
|
|
4236
4424
|
- {"path":"packages/eslint/be/health-ready.spec.mjs","editions":["lite","full"],"codes":["BE_READY_REAL","BE_HEALTH_SIGNALS"]}
|
|
4237
4425
|
|
|
4238
|
-
|
|
4426
|
+
- {path: packages/hfs/src/be-docker-health.spec.mjs, editions: [lite, full], codes: [HFS_DOCKER_HEALTHCHECK_FAKE]}
|
|
4239
4427
|
- id: R263
|
|
4240
4428
|
code: "BE_WEBHOOK_SCOPE"
|
|
4241
4429
|
amendedBy: [owner:oauth-redirect-not-webhook, owner:webhook-receipt-port]
|
|
@@ -4320,13 +4508,16 @@ rules:
|
|
|
4320
4508
|
codeEditions: {"STACKS_REALTIME_SCALED":["lite"]}
|
|
4321
4509
|
docs:
|
|
4322
4510
|
- "docs/application-stacks.md#r266"
|
|
4511
|
+
proves:
|
|
4512
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4513
|
+
- {path: packages/hfs/src/hfs-stacks-ingress.spec.mjs}
|
|
4514
|
+
- {path: packages/hfs/src/hfs-stacks-swarm.spec.mjs, editions: [lite, full]}
|
|
4323
4515
|
exemplifiedBy:
|
|
4324
4516
|
- {"path":"packages/hfs/templates/app/skeleton-lite/.starcistacks","edition":"lite"}
|
|
4325
4517
|
- {"path":"packages/hfs/templates/app/skeleton/.starcistacks","edition":"full"}
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
4518
|
+
- {path: packages/hfs/src/hfs-stacks-swarm.spec.mjs, editions: [lite, full]}
|
|
4519
|
+
witness:
|
|
4520
|
+
- {path: packages/hfs/src/hfs-stacks-swarm.spec.mjs, editions: [lite, full]}
|
|
4330
4521
|
- id: R267
|
|
4331
4522
|
code: "STACKS_RELEASE_UNDECLARED"
|
|
4332
4523
|
law: "Each Swarm environment declares an immutable images lock, active and previous release pointers and nonempty health assertions. Every stateful component and declared managed backing dependency declares backup target, retention and owner with a tracked restore proof. The rendered deployment model must be available and valid; an unavailable model is a finding, never a skipped check."
|
|
@@ -4338,13 +4529,17 @@ rules:
|
|
|
4338
4529
|
editions: ["lite","full"]
|
|
4339
4530
|
docs:
|
|
4340
4531
|
- "docs/application-stacks.md#r267"
|
|
4532
|
+
proves:
|
|
4533
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4534
|
+
- packages/hfs/src/hfs-stacks-release.spec.mjs
|
|
4341
4535
|
exemplifiedBy:
|
|
4342
4536
|
- {"path":"packages/hfs/templates/app/skeleton-lite/.starcistacks","edition":"lite"}
|
|
4343
4537
|
- {"path":"packages/hfs/templates/app/skeleton/.starcistacks","edition":"full"}
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
witness:
|
|
4347
|
-
|
|
4538
|
+
- {path: packages/hfs/src/hfs-stacks-release.spec.mjs, edition: lite}
|
|
4539
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4540
|
+
witness:
|
|
4541
|
+
- {path: packages/hfs/src/hfs-stacks-release.spec.mjs, edition: lite}
|
|
4542
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4348
4543
|
- id: R268
|
|
4349
4544
|
code: "HFS_SCHEDULE_UNDECLARED"
|
|
4350
4545
|
law: "Every app scheduler, active pg_cron schedule, selected scheduled component and rendered replicated-job has a matching top-level jobs declaration with its schedule and invocation of a named back-end CLI action. A rendered replicated-job uses the same declared CLI invocation; inline JavaScript and shell chaining are refused. Scheduling is app-owned; a manifest entry never grants host crontab or deployment business logic."
|
|
@@ -4356,13 +4551,17 @@ rules:
|
|
|
4356
4551
|
editions: ["lite","full"]
|
|
4357
4552
|
docs:
|
|
4358
4553
|
- "docs/application-stacks.md#r268"
|
|
4554
|
+
proves:
|
|
4555
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4556
|
+
- packages/hfs/src/hfs-stacks-release.spec.mjs
|
|
4359
4557
|
exemplifiedBy:
|
|
4360
4558
|
- {"path":"packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml","edition":"lite"}
|
|
4361
4559
|
- {"path":"packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml","edition":"full"}
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
witness:
|
|
4365
|
-
|
|
4560
|
+
- {path: packages/hfs/src/hfs-stacks-release.spec.mjs, edition: lite}
|
|
4561
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4562
|
+
witness:
|
|
4563
|
+
- {path: packages/hfs/src/hfs-stacks-release.spec.mjs, edition: lite}
|
|
4564
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4366
4565
|
- id: R269
|
|
4367
4566
|
code: "HFS_DEPENDABOT_MISSING"
|
|
4368
4567
|
law: "In lite and full apps, .github/dependabot.yml declares scheduled npm, github-actions and docker updates. Every npm entry declares a minor-and-patch version group and a security-updates group; every group explicitly restricts update-types to minor and patch, leaving majors per package, and npm entries ignore @starci/* without version or update-type restrictions. The CI workflow runs npm audit --omit=dev as an enabled gate whose failure stops the job. The images workflow generates an SBOM and provenance for release images; a disabled step, comment or label is not evidence."
|
|
@@ -4374,6 +4573,8 @@ rules:
|
|
|
4374
4573
|
editions: ["lite","full"]
|
|
4375
4574
|
docs:
|
|
4376
4575
|
- "docs/application-stacks.md#r269"
|
|
4576
|
+
proves:
|
|
4577
|
+
- {path: packages/hfs/src/hfs-supply-chain.spec.mjs, editions: [lite, full]}
|
|
4377
4578
|
exemplifiedBy:
|
|
4378
4579
|
- {"path":"packages/hfs/templates/app/skeleton-lite/.github/dependabot.yml","edition":"lite"}
|
|
4379
4580
|
- {"path":"packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml","edition":"lite"}
|
|
@@ -4381,10 +4582,11 @@ rules:
|
|
|
4381
4582
|
- {"path":"packages/hfs/templates/app/skeleton/.github/dependabot.yml","edition":"full"}
|
|
4382
4583
|
- {"path":"packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml","edition":"full"}
|
|
4383
4584
|
- {"path":"packages/hfs/templates/app/ci-workflows/github/workflows/images.yml","edition":"full"}
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
witness:
|
|
4387
|
-
|
|
4585
|
+
- {path: packages/hfs/src/hfs-supply-chain.spec.mjs, edition: lite}
|
|
4586
|
+
- {path: packages/hfs/src/hfs-supply-chain.spec.mjs, edition: full}
|
|
4587
|
+
witness:
|
|
4588
|
+
- {path: packages/hfs/src/hfs-supply-chain.spec.mjs, edition: lite}
|
|
4589
|
+
- {path: packages/hfs/src/hfs-supply-chain.spec.mjs, edition: full}
|
|
4388
4590
|
- id: R270
|
|
4389
4591
|
code: "HFS_DOC_PATH_MISSING"
|
|
4390
4592
|
law: "In lite and full products, READMEs, docs and stack READMEs cite existing repository paths, npm scripts, starci app verbs, environment keys declared by typed readers or KEYS.md, and rule ids from the HFS catalog. Documentation changes with the product it describes."
|
|
@@ -4396,12 +4598,16 @@ rules:
|
|
|
4396
4598
|
editions: ["lite","full"]
|
|
4397
4599
|
docs:
|
|
4398
4600
|
- "docs/quality-bar.md#r270"
|
|
4601
|
+
proves:
|
|
4602
|
+
- {path: packages/hfs/src/hfs-doc-fresh.spec.mjs, editions: [lite, full]}
|
|
4399
4603
|
exemplifiedBy:
|
|
4400
4604
|
- {"path":"packages/hfs/templates/app/skeleton-lite/README.md","edition":"lite"}
|
|
4401
4605
|
- {"path":"packages/hfs/templates/app/skeleton/README.md","edition":"full"}
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4606
|
+
- {path: packages/hfs/src/hfs-doc-fresh.spec.mjs, edition: lite}
|
|
4607
|
+
- {path: packages/hfs/src/hfs-doc-fresh.spec.mjs, edition: full}
|
|
4608
|
+
witness:
|
|
4609
|
+
- {path: packages/hfs/src/hfs-doc-fresh.spec.mjs, edition: lite}
|
|
4610
|
+
- {path: packages/hfs/src/hfs-doc-fresh.spec.mjs, edition: full}
|
|
4405
4611
|
- id: R271
|
|
4406
4612
|
code: "HFS_RELEASE_TAG_MISMATCH"
|
|
4407
4613
|
law: "A lite or full product release uses a v-prefixed semantic version tag equal to package.json version; images.yml publishes images under that release tag, and every database deployment refuses a non-tag ref before migration."
|
|
@@ -4413,14 +4619,17 @@ rules:
|
|
|
4413
4619
|
editions: ["lite","full"]
|
|
4414
4620
|
docs:
|
|
4415
4621
|
- "docs/application-stacks.md#r271"
|
|
4622
|
+
proves:
|
|
4623
|
+
- {path: packages/hfs/src/hfs-release-provenance.spec.mjs, editions: [lite, full]}
|
|
4416
4624
|
exemplifiedBy:
|
|
4417
4625
|
- {"path":"packages/hfs/templates/app/ci-workflows-lite/github/workflows/images.yml","edition":"lite"}
|
|
4418
4626
|
- {"path":"packages/hfs/templates/app/ci-workflows/github/workflows/images.yml","edition":"full"}
|
|
4419
4627
|
- {"path":"packages/hfs/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml","edition":"lite"}
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
witness:
|
|
4423
|
-
|
|
4628
|
+
- {path: packages/hfs/src/hfs-release-provenance.spec.mjs, edition: lite}
|
|
4629
|
+
- {path: packages/hfs/src/hfs-release-provenance.spec.mjs, edition: full}
|
|
4630
|
+
witness:
|
|
4631
|
+
- {path: packages/hfs/src/hfs-release-provenance.spec.mjs, edition: lite}
|
|
4632
|
+
- {path: packages/hfs/src/hfs-release-provenance.spec.mjs, edition: full}
|
|
4424
4633
|
- id: R272
|
|
4425
4634
|
code: "BE_APP_BOOT_PROOF_MISSING"
|
|
4426
4635
|
law: "Every lite back-end app proves its real Nest AppModule composition by compiling the dependency graph with explicit fixture options and infrastructure doubles; unresolved providers, circular dependencies and a missing or failed proof are refused. The app check wiring verb uses the same proof. Full retains its existing e2e boot proof."
|
|
@@ -4433,12 +4642,14 @@ rules:
|
|
|
4433
4642
|
editionWhy: "ruling:R272 requires the lite Nest wiring proof; full retains its existing e2e boot proof and the boot-proof finder skips full."
|
|
4434
4643
|
docs:
|
|
4435
4644
|
- "docs/quality-bar.md#r272"
|
|
4645
|
+
proves:
|
|
4646
|
+
- {path: packages/hfs/src/hfs-boot-proof.spec.mjs, editions: [lite]}
|
|
4436
4647
|
exemplifiedBy:
|
|
4437
4648
|
- {"path":"packages/hfs/templates/be/skeleton-lite/src/tests/fixtures/builders/api.builder.ts","edition":"lite"}
|
|
4438
4649
|
- {"path":"examples/lite-app/be/src/tests/fixtures/builders/api.builder.ts","edition":"lite"}
|
|
4439
|
-
|
|
4440
|
-
witness:
|
|
4441
|
-
|
|
4650
|
+
- {path: packages/hfs/src/hfs-boot-proof.spec.mjs, edition: lite}
|
|
4651
|
+
witness:
|
|
4652
|
+
- {path: packages/hfs/src/hfs-boot-proof.spec.mjs, edition: lite}
|
|
4442
4653
|
- id: R273
|
|
4443
4654
|
code: "HFS_COVERAGE_BELOW"
|
|
4444
4655
|
law: "An app check supplied with a coverage-from lcov report proves 100 percent lines, functions and branches per tracked back-end logic file in the edition's slot-derived measured scope; a missing source record or unavailable metric is refused. The unit runner also enforces statement coverage. Reports list the measured scope and the source files outside it, including features, cli and webhooks."
|
|
@@ -4450,13 +4661,18 @@ rules:
|
|
|
4450
4661
|
editions: ["lite","full"]
|
|
4451
4662
|
docs:
|
|
4452
4663
|
- "docs/quality-bar.md#r273"
|
|
4664
|
+
proves:
|
|
4665
|
+
- {path: packages/hfs/src/hfs-coverage-below.spec.mjs, editions: [lite, full]}
|
|
4453
4666
|
exemplifiedBy:
|
|
4454
4667
|
- {"path":"packages/hfs/templates/be/tool-config/jest.config.js","editions":["lite","full"]}
|
|
4455
4668
|
- {"path":"examples/lite-app/be/jest.config.js","edition":"lite"}
|
|
4456
4669
|
- {"path":"examples/full-app/be/jest.config.js","edition":"full"}
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4670
|
+
- {path: packages/hfs/src/hfs-coverage-below.spec.mjs, edition: lite}
|
|
4671
|
+
- {path: packages/hfs/src/hfs-coverage-below.spec.mjs, edition: full}
|
|
4672
|
+
- {path: examples/ecommerce-app/be/jest.config.js, edition: full}
|
|
4673
|
+
witness:
|
|
4674
|
+
- {path: packages/hfs/src/hfs-coverage-below.spec.mjs, edition: lite}
|
|
4675
|
+
- {path: packages/hfs/src/hfs-coverage-below.spec.mjs, edition: full}
|
|
4460
4676
|
- id: R274
|
|
4461
4677
|
code: "RT_RULING_STALE_CITE"
|
|
4462
4678
|
law: "Live prose, source comments and spec titles cite current owner rulings using ruling:R212/case-4 or a stable owner id. A superseded or amended ruling needs its live successor in the same paragraph; staleWhen statements outside historical case text and CHANGELOGs are refused, and a bare owner ruling date must match a catalog case or owner ruling."
|
|
@@ -4470,10 +4686,6 @@ rules:
|
|
|
4470
4686
|
templateNa: "Runtime owner-ruling citation metadata has no product scaffold surface; passing and stale authored-source fixtures live in the ruling-cites spec."
|
|
4471
4687
|
docs:
|
|
4472
4688
|
- "docs/quality-bar.md#r274"
|
|
4473
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
4474
|
-
|
|
4475
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
4476
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
4477
4689
|
- id: R275
|
|
4478
4690
|
code: "STACKS_INGRESS_UNDECLARED"
|
|
4479
4691
|
law: "Every Swarm environment declares its one ingress component and hosts. The named component has role ingress and a digest-pinned supported ingress image; Traefik and Caddy are both accepted without a preferred product. An absent declaration, unknown component or unsupported image is refused."
|
|
@@ -4485,13 +4697,17 @@ rules:
|
|
|
4485
4697
|
editions: ["lite","full"]
|
|
4486
4698
|
docs:
|
|
4487
4699
|
- "docs/application-stacks.md#r275"
|
|
4700
|
+
proves:
|
|
4701
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4702
|
+
- packages/hfs/src/hfs-stacks-ingress.spec.mjs
|
|
4488
4703
|
exemplifiedBy:
|
|
4489
4704
|
- {"path":"packages/hfs/templates/app/skeleton-lite/.starcistacks","edition":"lite"}
|
|
4490
4705
|
- {"path":"packages/hfs/templates/app/skeleton/.starcistacks","edition":"full"}
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
witness:
|
|
4494
|
-
|
|
4706
|
+
- {path: packages/hfs/src/hfs-stacks-ingress.spec.mjs, edition: lite}
|
|
4707
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4708
|
+
witness:
|
|
4709
|
+
- {path: packages/hfs/src/hfs-stacks-ingress.spec.mjs, edition: lite}
|
|
4710
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4495
4711
|
- id: R276
|
|
4496
4712
|
code: "STACKS_LITE_SELFHOSTED_DB"
|
|
4497
4713
|
law: "Lite uses managed Supabase and runs no PostgreSQL, Redis or MongoDB backing image. A sidecar that needs a database uses SQLite on a named persistent volume declared by its component and mounted in the rendered model; a sidecar requiring another database is refused. Full retains its declared backing topology."
|
|
@@ -4504,12 +4720,12 @@ rules:
|
|
|
4504
4720
|
editionWhy: "ruling:R276 records owner ruling 4: lite uses managed Supabase, refuses self-hosted backing images and permits database-dependent sidecars only with SQLite on declared persistent volumes; full keeps its declared backing topology."
|
|
4505
4721
|
docs:
|
|
4506
4722
|
- "docs/application-stacks.md#r276"
|
|
4723
|
+
proves: [packages/hfs/src/hfs-stacks-lite-backing.spec.mjs]
|
|
4507
4724
|
exemplifiedBy:
|
|
4508
4725
|
- {"path":"packages/hfs/templates/app/skeleton-lite/.starcistacks","edition":"lite"}
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
4726
|
+
- {path: packages/hfs/src/hfs-stacks-lite-backing.spec.mjs, edition: lite}
|
|
4727
|
+
witness:
|
|
4728
|
+
- {path: packages/hfs/src/hfs-stacks-lite-backing.spec.mjs, edition: lite}
|
|
4513
4729
|
- id: R277
|
|
4514
4730
|
code: "HFS_SECRET_PLAINTEXT_FILE"
|
|
4515
4731
|
law: "In every edition the only custody a tracked secret may take is a sops envelope at `.starcistacks/<env>/secrets/**.enc`. A tracked plaintext secret file is refused by being: `secrets.env` or `.secret(s).env` at any depth, a non-dot `*.env` or `*.env.<profile>` holding secret keys (deploy-side dotenv included), and a plaintext member of a `secrets/` directory; a sealed `.enc` outside the one sealed home is refused too (for lite it is already `HFS_LITE_SECRET_CUSTODY`)."
|
|
@@ -4522,10 +4738,15 @@ rules:
|
|
|
4522
4738
|
codeEditions: {HFS_SECRET_OUTSIDE_ENC: [full]}
|
|
4523
4739
|
docs: [docs/host-secrets.md#r277]
|
|
4524
4740
|
templateNa: "Sealed secret members are owner-created through starci app secret set after custody initialization; the scaffolder does not generate committed secret material."
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4741
|
+
proves:
|
|
4742
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [lite, full], codes: [HFS_SECRET_PLAINTEXT_FILE]}
|
|
4743
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [full], codes: [HFS_SECRET_OUTSIDE_ENC]}
|
|
4744
|
+
exemplifiedBy:
|
|
4745
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [lite, full], codes: [HFS_SECRET_PLAINTEXT_FILE]}
|
|
4746
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [full], codes: [HFS_SECRET_OUTSIDE_ENC]}
|
|
4747
|
+
witness:
|
|
4748
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [lite, full], codes: [HFS_SECRET_PLAINTEXT_FILE]}
|
|
4749
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [full], codes: [HFS_SECRET_OUTSIDE_ENC]}
|
|
4529
4750
|
- id: R278
|
|
4530
4751
|
code: "BE_REST_DOOR_EVIDENCE"
|
|
4531
4752
|
amendedBy: [owner:credential-guarded-rest-door]
|
|
@@ -4581,10 +4802,11 @@ rules:
|
|
|
4581
4802
|
exemplifiedBy:
|
|
4582
4803
|
- {path: packages/hfs/templates/be/skeleton/src/modules/domain/identity/errors/identity.error.ts, editions: [lite, full]}
|
|
4583
4804
|
- {path: packages/hfs/templates/be/skeleton/src/modules/domain/identity/admission.policy.ts, editions: [lite, full]}
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4805
|
+
- {path: packages/hfs/src/hfs-unused-symbol-ledger.spec.mjs, editions: [lite, full], codes: [HFS_UNUSED_SYMBOL]}
|
|
4806
|
+
proves:
|
|
4807
|
+
- {path: packages/hfs/src/hfs-unused-symbol-ledger.spec.mjs, editions: [lite, full], codes: [HFS_UNUSED_SYMBOL]}
|
|
4808
|
+
witness:
|
|
4809
|
+
- {path: packages/hfs/src/hfs-unused-symbol-ledger.spec.mjs, editions: [lite, full], codes: [HFS_UNUSED_SYMBOL]}
|
|
4588
4810
|
- id: R281
|
|
4589
4811
|
code: "BE_SPEC_FORM_ALL_ROLES"
|
|
4590
4812
|
law: "Unit spec form applies to every declared logic role, including policies, mappers, guards and integration clients. A spec obtains its subject from a compiled Nest testing module with explicit providers, never constructs the subject or mocks an own module or third-party library, and asserts behavior or state rather than only toBeDefined existence checks."
|
|
@@ -4620,10 +4842,12 @@ rules:
|
|
|
4620
4842
|
editions: [lite, full]
|
|
4621
4843
|
docs: [docs/quality-bar.md#r282]
|
|
4622
4844
|
templateNa: "Build assets are supplied by each application; the scaffolder does not generate binary assets, model weights or datasets."
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4845
|
+
proves:
|
|
4846
|
+
- {path: packages/hfs/src/hfs-assets.spec.mjs, editions: [lite, full], codes: [HFS_ASSET_OVERSIZE, HFS_ASSET_KIND]}
|
|
4847
|
+
exemplifiedBy:
|
|
4848
|
+
- {path: packages/hfs/src/hfs-assets.spec.mjs, editions: [lite, full], codes: [HFS_ASSET_OVERSIZE, HFS_ASSET_KIND]}
|
|
4849
|
+
witness:
|
|
4850
|
+
- {path: packages/hfs/src/hfs-assets.spec.mjs, editions: [lite, full], codes: [HFS_ASSET_OVERSIZE, HFS_ASSET_KIND]}
|
|
4627
4851
|
- id: R283
|
|
4628
4852
|
code: "HFS_APP_LEXICON"
|
|
4629
4853
|
law: "An app's source and documentation use the current product vocabulary: a word declared in hfs.json lexicon.removed is refused as a whole word or identifier segment, in both editions."
|
|
@@ -4635,10 +4859,12 @@ rules:
|
|
|
4635
4859
|
editions: [lite, full]
|
|
4636
4860
|
docs: [docs/quality-bar.md#r283]
|
|
4637
4861
|
templateNa: "Removed product vocabulary is application-specific hfs.json content; there is no canonical product lexicon to scaffold."
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4862
|
+
proves:
|
|
4863
|
+
- {path: packages/hfs/src/hfs-lexicon.spec.mjs, editions: [lite, full], codes: [HFS_APP_LEXICON]}
|
|
4864
|
+
exemplifiedBy:
|
|
4865
|
+
- {path: packages/hfs/src/hfs-lexicon.spec.mjs, editions: [lite, full], codes: [HFS_APP_LEXICON]}
|
|
4866
|
+
witness:
|
|
4867
|
+
- {path: packages/hfs/src/hfs-lexicon.spec.mjs, editions: [lite, full], codes: [HFS_APP_LEXICON]}
|
|
4642
4868
|
- id: R284
|
|
4643
4869
|
code: "BE_LITE_PROOF_LANE_MISSING"
|
|
4644
4870
|
law: "A lite back end declaring event-bus, queue, webhooks, realtime, fenced-job, projection or saga proves each declared pattern through integration specs under src/tests/integration: runnable tests carry titles `<pattern>/<scenario>: ...` for every required scenario of that pattern. A missing integration lane is refused; missing scenario proofs use R155's BE_PATTERN_SPEC_MISSING. Full-edition pattern proof behavior is unchanged."
|
|
@@ -4651,10 +4877,12 @@ rules:
|
|
|
4651
4877
|
editionWhy: "ruling:R212/case-2 (owner:lite-production-swarm) (with the Work boundary amended by ruling:R212/case-4): lite has no e2e world and proves declared patterns in its integration lane; R284 owns only the lite lane code while full retains its existing pattern-proof rules."
|
|
4652
4878
|
docs: [docs/quality-bar.md#r284]
|
|
4653
4879
|
templateNa: "Integration scenarios depend on the application patterns and providers; no universal runnable scenario lane is scaffolded."
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4880
|
+
proves:
|
|
4881
|
+
- {path: packages/hfs/src/hfs-lite-proof-lane.spec.mjs, editions: [lite], codes: [BE_LITE_PROOF_LANE_MISSING]}
|
|
4882
|
+
exemplifiedBy:
|
|
4883
|
+
- {path: packages/hfs/src/hfs-lite-proof-lane.spec.mjs, editions: [lite], codes: [BE_LITE_PROOF_LANE_MISSING]}
|
|
4884
|
+
witness:
|
|
4885
|
+
- {path: packages/hfs/src/hfs-lite-proof-lane.spec.mjs, editions: [lite], codes: [BE_LITE_PROOF_LANE_MISSING]}
|
|
4658
4886
|
- id: R285
|
|
4659
4887
|
code: "FE_SWR_OUTSIDE_FAMILY"
|
|
4660
4888
|
law: "SWR runtime calls belong to the declared SWR hook family. A component, feature or domain hook consumes its wrapper hook instead of importing an API operation or calling SWR itself; each back-end operation is imported and invoked only by its SWR wrapper under hooks/swr, regardless of whether the tier matrix still permits a direct transport edge."
|
|
@@ -4728,12 +4956,13 @@ rules:
|
|
|
4728
4956
|
- {kind: hfs, id: fe-stack-allowlist, at: scripts/hfs/rules/fe-stack.mjs}
|
|
4729
4957
|
editions: [lite, full]
|
|
4730
4958
|
docs: [docs/quality-bar.md#r288]
|
|
4959
|
+
proves:
|
|
4960
|
+
- {path: packages/hfs/src/hfs-fe-stack.spec.mjs, editions: [lite, full], codes: [FE_STACK_UNLISTED, FE_STACK_CORE_MISSING]}
|
|
4731
4961
|
exemplifiedBy:
|
|
4732
4962
|
- {path: packages/hfs/templates/fe/app/package.json.tpl, editions: [lite, full]}
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
exampleNa: "owner:no-runtime-specs (2026-10-17): the only example was a deleted runtime spec or fixture; the rule judges the runtime or the scaffold, which the scaffold e2e exercises"
|
|
4963
|
+
- {path: packages/hfs/src/hfs-fe-stack.spec.mjs, editions: [lite, full], codes: [FE_STACK_UNLISTED, FE_STACK_CORE_MISSING]}
|
|
4964
|
+
witness:
|
|
4965
|
+
- {path: packages/hfs/src/hfs-fe-stack.spec.mjs, editions: [lite, full], codes: [FE_STACK_UNLISTED, FE_STACK_CORE_MISSING]}
|
|
4737
4966
|
- id: R289
|
|
4738
4967
|
code: "BE_APP_ENV_REQUIRED"
|
|
4739
4968
|
law: "Every declared back-end app owns a tracked apps/<app>/src/<app>.env.ts exporting its typed environment interface and read<App>Env(env: EnvSource). main.ts constructs EnvSource once and delegates its reads to that reader, with no inline parsing. app.module.ts composes module lists only by spreading compose/<area>.ts groups; its own providers are limited to app-wide guards and filters."
|
|
@@ -4746,18 +4975,20 @@ rules:
|
|
|
4746
4975
|
- {kind: eslint-be, id: app-module-list-inline}
|
|
4747
4976
|
editions: [lite, full]
|
|
4748
4977
|
docs: [docs/microservices.md#r289]
|
|
4978
|
+
proves:
|
|
4979
|
+
- {path: packages/eslint/be/app-composition.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED, BE_APP_MODULE_LIST_INLINE]}
|
|
4980
|
+
- {path: packages/hfs/src/hfs-app-env-required.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED]}
|
|
4749
4981
|
exemplifiedBy:
|
|
4750
4982
|
- {path: packages/eslint/be/app-composition.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED, BE_APP_MODULE_LIST_INLINE]}
|
|
4751
4983
|
- {path: packages/hfs/templates/be/skeleton/apps/__app__/src/__app__.env.ts, editions: [full]}
|
|
4752
4984
|
- {path: packages/hfs/templates/be/skeleton/apps/__app__/src/app.module.ts, editions: [full]}
|
|
4753
4985
|
- {path: packages/hfs/templates/be/skeleton-lite/apps/api/src/api.env.ts, editions: [lite]}
|
|
4754
4986
|
- {path: packages/hfs/templates/be/skeleton-lite/apps/api/src/app.module.ts, editions: [lite]}
|
|
4755
|
-
|
|
4756
|
-
- {path: packages/eslint/be/app-composition.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED, BE_APP_MODULE_LIST_INLINE]}
|
|
4987
|
+
- {path: packages/hfs/src/hfs-app-env-required.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED]}
|
|
4757
4988
|
witness:
|
|
4758
4989
|
- {path: packages/eslint/be/app-composition.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED, BE_APP_MODULE_LIST_INLINE]}
|
|
4759
4990
|
|
|
4760
|
-
|
|
4991
|
+
- {path: packages/hfs/src/hfs-app-env-required.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED]}
|
|
4761
4992
|
- id: R290
|
|
4762
4993
|
code: "BE_PUBLIC_REASON_CLOSED"
|
|
4763
4994
|
amendedBy: [owner:credential-guarded-rest-door]
|
|
@@ -4812,13 +5043,16 @@ rules:
|
|
|
4812
5043
|
- {kind: hfs, id: feature-files, at: scripts/hfs/rules/feature-files.mjs}
|
|
4813
5044
|
editions: [lite, full]
|
|
4814
5045
|
docs: [docs/quality-bar.md#r292]
|
|
5046
|
+
proves:
|
|
5047
|
+
- {path: packages/hfs/src/hfs-feature-files.spec.mjs, editions: [lite, full], codes: [HFS_FEATURE_FILE_BUDGET]}
|
|
4815
5048
|
exemplifiedBy:
|
|
4816
5049
|
- {path: packages/hfs/templates/be/patterns/api, editions: [lite, full]}
|
|
4817
5050
|
- {path: examples/lite-app/be/src/features/api/bookings, editions: [lite]}
|
|
4818
5051
|
- {path: examples/full-app/be/src/features/api/checkout, editions: [full]}
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
witness:
|
|
5052
|
+
- {path: packages/hfs/src/hfs-feature-files.spec.mjs, editions: [lite, full], codes: [HFS_FEATURE_FILE_BUDGET]}
|
|
5053
|
+
- {path: examples/ecommerce-app/be/src/features/api/checkout, editions: [full]}
|
|
5054
|
+
witness:
|
|
5055
|
+
- {path: packages/hfs/src/hfs-feature-files.spec.mjs, editions: [lite, full], codes: [HFS_FEATURE_FILE_BUDGET]}
|
|
4822
5056
|
- id: R293
|
|
4823
5057
|
code: "STACK_TOOLING_REIMPLEMENTED"
|
|
4824
5058
|
law: "In lite and full apps, an app does not re-implement the Swarm deploy tooling the canon ships as `starci app stack <verb>`. Tracked deploy sources (files under deploy/ and scripts/, the scripts of package.json and every workflow except the managed stack-deploy.yml) never call a docker command a verb owns (docker stack deploy and config, docker secret and config create and rm, docker service ls, ps, inspect and update, docker swarm init, docker volume create, docker node ls), and deploy/ holds no render, provision, converge, verify, prune, rollback, release, backup, prepare, doctor, jobs or public script. A finding names the file and the replacing verb, never a snippet; docker stack rm, ls, ps and services, docker compose, docker run, exec, ps and logs, comments, documents and `starci app stack ...` command lines are not judged."
|
|
@@ -4830,15 +5064,14 @@ rules:
|
|
|
4830
5064
|
editions: [lite, full]
|
|
4831
5065
|
docs:
|
|
4832
5066
|
- {path: docs/application-stacks.md#r293, editions: [lite, full]}
|
|
5067
|
+
proves:
|
|
5068
|
+
- {path: packages/hfs/src/hfs-stack-tooling.spec.mjs, editions: [lite, full]}
|
|
4833
5069
|
exemplifiedBy:
|
|
4834
5070
|
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/stack-deploy.yml, edition: lite}
|
|
4835
5071
|
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/stack-deploy.yml, edition: full}
|
|
4836
5072
|
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
4837
5073
|
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4838
5074
|
- {path: examples/lite-app/.github/workflows/stack-deploy.yml, edition: lite}
|
|
4839
|
-
specNa: "owner:no-runtime-specs (2026-10-17): the runtime has no specs of its own; this code is enforced by runtime code and its spec proof was a deleted runtime spec"
|
|
4840
|
-
|
|
4841
|
-
witness: {status: unreachable, reason: "owner:no-runtime-specs (2026-10-17): the mutation witness was a deleted runtime spec or fixture", date: "2026-10-17"}
|
|
4842
5075
|
- id: R294
|
|
4843
5076
|
code: "STACKS_DEPLOY_CONFIG_INVALID"
|
|
4844
5077
|
law: "In lite and full apps, every docker-swarm environment of .starcistacks/application-stacks.yaml that declares environments.<env>.deploy declares a coherent block: it is judged by the same normalizeDeploy the `starci app stack` verbs use, against the real tree. Unknown fields are refused, names, keys, volumes, hosts, URLs and commands match their patterns, the config and public environment files exist below .starcistacks/<env>/, every service names a service of the first stack source, every sealed member has a secrets/<member>.enc file, verify entries and configs are well formed with unique config names, and the backup helper image is pinned by a real sha256 digest (no placeholder). Each problem is one finding at environments.<env>.<field>; an environment without a deploy block is not a finding."
|
|
@@ -4851,12 +5084,14 @@ rules:
|
|
|
4851
5084
|
docs:
|
|
4852
5085
|
- {path: docs/application-stacks.md#r294, editions: [lite, full]}
|
|
4853
5086
|
- {path: docs/application-stacks.md#r294-edge, editions: [lite, full]}
|
|
5087
|
+
proves:
|
|
5088
|
+
- {path: packages/hfs/src/hfs-stacks-deploy.spec.mjs, editions: [lite, full]}
|
|
4854
5089
|
exemplifiedBy:
|
|
4855
5090
|
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks, edition: lite}
|
|
4856
5091
|
- {path: packages/hfs/templates/app/skeleton/.starcistacks, edition: full}
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
5092
|
+
- {path: packages/hfs/src/hfs-stacks-deploy.spec.mjs, editions: [lite, full]}
|
|
5093
|
+
witness:
|
|
5094
|
+
- {path: packages/hfs/src/hfs-stacks-deploy.spec.mjs, editions: [lite, full]}
|
|
4860
5095
|
- id: R295
|
|
4861
5096
|
code: "BE_MODULE_DEFINITION_MISSING"
|
|
4862
5097
|
law: "Every NestJS module of the product has a module definition (owner ruling 2026-10-15, owner:module-definition-everywhere): capability modules, sub-modules, features, transport modules and cli groups alike. For a module `<x>` the folder holds `<x>.module-definition.ts` (`export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE } = new ConfigurableModuleBuilder<XOptions>().setClassMethodName(\"register\").build()`; the representative module of a capability keeps `.setExtras({ isGlobal: false }, ...)`), `<x>.options.ts` (`export type XOptions`, `Record<string, never>` with a one-line doc when it takes nothing yet) and `<x>.module.ts` (`@Module({...}) export class XModule extends ConfigurableModuleClass {}`, no `register` override except the capability representative's). A module appears in an `imports` array or in an app composition group only as `XModule.register({...})`, never as a bare class. The `AppModule` of an app root and the test world are composition roots and are not judged."
|
|
@@ -4899,8 +5134,11 @@ rules:
|
|
|
4899
5134
|
- {path: examples/shape-slot/.starcistacks/application-stacks.yaml, edition: full}
|
|
4900
5135
|
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
4901
5136
|
- {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
|
|
4902
|
-
|
|
4903
|
-
|
|
5137
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [CI_SECRET_SEALED]}
|
|
5138
|
+
proves:
|
|
5139
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [CI_SECRET_SEALED]}
|
|
5140
|
+
witness:
|
|
5141
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [CI_SECRET_SEALED]}
|
|
4904
5142
|
- id: R297
|
|
4905
5143
|
code: "APP_SECRET_IN_CI"
|
|
4906
5144
|
law: "A sealed member key granted to an app container by a deploy grant never appears in ci.secrets or ci.vars. The grant environment, member and selected key determine app custody; online GitHub custody is verified by starci app ci verify."
|
|
@@ -4918,8 +5156,11 @@ rules:
|
|
|
4918
5156
|
- {path: examples/shape-slot/.starcistacks/application-stacks.yaml, edition: full}
|
|
4919
5157
|
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
4920
5158
|
- {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
|
|
4921
|
-
|
|
4922
|
-
|
|
5159
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [APP_SECRET_IN_CI]}
|
|
5160
|
+
proves:
|
|
5161
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [APP_SECRET_IN_CI]}
|
|
5162
|
+
witness:
|
|
5163
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [APP_SECRET_IN_CI]}
|
|
4923
5164
|
- id: R298
|
|
4924
5165
|
code: "CI_DECLARATION_DRIFT"
|
|
4925
5166
|
law: "Workflow secrets and vars references are declared in their matching top-level ci class, except automatic GITHUB_TOKEN. Non-optional Actions declarations are consumed by a workflow; Dependabot secrets need no Actions read. Service token and variable bindings name declarations in the matching class. Missing declarations produce migration findings; a tree with neither ci declarations nor references stays quiet."
|
|
@@ -4937,8 +5178,11 @@ rules:
|
|
|
4937
5178
|
- {path: examples/shape-slot/.starcistacks/application-stacks.yaml, edition: full}
|
|
4938
5179
|
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
4939
5180
|
- {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
|
|
4940
|
-
|
|
4941
|
-
|
|
5181
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [CI_DECLARATION_DRIFT]}
|
|
5182
|
+
proves:
|
|
5183
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [CI_DECLARATION_DRIFT]}
|
|
5184
|
+
witness:
|
|
5185
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [CI_DECLARATION_DRIFT]}
|
|
4942
5186
|
- id: R299
|
|
4943
5187
|
code: "HFS_WORKFLOW_CONTEXT"
|
|
4944
5188
|
law: "GitHub Actions expressions use only contexts available at their workflow key. Job env cannot read runner, job, steps or env; runner-local data paths belong to step env or shell RUNNER_TEMP. Every tracked workflow is checked in both app editions."
|
|
@@ -4953,8 +5197,11 @@ rules:
|
|
|
4953
5197
|
exemplifiedBy:
|
|
4954
5198
|
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks, edition: lite}
|
|
4955
5199
|
- {path: packages/hfs/templates/app/skeleton/.starcistacks, edition: full}
|
|
4956
|
-
|
|
4957
|
-
|
|
5200
|
+
- {path: packages/hfs/src/workflow-contexts.spec.mjs, editions: [lite, full], codes: [HFS_WORKFLOW_CONTEXT]}
|
|
5201
|
+
proves:
|
|
5202
|
+
- {path: packages/hfs/src/workflow-contexts.spec.mjs, editions: [lite, full], codes: [HFS_WORKFLOW_CONTEXT]}
|
|
5203
|
+
witness:
|
|
5204
|
+
- {path: packages/hfs/src/workflow-contexts.spec.mjs, editions: [lite, full], codes: [HFS_WORKFLOW_CONTEXT]}
|
|
4958
5205
|
- id: R300
|
|
4959
5206
|
code: "FE_PUBLIC_BUILD_ARG_MISSING"
|
|
4960
5207
|
law: "Every front-end app with a Dockerfile supplies each required NEXT_PUBLIC_* source/config/schema name through a Dockerfile ARG default or through that image's buildArgs.values/buildArgs.sealed.keys in every environment deploying the image. Source reads with literal string ?? or || fallbacks are optional. The finding names missing keys and environments at the Dockerfile; sealed values are never opened. CI release images use the same starci app stack build-args verb and environment as deployment."
|
|
@@ -4969,8 +5216,11 @@ rules:
|
|
|
4969
5216
|
exemplifiedBy:
|
|
4970
5217
|
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks, edition: lite}
|
|
4971
5218
|
- {path: packages/hfs/templates/app/skeleton/.starcistacks, edition: full}
|
|
4972
|
-
|
|
4973
|
-
|
|
5219
|
+
- {path: packages/hfs/src/fe-build-args.spec.mjs, editions: [lite, full], codes: [FE_PUBLIC_BUILD_ARG_MISSING]}
|
|
5220
|
+
proves:
|
|
5221
|
+
- {path: packages/hfs/src/fe-build-args.spec.mjs, editions: [lite, full], codes: [FE_PUBLIC_BUILD_ARG_MISSING]}
|
|
5222
|
+
witness:
|
|
5223
|
+
- {path: packages/hfs/src/fe-build-args.spec.mjs, editions: [lite, full], codes: [FE_PUBLIC_BUILD_ARG_MISSING]}
|
|
4974
5224
|
- id: R301
|
|
4975
5225
|
code: "CI_STANDARD"
|
|
4976
5226
|
law: "The managed app CI, the example apps (the reference) and the runtime repository's own workflows follow the ONE CI standard of knowledge/hfs/ci-standard.yaml (owner ruling ci-standard, 2026-10-18): the job shape fast/test/build(/sonar) with the unit run and the Codecov upload in test alone, full history with STARCI_BASE_REF written before the lint, NODE_OPTIONS --max-old-space-size=6144 on every heavy step, the Sonar lint per side, optional providers probed before they skip, a timeout on every job and every action pinned to a commit sha; the other items (candidate trigger R221, per-fe-app build env, prettier-stable renders, R299 contexts) are owned by the rules the standard names. Apps get the standard only through starci app sync."
|
|
@@ -4986,8 +5236,11 @@ rules:
|
|
|
4986
5236
|
exemplifiedBy:
|
|
4987
5237
|
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
4988
5238
|
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4989
|
-
|
|
4990
|
-
|
|
5239
|
+
- {path: packages/hfs/src/ci-standard.spec.mjs, editions: [lite, full], codes: [CI_STANDARD]}
|
|
5240
|
+
proves:
|
|
5241
|
+
- {path: packages/hfs/src/ci-standard.spec.mjs, editions: [lite, full], codes: [CI_STANDARD]}
|
|
5242
|
+
witness:
|
|
5243
|
+
- {path: packages/hfs/src/ci-standard.spec.mjs, editions: [lite, full], codes: [CI_STANDARD]}
|
|
4991
5244
|
- id: R302
|
|
4992
5245
|
code: "HFS_MCP_TOOLS_SNAPSHOT"
|
|
4993
5246
|
law: "An app that commits the MCP tool catalog of its server keeps it at `be/contracts/<app>/<contract>.tools.json` (slot be.contract.mcp-tools, opt-in), `<contract>` being `<server>@<major>`, as the server's `tools/list` result: `{ contract, server: { name, version }, tools }` where the contract equals the file name and the server name, and every tool has a unique name, a description and an object `inputSchema`."
|
|
@@ -5000,6 +5253,28 @@ rules:
|
|
|
5000
5253
|
docs:
|
|
5001
5254
|
- {path: docs/hfs-contract-snapshots.md#r302, editions: [lite, full]}
|
|
5002
5255
|
templateNa: "The canon emits no MCP catalog: the app commits its server's tools/list result, so there is no scaffolded snapshot."
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5256
|
+
proves:
|
|
5257
|
+
- {path: packages/hfs/src/mcp-tools-snapshot.spec.mjs, editions: [lite, full], codes: [HFS_MCP_TOOLS_SNAPSHOT]}
|
|
5258
|
+
exemplifiedBy:
|
|
5259
|
+
- {path: packages/hfs/src/mcp-tools-snapshot.spec.mjs, editions: [lite, full], codes: [HFS_MCP_TOOLS_SNAPSHOT]}
|
|
5260
|
+
witness:
|
|
5261
|
+
- {path: packages/hfs/src/mcp-tools-snapshot.spec.mjs, editions: [lite, full], codes: [HFS_MCP_TOOLS_SNAPSHOT]}
|
|
5262
|
+
- id: R303
|
|
5263
|
+
code: "HFS_BYPASS_MARKER"
|
|
5264
|
+
law: "A product repository holds no bypass of a check (owner ruling loosening-always-red): no inline disable of any tool (eslint, stylelint, tslint, prettier, biome), no ts-ignore, ts-expect-error or ts-nocheck directive, no Sonar exclusion comment, no istanbul, c8 or v8 coverage ignore, no skipped, focused or todo test or skip option, and no failure swallowed in a hook, script or workflow (`|| true`, `continue-on-error`, `set +e`, `HUSKY=0`, `--no-verify`, `fail_ci_if_error: false`). A front end has no specs, but its source is still judged for the inline disables. `starci app check` reads the tracked tree and `starci app hygiene` (the managed pre-commit hook) the staged files from the index, so the bypass fails at the commit."
|
|
5265
|
+
kinds: [check]
|
|
5266
|
+
gates: [pre-commit, land, ci]
|
|
5267
|
+
failureCodes: ["HFS_BYPASS_MARKER"]
|
|
5268
|
+
enforcers:
|
|
5269
|
+
- {kind: hfs, id: bypass-markers, at: scripts/hfs/rules/bypass-markers.mjs}
|
|
5270
|
+
- {kind: hfs, id: bypass-guard, at: packages/hfs/sync/hygiene.mjs}
|
|
5271
|
+
editions: [lite, full]
|
|
5272
|
+
docs:
|
|
5273
|
+
- {path: docs/hfs-authored-file-boundaries.md#r303, editions: [lite, full]}
|
|
5274
|
+
templateNa: "A bypass is prohibited, so no template scaffolds one."
|
|
5275
|
+
proves:
|
|
5276
|
+
- {path: packages/hfs/src/bypass-detector.spec.mjs, editions: [lite, full], codes: [HFS_BYPASS_MARKER]}
|
|
5277
|
+
exemplifiedBy:
|
|
5278
|
+
- {path: packages/hfs/src/bypass-detector.spec.mjs, editions: [lite, full], codes: [HFS_BYPASS_MARKER]}
|
|
5279
|
+
witness:
|
|
5280
|
+
- {path: packages/hfs/src/bypass-detector.spec.mjs, editions: [lite, full], codes: [HFS_BYPASS_MARKER]}
|