@starci/hfs 4.7.47 → 4.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +4 -9
- package/emit/operation-schemas.mjs +3 -0
- package/lint/bound-sys.cjs +2 -2
- package/package.json +11 -5
- package/runtime/engine/admission.mjs +1 -1
- package/runtime/engine/config.mjs +2 -2
- package/runtime/engine/db/machine.mjs +2 -3
- package/runtime/engine/invalid-config.mjs +1 -1
- package/runtime/knowledge/grammars/{starci → core}/playbook.yaml +3 -3
- package/runtime/knowledge/grammars/index.yaml +14 -23
- package/runtime/knowledge/grammars/offset-pop/playbook.yaml +2 -2
- package/runtime/knowledge/hfs/canon-pins.yaml +23 -23
- package/runtime/knowledge/hfs/fe-stack.yaml +1 -1
- package/runtime/knowledge/hfs/rules.yaml +83 -60
- package/runtime/modules/kernel/failure-codes.yaml +23 -13
- package/runtime/scripts/guards/git-policy.mjs +2 -3
- package/runtime/scripts/hfs/rule-catalog.mjs +2 -2
- package/runtime/scripts/hfs/rules/pipeline.mjs +5 -5
- package/runtime/scripts/lib/example-refs.mjs +10 -3
- package/runtime/scripts/lib/grammar-lint.mjs +16 -3
- package/runtime/scripts/lib/package-at.mjs +5 -6
- package/runtime/scripts/lib/roots.mjs +2 -2
- package/runtime/scripts/work/draw/draw-dna-findings.mjs +23 -12
- package/runtime/scripts/work/draw/draw-dna.mjs +14 -8
- package/scaffold/app.mjs +6 -6
- package/src/main.mjs +3 -3
- package/sync/hygiene.mjs +1 -1
- package/sync/index.mjs +15 -2
- package/sync/managed.mjs +3 -2
- package/templates/app/codegen-graphql.mjs.partial +4 -4
- package/templates/app/quality-config/sonar-project.properties +4 -2
- package/runtime/engine/canonical-json.mjs +0 -14
- package/runtime/engine/db/ledger-open.mjs +0 -38
- package/runtime/engine/db/ledger-paths.mjs +0 -87
- package/runtime/engine/db/ledger.mjs +0 -1068
- package/runtime/engine/db/provision-authority.mjs +0 -76
- package/runtime/engine/db/provision-operations.mjs +0 -146
- package/runtime/packages/grammar/scripts/build-stamp.mjs +0 -98
- package/runtime/scripts/agent/codex-app-server.mjs +0 -79
- package/runtime/scripts/agent/codex-mirror-source.mjs +0 -34
- package/runtime/scripts/agent/host-agents.mjs +0 -80
- package/runtime/scripts/agent/launch-trust-policy.mjs +0 -53
- package/runtime/scripts/agent/trust-launch.mjs +0 -191
- package/runtime/scripts/agent/trust.mjs +0 -523
- package/runtime/scripts/api/fs/temp-path.mjs +0 -8
- package/runtime/scripts/api/git/diff-names.mjs +0 -8
- package/runtime/scripts/api/git/head-time.mjs +0 -10
- package/runtime/scripts/api/git/index-lock.mjs +0 -78
- package/runtime/scripts/api/git/log.mjs +0 -5
- package/runtime/scripts/api/git/merge-tree.mjs +0 -5
- package/runtime/scripts/api/git/rev-list.mjs +0 -5
- package/runtime/scripts/api/git/rev-parse.mjs +0 -13
- package/runtime/scripts/api/git/status-query.mjs +0 -5
- package/runtime/scripts/api/git/worktree-list-query.mjs +0 -5
- package/runtime/scripts/api/node/spawn-node.mjs +0 -6
- package/runtime/scripts/api/npm/dist-tag.mjs +0 -8
- package/runtime/scripts/api/npm/lib.mjs +0 -32
- package/runtime/scripts/api/npm/pack-dry-run.mjs +0 -9
- package/runtime/scripts/api/npm/run-npm.mjs +0 -6
- package/runtime/scripts/api/npm/view.mjs +0 -30
- package/runtime/scripts/api/npm/whoami.mjs +0 -8
- package/runtime/scripts/api/process/hide-child-windows.mjs +0 -31
- package/runtime/scripts/api/process/kill-tree.mjs +0 -22
- package/runtime/scripts/api/process/lib.mjs +0 -125
- package/runtime/scripts/api/process/probe-guard-command.mjs +0 -74
- package/runtime/scripts/api/process/process-list.mjs +0 -28
- package/runtime/scripts/api/process/system-tool.mjs +0 -37
- package/runtime/scripts/gates/canon-digest.mjs +0 -81
- package/runtime/scripts/gates/canon-pins.mjs +0 -119
- package/runtime/scripts/gates/gate-input.mjs +0 -98
- package/runtime/scripts/gates/gate.mjs +0 -636
- package/runtime/scripts/gates/grammar-dist.mjs +0 -206
- package/runtime/scripts/gates/output.mjs +0 -40
- package/runtime/scripts/gates/runtime-package-selection.mjs +0 -27
- package/runtime/scripts/gates/test-world-run.mjs +0 -252
- package/runtime/scripts/gates/type-impact.mjs +0 -277
- package/runtime/scripts/gates/type-program.mjs +0 -113
- package/runtime/scripts/guards/assigned-command.mjs +0 -12
- package/runtime/scripts/guards/call-rights.mjs +0 -47
- package/runtime/scripts/guards/command-guard.mjs +0 -468
- package/runtime/scripts/guards/command-policy.mjs +0 -342
- package/runtime/scripts/guards/critic-reach.mjs +0 -82
- package/runtime/scripts/guards/deps-guard.mjs +0 -150
- package/runtime/scripts/guards/env-dump-verdict.mjs +0 -89
- package/runtime/scripts/guards/guards-root.mjs +0 -27
- package/runtime/scripts/guards/hook-install.mjs +0 -343
- package/runtime/scripts/guards/hook-verdict.mjs +0 -12
- package/runtime/scripts/guards/install-verdict.mjs +0 -41
- package/runtime/scripts/guards/kernel-seat.mjs +0 -63
- package/runtime/scripts/guards/launch-verdict.mjs +0 -74
- package/runtime/scripts/guards/op-starci.mjs +0 -16
- package/runtime/scripts/guards/op-write-scope.mjs +0 -27
- package/runtime/scripts/guards/orca-self-lifecycle.mjs +0 -39
- package/runtime/scripts/guards/process-kill-verdict.mjs +0 -106
- package/runtime/scripts/guards/protected-zone.mjs +0 -56
- package/runtime/scripts/guards/refusals.mjs +0 -27
- package/runtime/scripts/guards/rights.mjs +0 -268
- package/runtime/scripts/guards/seat-tools.mjs +0 -47
- package/runtime/scripts/guards/shell-commands.mjs +0 -328
- package/runtime/scripts/guards/supervisor-seat.mjs +0 -80
- package/runtime/scripts/guards/verdict-process.mjs +0 -81
- package/runtime/scripts/lib/app-data.mjs +0 -11
- package/runtime/scripts/lib/canon-binding-text.mjs +0 -129
- package/runtime/scripts/lib/check-format.mjs +0 -7
- package/runtime/scripts/lib/failure-code-reads.mjs +0 -100
- package/runtime/scripts/lib/failure-code-template-errors.mjs +0 -161
- package/runtime/scripts/lib/git-dir.mjs +0 -120
- package/runtime/scripts/lib/guard-command.mjs +0 -24
- package/runtime/scripts/lib/interrupt-cleanup.mjs +0 -38
- package/runtime/scripts/lib/json-formats.mjs +0 -34
- package/runtime/scripts/lib/managed-json.mjs +0 -51
- package/runtime/scripts/lib/menu-parts.mjs +0 -11
- package/runtime/scripts/lib/op-gate.mjs +0 -15
- package/runtime/scripts/lib/provision-control-failure.mjs +0 -32
- package/runtime/scripts/lib/release-version.mjs +0 -134
- package/runtime/scripts/lib/runtime-location.mjs +0 -21
- package/runtime/scripts/lib/runtime-package-inventory.mjs +0 -21
- package/runtime/scripts/lib/runtime-package-manifests.mjs +0 -84
- package/runtime/scripts/lib/runtime-publication-tags.mjs +0 -56
- package/runtime/scripts/lib/seat-env.mjs +0 -43
- package/runtime/scripts/lib/sonar-new-code.mjs +0 -58
- package/runtime/scripts/lib/source-package-imports.mjs +0 -111
- package/runtime/scripts/lib/tar-files.mjs +0 -39
- package/runtime/scripts/lib/uat-run-folder.mjs +0 -118
- package/runtime/scripts/lib/worktree-record.mjs +0 -14
- package/runtime/scripts/machine/ask-receipts.mjs +0 -113
- package/runtime/scripts/machine/evidence-store.mjs +0 -223
- package/runtime/scripts/machine/home.mjs +0 -216
- package/runtime/scripts/machine/host-lock.mjs +0 -184
- package/runtime/scripts/machine/lock-recovery.mjs +0 -55
- package/runtime/scripts/machine/roles-contract.mjs +0 -90
- package/runtime/scripts/machine/runtime-change.mjs +0 -20
- package/runtime/scripts/machine/workflow-tree.mjs +0 -122
- package/runtime/scripts/reconciler/checklist-items.mjs +0 -7
- package/runtime/scripts/reconciler/guard-row.mjs +0 -25
- package/runtime/scripts/work/brand/brand-colour.mjs +0 -125
- package/runtime/scripts/work/brand/brand-tokens.mjs +0 -167
- package/runtime/scripts/work/brand/brand-value-source.mjs +0 -106
- package/runtime/scripts/work/brand/brand.mjs +0 -892
- package/runtime/scripts/work/draw/draw-layer.mjs +0 -306
- package/runtime/scripts/work/draw/draw-rationale-page.mjs +0 -237
- package/runtime/scripts/work/draw/draw-rationale-ref.mjs +0 -14
- package/runtime/scripts/work/draw/draw-rationale.mjs +0 -353
- package/runtime/scripts/work/draw/draw-source.mjs +0 -412
- package/runtime/scripts/work/draw/draw-taste.mjs +0 -278
- package/runtime/scripts/work/draw/draw-typecheck.mjs +0 -72
- package/runtime/scripts/work/draw/rationale-findings.mjs +0 -205
- package/runtime/scripts/work/draw-grammar.mjs +0 -175
- package/runtime/scripts/work/draw-render-page.mjs +0 -188
- package/runtime/scripts/work/draw-render.mjs +0 -626
- package/runtime/scripts/work/png.mjs +0 -237
- package/runtime/scripts/work/render-tools.mjs +0 -64
|
@@ -29,7 +29,7 @@ gates:
|
|
|
29
29
|
enforcerKinds:
|
|
30
30
|
eslint-be: a rule of the plugin @starci/eslint-canon-be (id without the plugin prefix)
|
|
31
31
|
eslint-fe: a universal rule of @starci/eslint-canon-fe (id without the plugin prefix)
|
|
32
|
-
eslint-grammar-
|
|
32
|
+
eslint-grammar-core: a selected Grammar family rule sharing the common component API, resolved through the family canon binding (id without the plugin prefix; FE-RULE-OWNERSHIP)
|
|
33
33
|
stylelint: a rule of the @starci/stylelint-canon package
|
|
34
34
|
machine: a check of the architecture machine (scripts/hfs/architecture), which reads the import graph
|
|
35
35
|
hfs: a check of the hfs CLI that reads the repository tree, configuration, contracts or catalogs
|
|
@@ -1273,49 +1273,49 @@ rules:
|
|
|
1273
1273
|
- {kind: stylelint, id: breakpoint-scale}
|
|
1274
1274
|
- {kind: stylelint, id: source-resolves}
|
|
1275
1275
|
- {kind: eslint-fe, id: no-raw-brand-value}
|
|
1276
|
-
- {kind: eslint-grammar-
|
|
1276
|
+
- {kind: eslint-grammar-core, id: no-fractional-step}
|
|
1277
1277
|
- {kind: eslint-fe, id: no-arbitrary-value}
|
|
1278
|
-
- {kind: eslint-grammar-
|
|
1279
|
-
- {kind: eslint-grammar-
|
|
1280
|
-
- {kind: eslint-grammar-
|
|
1281
|
-
- {kind: eslint-grammar-
|
|
1278
|
+
- {kind: eslint-grammar-core, id: no-hand-rolled-heading}
|
|
1279
|
+
- {kind: eslint-grammar-core, id: no-unresolved-token-class}
|
|
1280
|
+
- {kind: eslint-grammar-core, id: no-heading-tag-outside-heading-component}
|
|
1281
|
+
- {kind: eslint-grammar-core, id: status-text-uses-soft-foreground}
|
|
1282
1282
|
proves:
|
|
1283
1283
|
- {path: packages/stylelint/source-resolves.spec.mjs, editions: [lite, full], codes: [FE_STYLE_SOURCE_UNRESOLVED]}
|
|
1284
1284
|
- {path: packages/eslint/fe/brand-values.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1285
1285
|
- {path: packages/eslint/fe/tokens.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1286
|
-
- {path: packages/eslint/grammar-
|
|
1287
|
-
- {path: packages/eslint/grammar-
|
|
1288
|
-
- {path: packages/eslint/grammar-
|
|
1286
|
+
- {path: packages/eslint/grammar-core/status-colors.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1287
|
+
- {path: packages/eslint/grammar-core/typography.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1288
|
+
- {path: packages/eslint/grammar-core/tokens.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1289
1289
|
exemplifiedBy:
|
|
1290
1290
|
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/app/globals.css, edition: lite}
|
|
1291
1291
|
- {path: packages/hfs/templates/fe/skeleton/apps/app/src/app/globals.css, edition: full}
|
|
1292
1292
|
- {path: packages/stylelint/source-resolves.spec.mjs, editions: [lite, full], codes: [FE_STYLE_SOURCE_UNRESOLVED]}
|
|
1293
1293
|
- {path: packages/eslint/fe/brand-values.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1294
1294
|
- {path: packages/eslint/fe/tokens.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1295
|
-
- {path: packages/eslint/grammar-
|
|
1296
|
-
- {path: packages/eslint/grammar-
|
|
1297
|
-
- {path: packages/eslint/grammar-
|
|
1295
|
+
- {path: packages/eslint/grammar-core/status-colors.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1296
|
+
- {path: packages/eslint/grammar-core/typography.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1297
|
+
- {path: packages/eslint/grammar-core/tokens.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1298
1298
|
witness:
|
|
1299
1299
|
- {path: packages/stylelint/source-resolves.spec.mjs, editions: [lite, full], codes: [FE_STYLE_SOURCE_UNRESOLVED]}
|
|
1300
1300
|
- {path: packages/eslint/fe/brand-values.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1301
1301
|
- {path: packages/eslint/fe/tokens.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1302
|
-
- {path: packages/eslint/grammar-
|
|
1303
|
-
- {path: packages/eslint/grammar-
|
|
1304
|
-
- {path: packages/eslint/grammar-
|
|
1302
|
+
- {path: packages/eslint/grammar-core/status-colors.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1303
|
+
- {path: packages/eslint/grammar-core/typography.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1304
|
+
- {path: packages/eslint/grammar-core/tokens.spec.mjs, editions: [lite, full], codes: [FE_STYLE_TOKEN_ONLY]}
|
|
1305
1305
|
- id: R62
|
|
1306
1306
|
code: "FE_NATIVE_FORM_CONTROL"
|
|
1307
1307
|
editions: [lite, full]
|
|
1308
1308
|
docs: [docs/architecture.md#r62, knowledge/patterns/fe/index.yaml#FE-RULE-OWNERSHIP]
|
|
1309
1309
|
proves:
|
|
1310
|
-
- {path: packages/eslint/grammar-
|
|
1310
|
+
- {path: packages/eslint/grammar-core/r62-structural-elements-coverage.spec.mjs, editions: [lite, full], codes: [FE_NATIVE_FORM_CONTROL]}
|
|
1311
1311
|
- {path: packages/eslint/fe/r62-native-controls-coverage.spec.mjs, editions: [lite, full]}
|
|
1312
1312
|
exemplifiedBy:
|
|
1313
|
-
- {path: packages/eslint/grammar-
|
|
1313
|
+
- {path: packages/eslint/grammar-core/r62-structural-elements-coverage.spec.mjs, editions: [lite, full], codes: [FE_NATIVE_FORM_CONTROL]}
|
|
1314
1314
|
- {path: packages/hfs/templates/fe/skeleton-lite/apps/web/src/features/pages/AppHomePage/component.tsx, edition: lite}
|
|
1315
1315
|
- {path: packages/hfs/templates/fe/skeleton/apps/__app__/src/components/blocks/SignInForm/component.tsx, edition: full}
|
|
1316
1316
|
- {path: packages/eslint/fe/r62-native-controls-coverage.spec.mjs, editions: [lite, full]}
|
|
1317
1317
|
witness:
|
|
1318
|
-
- {path: packages/eslint/grammar-
|
|
1318
|
+
- {path: packages/eslint/grammar-core/r62-structural-elements-coverage.spec.mjs, editions: [lite, full], codes: [FE_NATIVE_FORM_CONTROL]}
|
|
1319
1319
|
- {path: packages/eslint/fe/r62-native-controls-coverage.spec.mjs, edition: lite, codes: [FE_NATIVE_FORM_CONTROL, FE_NATIVE_IMAGE]}
|
|
1320
1320
|
- {path: packages/eslint/fe/r62-native-controls-coverage.spec.mjs, edition: full, codes: [FE_NATIVE_FORM_CONTROL, FE_NATIVE_IMAGE]}
|
|
1321
1321
|
law: "Product tiers compose the selected Grammar renderers for form controls, images and structural elements that the Grammar owns; they never reproduce those renderers with raw HTML."
|
|
@@ -1325,7 +1325,7 @@ rules:
|
|
|
1325
1325
|
enforcers:
|
|
1326
1326
|
- {kind: eslint-fe, id: no-native-form-control}
|
|
1327
1327
|
- {kind: eslint-fe, id: no-native-img}
|
|
1328
|
-
- {kind: eslint-grammar-
|
|
1328
|
+
- {kind: eslint-grammar-core, id: no-raw-structural-element}
|
|
1329
1329
|
- {kind: eslint-fe, id: image-has-size}
|
|
1330
1330
|
|
|
1331
1331
|
- id: R63
|
|
@@ -1878,7 +1878,7 @@ rules:
|
|
|
1878
1878
|
- {kind: eslint-fe, id: base-props-atom}
|
|
1879
1879
|
- {kind: eslint-fe, id: base-import-pair}
|
|
1880
1880
|
- {kind: eslint-fe, id: no-data-status-shape}
|
|
1881
|
-
- {kind: eslint-grammar-
|
|
1881
|
+
- {kind: eslint-grammar-core, id: slot-status-through-slotview}
|
|
1882
1882
|
- {kind: eslint-fe, id: presentational-purity}
|
|
1883
1883
|
- {kind: eslint-fe, id: connected-block-has-presentational-twin}
|
|
1884
1884
|
- {kind: eslint-fe, id: no-resting-twin-component}
|
|
@@ -1891,18 +1891,18 @@ rules:
|
|
|
1891
1891
|
editions: [lite, full]
|
|
1892
1892
|
docs: [docs/architecture.md#r92, knowledge/patterns/fe/index.yaml#FE-RULE-OWNERSHIP]
|
|
1893
1893
|
proves:
|
|
1894
|
-
- {path: packages/eslint/grammar-
|
|
1894
|
+
- {path: packages/eslint/grammar-core/r92-slot-status-coverage.spec.mjs, editions: [lite, full], codes: [FE_COMPONENT_API]}
|
|
1895
1895
|
- {path: packages/eslint/fe/r92-fetch-barrel.spec.mjs, editions: [lite, full]}
|
|
1896
1896
|
- {path: packages/eslint/fe/r92-component-surface-coverage.spec.mjs, editions: [lite, full]}
|
|
1897
1897
|
- {path: packages/eslint/fe/r56-r92-graph-coverage.spec.mjs, editions: [lite, full]}
|
|
1898
1898
|
exemplifiedBy:
|
|
1899
|
-
- {path: packages/eslint/grammar-
|
|
1899
|
+
- {path: packages/eslint/grammar-core/r92-slot-status-coverage.spec.mjs, editions: [lite, full], codes: [FE_COMPONENT_API]}
|
|
1900
1900
|
- {path: packages/hfs/templates/fe/skeleton/apps/__app__/src/components/blocks/SignInForm/component.tsx, editions: [lite, full]}
|
|
1901
1901
|
- {path: packages/eslint/fe/r92-fetch-barrel.spec.mjs, editions: [lite, full]}
|
|
1902
1902
|
- {path: packages/eslint/fe/r92-component-surface-coverage.spec.mjs, editions: [lite, full]}
|
|
1903
1903
|
- {path: packages/eslint/fe/r56-r92-graph-coverage.spec.mjs, editions: [lite, full]}
|
|
1904
1904
|
witness:
|
|
1905
|
-
- {path: packages/eslint/grammar-
|
|
1905
|
+
- {path: packages/eslint/grammar-core/r92-slot-status-coverage.spec.mjs, editions: [lite, full], codes: [FE_COMPONENT_API]}
|
|
1906
1906
|
- {path: packages/eslint/fe/r92-fetch-barrel.spec.mjs, editions: [lite, full]}
|
|
1907
1907
|
- {path: packages/eslint/fe/r92-component-surface-coverage.spec.mjs, editions: [lite, full]}
|
|
1908
1908
|
- {path: packages/eslint/fe/r56-r92-graph-coverage.spec.mjs, editions: [lite, full]}
|
|
@@ -1913,29 +1913,29 @@ rules:
|
|
|
1913
1913
|
gates: [pre-commit, settle, land, ci]
|
|
1914
1914
|
failureCodes: ["FE_VENDOR_BOUNDARY", "ARCH_GRAMMAR_CONTRACT_INVALID", "ARCH_GRAMMAR_EXPORT_BYPASS"]
|
|
1915
1915
|
enforcers:
|
|
1916
|
-
- {kind: eslint-grammar-
|
|
1917
|
-
- {kind: eslint-grammar-
|
|
1918
|
-
- {kind: eslint-grammar-
|
|
1919
|
-
- {kind: eslint-grammar-
|
|
1920
|
-
- {kind: eslint-grammar-
|
|
1921
|
-
- {kind: eslint-grammar-
|
|
1922
|
-
- {kind: eslint-grammar-
|
|
1916
|
+
- {kind: eslint-grammar-core, id: no-vendor-icon-outside-icon-leaf}
|
|
1917
|
+
- {kind: eslint-grammar-core, id: heroicons-is-the-glyph-vendor}
|
|
1918
|
+
- {kind: eslint-grammar-core, id: no-off-scale-glyph-size}
|
|
1919
|
+
- {kind: eslint-grammar-core, id: no-icon-size-class}
|
|
1920
|
+
- {kind: eslint-grammar-core, id: destructive-menu-entry-needs-danger-tone}
|
|
1921
|
+
- {kind: eslint-grammar-core, id: no-decorative-icon-in-metric-cell}
|
|
1922
|
+
- {kind: eslint-grammar-core, id: vendor-primitive-has-named-owner}
|
|
1923
1923
|
- {kind: eslint-fe, id: grammar-entry}
|
|
1924
1924
|
- {kind: machine, id: grammar, at: scripts/hfs/architecture/frontend-grammar.mjs}
|
|
1925
1925
|
editions: [lite, full]
|
|
1926
1926
|
docs: ["docs/code-pattern-enforcement.md#r93-vendor-and-grammar-ownership", knowledge/patterns/fe/index.yaml#FE-RULE-OWNERSHIP]
|
|
1927
1927
|
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."
|
|
1928
1928
|
proves:
|
|
1929
|
-
- packages/eslint/grammar-
|
|
1929
|
+
- packages/eslint/grammar-core/r93-vendor-coverage.spec.mjs
|
|
1930
1930
|
- packages/eslint/fe/r93-grammar-ownership.spec.mjs
|
|
1931
|
-
- packages/eslint/grammar-
|
|
1931
|
+
- packages/eslint/grammar-core/menu-entries.spec.mjs
|
|
1932
1932
|
exemplifiedBy:
|
|
1933
|
-
- {path: packages/eslint/grammar-
|
|
1933
|
+
- {path: packages/eslint/grammar-core/r93-vendor-coverage.spec.mjs, editions: [lite, full]}
|
|
1934
1934
|
- {path: packages/eslint/fe/r93-grammar-ownership.spec.mjs, editions: [lite, full]}
|
|
1935
|
-
- {path: packages/eslint/grammar-
|
|
1935
|
+
- {path: packages/eslint/grammar-core/menu-entries.spec.mjs, editions: [lite, full]}
|
|
1936
1936
|
witness:
|
|
1937
|
-
- {path: packages/eslint/grammar-
|
|
1938
|
-
- {path: packages/eslint/grammar-
|
|
1937
|
+
- {path: packages/eslint/grammar-core/menu-entries.spec.mjs, editions: [lite, full], codes: [FE_VENDOR_BOUNDARY]}
|
|
1938
|
+
- {path: packages/eslint/grammar-core/r93-vendor-coverage.spec.mjs, editions: [lite, full], codes: [FE_VENDOR_BOUNDARY]}
|
|
1939
1939
|
- {path: packages/eslint/fe/r93-grammar-ownership.spec.mjs, editions: [lite, full], codes: [ARCH_GRAMMAR_CONTRACT_INVALID, ARCH_GRAMMAR_EXPORT_BYPASS]}
|
|
1940
1940
|
- id: R94
|
|
1941
1941
|
code: "FE_SLOT_FILE_ROLE"
|
|
@@ -5006,20 +5006,20 @@ rules:
|
|
|
5006
5006
|
enforcers:
|
|
5007
5007
|
- {kind: eslint-fe, id: no-copy-in-call}
|
|
5008
5008
|
- {kind: eslint-fe, id: no-alert}
|
|
5009
|
-
- {kind: eslint-grammar-
|
|
5009
|
+
- {kind: eslint-grammar-core, id: no-inline-svg-outside-brand-mark-leaf}
|
|
5010
5010
|
editions: [lite, full]
|
|
5011
5011
|
docs: [docs/quality-bar.md#r286, knowledge/patterns/fe/index.yaml#FE-RULE-OWNERSHIP]
|
|
5012
5012
|
exemplifiedBy:
|
|
5013
5013
|
- {path: packages/eslint/fe/translation.spec.mjs, editions: [lite, full], codes: [FE_COPY_IN_CALL, FE_NO_ALERT]}
|
|
5014
|
-
- {path: packages/eslint/grammar-
|
|
5014
|
+
- {path: packages/eslint/grammar-core/icon.spec.mjs, editions: [lite, full], codes: [FE_ICON_INLINE_SVG]}
|
|
5015
5015
|
- {path: packages/hfs/templates/fe/skeleton/apps/__app__/src/components/leaves/Icon/index.tsx, editions: [lite, full]}
|
|
5016
5016
|
- {path: packages/hfs/templates/fe/skeleton/apps/__app__/src/modules/toast, editions: [lite, full]}
|
|
5017
5017
|
proves:
|
|
5018
5018
|
- {path: packages/eslint/fe/translation.spec.mjs, editions: [lite, full], codes: [FE_COPY_IN_CALL, FE_NO_ALERT]}
|
|
5019
|
-
- {path: packages/eslint/grammar-
|
|
5019
|
+
- {path: packages/eslint/grammar-core/icon.spec.mjs, editions: [lite, full], codes: [FE_ICON_INLINE_SVG]}
|
|
5020
5020
|
witness:
|
|
5021
5021
|
- {path: packages/eslint/fe/translation.spec.mjs, editions: [lite, full], codes: [FE_COPY_IN_CALL, FE_NO_ALERT]}
|
|
5022
|
-
- {path: packages/eslint/grammar-
|
|
5022
|
+
- {path: packages/eslint/grammar-core/icon.spec.mjs, editions: [lite, full], codes: [FE_ICON_INLINE_SVG]}
|
|
5023
5023
|
|
|
5024
5024
|
- id: R287
|
|
5025
5025
|
code: "FE_CALLBACK_SHAPE"
|
|
@@ -5476,19 +5476,19 @@ rules:
|
|
|
5476
5476
|
gates: [pre-commit, settle, land, ci]
|
|
5477
5477
|
failureCodes: ["FE_APP_SHELL_FRAME"]
|
|
5478
5478
|
enforcers:
|
|
5479
|
-
- {kind: eslint-grammar-
|
|
5479
|
+
- {kind: eslint-grammar-core, id: app-shell-frame}
|
|
5480
5480
|
editions: [lite, full]
|
|
5481
5481
|
docs:
|
|
5482
5482
|
- knowledge/patterns/fe/index.yaml#FE-RULE-OWNERSHIP
|
|
5483
5483
|
- {path: knowledge/ui/composition/app-shell.yaml, editions: [lite, full]}
|
|
5484
5484
|
proves:
|
|
5485
|
-
- {path: packages/eslint/grammar-
|
|
5485
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_APP_SHELL_FRAME]}
|
|
5486
5486
|
exemplifiedBy:
|
|
5487
|
-
- {path: packages/eslint/grammar-
|
|
5487
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_APP_SHELL_FRAME]}
|
|
5488
5488
|
- {path: examples/full-app/fe/apps/app/src/features/layouts/ShopLayout/component.tsx, edition: full}
|
|
5489
5489
|
- {path: examples/lite-app/fe/apps/web/src/features/layouts/WorkspaceLayout/component.tsx, edition: lite}
|
|
5490
5490
|
witness:
|
|
5491
|
-
- {path: packages/eslint/grammar-
|
|
5491
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_APP_SHELL_FRAME]}
|
|
5492
5492
|
templateNa: "The app composes its shell from product destinations and identity; full and lite example shells provide the reference."
|
|
5493
5493
|
- id: R314
|
|
5494
5494
|
code: "FE_NAVBAR_CONTROL_SIZE"
|
|
@@ -5497,19 +5497,19 @@ rules:
|
|
|
5497
5497
|
gates: [pre-commit, settle, land, ci]
|
|
5498
5498
|
failureCodes: ["FE_NAVBAR_CONTROL_SIZE"]
|
|
5499
5499
|
enforcers:
|
|
5500
|
-
- {kind: eslint-grammar-
|
|
5500
|
+
- {kind: eslint-grammar-core, id: navbar-control-size}
|
|
5501
5501
|
editions: [lite, full]
|
|
5502
5502
|
docs:
|
|
5503
5503
|
- knowledge/patterns/fe/index.yaml#FE-RULE-OWNERSHIP
|
|
5504
5504
|
- {path: knowledge/ui/composition/app-shell.yaml, editions: [lite, full]}
|
|
5505
5505
|
proves:
|
|
5506
|
-
- {path: packages/eslint/grammar-
|
|
5506
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_NAVBAR_CONTROL_SIZE]}
|
|
5507
5507
|
exemplifiedBy:
|
|
5508
|
-
- {path: packages/eslint/grammar-
|
|
5508
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_NAVBAR_CONTROL_SIZE]}
|
|
5509
5509
|
- {path: examples/full-app/fe/packages/ecommerce-ui/src/branches/WorkspaceNavbar/component.tsx, edition: full}
|
|
5510
5510
|
- {path: examples/lite-app/fe/apps/web/src/components/branches/Navbar/component.tsx, edition: lite}
|
|
5511
5511
|
witness:
|
|
5512
|
-
- {path: packages/eslint/grammar-
|
|
5512
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_NAVBAR_CONTROL_SIZE]}
|
|
5513
5513
|
templateNa: "The app composes its shell from product destinations and identity; full and lite example shells provide the reference."
|
|
5514
5514
|
- id: R315
|
|
5515
5515
|
code: "FE_NAVBAR_CLUSTER"
|
|
@@ -5518,19 +5518,19 @@ rules:
|
|
|
5518
5518
|
gates: [pre-commit, settle, land, ci]
|
|
5519
5519
|
failureCodes: ["FE_NAVBAR_CLUSTER"]
|
|
5520
5520
|
enforcers:
|
|
5521
|
-
- {kind: eslint-grammar-
|
|
5521
|
+
- {kind: eslint-grammar-core, id: navbar-cluster}
|
|
5522
5522
|
editions: [lite, full]
|
|
5523
5523
|
docs:
|
|
5524
5524
|
- knowledge/patterns/fe/index.yaml#FE-RULE-OWNERSHIP
|
|
5525
5525
|
- {path: knowledge/ui/composition/app-shell.yaml, editions: [lite, full]}
|
|
5526
5526
|
proves:
|
|
5527
|
-
- {path: packages/eslint/grammar-
|
|
5527
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_NAVBAR_CLUSTER]}
|
|
5528
5528
|
exemplifiedBy:
|
|
5529
|
-
- {path: packages/eslint/grammar-
|
|
5529
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_NAVBAR_CLUSTER]}
|
|
5530
5530
|
- {path: examples/full-app/fe/packages/ecommerce-ui/src/branches/WorkspaceNavbar/component.tsx, edition: full}
|
|
5531
5531
|
- {path: examples/lite-app/fe/apps/web/src/components/branches/Navbar/component.tsx, edition: lite}
|
|
5532
5532
|
witness:
|
|
5533
|
-
- {path: packages/eslint/grammar-
|
|
5533
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_NAVBAR_CLUSTER]}
|
|
5534
5534
|
templateNa: "The app composes its shell from product destinations and identity; full and lite example shells provide the reference."
|
|
5535
5535
|
- id: R316
|
|
5536
5536
|
code: "FE_APP_SHELL_BOTTOM_TABS"
|
|
@@ -5539,19 +5539,19 @@ rules:
|
|
|
5539
5539
|
gates: [pre-commit, settle, land, ci]
|
|
5540
5540
|
failureCodes: ["FE_APP_SHELL_BOTTOM_TABS"]
|
|
5541
5541
|
enforcers:
|
|
5542
|
-
- {kind: eslint-grammar-
|
|
5542
|
+
- {kind: eslint-grammar-core, id: no-shell-bottom-tabs}
|
|
5543
5543
|
editions: [lite, full]
|
|
5544
5544
|
docs:
|
|
5545
5545
|
- knowledge/patterns/fe/index.yaml#FE-RULE-OWNERSHIP
|
|
5546
5546
|
- {path: knowledge/ui/composition/app-shell.yaml, editions: [lite, full]}
|
|
5547
5547
|
proves:
|
|
5548
|
-
- {path: packages/eslint/grammar-
|
|
5548
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_APP_SHELL_BOTTOM_TABS]}
|
|
5549
5549
|
exemplifiedBy:
|
|
5550
|
-
- {path: packages/eslint/grammar-
|
|
5550
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_APP_SHELL_BOTTOM_TABS]}
|
|
5551
5551
|
- {path: examples/full-app/fe/apps/app/src/features/layouts/ShopLayout/component.tsx, edition: full}
|
|
5552
5552
|
- {path: examples/lite-app/fe/apps/web/src/features/layouts/WorkspaceLayout/component.tsx, edition: lite}
|
|
5553
5553
|
witness:
|
|
5554
|
-
- {path: packages/eslint/grammar-
|
|
5554
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_APP_SHELL_BOTTOM_TABS]}
|
|
5555
5555
|
templateNa: "The app composes its shell from product destinations and identity; full and lite example shells provide the reference."
|
|
5556
5556
|
- id: R317
|
|
5557
5557
|
code: "FE_NAVBAR_CREATE"
|
|
@@ -5560,19 +5560,19 @@ rules:
|
|
|
5560
5560
|
gates: [pre-commit, settle, land, ci]
|
|
5561
5561
|
failureCodes: ["FE_NAVBAR_CREATE"]
|
|
5562
5562
|
enforcers:
|
|
5563
|
-
- {kind: eslint-grammar-
|
|
5563
|
+
- {kind: eslint-grammar-core, id: no-navbar-create}
|
|
5564
5564
|
editions: [lite, full]
|
|
5565
5565
|
docs:
|
|
5566
5566
|
- knowledge/patterns/fe/index.yaml#FE-RULE-OWNERSHIP
|
|
5567
5567
|
- {path: knowledge/ui/composition/app-shell.yaml, editions: [lite, full]}
|
|
5568
5568
|
proves:
|
|
5569
|
-
- {path: packages/eslint/grammar-
|
|
5569
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_NAVBAR_CREATE]}
|
|
5570
5570
|
exemplifiedBy:
|
|
5571
|
-
- {path: packages/eslint/grammar-
|
|
5571
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_NAVBAR_CREATE]}
|
|
5572
5572
|
- {path: examples/full-app/fe/packages/ecommerce-ui/src/branches/WorkspaceNavbar/component.tsx, edition: full}
|
|
5573
5573
|
- {path: examples/lite-app/fe/apps/web/src/components/branches/Navbar/component.tsx, edition: lite}
|
|
5574
5574
|
witness:
|
|
5575
|
-
- {path: packages/eslint/grammar-
|
|
5575
|
+
- {path: packages/eslint/grammar-core/app-shell.spec.mjs, editions: [lite, full], codes: [FE_NAVBAR_CREATE]}
|
|
5576
5576
|
templateNa: "The app composes its shell from product destinations and identity; full and lite example shells provide the reference."
|
|
5577
5577
|
- id: R318
|
|
5578
5578
|
code: "FE_NESTED_VARIANT"
|
|
@@ -5664,3 +5664,26 @@ rules:
|
|
|
5664
5664
|
source: owner
|
|
5665
5665
|
quote: "The size of the buttons and controls is uneven; the teacher thinks height = 40px (h-10) should be fixed for every button, switch, input, tabs and so on, what do you think? (translated from Vietnamese)"
|
|
5666
5666
|
ruling: "One 40px control height is the default of every standalone control (owner ruling control-height-40): Grammar draws it, an app omits size, sm is for a nested item or dense toolbar row, lg only for a landing hero call to action, and controls of one row share one size."
|
|
5667
|
+
- id: R322
|
|
5668
|
+
code: "FE_CHIP_LABEL_CASE"
|
|
5669
|
+
law: "The label of a status chip (a StatusDot with text, a Badge) starts with an uppercase letter, so every chip of an app reads in one vocabulary."
|
|
5670
|
+
kinds: [lint, codemod]
|
|
5671
|
+
gates: [pre-commit, settle, land, ci]
|
|
5672
|
+
failureCodes: ["FE_CHIP_LABEL_CASE"]
|
|
5673
|
+
enforcers:
|
|
5674
|
+
- {kind: eslint-grammar-core, id: chip-label-starts-uppercase}
|
|
5675
|
+
editions: [lite, full]
|
|
5676
|
+
docs: [knowledge/patterns/fe/index.yaml#FE-RULE-OWNERSHIP]
|
|
5677
|
+
templateNa: "A template states no chip label; the words are the app's."
|
|
5678
|
+
proves:
|
|
5679
|
+
- packages/eslint/grammar-core/chip-label.spec.mjs
|
|
5680
|
+
exemplifiedBy:
|
|
5681
|
+
- {path: packages/eslint/grammar-core/chip-label.spec.mjs, editions: [lite, full], codes: [FE_CHIP_LABEL_CASE]}
|
|
5682
|
+
witness:
|
|
5683
|
+
- {path: packages/eslint/grammar-core/chip-label.spec.mjs, editions: [lite, full], codes: [FE_CHIP_LABEL_CASE]}
|
|
5684
|
+
cases:
|
|
5685
|
+
- id: case-1
|
|
5686
|
+
date: "2026-10-27"
|
|
5687
|
+
source: owner
|
|
5688
|
+
quote: "A chip label starts uppercase."
|
|
5689
|
+
ruling: "The label of a status chip starts with an uppercase letter (owner ruling chip-label-uppercase); StatusDot capitalises a text label it renders, and the lint refuses a lowercase literal label at its source."
|
|
@@ -2130,7 +2130,7 @@ FE_APP_SHELL_BOTTOM_TABS:
|
|
|
2130
2130
|
meaning_vi: "Khung ứng dụng tại <file> đặt điều hướng trong thanh tab dưới thay vì Sidebar drawer."
|
|
2131
2131
|
causes_vi:
|
|
2132
2132
|
- "Cấu trúc shell không theo canon ứng dụng."
|
|
2133
|
-
nextStep_vi: "Dùng hàng mở drawer bên dưới navbar và Sidebar presentation=\"drawer\" (R316; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-
|
|
2133
|
+
nextStep_vi: "Dùng hàng mở drawer bên dưới navbar và Sidebar presentation=\"drawer\" (R316; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-core/README.md)."
|
|
2134
2134
|
owner: op-retry
|
|
2135
2135
|
kind: check-finding
|
|
2136
2136
|
|
|
@@ -2140,7 +2140,7 @@ FE_APP_SHELL_FRAME:
|
|
|
2140
2140
|
meaning_vi: "Khung ứng dụng tại <file> không giao bố cục và cuộn cho WorkspaceShell."
|
|
2141
2141
|
causes_vi:
|
|
2142
2142
|
- "Cấu trúc shell không theo canon ứng dụng."
|
|
2143
|
-
nextStep_vi: "Ghép khung ứng dụng bằng WorkspaceShell viewport=\"fixed\" (R313; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-
|
|
2143
|
+
nextStep_vi: "Ghép khung ứng dụng bằng WorkspaceShell viewport=\"fixed\" (R313; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-core/README.md)."
|
|
2144
2144
|
owner: op-retry
|
|
2145
2145
|
kind: check-finding
|
|
2146
2146
|
|
|
@@ -2237,7 +2237,7 @@ FE_COMPONENT_API:
|
|
|
2237
2237
|
- "Component nhận className từ ngoài"
|
|
2238
2238
|
- "Khối kết nối không có bản trình bày thuần"
|
|
2239
2239
|
- "Trạng thái dữ liệu tự chế thay vì qua SlotView"
|
|
2240
|
-
nextStep_vi: "Sửa chữ ký component theo luật drawing và tách phần trình bày; op vừa tạo ra bản này sẽ được chạy lại để sửa theo lời nhắn của bộ kiểm tra (R92; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-
|
|
2240
|
+
nextStep_vi: "Sửa chữ ký component theo luật drawing và tách phần trình bày; op vừa tạo ra bản này sẽ được chạy lại để sửa theo lời nhắn của bộ kiểm tra (R92; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-core/README.md)."
|
|
2241
2241
|
owner: op-retry
|
|
2242
2242
|
kind: check-finding
|
|
2243
2243
|
|
|
@@ -2284,6 +2284,16 @@ FE_CONSOLE_CALL:
|
|
|
2284
2284
|
owner: op-retry
|
|
2285
2285
|
kind: check-finding
|
|
2286
2286
|
|
|
2287
|
+
FE_CHIP_LABEL_CASE:
|
|
2288
|
+
title: "A status chip label starts with a lowercase letter"
|
|
2289
|
+
title_vi: "Nhãn chip trạng thái bắt đầu bằng chữ thường"
|
|
2290
|
+
meaning_vi: "Nhãn chữ của một StatusDot hoặc Badge tại <file> bắt đầu bằng chữ cái thường, nên các chip trong cùng một màn hình đọc thành hai lối viết."
|
|
2291
|
+
causes_vi:
|
|
2292
|
+
- "Viết nhãn chip như `running` thay vì `Running`."
|
|
2293
|
+
nextStep_vi: "Viết hoa chữ cái đầu của nhãn chip; luật tự sửa nhãn viết thẳng trong mã (quy định chip-label-uppercase)."
|
|
2294
|
+
owner: op-retry
|
|
2295
|
+
kind: check-finding
|
|
2296
|
+
|
|
2287
2297
|
FE_CONTROL_HEIGHT:
|
|
2288
2298
|
title: "A control picks a larger size or mixes sizes in one row"
|
|
2289
2299
|
title_vi: "Điều khiển chọn cỡ lớn hơn hoặc trộn nhiều cỡ trong một hàng"
|
|
@@ -2530,7 +2540,7 @@ FE_ICON_INLINE_SVG:
|
|
|
2530
2540
|
causes_vi:
|
|
2531
2541
|
- "Leaf Icon tự vẽ path hoặc SVG thay vì dùng Heroicons"
|
|
2532
2542
|
- "Component vẽ SVG trực tiếp mà không phải leaf nhãn hiệu được khai báo"
|
|
2533
|
-
nextStep_vi: "Thay glyph bằng Heroicons qua leaf Icon; nếu là nhãn hiệu, đặt nó trong leaf nhãn hiệu và khai báo đúng chủ của leaf (R286; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-
|
|
2543
|
+
nextStep_vi: "Thay glyph bằng Heroicons qua leaf Icon; nếu là nhãn hiệu, đặt nó trong leaf nhãn hiệu và khai báo đúng chủ của leaf (R286; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-core/README.md)."
|
|
2534
2544
|
owner: op-retry
|
|
2535
2545
|
kind: check-finding
|
|
2536
2546
|
|
|
@@ -2561,7 +2571,7 @@ FE_NATIVE_FORM_CONTROL:
|
|
|
2561
2571
|
meaning_vi: "`<tag>` thô ở `<file>`. Dùng renderer của grammar."
|
|
2562
2572
|
causes_vi:
|
|
2563
2573
|
- "Vi phạm luật R62: Không `<select>/<input>/<textarea>/<button>`, `<img>` thô và không thẻ cấu trúc thô (`<section>`, `<p>`, `<ul>`, `<h1>`...) ở tầng sản phẩm; dùng renderer grammar."
|
|
2564
|
-
nextStep_vi: "Op vừa tạo ra bản này sẽ được chạy lại để sửa theo lời nhắn của bộ kiểm tra và mục của luật trong tiêu chuẩn HFS; nợ cũ cần quyết định thiết kế nên op không thêm ngoại lệ, chỉ tách hoặc chuyển về đúng chủ (R62; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-
|
|
2574
|
+
nextStep_vi: "Op vừa tạo ra bản này sẽ được chạy lại để sửa theo lời nhắn của bộ kiểm tra và mục của luật trong tiêu chuẩn HFS; nợ cũ cần quyết định thiết kế nên op không thêm ngoại lệ, chỉ tách hoặc chuyển về đúng chủ (R62; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-core/README.md)."
|
|
2565
2575
|
owner: op-retry
|
|
2566
2576
|
kind: check-finding
|
|
2567
2577
|
|
|
@@ -2581,7 +2591,7 @@ FE_NAVBAR_CLUSTER:
|
|
|
2581
2591
|
meaning_vi: "Cụm navbar tại <file> không giữ thứ tự ngôn ngữ, giao diện, thông báo và tài khoản."
|
|
2582
2592
|
causes_vi:
|
|
2583
2593
|
- "Cấu trúc shell không theo canon ứng dụng."
|
|
2584
|
-
nextStep_vi: "Ghép IconButton ngôn ngữ, Switch giao diện, IconButton chuông và AvatarButton theo đúng thứ tự (R315; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-
|
|
2594
|
+
nextStep_vi: "Ghép IconButton ngôn ngữ, Switch giao diện, IconButton chuông và AvatarButton theo đúng thứ tự (R315; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-core/README.md)."
|
|
2585
2595
|
owner: op-retry
|
|
2586
2596
|
kind: check-finding
|
|
2587
2597
|
|
|
@@ -2591,7 +2601,7 @@ FE_NAVBAR_CONTROL_SIZE:
|
|
|
2591
2601
|
meaning_vi: "Điều khiển trong navbar tại <file> không khai báo cùng cỡ control của Grammar."
|
|
2592
2602
|
causes_vi:
|
|
2593
2603
|
- "Cấu trúc shell không theo canon ứng dụng."
|
|
2594
|
-
nextStep_vi: "Đặt size=\"control\" trên từng điều khiển trong thanh (R314; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-
|
|
2604
|
+
nextStep_vi: "Đặt size=\"control\" trên từng điều khiển trong thanh (R314; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-core/README.md)."
|
|
2595
2605
|
owner: op-retry
|
|
2596
2606
|
kind: check-finding
|
|
2597
2607
|
|
|
@@ -2601,7 +2611,7 @@ FE_NAVBAR_CREATE:
|
|
|
2601
2611
|
meaning_vi: "Navbar tại <file> chứa thao tác tạo mới thuộc nội dung trang."
|
|
2602
2612
|
causes_vi:
|
|
2603
2613
|
- "Cấu trúc shell không theo canon ứng dụng."
|
|
2604
|
-
nextStep_vi: "Đưa thao tác tạo mới về trang sở hữu nó (R317; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-
|
|
2614
|
+
nextStep_vi: "Đưa thao tác tạo mới về trang sở hữu nó (R317; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-core/README.md)."
|
|
2605
2615
|
owner: op-retry
|
|
2606
2616
|
kind: check-finding
|
|
2607
2617
|
|
|
@@ -2953,8 +2963,8 @@ FE_STACK_FAMILY_LINT_MISSING:
|
|
|
2953
2963
|
title_vi: "Front end dùng canon-fe 9 nhưng thiếu gói lint của họ Grammar đã chọn"
|
|
2954
2964
|
meaning_vi: "hfs.json chọn sides.fe.grammar (starci hoặc offset-pop) và front end khai báo @starci/eslint-canon-fe 9 trở lên, nhưng không manifest nào khai báo gói lint của họ đó; từ canon-fe 9 các luật component Grammar nằm trong gói này, thiếu gói thì các luật ấy không chạy."
|
|
2955
2965
|
causes_vi:
|
|
2956
|
-
- "Nâng @starci/eslint-canon-fe lên 9 mà chưa thêm @starci/eslint-grammar-
|
|
2957
|
-
nextStep_vi: "Thêm @starci/eslint-grammar-
|
|
2966
|
+
- "Nâng @starci/eslint-canon-fe lên 9 mà chưa thêm @starci/eslint-grammar-core (Grammar StarCi) hoặc @starci/eslint-grammar-offset-pop (Grammar Offset Pop)."
|
|
2967
|
+
nextStep_vi: "Thêm @starci/eslint-grammar-core (hoặc @starci/eslint-grammar-offset-pop) cạnh @starci/eslint-canon-fe, ghép coreGrammarConfig({ hfs }) (hoặc offsetPopGrammarConfig({ hfs })) sau starciFeConfig({ hfs }) trong fe/eslint.config.mjs, hoặc chạy starci app sync."
|
|
2958
2968
|
owner: op-retry
|
|
2959
2969
|
kind: check-finding
|
|
2960
2970
|
|
|
@@ -3011,7 +3021,7 @@ FE_STYLE_TOKEN_ONLY:
|
|
|
3011
3021
|
- "@media dùng breakpoint ngoài thang của grammar"
|
|
3012
3022
|
- "brand.css thiếu cặp mềm của một tông trạng thái ở sáng hoặc tối, chữ mềm dưới 3:1 trên nền nhạt hoặc nền trang, --foreground dưới 4.5:1, hoặc giá trị màu không phân giải được"
|
|
3013
3023
|
- "Component tô chữ hoặc icon bằng text-success, text-danger, fill-warning, stroke-info (tông đặc) thay vì text-<tông>-soft-foreground"
|
|
3014
|
-
nextStep_vi: "Op interface.implement bỏ CSS riêng, dùng component và token của grammar; giá trị màu thương hiệu chỉ khai ở modules/brand/brand.css cho cả sáng và tối, đủ cặp mềm cho mọi tông trạng thái; chữ và icon trạng thái dùng text-<tông>-soft-foreground (R61; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-
|
|
3024
|
+
nextStep_vi: "Op interface.implement bỏ CSS riêng, dùng component và token của grammar; giá trị màu thương hiệu chỉ khai ở modules/brand/brand.css cho cả sáng và tối, đủ cặp mềm cho mọi tông trạng thái; chữ và icon trạng thái dùng text-<tông>-soft-foreground (R61; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-core/README.md)."
|
|
3015
3025
|
owner: other-op:interface.implement
|
|
3016
3026
|
kind: check-finding
|
|
3017
3027
|
|
|
@@ -3130,7 +3140,7 @@ FE_VENDOR_BOUNDARY:
|
|
|
3130
3140
|
- "Dùng bộ glyph thứ hai ngoài họ heroicons (Phosphor, Lucide, Iconify...)"
|
|
3131
3141
|
- "Dùng kích thước biểu tượng ngoài thang"
|
|
3132
3142
|
- "Primitive thư viện ngoài dùng trực tiếp ở nhiều nơi"
|
|
3133
|
-
nextStep_vi: "Dùng lá icon và chủ sở hữu primitive có sẵn; op vừa tạo ra bản này sẽ được chạy lại để sửa theo lời nhắn của bộ kiểm tra (R93; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-
|
|
3143
|
+
nextStep_vi: "Dùng lá icon và chủ sở hữu primitive có sẵn; op vừa tạo ra bản này sẽ được chạy lại để sửa theo lời nhắn của bộ kiểm tra (R93; FE-RULE-OWNERSHIP: knowledge/patterns/fe/index.yaml; packages/eslint/grammar-core/README.md)."
|
|
3134
3144
|
owner: op-retry
|
|
3135
3145
|
kind: check-finding
|
|
3136
3146
|
|
|
@@ -5007,7 +5017,7 @@ RT_GENERATED_BLOCK_STALE:
|
|
|
5007
5017
|
RT_GENERATED_DRIFT:
|
|
5008
5018
|
title: "Generated copy drifted"
|
|
5009
5019
|
title_vi: "Bản sao sinh tự động bị lệch"
|
|
5010
|
-
meaning_vi: "Một bản sao sinh tự động trong packages/hfs/runtime, packages/eslint/be/runtime hoặc packages/eslint/fe/runtime, packages/eslint/grammar-
|
|
5020
|
+
meaning_vi: "Một bản sao sinh tự động trong packages/hfs/runtime, packages/eslint/be/runtime hoặc packages/eslint/fe/runtime, packages/eslint/grammar-core/runtime, packages/eslint/grammar-offset-pop/runtime khác với nội dung mà scripts/hfs/sync-runtime.mjs ghi ra từ nguồn duy nhất: thiếu, cũ, hoặc thừa tệp."
|
|
5011
5021
|
causes_vi:
|
|
5012
5022
|
- "Sửa một tệp nguồn được đóng gói mà quên chạy sync-runtime"
|
|
5013
5023
|
- "Sửa tay một tệp trong thư mục runtime/ của gói"
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// git-policy.mjs — which git commands an op worker may run in a checkout it
|
|
2
|
-
// shares with other workflows. Pure: argv in, verdict out;
|
|
3
|
-
//
|
|
4
|
-
// reference-transaction hook git itself runs backs it (scripts/guards/hook-install.mjs).
|
|
2
|
+
// shares with other workflows. Pure: argv in, verdict out; a caller applies it to a
|
|
3
|
+
// shell command before it runs.
|
|
5
4
|
//
|
|
6
5
|
// Several workflows of one product ledger build in ONE checkout on ONE branch.
|
|
7
6
|
// Their workers damaged each other with commands that are harmless alone:
|
|
@@ -12,7 +12,7 @@ import { fail } from './slot-errors.mjs';
|
|
|
12
12
|
|
|
13
13
|
const HFS_RULES_FILE = 'knowledge/hfs/rules.yaml';
|
|
14
14
|
const RULE_GATES = Object.freeze(['pre-commit', 'pre-push', 'settle', 'land', 'ci', 'sonar', 'runtime']);
|
|
15
|
-
const ENFORCER_FAMILIES = Object.freeze(['eslint-be', 'eslint-fe', 'eslint-grammar-
|
|
15
|
+
const ENFORCER_FAMILIES = Object.freeze(['eslint-be', 'eslint-fe', 'eslint-grammar-core', 'stylelint', 'machine', 'hfs', 'work-validate', 'sonar', 'runtime']);
|
|
16
16
|
const RULE_KINDS = Object.freeze(['codemod', 'lint', 'check', 'design']);
|
|
17
17
|
const FINDING_CODE = /^[A-Z][A-Z0-9]*(_[A-Z0-9]+)+$/;
|
|
18
18
|
const ENFORCER_ID = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
@@ -346,7 +346,7 @@ export function loadRuleCatalog({ root = skillRoot, file = path.join(root, HFS_R
|
|
|
346
346
|
/** The catalogued why code of a lint finding's rule id (`starci-be/<id>`, `starci-fe/<id>`), or undefined. */
|
|
347
347
|
lintCode: (ruleId) => {
|
|
348
348
|
const [plugin, id] = String(ruleId ?? '').split('/');
|
|
349
|
-
const kind = (plugin === 'starci-be' && 'eslint-be') || (plugin === 'starci-fe' && 'eslint-fe') || (plugin === 'starci-grammar' && 'eslint-grammar-
|
|
349
|
+
const kind = (plugin === 'starci-be' && 'eslint-be') || (plugin === 'starci-fe' && 'eslint-fe') || (plugin === 'starci-grammar' && 'eslint-grammar-core') || null;
|
|
350
350
|
return kind ? list.find((rule) => rule.enforcers.some((enforcer) => enforcer.kind === kind && enforcer.id === id))?.code : undefined;
|
|
351
351
|
},
|
|
352
352
|
/** The rules one enforcer judges, e.g. forEnforcer('eslint-be', 'error-home'). */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// pipeline.mjs - HFS_CI_MISSING_CANON (R13): CI runs the pinned `starci app lint`.
|
|
2
2
|
// .github/workflows/ci.yml a `run:` step that runs the one lint entry: `starci app lint`,
|
|
3
|
-
// `npx
|
|
4
|
-
// (`npm run lint`, arguments after `--` allowed); a version named in the step is the
|
|
3
|
+
// `npx starci-harness[@<version>] app lint`, or `npm run <script>` whose command runs `starci app lint`
|
|
4
|
+
// (`npm run lint`, arguments after `--` allowed); a version named in the step is the starci-harness pin of
|
|
5
5
|
// canon-pins.yaml (an installed one is pinned by the pin check, R15)
|
|
6
6
|
// (the push hook is no lint or typecheck step: it checks the release gate, scripts/hfs/runtime-rules/hook-shape.mjs keeps its shape)
|
|
7
7
|
// A missing file is the slot manifest's finding (HFS_SLOT_REQUIRED_MISSING); a file that is present and lacks the step is this rule's.
|
|
@@ -11,10 +11,10 @@ import { isRuntimeExampleApp } from '../../lib/runtime-example.mjs';
|
|
|
11
11
|
|
|
12
12
|
const CI_MISSING_CANON = 'HFS_CI_MISSING_CANON';
|
|
13
13
|
const CI_FILE = '.github/workflows/ci.yml';
|
|
14
|
-
const hfsPackage = '
|
|
14
|
+
const hfsPackage = 'starci-harness';
|
|
15
15
|
const RUN_PREFIX = /^\s*(?:-\s+)?run:/;
|
|
16
16
|
const NPX_PREFIX = /^npx\s+(?:(?:--no-install|-y)\s+)?/;
|
|
17
|
-
const LINT_COMMAND = /^(
|
|
17
|
+
const LINT_COMMAND = /^(?:starci-harness(?:@(\S+))?|starci)\s+app\s+lint/;
|
|
18
18
|
const NPM_RUN_PREFIX = 'npm run ';
|
|
19
19
|
const EXAMPLE_RUN_PREFIX = 'node node_modules/@starci/hfs/runtime/scripts/hfs/example-secrets.mjs --run . -- ';
|
|
20
20
|
const SCRIPT_NAME = /^[\w:.-]+/;
|
|
@@ -57,7 +57,7 @@ function parseNpmRun(command) {
|
|
|
57
57
|
return args !== null && !LINE_TERMINATOR.test(args) ? { script, args } : null;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
/** { version } of a `starci app lint` command (`version` undefined when no
|
|
60
|
+
/** { version } of a `starci app lint` command (`version` undefined when no starci-harness version is named), else null. */
|
|
61
61
|
function lintCommandOf(command) {
|
|
62
62
|
const rest = command.replace(NPX_PREFIX, '');
|
|
63
63
|
const match = LINT_COMMAND.exec(rest);
|
|
@@ -10,6 +10,7 @@ import path from 'node:path';
|
|
|
10
10
|
import { parseYaml } from '../../engine/yaml.mjs';
|
|
11
11
|
import { validateAgainstSchema } from './json-schema.mjs';
|
|
12
12
|
import { insidePath, samePath, slash } from './path-key.mjs';
|
|
13
|
+
import { resolveGrammarFamily } from './grammar-lint.mjs';
|
|
13
14
|
import { byCodeUnit } from './list.mjs';
|
|
14
15
|
import { isLiteWorkRoot, workPathAllowed } from './work-edition.mjs';
|
|
15
16
|
import { WORK_DIR_NAME } from './roots.mjs';
|
|
@@ -49,9 +50,15 @@ export const REFERENCE_APP_MANIFEST = `${EXAMPLES_ROOT}/full-app/hfs.json`;
|
|
|
49
50
|
/** The example app whose installed tree an fe-kit peer link points at by default. */
|
|
50
51
|
export const REFERENCE_EXAMPLE_APP = 'full-app';
|
|
51
52
|
|
|
52
|
-
/** The grammar css families a product repository may declare (`[data-grammar-family="<id>"]`)
|
|
53
|
-
* runtime's own product maps to the core sheet. */
|
|
54
|
-
export const GRAMMAR_FAMILIES = Object.freeze({
|
|
53
|
+
/** The grammar css families a product repository may declare (`[data-grammar-family="<id>"]`), keyed by the
|
|
54
|
+
* canonical catalog id; the runtime's own product maps to the core sheet. */
|
|
55
|
+
export const GRAMMAR_FAMILIES = Object.freeze({ core: 'core', nivo: 'nivo', 'offset-pop': 'offset-pop' });
|
|
56
|
+
|
|
57
|
+
/** A css family key through the Grammar catalog's alias table (`starci` reads as `core`); an id the catalog does not declare is kept. */
|
|
58
|
+
export function grammarCssFamilyKey(family) {
|
|
59
|
+
if (typeof family !== 'string' || !family) return family;
|
|
60
|
+
try { return resolveGrammarFamily(family).id; } catch { return family; }
|
|
61
|
+
}
|
|
55
62
|
|
|
56
63
|
/** A feature-folder segment that is only the product's own name - no useful leaf (display-names pathLabel). */
|
|
57
64
|
export const PRODUCT_NAME_SEGMENT = /^(nivo|starci|mia)[-\w]*$/i;
|
|
@@ -4,14 +4,27 @@ import { parseYamlCached } from './yaml-cached.mjs';
|
|
|
4
4
|
|
|
5
5
|
const CATALOG_FILE = new URL('../../knowledge/grammars/index.yaml', import.meta.url);
|
|
6
6
|
|
|
7
|
+
function readCatalog() {
|
|
8
|
+
return parseYamlCached(fs.readFileSync(CATALOG_FILE, 'utf8'));
|
|
9
|
+
}
|
|
10
|
+
|
|
7
11
|
function selectedFamily(family) {
|
|
8
12
|
if (typeof family !== 'string' || !family.trim()) throw new Error('sides.fe.grammar must explicitly name the selected Grammar family');
|
|
9
|
-
const catalog =
|
|
13
|
+
const catalog = readCatalog();
|
|
10
14
|
const matches = (catalog.families ?? []).filter(entry => entry.id === family);
|
|
11
15
|
if (matches.length !== 1) throw new Error(`Grammar family ${family} has no declared lint contract in knowledge/grammars/index.yaml`);
|
|
12
16
|
return { catalog, selected: matches[0] };
|
|
13
17
|
}
|
|
14
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Resolve a selection to its declared family id; only a catalog family id resolves, there are no aliases.
|
|
21
|
+
* @param {string} family - The id an app or caller names (sides.fe.grammar).
|
|
22
|
+
* @returns {{ id: string }} The declared family id.
|
|
23
|
+
*/
|
|
24
|
+
export function resolveGrammarFamily(family) {
|
|
25
|
+
return Object.freeze({ id: selectedFamily(family).selected.id });
|
|
26
|
+
}
|
|
27
|
+
|
|
15
28
|
/** The explicitly selected authored family entry; callers share the catalog lookup rather than inferring a family. */
|
|
16
29
|
export function grammarFamilyFor(family) {
|
|
17
30
|
return Object.freeze(selectedFamily(family).selected);
|
|
@@ -24,13 +37,13 @@ export function grammarLintFor(family) {
|
|
|
24
37
|
throw new Error(`Grammar family ${family} has no declared lint contract in knowledge/grammars/index.yaml`);
|
|
25
38
|
}
|
|
26
39
|
const lint = selected.lint;
|
|
27
|
-
if (lint.package === null) return Object.freeze({ family, package: null });
|
|
40
|
+
if (lint.package === null) return Object.freeze({ family: selected.id, package: null });
|
|
28
41
|
if (typeof lint.package !== 'string' || !lint.package.startsWith('@starci/eslint-grammar-')
|
|
29
42
|
|| typeof lint.factory !== 'string' || !/^[a-zA-Z][a-zA-Z0-9]*$/.test(lint.factory)
|
|
30
43
|
|| typeof lint.prefix !== 'string' || !/^[a-z][a-z0-9-]*$/.test(lint.prefix)) {
|
|
31
44
|
throw new Error(`Grammar family ${family} has an invalid lint contract in knowledge/grammars/index.yaml`);
|
|
32
45
|
}
|
|
33
|
-
return Object.freeze({ family, package: lint.package, factory: lint.factory, prefix: lint.prefix });
|
|
46
|
+
return Object.freeze({ family: selected.id, package: lint.package, factory: lint.factory, prefix: lint.prefix });
|
|
34
47
|
}
|
|
35
48
|
|
|
36
49
|
/** The selected family's shared component/export contract, resolved through its catalog reference. */
|