@starci/eslint-canon-be 3.4.34 → 3.4.36
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 +7 -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 +913 -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/eslint/fe/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/eslint/fe/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/eslint/fe/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/eslint/be/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/eslint/be/hfs-unused-export.spec.mjs, editions: [lite, full], codes: [HFS_UNUSED_EXPORT, HFS_UNUSED_FILE]}
|
|
461
|
+
witness:
|
|
462
|
+
- {path: packages/eslint/be/hfs-unused-export.spec.mjs, edition: lite, codes: [HFS_UNUSED_EXPORT, HFS_UNUSED_FILE]}
|
|
463
|
+
- {path: packages/eslint/be/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/eslint/be/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/eslint/be/a16-r29-r31.spec.mjs, editions: [lite, full]}
|
|
537
|
+
witness:
|
|
538
|
+
- {path: packages/eslint/be/a16-r29-r31.spec.mjs, edition: lite}
|
|
539
|
+
- {path: packages/eslint/be/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/eslint/fe/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/eslint/fe/r52-wire-generated.spec.mjs, editions: [lite, full], codes: [FE_WIRE_GENERATED]}
|
|
1071
|
+
witness:
|
|
1072
|
+
- {path: packages/eslint/fe/r52-wire-generated.spec.mjs, edition: lite, codes: [FE_WIRE_GENERATED]}
|
|
1073
|
+
- {path: packages/eslint/fe/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/eslint/fe/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/eslint/fe/r53-error-boundaries.spec.mjs, editions: [lite, full], codes: [FE_ERROR_BOUNDARY_MISSING, FE_SUSPENSE_NULL_FALLBACK]}
|
|
1091
|
+
witness:
|
|
1092
|
+
- {path: packages/eslint/fe/r53-error-boundaries.spec.mjs, edition: lite, codes: [FE_ERROR_BOUNDARY_MISSING, FE_SUSPENSE_NULL_FALLBACK]}
|
|
1093
|
+
- {path: packages/eslint/fe/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,16 @@ 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/eslint/be/be-r89-source-form-coverage.spec.mjs, editions: [lite, full]}
|
|
1784
|
+
- {path: packages/hfs/src/be-r89-source-suffix.spec.mjs, editions: [lite, full], codes: [BE_SOURCE_FORM]}
|
|
1785
|
+
exemplifiedBy:
|
|
1786
|
+
- {path: packages/hfs/templates/be/patterns/api/graphql.input.ts.tpl, editions: [lite, full]}
|
|
1787
|
+
- {path: packages/eslint/be/be-r89-source-form-coverage.spec.mjs, editions: [lite, full]}
|
|
1788
|
+
witness:
|
|
1789
|
+
- {path: packages/eslint/be/be-r89-source-form-coverage.spec.mjs, edition: lite, codes: [BE_SOURCE_FORM, BE_PUBLIC_CONTRACT_FORM]}
|
|
1790
|
+
- {path: packages/eslint/be/be-r89-source-form-coverage.spec.mjs, edition: full, codes: [BE_SOURCE_FORM, BE_PUBLIC_CONTRACT_FORM]}
|
|
1692
1791
|
- id: R90
|
|
1693
1792
|
code: "BE_INFRA_OWNER"
|
|
1694
1793
|
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 +1889,16 @@ rules:
|
|
|
1790
1889
|
- {kind: machine, id: grammar, at: scripts/hfs/architecture/frontend-grammar.mjs}
|
|
1791
1890
|
editions: [lite, full]
|
|
1792
1891
|
docs: ["docs/code-pattern-enforcement.md#r93-vendor-and-grammar-ownership"]
|
|
1892
|
+
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
1893
|
proves:
|
|
1794
1894
|
- packages/eslint/fe/r93-vendor-coverage.spec.mjs
|
|
1795
|
-
|
|
1895
|
+
- packages/eslint/fe/r93-grammar-ownership.spec.mjs
|
|
1796
1896
|
exemplifiedBy:
|
|
1797
1897
|
- {path: packages/eslint/fe/r93-vendor-coverage.spec.mjs, editions: [lite, full]}
|
|
1898
|
+
- {path: packages/eslint/fe/r93-grammar-ownership.spec.mjs, editions: [lite, full]}
|
|
1798
1899
|
witness:
|
|
1799
1900
|
- {path: packages/eslint/fe/r93-vendor-coverage.spec.mjs, editions: [lite, full], codes: [FE_VENDOR_BOUNDARY]}
|
|
1800
|
-
|
|
1901
|
+
- {path: packages/eslint/fe/r93-grammar-ownership.spec.mjs, editions: [lite, full], codes: [ARCH_GRAMMAR_CONTRACT_INVALID, ARCH_GRAMMAR_EXPORT_BYPASS]}
|
|
1801
1902
|
- id: R94
|
|
1802
1903
|
code: "FE_SLOT_FILE_ROLE"
|
|
1803
1904
|
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 +1909,13 @@ rules:
|
|
|
1808
1909
|
- {kind: machine, id: fe-slot-allows, at: scripts/hfs/architecture/fe-slot-allows.mjs}
|
|
1809
1910
|
editions: ["lite","full"]
|
|
1810
1911
|
docs: ["docs/hfs-authored-file-boundaries.md#r94-slot-file-roles"]
|
|
1811
|
-
|
|
1812
|
-
exemplifiedBy:
|
|
1813
|
-
|
|
1912
|
+
proves: [packages/hfs/src/r94-r96-r97-coverage.spec.mjs]
|
|
1913
|
+
exemplifiedBy:
|
|
1914
|
+
- {path: "packages/hfs/templates/fe/skeleton-lite/apps/web/src/app/[locale]/page.tsx", edition: lite}
|
|
1915
|
+
- {path: "packages/hfs/templates/fe/skeleton/apps/app/src/app/[locale]/page.tsx", edition: full}
|
|
1916
|
+
- {path: packages/hfs/src/r94-r96-r97-coverage.spec.mjs, editions: [lite, full], codes: [FE_SLOT_FILE_ROLE]}
|
|
1917
|
+
witness:
|
|
1918
|
+
- {path: packages/hfs/src/r94-r96-r97-coverage.spec.mjs, editions: [lite, full], codes: [FE_SLOT_FILE_ROLE]}
|
|
1814
1919
|
- id: R95
|
|
1815
1920
|
code: "BE_OPERATION_CONTRACT"
|
|
1816
1921
|
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 +1942,11 @@ rules:
|
|
|
1837
1942
|
editions: ["lite","full"]
|
|
1838
1943
|
docs: ["docs/hfs-authored-file-boundaries.md#r96-document-language"]
|
|
1839
1944
|
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
|
-
|
|
1945
|
+
proves: [packages/hfs/src/r94-r96-r97-coverage.spec.mjs]
|
|
1946
|
+
exemplifiedBy:
|
|
1947
|
+
- {path: packages/hfs/src/r94-r96-r97-coverage.spec.mjs, editions: [lite, full], codes: [HFS_DOC_NOT_ENGLISH]}
|
|
1948
|
+
witness:
|
|
1949
|
+
- {path: packages/hfs/src/r94-r96-r97-coverage.spec.mjs, editions: [lite, full], codes: [HFS_DOC_NOT_ENGLISH]}
|
|
1843
1950
|
- id: R97
|
|
1844
1951
|
code: "FE_NO_TESTS"
|
|
1845
1952
|
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 +1957,12 @@ rules:
|
|
|
1850
1957
|
editions: ["lite","full"]
|
|
1851
1958
|
docs: ["docs/hfs-authored-file-boundaries.md#r97-front-end-test-exclusion"]
|
|
1852
1959
|
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
1960
|
gates: ["settle","land","ci"]
|
|
1856
|
-
|
|
1961
|
+
proves: [packages/hfs/src/r94-r96-r97-coverage.spec.mjs]
|
|
1962
|
+
exemplifiedBy:
|
|
1963
|
+
- {path: packages/hfs/src/r94-r96-r97-coverage.spec.mjs, editions: [lite, full], codes: [FE_NO_TESTS]}
|
|
1964
|
+
witness:
|
|
1965
|
+
- {path: packages/hfs/src/r94-r96-r97-coverage.spec.mjs, editions: [lite, full], codes: [FE_NO_TESTS]}
|
|
1857
1966
|
- id: R98
|
|
1858
1967
|
code: "BE_TEST_BUILDER_HOME"
|
|
1859
1968
|
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 +2032,29 @@ rules:
|
|
|
1923
2032
|
code: "BE_SPEC_PLACEMENT"
|
|
1924
2033
|
editions: [lite, full]
|
|
1925
2034
|
docs: [docs/legacy-repo-rule-coverage.md#r102]
|
|
2035
|
+
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."
|
|
2036
|
+
kinds: [check, lint]
|
|
2037
|
+
gates: [land, ci]
|
|
2038
|
+
failureCodes: ["BE_SPEC_PLACEMENT"]
|
|
2039
|
+
enforcers:
|
|
2040
|
+
- {kind: hfs, id: spec-placement, at: scripts/hfs/rules/spec-placement.mjs}
|
|
2041
|
+
- {kind: eslint-be, id: spec-placement}
|
|
1926
2042
|
proves:
|
|
1927
2043
|
- {path: packages/eslint/be/spec-placement-coverage.spec.mjs, editions: [lite, full], codes: [BE_SPEC_PLACEMENT]}
|
|
2044
|
+
- {path: packages/hfs/src/hfs-spec-placement-coverage.spec.mjs, editions: [lite, full], codes: [BE_SPEC_PLACEMENT]}
|
|
1928
2045
|
exemplifiedBy:
|
|
1929
2046
|
- {path: packages/hfs/templates/be/patterns/cli/group.cli.spec.ts.tpl, editions: [lite, full]}
|
|
1930
2047
|
- {path: packages/eslint/be/spec-placement-coverage.spec.mjs, editions: [lite, full], codes: [BE_SPEC_PLACEMENT]}
|
|
2048
|
+
- {path: packages/hfs/src/hfs-spec-placement-coverage.spec.mjs, editions: [lite, full], codes: [BE_SPEC_PLACEMENT]}
|
|
1931
2049
|
witness:
|
|
1932
2050
|
- {path: packages/eslint/be/spec-placement-coverage.spec.mjs, edition: lite, codes: [BE_SPEC_PLACEMENT]}
|
|
1933
2051
|
- {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"
|
|
2052
|
+
- {path: packages/hfs/src/hfs-spec-placement-coverage.spec.mjs, edition: lite, codes: [BE_SPEC_PLACEMENT]}
|
|
2053
|
+
- {path: packages/hfs/src/hfs-spec-placement-coverage.spec.mjs, edition: full, codes: [BE_SPEC_PLACEMENT]}
|
|
1942
2054
|
- id: R103
|
|
1943
2055
|
code: "HFS_REPO_LOCAL_CHECK"
|
|
1944
2056
|
editions: [lite, full]
|
|
1945
2057
|
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
2058
|
templateNa: "Repository-local checks and lint plugins are forbidden artifacts and have no managed scaffold."
|
|
1949
2059
|
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
2060
|
kinds: [check]
|
|
@@ -1952,13 +2062,17 @@ rules:
|
|
|
1952
2062
|
failureCodes: ["HFS_REPO_LOCAL_CHECK"]
|
|
1953
2063
|
enforcers:
|
|
1954
2064
|
- {kind: hfs, id: repo-local-check, at: scripts/hfs/rules/repo-local-checks.mjs}
|
|
1955
|
-
|
|
2065
|
+
proves:
|
|
2066
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, editions: [lite, full], codes: [HFS_REPO_LOCAL_CHECK]}
|
|
2067
|
+
exemplifiedBy:
|
|
2068
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, editions: [lite, full], codes: [HFS_REPO_LOCAL_CHECK]}
|
|
2069
|
+
witness:
|
|
2070
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, edition: lite, codes: [HFS_REPO_LOCAL_CHECK]}
|
|
2071
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, edition: full, codes: [HFS_REPO_LOCAL_CHECK]}
|
|
1956
2072
|
- id: R104
|
|
1957
2073
|
code: "HFS_LINT_SUPPRESSION_FILE"
|
|
1958
2074
|
editions: [lite, full]
|
|
1959
2075
|
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
2076
|
templateNa: "Lint-suppression files and options are prohibited, so no suppression artifact is scaffolded."
|
|
1963
2077
|
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
2078
|
kinds: [check]
|
|
@@ -1966,21 +2080,31 @@ rules:
|
|
|
1966
2080
|
failureCodes: ["HFS_LINT_SUPPRESSION_FILE"]
|
|
1967
2081
|
enforcers:
|
|
1968
2082
|
- {kind: hfs, id: lint-suppression, at: scripts/hfs/rules/lint-suppression.mjs}
|
|
1969
|
-
|
|
2083
|
+
proves:
|
|
2084
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, editions: [lite, full], codes: [HFS_LINT_SUPPRESSION_FILE]}
|
|
2085
|
+
exemplifiedBy:
|
|
2086
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, editions: [lite, full], codes: [HFS_LINT_SUPPRESSION_FILE]}
|
|
2087
|
+
witness:
|
|
2088
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, edition: lite, codes: [HFS_LINT_SUPPRESSION_FILE]}
|
|
2089
|
+
- {path: packages/hfs/src/hfs-repository-hygiene-coverage.spec.mjs, edition: full, codes: [HFS_LINT_SUPPRESSION_FILE]}
|
|
1970
2090
|
- id: R105
|
|
1971
2091
|
code: "HFS_PROOF_COMMAND_FILE_MISSING"
|
|
1972
2092
|
editions: [lite, full]
|
|
1973
2093
|
docs: [docs/legacy-repo-rule-coverage.md#r105]
|
|
1974
2094
|
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
2095
|
law: "A proof command of a `.starciwork` record (`requiresProof.<kind>.command`) is runnable as written: every repository file it names exists."
|
|
1978
2096
|
kinds: [check]
|
|
1979
2097
|
gates: [land, ci]
|
|
1980
2098
|
failureCodes: ["HFS_PROOF_COMMAND_FILE_MISSING"]
|
|
1981
2099
|
enforcers:
|
|
1982
2100
|
- {kind: hfs, id: proof-command-files, at: scripts/hfs/rules/proof-commands.mjs}
|
|
1983
|
-
|
|
2101
|
+
proves:
|
|
2102
|
+
- {path: packages/hfs/src/hfs-proof-command-file-missing.spec.mjs, editions: [lite, full]}
|
|
2103
|
+
exemplifiedBy:
|
|
2104
|
+
- {path: packages/hfs/src/hfs-proof-command-file-missing.spec.mjs, editions: [lite, full]}
|
|
2105
|
+
witness:
|
|
2106
|
+
- {path: packages/hfs/src/hfs-proof-command-file-missing.spec.mjs, edition: lite, codes: [HFS_PROOF_COMMAND_FILE_MISSING]}
|
|
2107
|
+
- {path: packages/hfs/src/hfs-proof-command-file-missing.spec.mjs, edition: full, codes: [HFS_PROOF_COMMAND_FILE_MISSING]}
|
|
1984
2108
|
- id: R106
|
|
1985
2109
|
code: "FE_I18N_KEYS"
|
|
1986
2110
|
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 +2203,6 @@ rules:
|
|
|
2079
2203
|
code: "HFS_PEER_INTEGRATION_MISSING"
|
|
2080
2204
|
editions: [lite, full]
|
|
2081
2205
|
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
2206
|
templateNa: "Optional integration dependency pairs and their runtime peers are application-specific package.json dependencies, not a managed scaffold surface."
|
|
2085
2207
|
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
2208
|
kinds: [check]
|
|
@@ -2088,14 +2210,17 @@ rules:
|
|
|
2088
2210
|
failureCodes: ["HFS_PEER_INTEGRATION_MISSING"]
|
|
2089
2211
|
enforcers:
|
|
2090
2212
|
- {kind: hfs, id: peer-integrations, at: scripts/hfs/rules/peer-integrations.mjs}
|
|
2091
|
-
|
|
2213
|
+
proves:
|
|
2214
|
+
- {path: packages/hfs/src/hfs-peer-integrations-coverage.spec.mjs, editions: [lite, full]}
|
|
2215
|
+
exemplifiedBy:
|
|
2216
|
+
- {path: packages/hfs/src/hfs-peer-integrations-coverage.spec.mjs, editions: [lite, full]}
|
|
2217
|
+
witness:
|
|
2218
|
+
- {path: packages/hfs/src/hfs-peer-integrations-coverage.spec.mjs, editions: [lite, full], codes: [HFS_PEER_INTEGRATION_MISSING]}
|
|
2092
2219
|
- id: R112
|
|
2093
2220
|
code: "BE_INTEGRATION_SPEC_MISSING"
|
|
2094
2221
|
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
2222
|
docs: [docs/quality-bar.md#r112]
|
|
2096
2223
|
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
2224
|
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
2225
|
kinds: [check]
|
|
2101
2226
|
gates: [land, ci]
|
|
@@ -2103,21 +2228,29 @@ rules:
|
|
|
2103
2228
|
editions: [full]
|
|
2104
2229
|
enforcers:
|
|
2105
2230
|
- {kind: hfs, id: integration-specs, at: scripts/hfs/rules/integration-specs.mjs}
|
|
2106
|
-
|
|
2231
|
+
proves:
|
|
2232
|
+
- {path: packages/hfs/src/hfs-repo-scripts-rules.spec.mjs, editions: [full], codes: [BE_INTEGRATION_SPEC_MISSING]}
|
|
2233
|
+
exemplifiedBy:
|
|
2234
|
+
- {path: packages/hfs/src/hfs-repo-scripts-rules.spec.mjs, editions: [full], codes: [BE_INTEGRATION_SPEC_MISSING]}
|
|
2235
|
+
witness:
|
|
2236
|
+
- {path: packages/hfs/src/hfs-repo-scripts-rules.spec.mjs, editions: [full], codes: [BE_INTEGRATION_SPEC_MISSING]}
|
|
2107
2237
|
- id: R113
|
|
2108
2238
|
code: "FE_GRAPHQL_CONTRACT"
|
|
2109
2239
|
editions: [lite, full]
|
|
2110
2240
|
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
2241
|
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
2242
|
kinds: [check]
|
|
2117
2243
|
gates: [land, ci]
|
|
2118
2244
|
failureCodes: ["FE_GRAPHQL_CONTRACT"]
|
|
2119
2245
|
enforcers:
|
|
2120
2246
|
- {kind: hfs, id: fe-contract-documents, at: scripts/hfs/rules/fe-contract-documents.mjs}
|
|
2247
|
+
proves:
|
|
2248
|
+
- {path: packages/hfs/src/hfs-fe-contract-documents-coverage.spec.mjs, editions: [lite, full]}
|
|
2249
|
+
exemplifiedBy:
|
|
2250
|
+
- {path: packages/hfs/templates/fe/table/graphql/query.ts.tpl, editions: [lite, full]}
|
|
2251
|
+
- {path: packages/hfs/src/hfs-fe-contract-documents-coverage.spec.mjs, editions: [lite, full]}
|
|
2252
|
+
witness:
|
|
2253
|
+
- {path: packages/hfs/src/hfs-fe-contract-documents-coverage.spec.mjs, editions: [lite, full], codes: [FE_GRAPHQL_CONTRACT]}
|
|
2121
2254
|
- id: R114
|
|
2122
2255
|
code: "RT_EXTERNAL_OWNER"
|
|
2123
2256
|
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 +2263,6 @@ rules:
|
|
|
2130
2263
|
editions: [lite, full]
|
|
2131
2264
|
docs: [docs/legacy-runtime-shape.md#external-owner]
|
|
2132
2265
|
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
2266
|
- id: R115
|
|
2137
2267
|
code: "RT_TIER_DIRECTION"
|
|
2138
2268
|
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 +2275,6 @@ rules:
|
|
|
2145
2275
|
editions: [lite, full]
|
|
2146
2276
|
docs: [docs/legacy-runtime-shape.md#tier-direction]
|
|
2147
2277
|
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
2278
|
- id: R116
|
|
2152
2279
|
code: "RT_BASE_IMPURE"
|
|
2153
2280
|
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 +2287,6 @@ rules:
|
|
|
2160
2287
|
editions: [lite, full]
|
|
2161
2288
|
docs: [docs/legacy-runtime-shape.md#base-purity]
|
|
2162
2289
|
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
2290
|
- id: R117
|
|
2167
2291
|
code: "RT_API_SHAPE"
|
|
2168
2292
|
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 +2299,6 @@ rules:
|
|
|
2175
2299
|
editions: [lite, full]
|
|
2176
2300
|
docs: [docs/legacy-runtime-shape.md#api-shape]
|
|
2177
2301
|
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
2302
|
- id: R118
|
|
2182
2303
|
code: "RT_SPEC_PLACEMENT"
|
|
2183
2304
|
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 +2311,6 @@ rules:
|
|
|
2190
2311
|
editions: [lite, full]
|
|
2191
2312
|
docs: [docs/legacy-runtime-shape.md#spec-placement]
|
|
2192
2313
|
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
2314
|
- id: R119
|
|
2197
2315
|
code: "RT_SOURCE_NAME"
|
|
2198
2316
|
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 +2323,10 @@ rules:
|
|
|
2205
2323
|
editions: [lite, full]
|
|
2206
2324
|
docs: [docs/legacy-runtime-shape.md#source-name]
|
|
2207
2325
|
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
2326
|
- id: R121
|
|
2212
2327
|
editions: [lite, full]
|
|
2213
2328
|
docs: [docs/legacy-runtime-state.md#generated-runtime-output]
|
|
2214
2329
|
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
2330
|
code: "RT_GENERATED_DRIFT"
|
|
2218
2331
|
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
2332
|
scope: runtime
|
|
@@ -2223,7 +2336,6 @@ rules:
|
|
|
2223
2336
|
enforcers:
|
|
2224
2337
|
- {kind: runtime, id: generated-drift, at: scripts/hfs/sync-runtime.mjs}
|
|
2225
2338
|
- {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
2339
|
- id: R122
|
|
2228
2340
|
code: "RT_CITED_PATH_MISSING"
|
|
2229
2341
|
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 +2348,6 @@ rules:
|
|
|
2236
2348
|
editions: [lite, full]
|
|
2237
2349
|
docs: [docs/legacy-runtime-state.md#cited-runtime-paths]
|
|
2238
2350
|
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
2351
|
- id: R124
|
|
2243
2352
|
code: "RT_PINNED_PATH_MOVED"
|
|
2244
2353
|
law: "A pinned path of ruleParams.runtime.pinned (persisted outside git) exists."
|
|
@@ -2251,9 +2360,6 @@ rules:
|
|
|
2251
2360
|
editions: [lite, full]
|
|
2252
2361
|
docs: [docs/legacy-runtime-state.md#pinned-runtime-paths]
|
|
2253
2362
|
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
2363
|
- id: R125
|
|
2258
2364
|
code: "RT_NODE_MODULES_LINK"
|
|
2259
2365
|
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 +2372,6 @@ rules:
|
|
|
2266
2372
|
editions: [lite, full]
|
|
2267
2373
|
docs: [docs/legacy-runtime-state.md#dependency-directories]
|
|
2268
2374
|
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
2375
|
- id: R126
|
|
2273
2376
|
code: "RT_CONTROL_CHARACTER"
|
|
2274
2377
|
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 +2384,6 @@ rules:
|
|
|
2281
2384
|
editions: [lite, full]
|
|
2282
2385
|
docs: [docs/legacy-runtime-paths.md#r126]
|
|
2283
2386
|
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
2387
|
- id: R127
|
|
2288
2388
|
code: "RT_ABSOLUTE_PATH"
|
|
2289
2389
|
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 +2396,6 @@ rules:
|
|
|
2296
2396
|
editions: [lite, full]
|
|
2297
2397
|
docs: [docs/legacy-runtime-paths.md#r127]
|
|
2298
2398
|
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
2399
|
- id: R141
|
|
2303
2400
|
code: "BE_COOKIE_ATTRIBUTES"
|
|
2304
2401
|
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 +2416,7 @@ rules:
|
|
|
2319
2416
|
- {path: packages/eslint/be/cookies-coverage.spec.mjs, edition: full, codes: ["BE_COOKIE_ATTRIBUTES"]}
|
|
2320
2417
|
- id: R142
|
|
2321
2418
|
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]
|
|
2419
|
+
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
2420
|
kinds: [lint, codemod]
|
|
2325
2421
|
gates: [pre-commit, settle, land, ci]
|
|
2326
2422
|
failureCodes: ["BE_AMBIENT_ID"]
|
|
@@ -2328,7 +2424,7 @@ rules:
|
|
|
2328
2424
|
- {kind: eslint-be, id: no-ambient-id}
|
|
2329
2425
|
editions: [lite, full]
|
|
2330
2426
|
docs: [docs/quality-bar.md#r142]
|
|
2331
|
-
templateNa: "Ambient identifier sources are a negative lint constraint; the spec exercises owned
|
|
2427
|
+
templateNa: "Ambient identifier sources are a negative lint constraint; the spec exercises owned and injected identifiers rather than a scaffolded surface."
|
|
2332
2428
|
proves: [packages/eslint/be/ambient-id.spec.mjs]
|
|
2333
2429
|
exemplifiedBy:
|
|
2334
2430
|
- {path: packages/eslint/be/ambient-id.spec.mjs, editions: [lite, full], codes: [BE_AMBIENT_ID]}
|
|
@@ -2345,10 +2441,14 @@ rules:
|
|
|
2345
2441
|
- {kind: hfs, id: monorepo, at: scripts/hfs/rules/monorepo.mjs}
|
|
2346
2442
|
editions: [lite, full]
|
|
2347
2443
|
docs: [docs/legacy-monorepo-rules.md#r143-root-workspace-manifest]
|
|
2348
|
-
|
|
2444
|
+
proves:
|
|
2445
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_WORKSPACES]}
|
|
2349
2446
|
exemplifiedBy:
|
|
2350
2447
|
- {path: packages/hfs/templates/app/task-graph/turbo.json, editions: [lite, full]}
|
|
2351
|
-
|
|
2448
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_WORKSPACES]}
|
|
2449
|
+
witness:
|
|
2450
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, edition: lite, codes: [HFS_MONO_WORKSPACES]}
|
|
2451
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, edition: full, codes: [HFS_MONO_WORKSPACES]}
|
|
2352
2452
|
- id: R144
|
|
2353
2453
|
code: "HFS_MONO_FE_WORKSPACE"
|
|
2354
2454
|
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 +2459,68 @@ rules:
|
|
|
2359
2459
|
- {kind: hfs, id: monorepo, at: scripts/hfs/rules/monorepo.mjs}
|
|
2360
2460
|
editions: [lite, full]
|
|
2361
2461
|
docs: [docs/legacy-monorepo-rules.md#r144-front-end-workspace-manifests]
|
|
2362
|
-
|
|
2462
|
+
proves:
|
|
2463
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_FE_WORKSPACE]}
|
|
2363
2464
|
exemplifiedBy:
|
|
2364
2465
|
- {path: packages/hfs/templates/fe/app/package.json.tpl, editions: [lite, full]}
|
|
2365
|
-
|
|
2466
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_FE_WORKSPACE]}
|
|
2467
|
+
witness:
|
|
2468
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, edition: lite, codes: [HFS_MONO_FE_WORKSPACE]}
|
|
2469
|
+
- {path: packages/hfs/src/legacy-monorepo-coverage.spec.mjs, edition: full, codes: [HFS_MONO_FE_WORKSPACE]}
|
|
2366
2470
|
- id: R145
|
|
2367
2471
|
code: "HFS_MONO_NEST_PROJECTS"
|
|
2368
2472
|
editions: [lite, full]
|
|
2369
2473
|
docs: [docs/legacy-monorepo-rules.md#r145-nest-monorepo-projects]
|
|
2370
2474
|
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
2475
|
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
2476
|
kinds: [check]
|
|
2375
2477
|
gates: [settle, land, ci]
|
|
2376
2478
|
failureCodes: ["HFS_MONO_NEST_PROJECTS"]
|
|
2377
2479
|
enforcers:
|
|
2378
2480
|
- {kind: hfs, id: monorepo, at: scripts/hfs/rules/monorepo.mjs}
|
|
2379
|
-
|
|
2481
|
+
proves:
|
|
2482
|
+
- {path: packages/hfs/src/hfs-mono-nest-projects-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_NEST_PROJECTS]}
|
|
2483
|
+
exemplifiedBy:
|
|
2484
|
+
- {path: packages/hfs/src/hfs-mono-nest-projects-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_NEST_PROJECTS]}
|
|
2485
|
+
witness:
|
|
2486
|
+
- {path: packages/hfs/src/hfs-mono-nest-projects-coverage.spec.mjs, edition: lite, codes: [HFS_MONO_NEST_PROJECTS]}
|
|
2487
|
+
- {path: packages/hfs/src/hfs-mono-nest-projects-coverage.spec.mjs, edition: full, codes: [HFS_MONO_NEST_PROJECTS]}
|
|
2380
2488
|
- id: R146
|
|
2381
2489
|
code: "HFS_MONO_WORKSPACE_DEP"
|
|
2382
2490
|
editions: [lite, full]
|
|
2383
2491
|
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
2492
|
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
2493
|
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
2494
|
kinds: [check]
|
|
2389
2495
|
gates: [settle, land, ci]
|
|
2390
2496
|
failureCodes: ["HFS_MONO_WORKSPACE_DEP"]
|
|
2391
2497
|
enforcers:
|
|
2392
2498
|
- {kind: hfs, id: monorepo, at: scripts/hfs/rules/monorepo.mjs}
|
|
2393
|
-
|
|
2499
|
+
proves:
|
|
2500
|
+
- {path: packages/hfs/src/r146-workspace-version-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_WORKSPACE_DEP]}
|
|
2501
|
+
exemplifiedBy:
|
|
2502
|
+
- {path: packages/hfs/src/r146-workspace-version-coverage.spec.mjs, editions: [lite, full], codes: [HFS_MONO_WORKSPACE_DEP]}
|
|
2503
|
+
witness:
|
|
2504
|
+
- {path: packages/hfs/src/r146-workspace-version-coverage.spec.mjs, edition: lite, codes: [HFS_MONO_WORKSPACE_DEP]}
|
|
2505
|
+
- {path: packages/hfs/src/r146-workspace-version-coverage.spec.mjs, edition: full, codes: [HFS_MONO_WORKSPACE_DEP]}
|
|
2394
2506
|
- id: R147
|
|
2395
2507
|
code: "BE_CLI_REQUIRED"
|
|
2396
2508
|
editions: [lite, full]
|
|
2397
2509
|
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
2510
|
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
2511
|
kinds: [check]
|
|
2404
2512
|
gates: [settle, land, ci]
|
|
2405
2513
|
failureCodes: ["BE_CLI_REQUIRED"]
|
|
2406
2514
|
enforcers:
|
|
2407
2515
|
- {kind: hfs, id: cli, at: scripts/hfs/rules/cli.mjs}
|
|
2516
|
+
proves:
|
|
2517
|
+
- {path: packages/hfs/src/hfs-cli-coverage.spec.mjs, editions: [lite, full], codes: [BE_CLI_REQUIRED]}
|
|
2518
|
+
exemplifiedBy:
|
|
2519
|
+
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
2520
|
+
- {path: packages/hfs/src/hfs-cli-coverage.spec.mjs, editions: [lite, full], codes: [BE_CLI_REQUIRED]}
|
|
2521
|
+
witness:
|
|
2522
|
+
- {path: packages/hfs/src/hfs-cli-coverage.spec.mjs, edition: lite, codes: [BE_CLI_REQUIRED]}
|
|
2523
|
+
- {path: packages/hfs/src/hfs-cli-coverage.spec.mjs, edition: full, codes: [BE_CLI_REQUIRED]}
|
|
2408
2524
|
- id: R148
|
|
2409
2525
|
code: "BE_CLI_BOOTSTRAP"
|
|
2410
2526
|
editions: [lite, full]
|
|
@@ -2466,21 +2582,25 @@ rules:
|
|
|
2466
2582
|
code: "BE_EVENT_CLASS_CONTRACT"
|
|
2467
2583
|
editions: [lite, full]
|
|
2468
2584
|
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
2585
|
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
2586
|
kinds: [check, codemod]
|
|
2476
2587
|
gates: [settle, land, ci]
|
|
2477
2588
|
failureCodes: ["BE_EVENT_CLASS_CONTRACT"]
|
|
2478
2589
|
enforcers:
|
|
2479
2590
|
- {kind: hfs, id: event-class-contract, at: scripts/hfs/rules/event-bus.mjs}
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2591
|
+
proves:
|
|
2592
|
+
- {path: packages/hfs/src/hfs-event-class-coverage.spec.mjs, editions: [lite, full]}
|
|
2593
|
+
exemplifiedBy:
|
|
2594
|
+
- {path: packages/hfs/templates/be/inbox/delivery-recorded.event.ts.tpl, editions: [lite, full]}
|
|
2595
|
+
- {path: packages/hfs/templates/be/inbox/events.json.tpl, editions: [lite, full]}
|
|
2596
|
+
- {path: packages/hfs/src/hfs-event-class-coverage.spec.mjs, editions: [lite, full]}
|
|
2597
|
+
witness:
|
|
2598
|
+
- {path: packages/hfs/src/hfs-event-class-coverage.spec.mjs, edition: lite, codes: [BE_EVENT_CLASS_CONTRACT]}
|
|
2599
|
+
- {path: packages/hfs/src/hfs-event-class-coverage.spec.mjs, edition: full, codes: [BE_EVENT_CLASS_CONTRACT]}
|
|
2600
|
+
- id: R152
|
|
2601
|
+
code: "BE_OUTBOX_WRITE_TX"
|
|
2602
|
+
editions: [lite, full]
|
|
2603
|
+
docs: [docs/code-pattern-enforcement.md#backend-event-bus-rules]
|
|
2484
2604
|
proves:
|
|
2485
2605
|
- {path: packages/eslint/be/event-bus-coverage.spec.mjs, editions: [lite, full], codes: [BE_OUTBOX_WRITE_TX]}
|
|
2486
2606
|
exemplifiedBy:
|
|
@@ -2543,16 +2663,20 @@ rules:
|
|
|
2543
2663
|
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
2664
|
docs: [docs/quality-bar.md#r155]
|
|
2545
2665
|
templateNa: "Pattern scenarios depend on application behavior and providers; no universal runnable scenario proof is scaffolded."
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2666
|
+
proves:
|
|
2667
|
+
- {path: packages/hfs/src/hfs-pattern-spec-missing.spec.mjs, editions: [full], codes: [BE_PATTERN_SPEC_MISSING]}
|
|
2668
|
+
- {path: packages/hfs/src/hfs-lite-proof-lane.spec.mjs, editions: [lite], codes: [BE_PATTERN_SPEC_MISSING]}
|
|
2669
|
+
exemplifiedBy:
|
|
2670
|
+
- {path: packages/hfs/src/hfs-pattern-spec-missing.spec.mjs, editions: [full], codes: [BE_PATTERN_SPEC_MISSING]}
|
|
2671
|
+
- {path: packages/hfs/src/hfs-lite-proof-lane.spec.mjs, editions: [lite], codes: [BE_PATTERN_SPEC_MISSING]}
|
|
2672
|
+
witness:
|
|
2673
|
+
- {path: packages/hfs/src/hfs-pattern-spec-missing.spec.mjs, edition: full, codes: [BE_PATTERN_SPEC_MISSING]}
|
|
2674
|
+
- {path: packages/hfs/src/hfs-lite-proof-lane.spec.mjs, edition: lite, codes: [BE_PATTERN_SPEC_MISSING]}
|
|
2549
2675
|
- id: R156
|
|
2550
2676
|
code: "BE_KIND_ISOLATION"
|
|
2551
2677
|
editions: [lite, full]
|
|
2552
2678
|
docs: [docs/code-pattern-enforcement.md#r156-kind-isolation]
|
|
2553
2679
|
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
2680
|
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
2681
|
kinds: [lint, design]
|
|
2558
2682
|
gates: [settle, land, ci]
|
|
@@ -2560,7 +2684,11 @@ rules:
|
|
|
2560
2684
|
enforcers:
|
|
2561
2685
|
- {kind: eslint-be, id: kind-isolation}
|
|
2562
2686
|
- {kind: machine, id: tiers, at: scripts/hfs/architecture/tiers.mjs}
|
|
2563
|
-
|
|
2687
|
+
proves: [packages/eslint/be/architecture-kind-isolation-coverage.spec.mjs]
|
|
2688
|
+
exemplifiedBy:
|
|
2689
|
+
- {path: packages/eslint/be/architecture-kind-isolation-coverage.spec.mjs, editions: [lite, full], codes: [BE_KIND_ISOLATION]}
|
|
2690
|
+
witness:
|
|
2691
|
+
- {path: packages/eslint/be/architecture-kind-isolation-coverage.spec.mjs, editions: [lite, full], codes: [BE_KIND_ISOLATION]}
|
|
2564
2692
|
- id: R157
|
|
2565
2693
|
code: "BE_JOB_WRITE_OUTSIDE_OWNER"
|
|
2566
2694
|
editions: [lite, full]
|
|
@@ -2676,68 +2804,81 @@ rules:
|
|
|
2676
2804
|
code: "HFS_SERVICE_PLACEMENT"
|
|
2677
2805
|
editions: [lite, full]
|
|
2678
2806
|
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
2807
|
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
2808
|
kinds: [check]
|
|
2686
2809
|
gates: [land, ci]
|
|
2687
2810
|
failureCodes: ["HFS_SERVICE_PLACEMENT"]
|
|
2688
2811
|
enforcers:
|
|
2689
2812
|
- {kind: hfs, id: services-placement, at: scripts/hfs/rules/services.mjs}
|
|
2813
|
+
proves:
|
|
2814
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
2815
|
+
exemplifiedBy:
|
|
2816
|
+
- {path: packages/hfs/templates/be/skeleton-lite/apps/api/Dockerfile, edition: lite}
|
|
2817
|
+
- {path: packages/hfs/templates/be/image/api/Dockerfile, edition: full}
|
|
2818
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
2819
|
+
witness:
|
|
2820
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_SERVICE_PLACEMENT]}
|
|
2821
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, edition: full, codes: [HFS_SERVICE_PLACEMENT]}
|
|
2690
2822
|
- id: R164
|
|
2691
2823
|
code: "HFS_IMAGE_UNPINNED"
|
|
2692
2824
|
editions: [lite, full]
|
|
2693
2825
|
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
2826
|
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
2827
|
kinds: [check]
|
|
2701
2828
|
gates: [land, ci]
|
|
2702
2829
|
failureCodes: ["HFS_IMAGE_UNPINNED"]
|
|
2703
2830
|
enforcers:
|
|
2704
2831
|
- {kind: hfs, id: services-image-pins, at: scripts/hfs/rules/services.mjs}
|
|
2832
|
+
proves:
|
|
2833
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
2834
|
+
exemplifiedBy:
|
|
2835
|
+
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
2836
|
+
- {path: packages/hfs/templates/app/upgrade-full/.starcistacks/application-stacks.yaml, edition: full}
|
|
2837
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
2838
|
+
witness:
|
|
2839
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_IMAGE_UNPINNED]}
|
|
2840
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, edition: full, codes: [HFS_IMAGE_UNPINNED]}
|
|
2705
2841
|
- id: R165
|
|
2706
2842
|
code: "HFS_SERVICE_STACK_DECLARATION"
|
|
2707
2843
|
editions: [lite, full]
|
|
2708
2844
|
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
2845
|
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
2846
|
kinds: [check]
|
|
2716
2847
|
gates: [land, ci]
|
|
2717
2848
|
failureCodes: ["HFS_SERVICE_STACK_DECLARATION"]
|
|
2718
2849
|
enforcers:
|
|
2719
2850
|
- {kind: hfs, id: services-stack-declaration, at: scripts/hfs/rules/services.mjs}
|
|
2851
|
+
proves:
|
|
2852
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
2853
|
+
exemplifiedBy:
|
|
2854
|
+
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
2855
|
+
- {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
|
|
2856
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
2857
|
+
witness:
|
|
2858
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_SERVICE_STACK_DECLARATION]}
|
|
2859
|
+
- {path: packages/hfs/src/hfs-services-legacy-coverage.spec.mjs, edition: full, codes: [HFS_SERVICE_STACK_DECLARATION]}
|
|
2720
2860
|
- id: R166
|
|
2721
2861
|
code: "HFS_EVENT_CONTRACT"
|
|
2722
2862
|
editions: [lite, full]
|
|
2723
2863
|
docs: [docs/microservices.md#r166]
|
|
2724
2864
|
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
2865
|
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
2866
|
kinds: [check, codemod]
|
|
2729
2867
|
gates: [land, ci]
|
|
2730
2868
|
failureCodes: ["HFS_EVENT_CONTRACT"]
|
|
2731
2869
|
enforcers:
|
|
2732
2870
|
- {kind: hfs, id: services-event-contract, at: scripts/hfs/rules/services.mjs}
|
|
2733
|
-
|
|
2871
|
+
proves:
|
|
2872
|
+
- {path: packages/hfs/src/hfs-event-table-contract.spec.mjs, editions: [lite, full]}
|
|
2873
|
+
exemplifiedBy:
|
|
2874
|
+
- {path: packages/hfs/src/hfs-event-table-contract.spec.mjs, editions: [lite, full]}
|
|
2875
|
+
witness:
|
|
2876
|
+
- {path: packages/hfs/src/hfs-event-table-contract.spec.mjs, editions: [lite, full], codes: [HFS_EVENT_CONTRACT]}
|
|
2734
2877
|
- id: R167
|
|
2735
2878
|
code: "BE_ASYNC_SPEC_MISSING"
|
|
2736
2879
|
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
2880
|
docs: [docs/microservices.md#r167]
|
|
2738
2881
|
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
2882
|
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
2883
|
kinds: [check]
|
|
2743
2884
|
gates: [land, ci]
|
|
@@ -2745,7 +2886,12 @@ rules:
|
|
|
2745
2886
|
editions: [full]
|
|
2746
2887
|
enforcers:
|
|
2747
2888
|
- {kind: hfs, id: services-async-specs, at: scripts/hfs/rules/services.mjs}
|
|
2748
|
-
|
|
2889
|
+
proves:
|
|
2890
|
+
- {path: packages/hfs/src/hfs-microservice-rules.spec.mjs, edition: full}
|
|
2891
|
+
exemplifiedBy:
|
|
2892
|
+
- {path: packages/hfs/src/hfs-microservice-rules.spec.mjs, edition: full}
|
|
2893
|
+
witness:
|
|
2894
|
+
- {path: packages/hfs/src/hfs-microservice-rules.spec.mjs, edition: full}
|
|
2749
2895
|
- id: R168
|
|
2750
2896
|
code: "BE_SERVICE_ISOLATION"
|
|
2751
2897
|
editions: [lite, full]
|
|
@@ -2768,69 +2914,82 @@ rules:
|
|
|
2768
2914
|
code: "BE_SAGA_STEP_COMPENSATION"
|
|
2769
2915
|
editions: [lite, full]
|
|
2770
2916
|
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
2917
|
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
2918
|
kinds: [check]
|
|
2779
2919
|
gates: [land, ci]
|
|
2780
2920
|
failureCodes: ["BE_SAGA_STEP_COMPENSATION"]
|
|
2781
2921
|
enforcers:
|
|
2782
2922
|
- {kind: hfs, id: saga-step-compensation, at: scripts/hfs/rules/saga.mjs}
|
|
2923
|
+
proves:
|
|
2924
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, editions: [lite, full], codes: [BE_SAGA_STEP_COMPENSATION]}
|
|
2925
|
+
exemplifiedBy:
|
|
2926
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.service.ts.tpl, editions: [lite, full]}
|
|
2927
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.step.ts.tpl, editions: [lite, full]}
|
|
2928
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.compensation.ts.tpl, editions: [lite, full]}
|
|
2929
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, editions: [lite, full], codes: [BE_SAGA_STEP_COMPENSATION]}
|
|
2930
|
+
witness:
|
|
2931
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, edition: lite, codes: [BE_SAGA_STEP_COMPENSATION]}
|
|
2932
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, edition: full, codes: [BE_SAGA_STEP_COMPENSATION]}
|
|
2783
2933
|
- id: R170
|
|
2784
2934
|
code: "BE_SAGA_STATE_VERSIONED"
|
|
2785
2935
|
editions: [lite, full]
|
|
2786
2936
|
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
2937
|
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
2938
|
kinds: [check]
|
|
2794
2939
|
gates: [land, ci]
|
|
2795
2940
|
failureCodes: ["BE_SAGA_STATE_VERSIONED"]
|
|
2796
2941
|
enforcers:
|
|
2797
2942
|
- {kind: hfs, id: saga-state-versioned, at: scripts/hfs/rules/saga.mjs}
|
|
2943
|
+
proves:
|
|
2944
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, editions: [lite, full], codes: [BE_SAGA_STATE_VERSIONED]}
|
|
2945
|
+
exemplifiedBy:
|
|
2946
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.service.ts.tpl, editions: [lite, full]}
|
|
2947
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.state.ts.tpl, editions: [lite, full]}
|
|
2948
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, editions: [lite, full], codes: [BE_SAGA_STATE_VERSIONED]}
|
|
2949
|
+
witness:
|
|
2950
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, edition: lite, codes: [BE_SAGA_STATE_VERSIONED]}
|
|
2951
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, edition: full, codes: [BE_SAGA_STATE_VERSIONED]}
|
|
2798
2952
|
- id: R171
|
|
2799
2953
|
code: "BE_SAGA_EVENT_CONTRACT"
|
|
2800
2954
|
editions: [lite, full]
|
|
2801
2955
|
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
2956
|
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
2957
|
kinds: [check]
|
|
2809
2958
|
gates: [land, ci]
|
|
2810
2959
|
failureCodes: ["BE_SAGA_EVENT_CONTRACT"]
|
|
2811
2960
|
enforcers:
|
|
2812
2961
|
- {kind: hfs, id: saga-event-contract, at: scripts/hfs/rules/saga.mjs}
|
|
2962
|
+
proves:
|
|
2963
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, editions: [lite, full], codes: [BE_SAGA_EVENT_CONTRACT]}
|
|
2964
|
+
exemplifiedBy:
|
|
2965
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.step.ts.tpl, editions: [lite, full]}
|
|
2966
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.compensation.ts.tpl, editions: [lite, full]}
|
|
2967
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, editions: [lite, full], codes: [BE_SAGA_EVENT_CONTRACT]}
|
|
2968
|
+
witness:
|
|
2969
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, edition: lite, codes: [BE_SAGA_EVENT_CONTRACT]}
|
|
2970
|
+
- {path: packages/hfs/src/hfs-saga-coverage.spec.mjs, edition: full, codes: [BE_SAGA_EVENT_CONTRACT]}
|
|
2813
2971
|
- id: R172
|
|
2814
2972
|
code: "BE_SAGA_CONSUMER_DEDUPE"
|
|
2815
2973
|
editions: [lite, full]
|
|
2816
2974
|
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
2975
|
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
2976
|
kinds: [check]
|
|
2823
2977
|
gates: [land, ci]
|
|
2824
2978
|
failureCodes: ["BE_SAGA_CONSUMER_DEDUPE"]
|
|
2825
2979
|
enforcers:
|
|
2826
2980
|
- {kind: hfs, id: saga-consumer-dedupe, at: scripts/hfs/rules/saga.mjs}
|
|
2981
|
+
proves:
|
|
2982
|
+
- {path: packages/hfs/src/hfs-saga-consumer-dedupe.spec.mjs, editions: [lite, full]}
|
|
2983
|
+
exemplifiedBy:
|
|
2984
|
+
- {path: packages/hfs/templates/be/patterns/saga/saga.done.consumer.ts.tpl, editions: [lite, full]}
|
|
2985
|
+
- {path: packages/hfs/src/hfs-saga-consumer-dedupe.spec.mjs, editions: [lite, full]}
|
|
2986
|
+
witness:
|
|
2987
|
+
- {path: packages/hfs/src/hfs-saga-consumer-dedupe.spec.mjs, editions: [lite, full], codes: [BE_SAGA_CONSUMER_DEDUPE]}
|
|
2827
2988
|
- id: R173
|
|
2828
2989
|
code: "BE_SAGA_E2E_MISSING"
|
|
2829
2990
|
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
2991
|
docs: [docs/microservices.md#r173]
|
|
2831
2992
|
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
2993
|
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
2994
|
kinds: [check]
|
|
2836
2995
|
gates: [land, ci]
|
|
@@ -2838,7 +2997,12 @@ rules:
|
|
|
2838
2997
|
editions: [full]
|
|
2839
2998
|
enforcers:
|
|
2840
2999
|
- {kind: hfs, id: saga-e2e, at: scripts/hfs/rules/saga.mjs}
|
|
2841
|
-
|
|
3000
|
+
proves:
|
|
3001
|
+
- {path: packages/hfs/src/hfs-saga-rules.spec.mjs, edition: full}
|
|
3002
|
+
exemplifiedBy:
|
|
3003
|
+
- {path: packages/hfs/src/hfs-saga-rules.spec.mjs, edition: full}
|
|
3004
|
+
witness:
|
|
3005
|
+
- {path: packages/hfs/src/hfs-saga-rules.spec.mjs, edition: full}
|
|
2842
3006
|
- id: R174
|
|
2843
3007
|
code: "BE_CONTEXT_OWNER"
|
|
2844
3008
|
editions: [lite, full]
|
|
@@ -2899,8 +3063,6 @@ rules:
|
|
|
2899
3063
|
code: "BE_CONTRACT_BREAKING"
|
|
2900
3064
|
editions: [lite, full]
|
|
2901
3065
|
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
3066
|
templateNa: "Published event-contract pins are service-owned release snapshots, not scaffolded files."
|
|
2905
3067
|
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
3068
|
kinds: [check]
|
|
@@ -2908,7 +3070,13 @@ rules:
|
|
|
2908
3070
|
failureCodes: ["BE_CONTRACT_BREAKING"]
|
|
2909
3071
|
enforcers:
|
|
2910
3072
|
- {kind: hfs, id: contract-compat, at: scripts/hfs/rules/contract-compat.mjs}
|
|
2911
|
-
|
|
3073
|
+
proves:
|
|
3074
|
+
- {path: packages/hfs/src/hfs-contract-compat-coverage.spec.mjs, editions: [lite, full], codes: [BE_CONTRACT_BREAKING]}
|
|
3075
|
+
exemplifiedBy:
|
|
3076
|
+
- {path: packages/hfs/src/hfs-contract-compat-coverage.spec.mjs, editions: [lite, full], codes: [BE_CONTRACT_BREAKING]}
|
|
3077
|
+
witness:
|
|
3078
|
+
- {path: packages/hfs/src/hfs-contract-compat-coverage.spec.mjs, edition: lite, codes: [BE_CONTRACT_BREAKING]}
|
|
3079
|
+
- {path: packages/hfs/src/hfs-contract-compat-coverage.spec.mjs, edition: full, codes: [BE_CONTRACT_BREAKING]}
|
|
2912
3080
|
- id: R178
|
|
2913
3081
|
code: "BE_CONTEXT_PLATFORM_TABLES"
|
|
2914
3082
|
editions: [lite, full]
|
|
@@ -2931,30 +3099,38 @@ rules:
|
|
|
2931
3099
|
code: "BE_KIND_DECLARATION"
|
|
2932
3100
|
editions: [lite, full]
|
|
2933
3101
|
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
3102
|
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
3103
|
kinds: [check]
|
|
2940
3104
|
gates: [settle, land, ci]
|
|
2941
3105
|
failureCodes: ["BE_KIND_DECLARATION"]
|
|
2942
3106
|
enforcers:
|
|
2943
3107
|
- {kind: hfs, id: kind-declaration, at: scripts/hfs/rules/kinds.mjs}
|
|
3108
|
+
proves:
|
|
3109
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, editions: [lite, full], codes: [BE_KIND_DECLARATION]}
|
|
3110
|
+
exemplifiedBy:
|
|
3111
|
+
- {path: packages/hfs/templates/be/patterns/jobs/job.processor.ts.tpl, editions: [lite, full]}
|
|
3112
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, editions: [lite, full], codes: [BE_KIND_DECLARATION]}
|
|
3113
|
+
witness:
|
|
3114
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, edition: lite, codes: [BE_KIND_DECLARATION]}
|
|
3115
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, edition: full, codes: [BE_KIND_DECLARATION]}
|
|
2944
3116
|
- id: R180
|
|
2945
3117
|
code: "BE_KIND_EMPTY"
|
|
2946
3118
|
editions: [lite, full]
|
|
2947
3119
|
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
3120
|
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
3121
|
kinds: [check]
|
|
2954
3122
|
gates: [settle, land, ci]
|
|
2955
3123
|
failureCodes: ["BE_KIND_EMPTY"]
|
|
2956
3124
|
enforcers:
|
|
2957
3125
|
- {kind: hfs, id: kind-empty, at: scripts/hfs/rules/kinds.mjs}
|
|
3126
|
+
proves:
|
|
3127
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, editions: [lite, full], codes: [BE_KIND_EMPTY]}
|
|
3128
|
+
exemplifiedBy:
|
|
3129
|
+
- {path: packages/hfs/templates/be/patterns/jobs/job.processor.ts.tpl, editions: [lite, full]}
|
|
3130
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, editions: [lite, full], codes: [BE_KIND_EMPTY]}
|
|
3131
|
+
witness:
|
|
3132
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, edition: lite, codes: [BE_KIND_EMPTY]}
|
|
3133
|
+
- {path: packages/hfs/src/hfs-kind-coverage.spec.mjs, edition: full, codes: [BE_KIND_EMPTY]}
|
|
2958
3134
|
- id: R181
|
|
2959
3135
|
code: "BE_SQL_RETURNING_SHAPE"
|
|
2960
3136
|
editions: [lite, full]
|
|
@@ -3067,77 +3243,92 @@ rules:
|
|
|
3067
3243
|
code: "HFS_DOCKER_BUILD_CONTEXT"
|
|
3068
3244
|
editions: [lite, full]
|
|
3069
3245
|
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
3246
|
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
3247
|
kinds: [check]
|
|
3077
3248
|
gates: [settle, land, ci]
|
|
3078
3249
|
failureCodes: ["HFS_DOCKER_BUILD_CONTEXT"]
|
|
3079
3250
|
enforcers:
|
|
3080
3251
|
- {kind: hfs, id: docker, at: scripts/hfs/rules/docker.mjs}
|
|
3252
|
+
proves: [packages/hfs/src/docker-legacy-coverage.spec.mjs]
|
|
3253
|
+
exemplifiedBy:
|
|
3254
|
+
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3255
|
+
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3256
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
3257
|
+
witness:
|
|
3258
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_DOCKER_BUILD_CONTEXT]}
|
|
3259
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: full, codes: [HFS_DOCKER_BUILD_CONTEXT]}
|
|
3081
3260
|
- id: R188
|
|
3082
3261
|
code: "HFS_DOCKER_STAGES"
|
|
3083
3262
|
editions: [lite, full]
|
|
3084
3263
|
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
3264
|
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
3265
|
kinds: [check]
|
|
3092
3266
|
gates: [settle, land, ci]
|
|
3093
3267
|
failureCodes: ["HFS_DOCKER_STAGES"]
|
|
3094
3268
|
enforcers:
|
|
3095
3269
|
- {kind: hfs, id: docker, at: scripts/hfs/rules/docker.mjs}
|
|
3270
|
+
proves: [packages/hfs/src/docker-legacy-coverage.spec.mjs]
|
|
3271
|
+
exemplifiedBy:
|
|
3272
|
+
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3273
|
+
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3274
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
3275
|
+
witness:
|
|
3276
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_DOCKER_STAGES]}
|
|
3277
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: full, codes: [HFS_DOCKER_STAGES]}
|
|
3096
3278
|
- id: R189
|
|
3097
3279
|
code: "HFS_DOCKER_ENTRY"
|
|
3098
3280
|
editions: [lite, full]
|
|
3099
3281
|
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
3282
|
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
3283
|
kinds: [check]
|
|
3107
3284
|
gates: [settle, land, ci]
|
|
3108
3285
|
failureCodes: ["HFS_DOCKER_ENTRY"]
|
|
3109
3286
|
enforcers:
|
|
3110
3287
|
- {kind: hfs, id: docker, at: scripts/hfs/rules/docker.mjs}
|
|
3288
|
+
proves: [packages/hfs/src/docker-legacy-coverage.spec.mjs]
|
|
3289
|
+
exemplifiedBy:
|
|
3290
|
+
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3291
|
+
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3292
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
3293
|
+
witness:
|
|
3294
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_DOCKER_ENTRY]}
|
|
3295
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: full, codes: [HFS_DOCKER_ENTRY]}
|
|
3111
3296
|
- id: R190
|
|
3112
3297
|
code: "HFS_DOCKER_BASE_PIN"
|
|
3113
3298
|
editions: [lite, full]
|
|
3114
3299
|
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
3300
|
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
3301
|
kinds: [check]
|
|
3122
3302
|
gates: [settle, land, ci]
|
|
3123
3303
|
failureCodes: ["HFS_DOCKER_BASE_PIN"]
|
|
3124
3304
|
enforcers:
|
|
3125
3305
|
- {kind: hfs, id: docker, at: scripts/hfs/rules/docker.mjs}
|
|
3306
|
+
proves: [packages/hfs/src/docker-legacy-coverage.spec.mjs]
|
|
3307
|
+
exemplifiedBy:
|
|
3308
|
+
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3309
|
+
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3310
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
3311
|
+
witness:
|
|
3312
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_DOCKER_BASE_PIN]}
|
|
3313
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: full, codes: [HFS_DOCKER_BASE_PIN]}
|
|
3126
3314
|
- id: R191
|
|
3127
3315
|
code: "HFS_DOCKER_SECRETS"
|
|
3128
3316
|
editions: [lite, full]
|
|
3129
3317
|
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
3318
|
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
3319
|
kinds: [check]
|
|
3137
3320
|
gates: [settle, land, ci]
|
|
3138
3321
|
failureCodes: ["HFS_DOCKER_SECRETS"]
|
|
3139
3322
|
enforcers:
|
|
3140
3323
|
- {kind: hfs, id: docker, at: scripts/hfs/rules/docker.mjs}
|
|
3324
|
+
proves: [packages/hfs/src/docker-legacy-coverage.spec.mjs]
|
|
3325
|
+
exemplifiedBy:
|
|
3326
|
+
- {path: packages/hfs/templates/be/image/cli/Dockerfile, editions: [lite, full]}
|
|
3327
|
+
- {path: packages/hfs/templates/fe/image/next/Dockerfile, editions: [lite, full]}
|
|
3328
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, editions: [lite, full]}
|
|
3329
|
+
witness:
|
|
3330
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: lite, codes: [HFS_DOCKER_SECRETS]}
|
|
3331
|
+
- {path: packages/hfs/src/docker-legacy-coverage.spec.mjs, edition: full, codes: [HFS_DOCKER_SECRETS]}
|
|
3141
3332
|
- id: R192
|
|
3142
3333
|
code: "RT_FACT_FALSE"
|
|
3143
3334
|
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 +3336,11 @@ rules:
|
|
|
3145
3336
|
editions: [lite, full]
|
|
3146
3337
|
docs: [docs/knowledge-yaml.md#runtime-knowledge-evidence]
|
|
3147
3338
|
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
3339
|
kinds: [check]
|
|
3151
3340
|
gates: [runtime]
|
|
3152
3341
|
failureCodes: ["RT_FACT_FALSE"]
|
|
3153
3342
|
enforcers:
|
|
3154
3343
|
- {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
3344
|
- id: R193
|
|
3157
3345
|
code: "RT_RULE_ID_UNKNOWN"
|
|
3158
3346
|
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 +3348,11 @@ rules:
|
|
|
3160
3348
|
editions: [lite, full]
|
|
3161
3349
|
docs: [docs/knowledge-yaml.md#runtime-knowledge-evidence]
|
|
3162
3350
|
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
3351
|
kinds: [check]
|
|
3166
3352
|
gates: [runtime]
|
|
3167
3353
|
failureCodes: ["RT_RULE_ID_UNKNOWN", "RT_RULE_UNCITED"]
|
|
3168
3354
|
enforcers:
|
|
3169
3355
|
- {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
3356
|
- id: R194
|
|
3172
3357
|
code: "RT_GENERATED_BLOCK_STALE"
|
|
3173
3358
|
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 +3360,16 @@ rules:
|
|
|
3175
3360
|
editions: [lite, full]
|
|
3176
3361
|
docs: [docs/knowledge-yaml.md#runtime-knowledge-evidence]
|
|
3177
3362
|
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
3363
|
kinds: [check]
|
|
3181
3364
|
gates: [runtime]
|
|
3182
3365
|
failureCodes: ["RT_GENERATED_BLOCK_STALE"]
|
|
3183
3366
|
enforcers:
|
|
3184
3367
|
- {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
3368
|
- id: R195
|
|
3187
3369
|
code: "RT_PROSE_PATH_NO_SLOT"
|
|
3188
3370
|
editions: [lite, full]
|
|
3189
3371
|
docs: [docs/knowledge-yaml.md#r195]
|
|
3190
3372
|
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
3373
|
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
3374
|
scope: runtime
|
|
3195
3375
|
kinds: [check]
|
|
@@ -3197,7 +3377,6 @@ rules:
|
|
|
3197
3377
|
failureCodes: ["RT_PROSE_PATH_NO_SLOT"]
|
|
3198
3378
|
enforcers:
|
|
3199
3379
|
- {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
3380
|
- id: R196
|
|
3202
3381
|
code: "RT_PROSE_RESTATES_SLOTS"
|
|
3203
3382
|
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 +3384,16 @@ rules:
|
|
|
3205
3384
|
editions: [lite, full]
|
|
3206
3385
|
docs: [docs/knowledge-yaml.md#runtime-knowledge-evidence]
|
|
3207
3386
|
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
3387
|
kinds: [check]
|
|
3211
3388
|
gates: [runtime]
|
|
3212
3389
|
failureCodes: ["RT_PROSE_RESTATES_SLOTS"]
|
|
3213
3390
|
enforcers:
|
|
3214
3391
|
- {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
3392
|
- id: R198
|
|
3217
3393
|
code: "RT_CLI_CATALOG_DRIFT"
|
|
3218
3394
|
editions: [lite, full]
|
|
3219
3395
|
docs: [docs/installation.md#r198-cli-catalog-drift]
|
|
3220
3396
|
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
3397
|
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
3398
|
scope: runtime
|
|
3225
3399
|
kinds: [check]
|
|
@@ -3227,14 +3401,11 @@ rules:
|
|
|
3227
3401
|
failureCodes: ["RT_CLI_CATALOG_DRIFT"]
|
|
3228
3402
|
enforcers:
|
|
3229
3403
|
- {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
3404
|
- id: R199
|
|
3232
3405
|
code: "RT_CLI_VERB_PARITY"
|
|
3233
3406
|
editions: [lite, full]
|
|
3234
3407
|
docs: [docs/installation.md#cli-catalog-parity]
|
|
3235
3408
|
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
3409
|
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
3410
|
scope: runtime
|
|
3240
3411
|
kinds: [check]
|
|
@@ -3242,15 +3413,10 @@ rules:
|
|
|
3242
3413
|
failureCodes: ["RT_CLI_VERB_PARITY"]
|
|
3243
3414
|
enforcers:
|
|
3244
3415
|
- {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
3416
|
- id: R200
|
|
3247
3417
|
code: "RT_CLI_APP_ONLY_TEMPLATES"
|
|
3248
3418
|
editions: [lite, full]
|
|
3249
3419
|
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
3420
|
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
3421
|
scope: runtime
|
|
3256
3422
|
kinds: [check]
|
|
@@ -3258,13 +3424,13 @@ rules:
|
|
|
3258
3424
|
failureCodes: ["RT_CLI_APP_ONLY_TEMPLATES"]
|
|
3259
3425
|
enforcers:
|
|
3260
3426
|
- {kind: runtime, id: cli-app-only-templates, at: scripts/hfs/runtime-rules/app-cli-templates.mjs}
|
|
3427
|
+
exemplifiedBy:
|
|
3428
|
+
- {path: packages/hfs/templates/app/hooks/husky/pre-commit, editions: [lite, full]}
|
|
3261
3429
|
- id: R201
|
|
3262
3430
|
code: "CLI_ONLY_ENTRY"
|
|
3263
3431
|
editions: [lite, full]
|
|
3264
3432
|
docs: [docs/installation.md#catalog-entry-boundary]
|
|
3265
3433
|
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
3434
|
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
3435
|
scope: runtime
|
|
3270
3436
|
kinds: [check]
|
|
@@ -3272,16 +3438,10 @@ rules:
|
|
|
3272
3438
|
failureCodes: ["CLI_ONLY_ENTRY"]
|
|
3273
3439
|
enforcers:
|
|
3274
3440
|
- {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
3441
|
- id: R202
|
|
3277
3442
|
code: "CI_UPLOAD_NOT_SILENT"
|
|
3278
3443
|
editions: [lite, full]
|
|
3279
3444
|
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
3445
|
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
3446
|
scope: runtime
|
|
3287
3447
|
kinds: [check]
|
|
@@ -3289,6 +3449,9 @@ rules:
|
|
|
3289
3449
|
failureCodes: ["CI_UPLOAD_NOT_SILENT"]
|
|
3290
3450
|
enforcers:
|
|
3291
3451
|
- {kind: runtime, id: ci-upload, at: scripts/hfs/runtime-rules/ci-upload.mjs}
|
|
3452
|
+
exemplifiedBy:
|
|
3453
|
+
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
3454
|
+
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
3292
3455
|
- id: R203
|
|
3293
3456
|
code: "BE_FEATURE_THIN"
|
|
3294
3457
|
editions: [lite, full]
|
|
@@ -3311,23 +3474,25 @@ rules:
|
|
|
3311
3474
|
code: "HFS_COVERAGE_SCOPE_DRIFT"
|
|
3312
3475
|
editions: [lite, full]
|
|
3313
3476
|
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
3477
|
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
3478
|
kinds: [check, codemod]
|
|
3320
3479
|
gates: [land, ci]
|
|
3321
3480
|
failureCodes: ["HFS_COVERAGE_SCOPE_DRIFT"]
|
|
3322
3481
|
enforcers:
|
|
3323
3482
|
- {kind: hfs, id: coverage-scope-drift, at: packages/hfs/sync/managed.mjs}
|
|
3483
|
+
proves:
|
|
3484
|
+
- {path: packages/hfs/src/coverage-scope-evidence.spec.mjs, editions: [lite, full]}
|
|
3485
|
+
exemplifiedBy:
|
|
3486
|
+
- {path: packages/hfs/templates/app/quality-config/codecov.yml, editions: [lite, full]}
|
|
3487
|
+
- {path: packages/hfs/src/coverage-scope-evidence.spec.mjs, editions: [lite, full]}
|
|
3488
|
+
witness:
|
|
3489
|
+
- {path: packages/hfs/src/coverage-scope-evidence.spec.mjs, edition: lite, codes: [HFS_COVERAGE_SCOPE_DRIFT]}
|
|
3490
|
+
- {path: packages/hfs/src/coverage-scope-evidence.spec.mjs, edition: full, codes: [HFS_COVERAGE_SCOPE_DRIFT]}
|
|
3324
3491
|
- id: R205
|
|
3325
3492
|
code: "RT_DOC_NO_OWNER"
|
|
3326
3493
|
editions: [lite, full]
|
|
3327
3494
|
docs: [docs/architecture.md#r205]
|
|
3328
3495
|
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
3496
|
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
3497
|
scope: runtime
|
|
3333
3498
|
kinds: [check]
|
|
@@ -3335,15 +3500,10 @@ rules:
|
|
|
3335
3500
|
failureCodes: ["RT_DOC_NO_OWNER"]
|
|
3336
3501
|
enforcers:
|
|
3337
3502
|
- {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
3503
|
- id: R206
|
|
3340
3504
|
code: "RT_EXAMPLE_COUPLING"
|
|
3341
3505
|
editions: [lite, full]
|
|
3342
3506
|
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
3507
|
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
3508
|
scope: runtime
|
|
3349
3509
|
kinds: [check]
|
|
@@ -3351,6 +3511,8 @@ rules:
|
|
|
3351
3511
|
failureCodes: ["RT_EXAMPLE_COUPLING", "RT_PRODUCT_NAME_IN_SOURCE", "RT_HOST_PATH_IN_TEMPLATE"]
|
|
3352
3512
|
enforcers:
|
|
3353
3513
|
- {kind: runtime, id: example-coupling, at: scripts/checks/check-example-coupling.mjs}
|
|
3514
|
+
exemplifiedBy:
|
|
3515
|
+
- {path: packages/hfs/templates/app/hooks/husky/pre-commit, editions: [lite, full]}
|
|
3354
3516
|
- id: R208
|
|
3355
3517
|
code: "RT_PORT_RESTATED"
|
|
3356
3518
|
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 +3525,6 @@ rules:
|
|
|
3363
3525
|
editions: [lite, full]
|
|
3364
3526
|
docs: [docs/source-process.md#r208]
|
|
3365
3527
|
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
3528
|
- id: R209
|
|
3370
3529
|
code: "RT_CONFIG_DEFAULT_TWICE"
|
|
3371
3530
|
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 +3537,6 @@ rules:
|
|
|
3378
3537
|
editions: [lite, full]
|
|
3379
3538
|
docs: [docs/source-process.md#r209]
|
|
3380
3539
|
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
3540
|
- id: R210
|
|
3385
3541
|
code: "RT_VERSION_RESTATED"
|
|
3386
3542
|
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 +3549,6 @@ rules:
|
|
|
3393
3549
|
editions: [lite, full]
|
|
3394
3550
|
docs: [docs/source-process.md#r210]
|
|
3395
3551
|
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
3552
|
- id: R211
|
|
3400
3553
|
code: "RT_SLOT_ID_SHAPE"
|
|
3401
3554
|
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 +3561,12 @@ rules:
|
|
|
3408
3561
|
editions: [lite, full]
|
|
3409
3562
|
docs: [docs/source-process.md#r211]
|
|
3410
3563
|
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
3564
|
- id: R212
|
|
3415
3565
|
editions: [lite, full]
|
|
3416
3566
|
codeEditions: {HFS_EDITION_FORBIDDEN_PRESENT: [lite], HFS_STARCIWORK_LITE_FORBIDDEN: [lite]}
|
|
3417
3567
|
editionWhy: "R212/case-3 and R212/case-4 (owner:lite-production-swarm) preserve full Work and limit the lite infrastructure and Work surfaces."
|
|
3418
3568
|
docs: [docs/lite-edition.md#edition-validation]
|
|
3419
3569
|
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
3570
|
code: "HFS_EDITION_INVALID"
|
|
3423
3571
|
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
3572
|
kinds: [check]
|
|
@@ -3450,60 +3598,86 @@ rules:
|
|
|
3450
3598
|
source: owner
|
|
3451
3599
|
quote: "In a lite app, .starciwork keeps only the brand records."
|
|
3452
3600
|
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
|
-
|
|
3601
|
+
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]
|
|
3602
|
+
exemplifiedBy:
|
|
3603
|
+
- {path: packages/hfs/src/hfs-edition-invalid.spec.mjs, editions: [lite, full]}
|
|
3604
|
+
- {path: packages/hfs/src/hfs-edition-forbidden-present.spec.mjs, edition: lite}
|
|
3605
|
+
- {path: packages/hfs/src/hfs-starciwork-lite-forbidden.spec.mjs, edition: lite}
|
|
3606
|
+
witness:
|
|
3607
|
+
- {path: packages/hfs/src/hfs-edition-invalid.spec.mjs, editions: [lite, full], codes: [HFS_EDITION_INVALID]}
|
|
3608
|
+
- {path: packages/hfs/src/hfs-edition-forbidden-present.spec.mjs, edition: lite, codes: [HFS_EDITION_FORBIDDEN_PRESENT]}
|
|
3609
|
+
- {path: packages/hfs/src/hfs-starciwork-lite-forbidden.spec.mjs, edition: lite, codes: [HFS_STARCIWORK_LITE_FORBIDDEN]}
|
|
3455
3610
|
- id: R213
|
|
3456
3611
|
code: "DB_MIGRATION_SHAPE"
|
|
3457
3612
|
editions: [lite, full]
|
|
3458
3613
|
docs: [docs/architecture.md#r213]
|
|
3459
3614
|
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
3615
|
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
3616
|
kinds: [check]
|
|
3466
3617
|
gates: [settle, land, ci]
|
|
3467
3618
|
failureCodes: ["DB_MIGRATION_SHAPE"]
|
|
3468
3619
|
enforcers:
|
|
3469
3620
|
- {kind: hfs, id: db-migration-shape, at: scripts/hfs/rules/database.mjs}
|
|
3621
|
+
proves:
|
|
3622
|
+
- {path: packages/hfs/src/db-migration-shape.spec.mjs, editions: [lite, full]}
|
|
3623
|
+
exemplifiedBy:
|
|
3624
|
+
- {path: packages/hfs/templates/app/skeleton-lite/supabase/migrations/__timestamp___baseline.sql, edition: lite}
|
|
3625
|
+
- {path: packages/hfs/src/db-migration-shape.spec.mjs, editions: [lite, full]}
|
|
3626
|
+
witness:
|
|
3627
|
+
- {path: packages/hfs/src/db-migration-shape.spec.mjs, editions: [lite, full], codes: [DB_MIGRATION_SHAPE]}
|
|
3470
3628
|
- id: R214
|
|
3471
3629
|
code: "DB_RLS_REQUIRED"
|
|
3472
3630
|
editions: [lite, full]
|
|
3473
3631
|
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
3632
|
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
3633
|
kinds: [check, codemod]
|
|
3480
3634
|
gates: [settle, land, ci]
|
|
3481
3635
|
failureCodes: ["DB_RLS_REQUIRED", "DB_DYNAMIC_DDL", "DB_POLICY_SHAPE"]
|
|
3482
3636
|
enforcers:
|
|
3483
3637
|
- {kind: hfs, id: db-rls, at: scripts/hfs/rules/database.mjs}
|
|
3638
|
+
proves:
|
|
3639
|
+
- {path: packages/hfs/src/db-rls-required.spec.mjs, editions: [lite, full], codes: [DB_RLS_REQUIRED]}
|
|
3640
|
+
- {path: packages/hfs/src/db-dynamic-ddl.spec.mjs, editions: [lite, full], codes: [DB_DYNAMIC_DDL]}
|
|
3641
|
+
- {path: packages/hfs/src/db-policy-shape.spec.mjs, editions: [lite, full], codes: [DB_POLICY_SHAPE]}
|
|
3642
|
+
exemplifiedBy:
|
|
3643
|
+
- {path: packages/hfs/templates/be/table/migration.sql.tpl, editions: [lite, full]}
|
|
3644
|
+
- {path: packages/hfs/src/db-rls-required.spec.mjs, editions: [lite, full]}
|
|
3645
|
+
- {path: packages/hfs/src/db-dynamic-ddl.spec.mjs, editions: [lite, full]}
|
|
3646
|
+
- {path: packages/hfs/src/db-policy-shape.spec.mjs, editions: [lite, full]}
|
|
3647
|
+
witness:
|
|
3648
|
+
- {path: packages/hfs/src/db-rls-required.spec.mjs, edition: lite, codes: [DB_RLS_REQUIRED]}
|
|
3649
|
+
- {path: packages/hfs/src/db-dynamic-ddl.spec.mjs, edition: lite, codes: [DB_DYNAMIC_DDL]}
|
|
3650
|
+
- {path: packages/hfs/src/db-policy-shape.spec.mjs, edition: lite, codes: [DB_POLICY_SHAPE]}
|
|
3651
|
+
- {path: packages/hfs/src/db-rls-required.spec.mjs, edition: full, codes: [DB_RLS_REQUIRED]}
|
|
3652
|
+
- {path: packages/hfs/src/db-dynamic-ddl.spec.mjs, edition: full, codes: [DB_DYNAMIC_DDL]}
|
|
3653
|
+
- {path: packages/hfs/src/db-policy-shape.spec.mjs, edition: full, codes: [DB_POLICY_SHAPE]}
|
|
3484
3654
|
- id: R215
|
|
3485
3655
|
code: "DB_DEFINER_SAFE"
|
|
3486
3656
|
editions: [lite, full]
|
|
3487
3657
|
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
3658
|
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
3659
|
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
3660
|
kinds: [check]
|
|
3493
3661
|
gates: [settle, land, ci]
|
|
3494
3662
|
failureCodes: ["DB_DEFINER_SAFE", "DB_STORAGE_POLICY"]
|
|
3495
3663
|
enforcers:
|
|
3496
3664
|
- {kind: hfs, id: db-privileged-objects, at: scripts/hfs/rules/database.mjs}
|
|
3497
|
-
|
|
3665
|
+
proves:
|
|
3666
|
+
- {path: packages/hfs/src/db-definer-safe.spec.mjs, editions: [lite, full], codes: [DB_DEFINER_SAFE]}
|
|
3667
|
+
- {path: packages/hfs/src/db-storage-policy.spec.mjs, editions: [lite, full], codes: [DB_STORAGE_POLICY]}
|
|
3668
|
+
exemplifiedBy:
|
|
3669
|
+
- {path: packages/hfs/src/db-definer-safe.spec.mjs, editions: [lite, full]}
|
|
3670
|
+
- {path: packages/hfs/src/db-storage-policy.spec.mjs, editions: [lite, full]}
|
|
3671
|
+
witness:
|
|
3672
|
+
- {path: packages/hfs/src/db-definer-safe.spec.mjs, edition: lite, codes: [DB_DEFINER_SAFE]}
|
|
3673
|
+
- {path: packages/hfs/src/db-storage-policy.spec.mjs, edition: lite, codes: [DB_STORAGE_POLICY]}
|
|
3674
|
+
- {path: packages/hfs/src/db-definer-safe.spec.mjs, edition: full, codes: [DB_DEFINER_SAFE]}
|
|
3675
|
+
- {path: packages/hfs/src/db-storage-policy.spec.mjs, edition: full, codes: [DB_STORAGE_POLICY]}
|
|
3498
3676
|
- id: R216
|
|
3499
3677
|
code: "DB_CONFIG_POLICY"
|
|
3500
3678
|
editions: [lite, full]
|
|
3501
3679
|
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
3680
|
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
3681
|
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
3682
|
kinds: [check]
|
|
3509
3683
|
gates: [land, ci]
|
|
@@ -3511,15 +3685,25 @@ rules:
|
|
|
3511
3685
|
enforcers:
|
|
3512
3686
|
- {kind: hfs, id: db-config-types, at: scripts/hfs/rules/database.mjs}
|
|
3513
3687
|
- {kind: hfs, id: db-types-emit, at: packages/hfs/emit/db-types.mjs}
|
|
3688
|
+
proves:
|
|
3689
|
+
- {path: packages/hfs/src/db-types-returned-collector.spec.mjs, editions: [lite, full], codes: [DB_TYPES_DRIFT]}
|
|
3690
|
+
- {path: packages/hfs/src/db-config-policy.spec.mjs, editions: [lite, full], codes: [DB_CONFIG_POLICY]}
|
|
3691
|
+
- {path: packages/hfs/src/db-types-emit-stale.spec.mjs, editions: [lite, full], codes: [HFS_EMIT_DB_TYPES_STALE]}
|
|
3692
|
+
exemplifiedBy:
|
|
3693
|
+
- {path: packages/hfs/templates/app/skeleton-lite/supabase/config.toml, edition: lite}
|
|
3694
|
+
- {path: packages/hfs/src/db-types-returned-collector.spec.mjs, editions: [lite, full]}
|
|
3695
|
+
- {path: packages/hfs/src/db-config-policy.spec.mjs, editions: [lite, full]}
|
|
3696
|
+
- {path: packages/hfs/src/db-types-emit-stale.spec.mjs, editions: [lite, full], codes: [HFS_EMIT_DB_TYPES_STALE]}
|
|
3697
|
+
witness:
|
|
3698
|
+
- {path: packages/hfs/src/db-types-returned-collector.spec.mjs, edition: lite, codes: [DB_TYPES_DRIFT]}
|
|
3699
|
+
- {path: packages/hfs/src/db-types-returned-collector.spec.mjs, edition: full, codes: [DB_TYPES_DRIFT]}
|
|
3700
|
+
- {path: packages/hfs/src/db-config-policy.spec.mjs, edition: lite, codes: [DB_CONFIG_POLICY]}
|
|
3701
|
+
- {path: packages/hfs/src/db-config-policy.spec.mjs, edition: full, codes: [DB_CONFIG_POLICY]}
|
|
3702
|
+
- {path: packages/hfs/src/db-types-emit-stale.spec.mjs, editions: [lite, full], codes: [HFS_EMIT_DB_TYPES_STALE]}
|
|
3514
3703
|
- id: R217
|
|
3515
3704
|
code: "FE_SUPABASE_CLIENT_OWNER"
|
|
3516
3705
|
editions: [lite, full]
|
|
3517
3706
|
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
3707
|
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
3708
|
kinds: [check, design]
|
|
3525
3709
|
gates: [settle, land, ci]
|
|
@@ -3527,52 +3711,74 @@ rules:
|
|
|
3527
3711
|
enforcers:
|
|
3528
3712
|
- {kind: machine, id: supabase-client-owner, at: scripts/hfs/architecture/supabase.mjs}
|
|
3529
3713
|
- {kind: machine, id: supabase-service-role, at: scripts/hfs/architecture/supabase.mjs}
|
|
3714
|
+
proves:
|
|
3715
|
+
- {path: packages/hfs/src/fe-supabase-client-owner.spec.mjs, editions: [lite, full], codes: [FE_SUPABASE_CLIENT_OWNER]}
|
|
3716
|
+
- {path: packages/hfs/src/r217-backend-client-owner.spec.mjs, editions: [lite, full], codes: [BE_SUPABASE_CLIENT_OWNER]}
|
|
3717
|
+
- {path: packages/hfs/src/fe-service-role-forbidden.spec.mjs, editions: [lite, full], codes: [FE_SERVICE_ROLE_FORBIDDEN]}
|
|
3718
|
+
exemplifiedBy:
|
|
3719
|
+
- {path: packages/hfs/templates/fe/auth/supabase-client.ts.tpl, editions: [lite, full]}
|
|
3720
|
+
- {path: packages/hfs/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.client.ts, edition: lite}
|
|
3721
|
+
- {path: packages/hfs/src/fe-supabase-client-owner.spec.mjs, editions: [lite, full]}
|
|
3722
|
+
- {path: packages/hfs/src/r217-backend-client-owner.spec.mjs, editions: [lite, full]}
|
|
3723
|
+
- {path: packages/hfs/src/fe-service-role-forbidden.spec.mjs, editions: [lite, full]}
|
|
3724
|
+
witness:
|
|
3725
|
+
- {path: packages/hfs/src/fe-supabase-client-owner.spec.mjs, edition: lite, codes: [FE_SUPABASE_CLIENT_OWNER]}
|
|
3726
|
+
- {path: packages/hfs/src/r217-backend-client-owner.spec.mjs, edition: lite, codes: [BE_SUPABASE_CLIENT_OWNER]}
|
|
3727
|
+
- {path: packages/hfs/src/fe-service-role-forbidden.spec.mjs, edition: lite, codes: [FE_SERVICE_ROLE_FORBIDDEN]}
|
|
3728
|
+
- {path: packages/hfs/src/fe-supabase-client-owner.spec.mjs, edition: full, codes: [FE_SUPABASE_CLIENT_OWNER]}
|
|
3729
|
+
- {path: packages/hfs/src/r217-backend-client-owner.spec.mjs, edition: full, codes: [BE_SUPABASE_CLIENT_OWNER]}
|
|
3730
|
+
- {path: packages/hfs/src/fe-service-role-forbidden.spec.mjs, edition: full, codes: [FE_SERVICE_ROLE_FORBIDDEN]}
|
|
3530
3731
|
- id: R219
|
|
3531
3732
|
code: "BE_SUPABASE_JWT_VERIFIED"
|
|
3532
3733
|
editions: [lite, full]
|
|
3533
3734
|
docs: [docs/lite-edition.md#r219]
|
|
3534
3735
|
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
3736
|
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
3737
|
kinds: [check, design]
|
|
3541
3738
|
gates: [settle, land, ci]
|
|
3542
3739
|
failureCodes: ["BE_SUPABASE_JWT_VERIFIED"]
|
|
3543
3740
|
enforcers:
|
|
3544
3741
|
- {kind: machine, id: supabase-principal, at: scripts/hfs/architecture/supabase.mjs}
|
|
3742
|
+
proves:
|
|
3743
|
+
- {path: packages/hfs/src/be-supabase-jwt-verified.spec.mjs, editions: [lite, full]}
|
|
3744
|
+
exemplifiedBy:
|
|
3745
|
+
- {path: packages/hfs/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.jwks.ts, edition: lite}
|
|
3746
|
+
- {path: packages/hfs/src/be-supabase-jwt-verified.spec.mjs, editions: [lite, full]}
|
|
3747
|
+
witness:
|
|
3748
|
+
- {path: packages/hfs/src/be-supabase-jwt-verified.spec.mjs, edition: lite, codes: [BE_SUPABASE_JWT_VERIFIED]}
|
|
3749
|
+
- {path: packages/hfs/src/be-supabase-jwt-verified.spec.mjs, edition: full, codes: [BE_SUPABASE_JWT_VERIFIED]}
|
|
3545
3750
|
- id: R220
|
|
3546
3751
|
code: "HFS_LITE_SECRET_CUSTODY"
|
|
3547
3752
|
editions: [lite]
|
|
3548
3753
|
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
3754
|
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
3755
|
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
3756
|
kinds: [check]
|
|
3556
3757
|
gates: [settle, land, ci]
|
|
3557
3758
|
failureCodes: ["HFS_LITE_SECRET_CUSTODY"]
|
|
3558
3759
|
enforcers:
|
|
3559
3760
|
- {kind: hfs, id: lite-secret-custody, at: scripts/hfs/rules/supabase-secrets.mjs}
|
|
3761
|
+
proves:
|
|
3762
|
+
- {path: packages/hfs/src/hfs-supabase-secrets.spec.mjs, edition: lite}
|
|
3763
|
+
exemplifiedBy:
|
|
3764
|
+
- {path: packages/hfs/templates/app/skeleton-lite/.sops.yaml, edition: lite}
|
|
3765
|
+
- {path: packages/hfs/src/hfs-supabase-secrets.spec.mjs, edition: lite}
|
|
3766
|
+
witness:
|
|
3767
|
+
- {path: packages/hfs/src/hfs-supabase-secrets.spec.mjs, edition: lite}
|
|
3560
3768
|
- id: R221
|
|
3561
3769
|
code: "CI_TRIGGERS_RELEASE_ONLY"
|
|
3562
3770
|
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
3771
|
scope: runtime
|
|
3564
3772
|
editions: [lite, full]
|
|
3565
3773
|
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
3774
|
kinds: [check]
|
|
3572
3775
|
gates: [runtime]
|
|
3573
3776
|
failureCodes: ["CI_TRIGGERS_RELEASE_ONLY"]
|
|
3574
3777
|
enforcers:
|
|
3575
3778
|
- {kind: runtime, id: git-triggers, at: scripts/hfs/runtime-rules/git-triggers.mjs}
|
|
3779
|
+
exemplifiedBy:
|
|
3780
|
+
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
3781
|
+
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
3576
3782
|
- id: R222
|
|
3577
3783
|
code: "RELEASE_NOTES"
|
|
3578
3784
|
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 +3786,11 @@ rules:
|
|
|
3580
3786
|
editions: [lite, full]
|
|
3581
3787
|
docs: [docs/git-governance.md#r222]
|
|
3582
3788
|
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
3789
|
kinds: [check]
|
|
3586
3790
|
gates: [runtime]
|
|
3587
3791
|
failureCodes: ["RELEASE_NOTES"]
|
|
3588
3792
|
enforcers:
|
|
3589
3793
|
- {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
3794
|
- id: R223
|
|
3592
3795
|
code: "RIGHTS_ROLE_DENIED"
|
|
3593
3796
|
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 +3800,6 @@ rules:
|
|
|
3597
3800
|
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
3801
|
enforcers:
|
|
3599
3802
|
- {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
3803
|
- id: R224
|
|
3602
3804
|
code: "RIGHTS_PROTECTED_ZONE"
|
|
3603
3805
|
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 +3809,6 @@ rules:
|
|
|
3607
3809
|
failureCodes: ["RIGHTS_PROTECTED_ZONE", "RIGHTS_OP_RUNTIME_WRITE"]
|
|
3608
3810
|
enforcers:
|
|
3609
3811
|
- {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
3812
|
- id: R225
|
|
3612
3813
|
code: "RT_HOOK_SHAPE"
|
|
3613
3814
|
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 +3818,11 @@ rules:
|
|
|
3617
3818
|
failureCodes: ["RT_HOOK_SHAPE", "RIGHTS_PUSH_NOT_RELEASE"]
|
|
3618
3819
|
enforcers:
|
|
3619
3820
|
- {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
3821
|
- id: R227
|
|
3622
3822
|
code: "RT_SYNTAX_INVALID"
|
|
3623
3823
|
editions: [lite, full]
|
|
3624
3824
|
docs: [docs/source-process.md#r227]
|
|
3625
3825
|
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
3826
|
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
3827
|
scope: runtime
|
|
3630
3828
|
kinds: [check]
|
|
@@ -3632,7 +3830,6 @@ rules:
|
|
|
3632
3830
|
failureCodes: ["RT_SYNTAX_INVALID"]
|
|
3633
3831
|
enforcers:
|
|
3634
3832
|
- {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
3833
|
- id: R228
|
|
3637
3834
|
code: "RT_IDENTIFIER_UNDECLARED"
|
|
3638
3835
|
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 +3842,6 @@ rules:
|
|
|
3645
3842
|
editions: [lite, full]
|
|
3646
3843
|
docs: [docs/source-process.md#r228]
|
|
3647
3844
|
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
3845
|
- id: R229
|
|
3652
3846
|
code: "RT_REMOVED_VOCABULARY"
|
|
3653
3847
|
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 +3854,6 @@ rules:
|
|
|
3660
3854
|
editions: [lite, full]
|
|
3661
3855
|
docs: [docs/source-process.md#r229]
|
|
3662
3856
|
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
3857
|
- id: R230
|
|
3667
3858
|
code: "RT_PROSE_COMMAND_UNKNOWN"
|
|
3668
3859
|
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 +3861,11 @@ rules:
|
|
|
3670
3861
|
editions: [lite, full]
|
|
3671
3862
|
docs: [docs/debugging.md#r230-instruction-commands]
|
|
3672
3863
|
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
3864
|
kinds: [check]
|
|
3676
3865
|
gates: [runtime]
|
|
3677
3866
|
failureCodes: ["RT_PROSE_COMMAND_UNKNOWN"]
|
|
3678
3867
|
enforcers:
|
|
3679
3868
|
- {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
3869
|
- id: R231
|
|
3682
3870
|
code: "RT_DOCUMENTED_DEFAULT_DRIFT"
|
|
3683
3871
|
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 +3873,11 @@ rules:
|
|
|
3685
3873
|
editions: [lite, full]
|
|
3686
3874
|
docs: [docs/debugging.md#r231-documented-defaults]
|
|
3687
3875
|
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
3876
|
kinds: [check]
|
|
3691
3877
|
gates: [runtime]
|
|
3692
3878
|
failureCodes: ["RT_DOCUMENTED_DEFAULT_DRIFT"]
|
|
3693
3879
|
enforcers:
|
|
3694
3880
|
- {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
3881
|
- id: R232
|
|
3697
3882
|
code: "RT_ROLES_CONTRACT_DRIFT"
|
|
3698
3883
|
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 +3885,11 @@ rules:
|
|
|
3700
3885
|
editions: [lite, full]
|
|
3701
3886
|
docs: [docs/debugging.md#r232-generated-role-contracts]
|
|
3702
3887
|
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
3888
|
kinds: [check]
|
|
3706
3889
|
gates: [runtime]
|
|
3707
3890
|
failureCodes: ["RT_ROLES_CONTRACT_DRIFT"]
|
|
3708
3891
|
enforcers:
|
|
3709
3892
|
- {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
3893
|
- id: R233
|
|
3712
3894
|
code: "RT_EDGE_CASE_REGISTRY"
|
|
3713
3895
|
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 +3897,16 @@ rules:
|
|
|
3715
3897
|
editions: [lite, full]
|
|
3716
3898
|
docs: [docs/debugging.md#r233-edge-case-evidence]
|
|
3717
3899
|
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
3900
|
kinds: [check]
|
|
3721
3901
|
gates: [runtime]
|
|
3722
3902
|
failureCodes: ["RT_EDGE_CASE_REGISTRY"]
|
|
3723
3903
|
enforcers:
|
|
3724
3904
|
- {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
3905
|
- id: R234
|
|
3727
3906
|
code: "RT_SECRET_TRACKED"
|
|
3728
3907
|
editions: [lite, full]
|
|
3729
3908
|
docs: [docs/application-stacks.md#where-a-secret-may-live]
|
|
3730
3909
|
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
3910
|
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
3911
|
scope: runtime
|
|
3735
3912
|
kinds: [check]
|
|
@@ -3737,7 +3914,6 @@ rules:
|
|
|
3737
3914
|
failureCodes: ["RT_SECRET_TRACKED"]
|
|
3738
3915
|
enforcers:
|
|
3739
3916
|
- {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
3917
|
- id: R235
|
|
3742
3918
|
code: "SCAN_SMELL"
|
|
3743
3919
|
editions: [lite, full]
|
|
@@ -3782,8 +3958,6 @@ rules:
|
|
|
3782
3958
|
editions: [lite, full]
|
|
3783
3959
|
docs: [docs/debugging.md#r236]
|
|
3784
3960
|
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
3961
|
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
3962
|
scope: runtime
|
|
3789
3963
|
kinds: [check]
|
|
@@ -3791,14 +3965,11 @@ rules:
|
|
|
3791
3965
|
failureCodes: ["RT_GATE_LOOSENING"]
|
|
3792
3966
|
enforcers:
|
|
3793
3967
|
- {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
3968
|
- id: R237
|
|
3796
3969
|
code: "RT_REVISION_SCOPE"
|
|
3797
3970
|
editions: [lite, full]
|
|
3798
3971
|
docs: [docs/debugging.md#r237]
|
|
3799
3972
|
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
3973
|
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
3974
|
scope: runtime
|
|
3804
3975
|
kinds: [check]
|
|
@@ -3806,7 +3977,6 @@ rules:
|
|
|
3806
3977
|
failureCodes: ["RT_REVISION_SCOPE"]
|
|
3807
3978
|
enforcers:
|
|
3808
3979
|
- {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
3980
|
- id: R238
|
|
3811
3981
|
code: "RT_EVENT_SPILL_BYPASS"
|
|
3812
3982
|
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 +3984,11 @@ rules:
|
|
|
3814
3984
|
editions: [lite, full]
|
|
3815
3985
|
docs: [docs/ledger-db.md#the-storage-convention-owner-ruling-2026-10-09]
|
|
3816
3986
|
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
3987
|
kinds: [check]
|
|
3820
3988
|
gates: [runtime]
|
|
3821
3989
|
failureCodes: ["RT_EVENT_SPILL_BYPASS"]
|
|
3822
3990
|
enforcers:
|
|
3823
3991
|
- {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
3992
|
- id: R239
|
|
3826
3993
|
code: "RT_STORAGE_UNDECLARED"
|
|
3827
3994
|
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 +3996,11 @@ rules:
|
|
|
3829
3996
|
editions: [lite, full]
|
|
3830
3997
|
docs: [docs/ledger-db.md#the-storage-convention-owner-ruling-2026-10-09]
|
|
3831
3998
|
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
3999
|
kinds: [check]
|
|
3835
4000
|
gates: [runtime]
|
|
3836
4001
|
failureCodes: ["RT_STORAGE_UNDECLARED"]
|
|
3837
4002
|
enforcers:
|
|
3838
4003
|
- {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
4004
|
- id: R240
|
|
3841
4005
|
code: "RT_ROOT_ADHOC"
|
|
3842
4006
|
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 +4008,11 @@ rules:
|
|
|
3844
4008
|
editions: [lite, full]
|
|
3845
4009
|
docs: [docs/architecture.md#r240]
|
|
3846
4010
|
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
4011
|
kinds: [check]
|
|
3850
4012
|
gates: [runtime]
|
|
3851
4013
|
failureCodes: ["RT_ROOT_ADHOC"]
|
|
3852
4014
|
enforcers:
|
|
3853
4015
|
- {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
4016
|
- id: R241
|
|
3856
4017
|
code: "RT_HELD_UNSURFACED"
|
|
3857
4018
|
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 +4020,11 @@ rules:
|
|
|
3859
4020
|
editions: [lite, full]
|
|
3860
4021
|
docs: [docs/debugging.md#r241]
|
|
3861
4022
|
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
4023
|
kinds: [check]
|
|
3865
4024
|
gates: [runtime]
|
|
3866
4025
|
failureCodes: ["RT_HELD_UNSURFACED"]
|
|
3867
4026
|
enforcers:
|
|
3868
4027
|
- {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
4028
|
- id: R242
|
|
3871
4029
|
code: "RT_OP_JUDGE_UNDECLARED"
|
|
3872
4030
|
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 +4032,15 @@ rules:
|
|
|
3874
4032
|
editions: [lite, full]
|
|
3875
4033
|
docs: [docs/ops.md#r242]
|
|
3876
4034
|
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
4035
|
kinds: [check]
|
|
3880
4036
|
gates: [runtime]
|
|
3881
4037
|
failureCodes: ["RT_OP_JUDGE_UNDECLARED"]
|
|
3882
4038
|
enforcers:
|
|
3883
4039
|
- {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
4040
|
- id: R243
|
|
3886
4041
|
code: "FE_SERVER_ACTION_FORBIDDEN"
|
|
3887
4042
|
editions: [lite, full]
|
|
3888
4043
|
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
4044
|
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
4045
|
kinds: [check, lint]
|
|
3897
4046
|
gates: [pre-commit, settle, land, ci]
|
|
@@ -3899,17 +4048,19 @@ rules:
|
|
|
3899
4048
|
enforcers:
|
|
3900
4049
|
- {kind: machine, id: server-action-forbidden, at: scripts/hfs/architecture/server-action.mjs}
|
|
3901
4050
|
- {kind: eslint-fe, id: no-server-action}
|
|
3902
|
-
|
|
4051
|
+
proves:
|
|
4052
|
+
- {path: packages/eslint/fe/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_SERVER_ACTION_FORBIDDEN]}
|
|
4053
|
+
- {path: packages/hfs/src/frontend-boundary-coverage.spec.mjs, editions: [lite, full]}
|
|
4054
|
+
exemplifiedBy:
|
|
4055
|
+
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/app/health/live/route.ts, edition: lite}
|
|
4056
|
+
- {path: packages/hfs/templates/fe/skeleton/apps/app/src/app/health/live/route.ts, edition: full}
|
|
4057
|
+
- {path: packages/hfs/src/frontend-boundary-coverage.spec.mjs, editions: [lite, full]}
|
|
4058
|
+
witness:
|
|
4059
|
+
- {path: packages/hfs/src/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_SERVER_ACTION_FORBIDDEN, FE_ROUTE_HANDLER_FORBIDDEN]}
|
|
3903
4060
|
- id: R244
|
|
3904
4061
|
code: "FE_STACK_FORBIDDEN"
|
|
3905
4062
|
editions: [lite, full]
|
|
3906
4063
|
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
4064
|
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
4065
|
kinds: [check, lint]
|
|
3915
4066
|
gates: [pre-commit, settle, land, ci]
|
|
@@ -3917,7 +4068,15 @@ rules:
|
|
|
3917
4068
|
enforcers:
|
|
3918
4069
|
- {kind: hfs, id: fe-stack, at: scripts/hfs/rules/fe-stack.mjs}
|
|
3919
4070
|
- {kind: eslint-fe, id: fe-stack-import}
|
|
3920
|
-
|
|
4071
|
+
proves:
|
|
4072
|
+
- {path: packages/eslint/fe/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_STACK_FORBIDDEN]}
|
|
4073
|
+
- {path: packages/hfs/src/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_STACK_FORBIDDEN]}
|
|
4074
|
+
exemplifiedBy:
|
|
4075
|
+
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/proxy.ts, edition: lite}
|
|
4076
|
+
- {path: packages/hfs/templates/fe/skeleton/apps/app/src/proxy.ts, edition: full}
|
|
4077
|
+
- {path: packages/hfs/src/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_STACK_FORBIDDEN]}
|
|
4078
|
+
witness:
|
|
4079
|
+
- {path: packages/hfs/src/frontend-boundary-coverage.spec.mjs, editions: [lite, full], codes: [FE_STACK_FORBIDDEN]}
|
|
3921
4080
|
- id: R245
|
|
3922
4081
|
code: "BE_APP_OPTIONS_COMPOSITION"
|
|
3923
4082
|
amendedBy: R289
|
|
@@ -3962,74 +4121,71 @@ rules:
|
|
|
3962
4121
|
editions: [lite, full]
|
|
3963
4122
|
docs: [docs/quality-bar.md#coverage-matrix]
|
|
3964
4123
|
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
4124
|
kinds: [check]
|
|
3968
4125
|
gates: [runtime]
|
|
3969
4126
|
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
4127
|
enforcers:
|
|
3971
4128
|
- {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
4129
|
- id: R248
|
|
3974
4130
|
code: "ENV_REQUIRED_UNSET"
|
|
3975
4131
|
editions: [lite, full]
|
|
3976
4132
|
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
4133
|
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
4134
|
kinds: [check]
|
|
3984
4135
|
gates: [settle, land, ci]
|
|
3985
4136
|
failureCodes: ["ENV_REQUIRED_UNSET", "ENV_SEALED_UNREAD", "ENV_DUPLICATE", "ENV_PUBLIC_SEALED", "ENV_EXAMPLE_DRIFT"]
|
|
3986
4137
|
enforcers:
|
|
3987
4138
|
- {kind: hfs, id: env-parity, at: scripts/hfs/rules/env-parity.mjs}
|
|
3988
|
-
|
|
4139
|
+
proves:
|
|
4140
|
+
- {path: packages/hfs/src/hfs-env-parity.spec.mjs, editions: [lite, full]}
|
|
4141
|
+
exemplifiedBy:
|
|
4142
|
+
- {path: packages/hfs/templates/be/skeleton-lite/apps/api/src/api.env.ts, edition: lite}
|
|
4143
|
+
- {path: packages/hfs/templates/be/skeleton/apps/__app__/src/__app__.env.ts, edition: full}
|
|
4144
|
+
- {path: packages/hfs/src/hfs-env-parity.spec.mjs, editions: [lite, full]}
|
|
4145
|
+
witness:
|
|
4146
|
+
- {path: packages/hfs/src/hfs-env-parity.spec.mjs, editions: [lite, full]}
|
|
3989
4147
|
- id: R249
|
|
3990
4148
|
code: "ENV_VALUE_SHAPE"
|
|
3991
4149
|
editions: [lite, full]
|
|
3992
4150
|
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
4151
|
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
4152
|
kinds: [check]
|
|
4000
4153
|
gates: [settle, land, ci]
|
|
4001
4154
|
failureCodes: ["ENV_VALUE_SHAPE"]
|
|
4002
4155
|
enforcers:
|
|
4003
4156
|
- {kind: hfs, id: env-value-shape, at: scripts/hfs/rules/env-value-shape.mjs}
|
|
4004
|
-
|
|
4005
|
-
|
|
4157
|
+
proves:
|
|
4158
|
+
- {path: packages/hfs/src/hfs-env-parity.spec.mjs, editions: [lite, full]}
|
|
4159
|
+
exemplifiedBy:
|
|
4160
|
+
- {path: packages/hfs/templates/be/skeleton-lite/apps/api/src/api.env.ts, edition: lite}
|
|
4161
|
+
- {path: packages/hfs/templates/be/skeleton/apps/__app__/src/__app__.env.ts, edition: full}
|
|
4162
|
+
- {path: packages/hfs/src/hfs-env-parity.spec.mjs, editions: [lite, full]}
|
|
4163
|
+
witness:
|
|
4164
|
+
- {path: packages/hfs/src/hfs-env-parity.spec.mjs, editions: [lite, full]}
|
|
4006
4165
|
- id: R250
|
|
4007
4166
|
code: "HFS_HOST_CRON"
|
|
4008
4167
|
editions: [lite, full]
|
|
4009
4168
|
docs:
|
|
4010
4169
|
- {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
4170
|
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
4171
|
kinds: [check]
|
|
4018
4172
|
gates: [settle, land, ci]
|
|
4019
4173
|
failureCodes: ["HFS_HOST_CRON", "HFS_DEPLOY_NO_LOGIC", "HFS_DEPLOY_COMPOSE_ON_VPS", "HFS_DEPLOY_SCHEDULER"]
|
|
4020
4174
|
enforcers:
|
|
4021
4175
|
- {kind: hfs, id: deploy-scan, at: scripts/hfs/rules/deploy-scan.mjs}
|
|
4022
|
-
|
|
4176
|
+
proves:
|
|
4177
|
+
- {path: packages/hfs/src/hfs-deploy-scan.spec.mjs, editions: [lite, full]}
|
|
4178
|
+
exemplifiedBy:
|
|
4179
|
+
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
4180
|
+
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4181
|
+
- {path: packages/hfs/src/hfs-deploy-scan.spec.mjs, editions: [lite, full]}
|
|
4182
|
+
witness:
|
|
4183
|
+
- {path: packages/hfs/src/hfs-deploy-scan.spec.mjs, editions: [lite, full]}
|
|
4023
4184
|
- id: R251
|
|
4024
4185
|
code: "HFS_DEPLOY_WORKFLOW"
|
|
4025
4186
|
editions: [lite, full]
|
|
4026
4187
|
docs:
|
|
4027
4188
|
- {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
4189
|
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
4190
|
kinds: [check]
|
|
4035
4191
|
gates: [settle, land, ci]
|
|
@@ -4037,34 +4193,37 @@ rules:
|
|
|
4037
4193
|
enforcers:
|
|
4038
4194
|
- {kind: hfs, id: deploy-workflow, at: scripts/hfs/rules/deploy-workflow.mjs}
|
|
4039
4195
|
- {kind: hfs, id: supply-chain, at: scripts/hfs/rules/supply-chain.mjs}
|
|
4040
|
-
|
|
4196
|
+
proves:
|
|
4197
|
+
- {path: packages/hfs/src/hfs-deploy-workflow.spec.mjs, editions: [lite, full]}
|
|
4198
|
+
exemplifiedBy:
|
|
4199
|
+
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml, edition: lite}
|
|
4200
|
+
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4201
|
+
- {path: packages/hfs/src/hfs-deploy-workflow.spec.mjs, editions: [lite, full]}
|
|
4202
|
+
witness:
|
|
4203
|
+
- {path: packages/hfs/src/hfs-deploy-workflow.spec.mjs, editions: [lite, full]}
|
|
4041
4204
|
- id: R252
|
|
4042
4205
|
code: "HFS_SCRIPT_PLAINTEXT_LOAD"
|
|
4043
4206
|
editions: [lite, full]
|
|
4044
4207
|
docs:
|
|
4045
4208
|
- {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
4209
|
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
4210
|
kinds: [check]
|
|
4053
4211
|
gates: [settle, land, ci]
|
|
4054
4212
|
failureCodes: ["HFS_SCRIPT_PLAINTEXT_LOAD", "HFS_SCRIPT_XTRACE", "HFS_SERVICE_ROLE_SCOPE"]
|
|
4055
4213
|
enforcers:
|
|
4056
4214
|
- {kind: hfs, id: script-hygiene, at: scripts/hfs/rules/script-hygiene.mjs}
|
|
4057
|
-
|
|
4215
|
+
proves:
|
|
4216
|
+
- {path: packages/hfs/src/hfs-script-hygiene.spec.mjs, editions: [lite, full]}
|
|
4217
|
+
exemplifiedBy:
|
|
4218
|
+
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml, edition: lite}
|
|
4219
|
+
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4220
|
+
- {path: packages/hfs/src/hfs-script-hygiene.spec.mjs, editions: [lite, full]}
|
|
4221
|
+
witness:
|
|
4222
|
+
- {path: packages/hfs/src/hfs-script-hygiene.spec.mjs, editions: [lite, full]}
|
|
4058
4223
|
- id: R253
|
|
4059
4224
|
code: "HFS_AGE_KEY_CUSTODY"
|
|
4060
4225
|
editions: [lite, full]
|
|
4061
4226
|
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
4227
|
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
4228
|
kinds: [check]
|
|
4070
4229
|
gates: [settle, land, ci]
|
|
@@ -4072,45 +4231,57 @@ rules:
|
|
|
4072
4231
|
enforcers:
|
|
4073
4232
|
- {kind: hfs, id: secret-age-key-custody, at: scripts/hfs/rules/secrets.mjs}
|
|
4074
4233
|
- {kind: hfs, id: canon-copy-drift, at: scripts/hfs/rules/canon-copy-drift.mjs}
|
|
4075
|
-
|
|
4234
|
+
proves:
|
|
4235
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [lite, full]}
|
|
4236
|
+
exemplifiedBy:
|
|
4237
|
+
- {path: packages/hfs/templates/be/skeleton/src/modules/platform/config/env-source.config.ts, editions: [lite, full]}
|
|
4238
|
+
- {path: packages/hfs/templates/be/skeleton/src/modules/platform/http-security/origin.guard.ts, editions: [lite, full]}
|
|
4239
|
+
- {path: packages/hfs/templates/be/skeleton/src/modules/platform/http-security/webhook-signature.service.ts, editions: [lite, full]}
|
|
4240
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [lite, full]}
|
|
4241
|
+
witness:
|
|
4242
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [lite, full]}
|
|
4076
4243
|
- id: R254
|
|
4077
4244
|
code: "DB_BE_ONLY_ACCESS"
|
|
4078
4245
|
editions: [lite]
|
|
4079
4246
|
editionWhy: "owner:lite-backing-services makes Supabase lite's database backing; these SQL access requirements apply to that backing."
|
|
4080
4247
|
docs: [docs/microservices.md#r254]
|
|
4081
4248
|
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
4249
|
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
4250
|
kinds: [check]
|
|
4086
4251
|
gates: [settle, land, ci]
|
|
4087
4252
|
failureCodes: ["DB_BE_ONLY_ACCESS", "DB_REALTIME_UNLISTED"]
|
|
4088
4253
|
enforcers:
|
|
4089
4254
|
- {kind: hfs, id: db-be-only-access, at: scripts/hfs/rules/database-access.mjs}
|
|
4090
|
-
|
|
4255
|
+
proves:
|
|
4256
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_BE_ONLY_ACCESS, DB_REALTIME_UNLISTED]}
|
|
4257
|
+
exemplifiedBy:
|
|
4258
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_BE_ONLY_ACCESS, DB_REALTIME_UNLISTED]}
|
|
4259
|
+
witness:
|
|
4260
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_BE_ONLY_ACCESS, DB_REALTIME_UNLISTED]}
|
|
4091
4261
|
- id: R255
|
|
4092
4262
|
code: "DB_APP_ROLE"
|
|
4093
4263
|
editions: [lite]
|
|
4094
4264
|
editionWhy: "owner:lite-backing-services makes Supabase lite's database backing; application-role and forced-RLS requirements apply to that backing."
|
|
4095
4265
|
docs: [docs/microservices.md#r255]
|
|
4096
4266
|
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
4267
|
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
4268
|
kinds: [check]
|
|
4101
4269
|
gates: [settle, land, ci]
|
|
4102
4270
|
failureCodes: ["DB_APP_ROLE", "DB_FORCE_RLS_DEFAULT"]
|
|
4103
4271
|
enforcers:
|
|
4104
4272
|
- {kind: hfs, id: db-app-role, at: scripts/hfs/rules/database-access.mjs}
|
|
4105
|
-
|
|
4273
|
+
proves:
|
|
4274
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_APP_ROLE, DB_FORCE_RLS_DEFAULT]}
|
|
4275
|
+
exemplifiedBy:
|
|
4276
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_APP_ROLE, DB_FORCE_RLS_DEFAULT]}
|
|
4277
|
+
witness:
|
|
4278
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_APP_ROLE, DB_FORCE_RLS_DEFAULT]}
|
|
4106
4279
|
- id: R256
|
|
4107
4280
|
code: "DB_POLICY_TAUTOLOGY"
|
|
4108
4281
|
editions: [lite]
|
|
4109
4282
|
editionWhy: "owner:lite-backing-services makes Supabase lite's database backing; access-policy, view, definer and storage SQL requirements apply to that backing."
|
|
4110
4283
|
docs: [docs/microservices.md#r256]
|
|
4111
4284
|
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
4285
|
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
4286
|
kinds: [check]
|
|
4116
4287
|
gates: [settle, land, ci]
|
|
@@ -4118,46 +4289,57 @@ rules:
|
|
|
4118
4289
|
enforcers:
|
|
4119
4290
|
- {kind: hfs, id: db-policy-hardening, at: scripts/hfs/rules/database-access.mjs}
|
|
4120
4291
|
- {kind: hfs, id: db-definer-revoke, at: scripts/hfs/rules/database-plpgsql.mjs}
|
|
4121
|
-
|
|
4122
|
-
|
|
4292
|
+
proves:
|
|
4293
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_POLICY_TAUTOLOGY, DB_VIEW_UNSAFE, DB_STORAGE_PREFIX]}
|
|
4294
|
+
- {path: packages/hfs/src/hfs-database-rules.spec.mjs, edition: lite, codes: [DB_DEFINER_REVOKE]}
|
|
4295
|
+
exemplifiedBy:
|
|
4296
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_POLICY_TAUTOLOGY, DB_VIEW_UNSAFE, DB_STORAGE_PREFIX]}
|
|
4297
|
+
- {path: packages/hfs/src/hfs-database-rules.spec.mjs, edition: lite, codes: [DB_DEFINER_REVOKE]}
|
|
4298
|
+
witness:
|
|
4299
|
+
- {path: packages/hfs/src/hfs-database-access.spec.mjs, edition: lite, codes: [DB_POLICY_TAUTOLOGY, DB_VIEW_UNSAFE, DB_STORAGE_PREFIX]}
|
|
4300
|
+
- {path: packages/hfs/src/hfs-database-rules.spec.mjs, edition: lite, codes: [DB_DEFINER_REVOKE]}
|
|
4123
4301
|
- id: R257
|
|
4124
4302
|
code: "DB_BASELINE_SHAPE"
|
|
4125
4303
|
editions: [lite]
|
|
4126
4304
|
editionWhy: "owner:lite-backing-services makes Supabase lite's database backing; baseline and archive requirements apply to its migration history."
|
|
4127
4305
|
docs: [docs/microservices.md#r257]
|
|
4128
4306
|
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
4307
|
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
4308
|
kinds: [check]
|
|
4133
4309
|
gates: [settle, land, ci]
|
|
4134
4310
|
failureCodes: ["DB_BASELINE_SHAPE", "DB_ARCHIVE_MUTATED"]
|
|
4135
4311
|
enforcers:
|
|
4136
4312
|
- {kind: hfs, id: db-baseline-shape, at: scripts/hfs/rules/database-baseline.mjs}
|
|
4137
|
-
|
|
4313
|
+
proves:
|
|
4314
|
+
- {path: packages/hfs/src/hfs-database-baseline.spec.mjs, edition: lite, codes: [DB_BASELINE_SHAPE, DB_ARCHIVE_MUTATED]}
|
|
4315
|
+
exemplifiedBy:
|
|
4316
|
+
- {path: packages/hfs/src/hfs-database-baseline.spec.mjs, edition: lite, codes: [DB_BASELINE_SHAPE, DB_ARCHIVE_MUTATED]}
|
|
4317
|
+
witness:
|
|
4318
|
+
- {path: packages/hfs/src/hfs-database-baseline.spec.mjs, edition: lite, codes: [DB_BASELINE_SHAPE, DB_ARCHIVE_MUTATED]}
|
|
4138
4319
|
- id: R258
|
|
4139
4320
|
code: "DB_PGMQ_DECLARED"
|
|
4140
4321
|
editions: [lite]
|
|
4141
4322
|
editionWhy: "owner:lite-backing-services makes Supabase lite's database backing; pgmq and pg_cron ownership requirements apply to that backing."
|
|
4142
4323
|
docs: [docs/microservices.md#r258]
|
|
4143
4324
|
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
4325
|
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
4326
|
kinds: [check]
|
|
4148
4327
|
gates: [settle, land, ci]
|
|
4149
4328
|
failureCodes: ["DB_PGMQ_DECLARED", "DB_CRON_OWNED"]
|
|
4150
4329
|
enforcers:
|
|
4151
4330
|
- {kind: hfs, id: db-queue-cron, at: scripts/hfs/rules/database-queues.mjs}
|
|
4152
|
-
|
|
4331
|
+
proves:
|
|
4332
|
+
- {path: packages/hfs/src/hfs-database-queues.spec.mjs, edition: lite, codes: [DB_PGMQ_DECLARED, DB_CRON_OWNED]}
|
|
4333
|
+
exemplifiedBy:
|
|
4334
|
+
- {path: packages/hfs/src/hfs-database-queues.spec.mjs, edition: lite, codes: [DB_PGMQ_DECLARED, DB_CRON_OWNED]}
|
|
4335
|
+
witness:
|
|
4336
|
+
- {path: packages/hfs/src/hfs-database-queues.spec.mjs, edition: lite, codes: [DB_PGMQ_DECLARED, DB_CRON_OWNED]}
|
|
4153
4337
|
- id: R259
|
|
4154
4338
|
code: "DB_EXTENSION_ALLOWED"
|
|
4155
4339
|
editions: [lite]
|
|
4156
4340
|
editionWhy: "owner:lite-backing-services makes Supabase lite's database backing; database configuration, extension, migration and seed requirements apply to that backing."
|
|
4157
4341
|
docs: [docs/microservices.md#r259]
|
|
4158
4342
|
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
4343
|
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
4344
|
kinds: [check]
|
|
4163
4345
|
gates: [settle, land, ci]
|
|
@@ -4165,8 +4347,12 @@ rules:
|
|
|
4165
4347
|
enforcers:
|
|
4166
4348
|
- {kind: hfs, id: db-config-ext, at: scripts/hfs/rules/database-config.mjs}
|
|
4167
4349
|
- {kind: hfs, id: db-migration-destructive, at: scripts/hfs/rules/database-migrations.mjs}
|
|
4168
|
-
|
|
4169
|
-
|
|
4350
|
+
proves:
|
|
4351
|
+
- {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]}
|
|
4352
|
+
exemplifiedBy:
|
|
4353
|
+
- {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]}
|
|
4354
|
+
witness:
|
|
4355
|
+
- {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
4356
|
- id: R260
|
|
4171
4357
|
code: "BE_JWT_ALG_PINNED"
|
|
4172
4358
|
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 +4366,16 @@ rules:
|
|
|
4180
4366
|
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
4367
|
docs:
|
|
4182
4368
|
- "docs/microservices.md#r260"
|
|
4369
|
+
proves:
|
|
4370
|
+
- "packages/eslint/be/jwt-alg.spec.mjs"
|
|
4371
|
+
- packages/hfs/src/architecture-jwt-policy.spec.mjs
|
|
4183
4372
|
exemplifiedBy:
|
|
4184
4373
|
- {"path":"packages/hfs/templates/be/skeleton-lite/src/modules/integrations/supabase/supabase.jwks.ts","edition":"lite"}
|
|
4185
4374
|
- {"path":"examples/lite-app/be/src/modules/integrations/supabase/supabase.jwks.ts","edition":"lite"}
|
|
4186
4375
|
- {"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
4376
|
witness:
|
|
4190
4377
|
- {"path":"packages/eslint/be/jwt-alg.spec.mjs","editions":["lite","full"],"codes":["BE_JWT_ALG_PINNED"]}
|
|
4191
|
-
|
|
4378
|
+
- {path: packages/hfs/src/architecture-jwt-policy.spec.mjs, editions: [lite, full], codes: [BE_JWT_ALG_PINNED]}
|
|
4192
4379
|
- id: R261
|
|
4193
4380
|
code: "BE_CORS_ALLOWLIST"
|
|
4194
4381
|
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 +4412,19 @@ rules:
|
|
|
4225
4412
|
editions: ["lite","full"]
|
|
4226
4413
|
docs:
|
|
4227
4414
|
- "docs/microservices.md#r262"
|
|
4415
|
+
proves:
|
|
4416
|
+
- {"path":"packages/eslint/be/health-ready.spec.mjs","editions":["lite","full"],"codes":["BE_READY_REAL","BE_HEALTH_SIGNALS"]}
|
|
4417
|
+
- {path: packages/hfs/src/be-docker-health.spec.mjs, editions: [lite, full], codes: [HFS_DOCKER_HEALTHCHECK_FAKE]}
|
|
4228
4418
|
exemplifiedBy:
|
|
4229
4419
|
- {"path":"packages/hfs/templates/be/skeleton/src/features/api/system-health/transport/http/ready.controller.ts","editions":["lite","full"]}
|
|
4230
4420
|
- {"path":"packages/hfs/templates/be/skeleton/src/modules/platform/http-security/readiness.service.ts","editions":["lite","full"]}
|
|
4231
4421
|
- {"path":"packages/hfs/templates/be/image/api/Dockerfile","editions":["lite","full"]}
|
|
4232
4422
|
- {"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"]}
|
|
4423
|
+
- {path: packages/hfs/src/be-docker-health.spec.mjs, editions: [lite, full], codes: [HFS_DOCKER_HEALTHCHECK_FAKE]}
|
|
4235
4424
|
witness:
|
|
4236
4425
|
- {"path":"packages/eslint/be/health-ready.spec.mjs","editions":["lite","full"],"codes":["BE_READY_REAL","BE_HEALTH_SIGNALS"]}
|
|
4237
4426
|
|
|
4238
|
-
|
|
4427
|
+
- {path: packages/hfs/src/be-docker-health.spec.mjs, editions: [lite, full], codes: [HFS_DOCKER_HEALTHCHECK_FAKE]}
|
|
4239
4428
|
- id: R263
|
|
4240
4429
|
code: "BE_WEBHOOK_SCOPE"
|
|
4241
4430
|
amendedBy: [owner:oauth-redirect-not-webhook, owner:webhook-receipt-port]
|
|
@@ -4320,13 +4509,16 @@ rules:
|
|
|
4320
4509
|
codeEditions: {"STACKS_REALTIME_SCALED":["lite"]}
|
|
4321
4510
|
docs:
|
|
4322
4511
|
- "docs/application-stacks.md#r266"
|
|
4512
|
+
proves:
|
|
4513
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4514
|
+
- {path: packages/hfs/src/hfs-stacks-ingress.spec.mjs}
|
|
4515
|
+
- {path: packages/hfs/src/hfs-stacks-swarm.spec.mjs, editions: [lite, full]}
|
|
4323
4516
|
exemplifiedBy:
|
|
4324
4517
|
- {"path":"packages/hfs/templates/app/skeleton-lite/.starcistacks","edition":"lite"}
|
|
4325
4518
|
- {"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"
|
|
4519
|
+
- {path: packages/hfs/src/hfs-stacks-swarm.spec.mjs, editions: [lite, full]}
|
|
4520
|
+
witness:
|
|
4521
|
+
- {path: packages/hfs/src/hfs-stacks-swarm.spec.mjs, editions: [lite, full]}
|
|
4330
4522
|
- id: R267
|
|
4331
4523
|
code: "STACKS_RELEASE_UNDECLARED"
|
|
4332
4524
|
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 +4530,17 @@ rules:
|
|
|
4338
4530
|
editions: ["lite","full"]
|
|
4339
4531
|
docs:
|
|
4340
4532
|
- "docs/application-stacks.md#r267"
|
|
4533
|
+
proves:
|
|
4534
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4535
|
+
- packages/hfs/src/hfs-stacks-release.spec.mjs
|
|
4341
4536
|
exemplifiedBy:
|
|
4342
4537
|
- {"path":"packages/hfs/templates/app/skeleton-lite/.starcistacks","edition":"lite"}
|
|
4343
4538
|
- {"path":"packages/hfs/templates/app/skeleton/.starcistacks","edition":"full"}
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
witness:
|
|
4347
|
-
|
|
4539
|
+
- {path: packages/hfs/src/hfs-stacks-release.spec.mjs, edition: lite}
|
|
4540
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4541
|
+
witness:
|
|
4542
|
+
- {path: packages/hfs/src/hfs-stacks-release.spec.mjs, edition: lite}
|
|
4543
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4348
4544
|
- id: R268
|
|
4349
4545
|
code: "HFS_SCHEDULE_UNDECLARED"
|
|
4350
4546
|
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 +4552,17 @@ rules:
|
|
|
4356
4552
|
editions: ["lite","full"]
|
|
4357
4553
|
docs:
|
|
4358
4554
|
- "docs/application-stacks.md#r268"
|
|
4555
|
+
proves:
|
|
4556
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4557
|
+
- packages/hfs/src/hfs-stacks-release.spec.mjs
|
|
4359
4558
|
exemplifiedBy:
|
|
4360
4559
|
- {"path":"packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml","edition":"lite"}
|
|
4361
4560
|
- {"path":"packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml","edition":"full"}
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
witness:
|
|
4365
|
-
|
|
4561
|
+
- {path: packages/hfs/src/hfs-stacks-release.spec.mjs, edition: lite}
|
|
4562
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4563
|
+
witness:
|
|
4564
|
+
- {path: packages/hfs/src/hfs-stacks-release.spec.mjs, edition: lite}
|
|
4565
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4366
4566
|
- id: R269
|
|
4367
4567
|
code: "HFS_DEPENDABOT_MISSING"
|
|
4368
4568
|
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 +4574,8 @@ rules:
|
|
|
4374
4574
|
editions: ["lite","full"]
|
|
4375
4575
|
docs:
|
|
4376
4576
|
- "docs/application-stacks.md#r269"
|
|
4577
|
+
proves:
|
|
4578
|
+
- {path: packages/hfs/src/hfs-supply-chain.spec.mjs, editions: [lite, full]}
|
|
4377
4579
|
exemplifiedBy:
|
|
4378
4580
|
- {"path":"packages/hfs/templates/app/skeleton-lite/.github/dependabot.yml","edition":"lite"}
|
|
4379
4581
|
- {"path":"packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml","edition":"lite"}
|
|
@@ -4381,10 +4583,11 @@ rules:
|
|
|
4381
4583
|
- {"path":"packages/hfs/templates/app/skeleton/.github/dependabot.yml","edition":"full"}
|
|
4382
4584
|
- {"path":"packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml","edition":"full"}
|
|
4383
4585
|
- {"path":"packages/hfs/templates/app/ci-workflows/github/workflows/images.yml","edition":"full"}
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
witness:
|
|
4387
|
-
|
|
4586
|
+
- {path: packages/hfs/src/hfs-supply-chain.spec.mjs, edition: lite}
|
|
4587
|
+
- {path: packages/hfs/src/hfs-supply-chain.spec.mjs, edition: full}
|
|
4588
|
+
witness:
|
|
4589
|
+
- {path: packages/hfs/src/hfs-supply-chain.spec.mjs, edition: lite}
|
|
4590
|
+
- {path: packages/hfs/src/hfs-supply-chain.spec.mjs, edition: full}
|
|
4388
4591
|
- id: R270
|
|
4389
4592
|
code: "HFS_DOC_PATH_MISSING"
|
|
4390
4593
|
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 +4599,16 @@ rules:
|
|
|
4396
4599
|
editions: ["lite","full"]
|
|
4397
4600
|
docs:
|
|
4398
4601
|
- "docs/quality-bar.md#r270"
|
|
4602
|
+
proves:
|
|
4603
|
+
- {path: packages/hfs/src/hfs-doc-fresh.spec.mjs, editions: [lite, full]}
|
|
4399
4604
|
exemplifiedBy:
|
|
4400
4605
|
- {"path":"packages/hfs/templates/app/skeleton-lite/README.md","edition":"lite"}
|
|
4401
4606
|
- {"path":"packages/hfs/templates/app/skeleton/README.md","edition":"full"}
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4607
|
+
- {path: packages/hfs/src/hfs-doc-fresh.spec.mjs, edition: lite}
|
|
4608
|
+
- {path: packages/hfs/src/hfs-doc-fresh.spec.mjs, edition: full}
|
|
4609
|
+
witness:
|
|
4610
|
+
- {path: packages/hfs/src/hfs-doc-fresh.spec.mjs, edition: lite}
|
|
4611
|
+
- {path: packages/hfs/src/hfs-doc-fresh.spec.mjs, edition: full}
|
|
4405
4612
|
- id: R271
|
|
4406
4613
|
code: "HFS_RELEASE_TAG_MISMATCH"
|
|
4407
4614
|
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 +4620,17 @@ rules:
|
|
|
4413
4620
|
editions: ["lite","full"]
|
|
4414
4621
|
docs:
|
|
4415
4622
|
- "docs/application-stacks.md#r271"
|
|
4623
|
+
proves:
|
|
4624
|
+
- {path: packages/hfs/src/hfs-release-provenance.spec.mjs, editions: [lite, full]}
|
|
4416
4625
|
exemplifiedBy:
|
|
4417
4626
|
- {"path":"packages/hfs/templates/app/ci-workflows-lite/github/workflows/images.yml","edition":"lite"}
|
|
4418
4627
|
- {"path":"packages/hfs/templates/app/ci-workflows/github/workflows/images.yml","edition":"full"}
|
|
4419
4628
|
- {"path":"packages/hfs/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml","edition":"lite"}
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
witness:
|
|
4423
|
-
|
|
4629
|
+
- {path: packages/hfs/src/hfs-release-provenance.spec.mjs, edition: lite}
|
|
4630
|
+
- {path: packages/hfs/src/hfs-release-provenance.spec.mjs, edition: full}
|
|
4631
|
+
witness:
|
|
4632
|
+
- {path: packages/hfs/src/hfs-release-provenance.spec.mjs, edition: lite}
|
|
4633
|
+
- {path: packages/hfs/src/hfs-release-provenance.spec.mjs, edition: full}
|
|
4424
4634
|
- id: R272
|
|
4425
4635
|
code: "BE_APP_BOOT_PROOF_MISSING"
|
|
4426
4636
|
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 +4643,14 @@ rules:
|
|
|
4433
4643
|
editionWhy: "ruling:R272 requires the lite Nest wiring proof; full retains its existing e2e boot proof and the boot-proof finder skips full."
|
|
4434
4644
|
docs:
|
|
4435
4645
|
- "docs/quality-bar.md#r272"
|
|
4646
|
+
proves:
|
|
4647
|
+
- {path: packages/hfs/src/hfs-boot-proof.spec.mjs, editions: [lite]}
|
|
4436
4648
|
exemplifiedBy:
|
|
4437
4649
|
- {"path":"packages/hfs/templates/be/skeleton-lite/src/tests/fixtures/builders/api.builder.ts","edition":"lite"}
|
|
4438
4650
|
- {"path":"examples/lite-app/be/src/tests/fixtures/builders/api.builder.ts","edition":"lite"}
|
|
4439
|
-
|
|
4440
|
-
witness:
|
|
4441
|
-
|
|
4651
|
+
- {path: packages/hfs/src/hfs-boot-proof.spec.mjs, edition: lite}
|
|
4652
|
+
witness:
|
|
4653
|
+
- {path: packages/hfs/src/hfs-boot-proof.spec.mjs, edition: lite}
|
|
4442
4654
|
- id: R273
|
|
4443
4655
|
code: "HFS_COVERAGE_BELOW"
|
|
4444
4656
|
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 +4662,18 @@ rules:
|
|
|
4450
4662
|
editions: ["lite","full"]
|
|
4451
4663
|
docs:
|
|
4452
4664
|
- "docs/quality-bar.md#r273"
|
|
4665
|
+
proves:
|
|
4666
|
+
- {path: packages/hfs/src/hfs-coverage-below.spec.mjs, editions: [lite, full]}
|
|
4453
4667
|
exemplifiedBy:
|
|
4454
4668
|
- {"path":"packages/hfs/templates/be/tool-config/jest.config.js","editions":["lite","full"]}
|
|
4455
4669
|
- {"path":"examples/lite-app/be/jest.config.js","edition":"lite"}
|
|
4456
4670
|
- {"path":"examples/full-app/be/jest.config.js","edition":"full"}
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4671
|
+
- {path: packages/hfs/src/hfs-coverage-below.spec.mjs, edition: lite}
|
|
4672
|
+
- {path: packages/hfs/src/hfs-coverage-below.spec.mjs, edition: full}
|
|
4673
|
+
- {path: examples/ecommerce-app/be/jest.config.js, edition: full}
|
|
4674
|
+
witness:
|
|
4675
|
+
- {path: packages/hfs/src/hfs-coverage-below.spec.mjs, edition: lite}
|
|
4676
|
+
- {path: packages/hfs/src/hfs-coverage-below.spec.mjs, edition: full}
|
|
4460
4677
|
- id: R274
|
|
4461
4678
|
code: "RT_RULING_STALE_CITE"
|
|
4462
4679
|
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 +4687,6 @@ rules:
|
|
|
4470
4687
|
templateNa: "Runtime owner-ruling citation metadata has no product scaffold surface; passing and stale authored-source fixtures live in the ruling-cites spec."
|
|
4471
4688
|
docs:
|
|
4472
4689
|
- "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
4690
|
- id: R275
|
|
4478
4691
|
code: "STACKS_INGRESS_UNDECLARED"
|
|
4479
4692
|
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 +4698,17 @@ rules:
|
|
|
4485
4698
|
editions: ["lite","full"]
|
|
4486
4699
|
docs:
|
|
4487
4700
|
- "docs/application-stacks.md#r275"
|
|
4701
|
+
proves:
|
|
4702
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4703
|
+
- packages/hfs/src/hfs-stacks-ingress.spec.mjs
|
|
4488
4704
|
exemplifiedBy:
|
|
4489
4705
|
- {"path":"packages/hfs/templates/app/skeleton-lite/.starcistacks","edition":"lite"}
|
|
4490
4706
|
- {"path":"packages/hfs/templates/app/skeleton/.starcistacks","edition":"full"}
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
witness:
|
|
4494
|
-
|
|
4707
|
+
- {path: packages/hfs/src/hfs-stacks-ingress.spec.mjs, edition: lite}
|
|
4708
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4709
|
+
witness:
|
|
4710
|
+
- {path: packages/hfs/src/hfs-stacks-ingress.spec.mjs, edition: lite}
|
|
4711
|
+
- {path: packages/hfs/src/hfs-stacks-full-fixtures.spec.mjs, edition: full}
|
|
4495
4712
|
- id: R276
|
|
4496
4713
|
code: "STACKS_LITE_SELFHOSTED_DB"
|
|
4497
4714
|
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 +4721,12 @@ rules:
|
|
|
4504
4721
|
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
4722
|
docs:
|
|
4506
4723
|
- "docs/application-stacks.md#r276"
|
|
4724
|
+
proves: [packages/hfs/src/hfs-stacks-lite-backing.spec.mjs]
|
|
4507
4725
|
exemplifiedBy:
|
|
4508
4726
|
- {"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"
|
|
4727
|
+
- {path: packages/hfs/src/hfs-stacks-lite-backing.spec.mjs, edition: lite}
|
|
4728
|
+
witness:
|
|
4729
|
+
- {path: packages/hfs/src/hfs-stacks-lite-backing.spec.mjs, edition: lite}
|
|
4513
4730
|
- id: R277
|
|
4514
4731
|
code: "HFS_SECRET_PLAINTEXT_FILE"
|
|
4515
4732
|
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 +4739,15 @@ rules:
|
|
|
4522
4739
|
codeEditions: {HFS_SECRET_OUTSIDE_ENC: [full]}
|
|
4523
4740
|
docs: [docs/host-secrets.md#r277]
|
|
4524
4741
|
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
|
-
|
|
4742
|
+
proves:
|
|
4743
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [lite, full], codes: [HFS_SECRET_PLAINTEXT_FILE]}
|
|
4744
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [full], codes: [HFS_SECRET_OUTSIDE_ENC]}
|
|
4745
|
+
exemplifiedBy:
|
|
4746
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [lite, full], codes: [HFS_SECRET_PLAINTEXT_FILE]}
|
|
4747
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [full], codes: [HFS_SECRET_OUTSIDE_ENC]}
|
|
4748
|
+
witness:
|
|
4749
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [lite, full], codes: [HFS_SECRET_PLAINTEXT_FILE]}
|
|
4750
|
+
- {path: packages/hfs/src/hfs-secret-custody.spec.mjs, editions: [full], codes: [HFS_SECRET_OUTSIDE_ENC]}
|
|
4529
4751
|
- id: R278
|
|
4530
4752
|
code: "BE_REST_DOOR_EVIDENCE"
|
|
4531
4753
|
amendedBy: [owner:credential-guarded-rest-door]
|
|
@@ -4581,10 +4803,11 @@ rules:
|
|
|
4581
4803
|
exemplifiedBy:
|
|
4582
4804
|
- {path: packages/hfs/templates/be/skeleton/src/modules/domain/identity/errors/identity.error.ts, editions: [lite, full]}
|
|
4583
4805
|
- {path: packages/hfs/templates/be/skeleton/src/modules/domain/identity/admission.policy.ts, editions: [lite, full]}
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4806
|
+
- {path: packages/hfs/src/hfs-unused-symbol-ledger.spec.mjs, editions: [lite, full], codes: [HFS_UNUSED_SYMBOL]}
|
|
4807
|
+
proves:
|
|
4808
|
+
- {path: packages/hfs/src/hfs-unused-symbol-ledger.spec.mjs, editions: [lite, full], codes: [HFS_UNUSED_SYMBOL]}
|
|
4809
|
+
witness:
|
|
4810
|
+
- {path: packages/hfs/src/hfs-unused-symbol-ledger.spec.mjs, editions: [lite, full], codes: [HFS_UNUSED_SYMBOL]}
|
|
4588
4811
|
- id: R281
|
|
4589
4812
|
code: "BE_SPEC_FORM_ALL_ROLES"
|
|
4590
4813
|
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 +4843,12 @@ rules:
|
|
|
4620
4843
|
editions: [lite, full]
|
|
4621
4844
|
docs: [docs/quality-bar.md#r282]
|
|
4622
4845
|
templateNa: "Build assets are supplied by each application; the scaffolder does not generate binary assets, model weights or datasets."
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4846
|
+
proves:
|
|
4847
|
+
- {path: packages/hfs/src/hfs-assets.spec.mjs, editions: [lite, full], codes: [HFS_ASSET_OVERSIZE, HFS_ASSET_KIND]}
|
|
4848
|
+
exemplifiedBy:
|
|
4849
|
+
- {path: packages/hfs/src/hfs-assets.spec.mjs, editions: [lite, full], codes: [HFS_ASSET_OVERSIZE, HFS_ASSET_KIND]}
|
|
4850
|
+
witness:
|
|
4851
|
+
- {path: packages/hfs/src/hfs-assets.spec.mjs, editions: [lite, full], codes: [HFS_ASSET_OVERSIZE, HFS_ASSET_KIND]}
|
|
4627
4852
|
- id: R283
|
|
4628
4853
|
code: "HFS_APP_LEXICON"
|
|
4629
4854
|
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 +4860,12 @@ rules:
|
|
|
4635
4860
|
editions: [lite, full]
|
|
4636
4861
|
docs: [docs/quality-bar.md#r283]
|
|
4637
4862
|
templateNa: "Removed product vocabulary is application-specific hfs.json content; there is no canonical product lexicon to scaffold."
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4863
|
+
proves:
|
|
4864
|
+
- {path: packages/hfs/src/hfs-lexicon.spec.mjs, editions: [lite, full], codes: [HFS_APP_LEXICON]}
|
|
4865
|
+
exemplifiedBy:
|
|
4866
|
+
- {path: packages/hfs/src/hfs-lexicon.spec.mjs, editions: [lite, full], codes: [HFS_APP_LEXICON]}
|
|
4867
|
+
witness:
|
|
4868
|
+
- {path: packages/hfs/src/hfs-lexicon.spec.mjs, editions: [lite, full], codes: [HFS_APP_LEXICON]}
|
|
4642
4869
|
- id: R284
|
|
4643
4870
|
code: "BE_LITE_PROOF_LANE_MISSING"
|
|
4644
4871
|
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 +4878,12 @@ rules:
|
|
|
4651
4878
|
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
4879
|
docs: [docs/quality-bar.md#r284]
|
|
4653
4880
|
templateNa: "Integration scenarios depend on the application patterns and providers; no universal runnable scenario lane is scaffolded."
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4881
|
+
proves:
|
|
4882
|
+
- {path: packages/hfs/src/hfs-lite-proof-lane.spec.mjs, editions: [lite], codes: [BE_LITE_PROOF_LANE_MISSING]}
|
|
4883
|
+
exemplifiedBy:
|
|
4884
|
+
- {path: packages/hfs/src/hfs-lite-proof-lane.spec.mjs, editions: [lite], codes: [BE_LITE_PROOF_LANE_MISSING]}
|
|
4885
|
+
witness:
|
|
4886
|
+
- {path: packages/hfs/src/hfs-lite-proof-lane.spec.mjs, editions: [lite], codes: [BE_LITE_PROOF_LANE_MISSING]}
|
|
4658
4887
|
- id: R285
|
|
4659
4888
|
code: "FE_SWR_OUTSIDE_FAMILY"
|
|
4660
4889
|
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 +4957,13 @@ rules:
|
|
|
4728
4957
|
- {kind: hfs, id: fe-stack-allowlist, at: scripts/hfs/rules/fe-stack.mjs}
|
|
4729
4958
|
editions: [lite, full]
|
|
4730
4959
|
docs: [docs/quality-bar.md#r288]
|
|
4960
|
+
proves:
|
|
4961
|
+
- {path: packages/hfs/src/hfs-fe-stack.spec.mjs, editions: [lite, full], codes: [FE_STACK_UNLISTED, FE_STACK_CORE_MISSING]}
|
|
4731
4962
|
exemplifiedBy:
|
|
4732
4963
|
- {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"
|
|
4964
|
+
- {path: packages/hfs/src/hfs-fe-stack.spec.mjs, editions: [lite, full], codes: [FE_STACK_UNLISTED, FE_STACK_CORE_MISSING]}
|
|
4965
|
+
witness:
|
|
4966
|
+
- {path: packages/hfs/src/hfs-fe-stack.spec.mjs, editions: [lite, full], codes: [FE_STACK_UNLISTED, FE_STACK_CORE_MISSING]}
|
|
4737
4967
|
- id: R289
|
|
4738
4968
|
code: "BE_APP_ENV_REQUIRED"
|
|
4739
4969
|
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 +4976,20 @@ rules:
|
|
|
4746
4976
|
- {kind: eslint-be, id: app-module-list-inline}
|
|
4747
4977
|
editions: [lite, full]
|
|
4748
4978
|
docs: [docs/microservices.md#r289]
|
|
4979
|
+
proves:
|
|
4980
|
+
- {path: packages/eslint/be/app-composition.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED, BE_APP_MODULE_LIST_INLINE]}
|
|
4981
|
+
- {path: packages/hfs/src/hfs-app-env-required.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED]}
|
|
4749
4982
|
exemplifiedBy:
|
|
4750
4983
|
- {path: packages/eslint/be/app-composition.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED, BE_APP_MODULE_LIST_INLINE]}
|
|
4751
4984
|
- {path: packages/hfs/templates/be/skeleton/apps/__app__/src/__app__.env.ts, editions: [full]}
|
|
4752
4985
|
- {path: packages/hfs/templates/be/skeleton/apps/__app__/src/app.module.ts, editions: [full]}
|
|
4753
4986
|
- {path: packages/hfs/templates/be/skeleton-lite/apps/api/src/api.env.ts, editions: [lite]}
|
|
4754
4987
|
- {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]}
|
|
4988
|
+
- {path: packages/hfs/src/hfs-app-env-required.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED]}
|
|
4757
4989
|
witness:
|
|
4758
4990
|
- {path: packages/eslint/be/app-composition.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED, BE_APP_MODULE_LIST_INLINE]}
|
|
4759
4991
|
|
|
4760
|
-
|
|
4992
|
+
- {path: packages/hfs/src/hfs-app-env-required.spec.mjs, editions: [lite, full], codes: [BE_APP_ENV_REQUIRED]}
|
|
4761
4993
|
- id: R290
|
|
4762
4994
|
code: "BE_PUBLIC_REASON_CLOSED"
|
|
4763
4995
|
amendedBy: [owner:credential-guarded-rest-door]
|
|
@@ -4812,13 +5044,16 @@ rules:
|
|
|
4812
5044
|
- {kind: hfs, id: feature-files, at: scripts/hfs/rules/feature-files.mjs}
|
|
4813
5045
|
editions: [lite, full]
|
|
4814
5046
|
docs: [docs/quality-bar.md#r292]
|
|
5047
|
+
proves:
|
|
5048
|
+
- {path: packages/hfs/src/hfs-feature-files.spec.mjs, editions: [lite, full], codes: [HFS_FEATURE_FILE_BUDGET]}
|
|
4815
5049
|
exemplifiedBy:
|
|
4816
5050
|
- {path: packages/hfs/templates/be/patterns/api, editions: [lite, full]}
|
|
4817
5051
|
- {path: examples/lite-app/be/src/features/api/bookings, editions: [lite]}
|
|
4818
5052
|
- {path: examples/full-app/be/src/features/api/checkout, editions: [full]}
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
witness:
|
|
5053
|
+
- {path: packages/hfs/src/hfs-feature-files.spec.mjs, editions: [lite, full], codes: [HFS_FEATURE_FILE_BUDGET]}
|
|
5054
|
+
- {path: examples/ecommerce-app/be/src/features/api/checkout, editions: [full]}
|
|
5055
|
+
witness:
|
|
5056
|
+
- {path: packages/hfs/src/hfs-feature-files.spec.mjs, editions: [lite, full], codes: [HFS_FEATURE_FILE_BUDGET]}
|
|
4822
5057
|
- id: R293
|
|
4823
5058
|
code: "STACK_TOOLING_REIMPLEMENTED"
|
|
4824
5059
|
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 +5065,14 @@ rules:
|
|
|
4830
5065
|
editions: [lite, full]
|
|
4831
5066
|
docs:
|
|
4832
5067
|
- {path: docs/application-stacks.md#r293, editions: [lite, full]}
|
|
5068
|
+
proves:
|
|
5069
|
+
- {path: packages/hfs/src/hfs-stack-tooling.spec.mjs, editions: [lite, full]}
|
|
4833
5070
|
exemplifiedBy:
|
|
4834
5071
|
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/stack-deploy.yml, edition: lite}
|
|
4835
5072
|
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/stack-deploy.yml, edition: full}
|
|
4836
5073
|
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
4837
5074
|
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4838
5075
|
- {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
5076
|
- id: R294
|
|
4843
5077
|
code: "STACKS_DEPLOY_CONFIG_INVALID"
|
|
4844
5078
|
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 +5085,14 @@ rules:
|
|
|
4851
5085
|
docs:
|
|
4852
5086
|
- {path: docs/application-stacks.md#r294, editions: [lite, full]}
|
|
4853
5087
|
- {path: docs/application-stacks.md#r294-edge, editions: [lite, full]}
|
|
5088
|
+
proves:
|
|
5089
|
+
- {path: packages/hfs/src/hfs-stacks-deploy.spec.mjs, editions: [lite, full]}
|
|
4854
5090
|
exemplifiedBy:
|
|
4855
5091
|
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks, edition: lite}
|
|
4856
5092
|
- {path: packages/hfs/templates/app/skeleton/.starcistacks, edition: full}
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
5093
|
+
- {path: packages/hfs/src/hfs-stacks-deploy.spec.mjs, editions: [lite, full]}
|
|
5094
|
+
witness:
|
|
5095
|
+
- {path: packages/hfs/src/hfs-stacks-deploy.spec.mjs, editions: [lite, full]}
|
|
4860
5096
|
- id: R295
|
|
4861
5097
|
code: "BE_MODULE_DEFINITION_MISSING"
|
|
4862
5098
|
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 +5135,11 @@ rules:
|
|
|
4899
5135
|
- {path: examples/shape-slot/.starcistacks/application-stacks.yaml, edition: full}
|
|
4900
5136
|
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
4901
5137
|
- {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
|
|
4902
|
-
|
|
4903
|
-
|
|
5138
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [CI_SECRET_SEALED]}
|
|
5139
|
+
proves:
|
|
5140
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [CI_SECRET_SEALED]}
|
|
5141
|
+
witness:
|
|
5142
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [CI_SECRET_SEALED]}
|
|
4904
5143
|
- id: R297
|
|
4905
5144
|
code: "APP_SECRET_IN_CI"
|
|
4906
5145
|
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 +5157,11 @@ rules:
|
|
|
4918
5157
|
- {path: examples/shape-slot/.starcistacks/application-stacks.yaml, edition: full}
|
|
4919
5158
|
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
4920
5159
|
- {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
|
|
4921
|
-
|
|
4922
|
-
|
|
5160
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [APP_SECRET_IN_CI]}
|
|
5161
|
+
proves:
|
|
5162
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [APP_SECRET_IN_CI]}
|
|
5163
|
+
witness:
|
|
5164
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [APP_SECRET_IN_CI]}
|
|
4923
5165
|
- id: R298
|
|
4924
5166
|
code: "CI_DECLARATION_DRIFT"
|
|
4925
5167
|
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 +5179,11 @@ rules:
|
|
|
4937
5179
|
- {path: examples/shape-slot/.starcistacks/application-stacks.yaml, edition: full}
|
|
4938
5180
|
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml, edition: lite}
|
|
4939
5181
|
- {path: packages/hfs/templates/app/skeleton/.starcistacks/application-stacks.yaml, edition: full}
|
|
4940
|
-
|
|
4941
|
-
|
|
5182
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [CI_DECLARATION_DRIFT]}
|
|
5183
|
+
proves:
|
|
5184
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [CI_DECLARATION_DRIFT]}
|
|
5185
|
+
witness:
|
|
5186
|
+
- {path: packages/hfs/src/ci-custody.spec.mjs, editions: [lite, full], codes: [CI_DECLARATION_DRIFT]}
|
|
4942
5187
|
- id: R299
|
|
4943
5188
|
code: "HFS_WORKFLOW_CONTEXT"
|
|
4944
5189
|
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 +5198,11 @@ rules:
|
|
|
4953
5198
|
exemplifiedBy:
|
|
4954
5199
|
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks, edition: lite}
|
|
4955
5200
|
- {path: packages/hfs/templates/app/skeleton/.starcistacks, edition: full}
|
|
4956
|
-
|
|
4957
|
-
|
|
5201
|
+
- {path: packages/hfs/src/workflow-contexts.spec.mjs, editions: [lite, full], codes: [HFS_WORKFLOW_CONTEXT]}
|
|
5202
|
+
proves:
|
|
5203
|
+
- {path: packages/hfs/src/workflow-contexts.spec.mjs, editions: [lite, full], codes: [HFS_WORKFLOW_CONTEXT]}
|
|
5204
|
+
witness:
|
|
5205
|
+
- {path: packages/hfs/src/workflow-contexts.spec.mjs, editions: [lite, full], codes: [HFS_WORKFLOW_CONTEXT]}
|
|
4958
5206
|
- id: R300
|
|
4959
5207
|
code: "FE_PUBLIC_BUILD_ARG_MISSING"
|
|
4960
5208
|
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 +5217,11 @@ rules:
|
|
|
4969
5217
|
exemplifiedBy:
|
|
4970
5218
|
- {path: packages/hfs/templates/app/skeleton-lite/.starcistacks, edition: lite}
|
|
4971
5219
|
- {path: packages/hfs/templates/app/skeleton/.starcistacks, edition: full}
|
|
4972
|
-
|
|
4973
|
-
|
|
5220
|
+
- {path: packages/hfs/src/fe-build-args.spec.mjs, editions: [lite, full], codes: [FE_PUBLIC_BUILD_ARG_MISSING]}
|
|
5221
|
+
proves:
|
|
5222
|
+
- {path: packages/hfs/src/fe-build-args.spec.mjs, editions: [lite, full], codes: [FE_PUBLIC_BUILD_ARG_MISSING]}
|
|
5223
|
+
witness:
|
|
5224
|
+
- {path: packages/hfs/src/fe-build-args.spec.mjs, editions: [lite, full], codes: [FE_PUBLIC_BUILD_ARG_MISSING]}
|
|
4974
5225
|
- id: R301
|
|
4975
5226
|
code: "CI_STANDARD"
|
|
4976
5227
|
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 +5237,11 @@ rules:
|
|
|
4986
5237
|
exemplifiedBy:
|
|
4987
5238
|
- {path: packages/hfs/templates/app/ci-workflows-lite/github/workflows/ci.yml, edition: lite}
|
|
4988
5239
|
- {path: packages/hfs/templates/app/ci-workflows/github/workflows/ci.yml, edition: full}
|
|
4989
|
-
|
|
4990
|
-
|
|
5240
|
+
- {path: packages/hfs/src/ci-standard.spec.mjs, editions: [lite, full], codes: [CI_STANDARD]}
|
|
5241
|
+
proves:
|
|
5242
|
+
- {path: packages/hfs/src/ci-standard.spec.mjs, editions: [lite, full], codes: [CI_STANDARD]}
|
|
5243
|
+
witness:
|
|
5244
|
+
- {path: packages/hfs/src/ci-standard.spec.mjs, editions: [lite, full], codes: [CI_STANDARD]}
|
|
4991
5245
|
- id: R302
|
|
4992
5246
|
code: "HFS_MCP_TOOLS_SNAPSHOT"
|
|
4993
5247
|
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 +5254,28 @@ rules:
|
|
|
5000
5254
|
docs:
|
|
5001
5255
|
- {path: docs/hfs-contract-snapshots.md#r302, editions: [lite, full]}
|
|
5002
5256
|
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
|
-
|
|
5257
|
+
proves:
|
|
5258
|
+
- {path: packages/hfs/src/mcp-tools-snapshot.spec.mjs, editions: [lite, full], codes: [HFS_MCP_TOOLS_SNAPSHOT]}
|
|
5259
|
+
exemplifiedBy:
|
|
5260
|
+
- {path: packages/hfs/src/mcp-tools-snapshot.spec.mjs, editions: [lite, full], codes: [HFS_MCP_TOOLS_SNAPSHOT]}
|
|
5261
|
+
witness:
|
|
5262
|
+
- {path: packages/hfs/src/mcp-tools-snapshot.spec.mjs, editions: [lite, full], codes: [HFS_MCP_TOOLS_SNAPSHOT]}
|
|
5263
|
+
- id: R303
|
|
5264
|
+
code: "HFS_BYPASS_MARKER"
|
|
5265
|
+
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."
|
|
5266
|
+
kinds: [check]
|
|
5267
|
+
gates: [pre-commit, land, ci]
|
|
5268
|
+
failureCodes: ["HFS_BYPASS_MARKER"]
|
|
5269
|
+
enforcers:
|
|
5270
|
+
- {kind: hfs, id: bypass-markers, at: scripts/hfs/rules/bypass-markers.mjs}
|
|
5271
|
+
- {kind: hfs, id: bypass-guard, at: packages/hfs/sync/hygiene.mjs}
|
|
5272
|
+
editions: [lite, full]
|
|
5273
|
+
docs:
|
|
5274
|
+
- {path: docs/hfs-authored-file-boundaries.md#r303, editions: [lite, full]}
|
|
5275
|
+
templateNa: "A bypass is prohibited, so no template scaffolds one."
|
|
5276
|
+
proves:
|
|
5277
|
+
- {path: packages/hfs/src/bypass-detector.spec.mjs, editions: [lite, full], codes: [HFS_BYPASS_MARKER]}
|
|
5278
|
+
exemplifiedBy:
|
|
5279
|
+
- {path: packages/hfs/src/bypass-detector.spec.mjs, editions: [lite, full], codes: [HFS_BYPASS_MARKER]}
|
|
5280
|
+
witness:
|
|
5281
|
+
- {path: packages/hfs/src/bypass-detector.spec.mjs, editions: [lite, full], codes: [HFS_BYPASS_MARKER]}
|