@starci/hfs 4.7.26 → 4.7.28

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +2 -3
  3. package/package.json +7 -1
  4. package/release/candidate-ci.mjs +3 -21
  5. package/runtime/engine/yaml.mjs +1 -1
  6. package/runtime/knowledge/hfs/canon-pins.yaml +4 -4
  7. package/runtime/knowledge/hfs/rules.yaml +913 -637
  8. package/runtime/knowledge/hfs/slots.yaml +21 -14
  9. package/runtime/modules/kernel/failure-codes.yaml +10 -0
  10. package/runtime/packages/cli/src/catalog.generated.mjs +130 -54
  11. package/runtime/scripts/api/git/check-ignore.mjs +5 -0
  12. package/runtime/scripts/gates/runtime-host.mjs +83 -0
  13. package/runtime/scripts/gates/sonar-gate.mjs +251 -0
  14. package/runtime/scripts/gates/starcistacks-ci.mjs +55 -0
  15. package/runtime/scripts/gates/starcistacks-form.mjs +26 -0
  16. package/runtime/scripts/gates/starcistacks-runtime.mjs +2 -0
  17. package/runtime/scripts/gates/starcistacks-value-file.mjs +17 -0
  18. package/runtime/scripts/gates/starcistacks.mjs +499 -0
  19. package/runtime/scripts/hfs/app-wiring.mjs +2 -2
  20. package/runtime/scripts/hfs/architecture/supabase.mjs +1 -1
  21. package/runtime/scripts/hfs/check.mjs +4 -1
  22. package/runtime/scripts/hfs/coverage-from.mjs +1 -1
  23. package/runtime/scripts/hfs/manifest-shape.mjs +1 -3
  24. package/runtime/scripts/hfs/rule-catalog.mjs +7 -10
  25. package/runtime/scripts/hfs/rules/a15-findings.mjs +1 -1
  26. package/runtime/scripts/hfs/rules/assets.mjs +1 -1
  27. package/runtime/scripts/hfs/rules/bypass-markers.mjs +24 -0
  28. package/runtime/scripts/hfs/rules/frontend-tree.mjs +2 -2
  29. package/runtime/scripts/hfs/rules/supabase-secrets.mjs +1 -1
  30. package/runtime/scripts/lib/bypass-markers.mjs +116 -0
  31. package/runtime/scripts/lib/check-code-loosening.mjs +128 -0
  32. package/runtime/scripts/lib/example-refs.mjs +205 -0
  33. package/runtime/scripts/lib/failure-code-reads.mjs +100 -0
  34. package/runtime/scripts/lib/gate-loosening.mjs +52 -8
  35. package/runtime/scripts/lib/json-formats.mjs +34 -0
  36. package/runtime/scripts/lib/managed-json.mjs +1 -1
  37. package/runtime/scripts/lib/package-at.mjs +1 -1
  38. package/runtime/scripts/lib/properties.mjs +16 -0
  39. package/runtime/scripts/lib/provision-control-failure.mjs +32 -0
  40. package/runtime/scripts/lib/sonar-new-code.mjs +58 -0
  41. package/runtime/scripts/lib/starciwork-boundary.mjs +164 -0
  42. package/runtime/scripts/lib/work-edition.mjs +40 -0
  43. package/sync/format.mjs +1 -1
  44. package/sync/hygiene.mjs +16 -4
  45. package/templates/app/hooks/husky/pre-commit +8 -7
package/sync/hygiene.mjs CHANGED
@@ -3,7 +3,9 @@
3
3
  // .starcistacks must not be a plaintext secret (only *.enc is sealed). It is also the secrets guard of the commit: every staged file, in
4
4
  // any tree, is read from the index and judged with the one secret judgement of `starci app check` (scripts/hfs/rules/secrets.mjs: a secret by
5
5
  // being, an .enc that is no sops envelope, a line that matches a secret pattern), so no plaintext secret reaches the history whatever
6
- // .gitignore says (`git add -f`, a path tracked before a rule tightened). There is no override. At an HFS app root (hfs.json) it also
6
+ // .gitignore says (`git add -f`, a path tracked before a rule tightened). There is no override. It also
7
+ // refuses every bypass marker the index holds (R303: an inline disable, a type-check escape, a skipped test, a failure swallowed in a hook or
8
+ // workflow; scripts/lib/bypass-markers.mjs), so a bypass fails at the commit and not only at the release. At an HFS app root (hfs.json) it also
7
9
  // refuses a back-end logic file the index adds without its unit spec beside it (BE_UNIT_SPEC_NOT_STAGED,
8
10
  // scripts/hfs/rules/staged-specs.mjs over the coverage scope; a constants-only file has nothing to test), naming the file. The pre-commit hook judges the staged files;
9
11
  // scripts/gates/hfs-sync.mjs judges every tracked file.
@@ -17,6 +19,8 @@ import path from 'node:path';
17
19
  import { pathToFileURL } from 'node:url';
18
20
  import { secretFileFindings } from '../runtime/scripts/hfs/rules/secrets.mjs';
19
21
  import { stagedSpecFindings } from '../runtime/scripts/hfs/rules/staged-specs.mjs';
22
+ import { HFS_BYPASS_MARKER, bypassMessage } from '../runtime/scripts/hfs/rules/bypass-markers.mjs';
23
+ import { bypassesIn } from '../runtime/scripts/lib/bypass-markers.mjs';
20
24
  import { loadSlotManifest } from '../runtime/scripts/hfs/slots.mjs';
21
25
  import { runGit } from '../runtime/scripts/api/git/lib.mjs';
22
26
  import { loadTypescript } from '../runtime/scripts/lib/package-at.mjs';
@@ -48,7 +52,7 @@ function ignoredAmong(cwd, files) {
48
52
  }
49
53
 
50
54
  /** Violations among `files` (repository-relative, '/'-separated): [{ file, code, message }]. `ignored` is a Set of ignored paths. */
51
- function hygieneFindings(files, ignored) {
55
+ export function hygieneFindings(files, ignored) {
52
56
  const findings = [];
53
57
  for (const file of files) {
54
58
  if (file.startsWith(WORK) && ignored.has(file)) {
@@ -104,12 +108,20 @@ function secretGuardFindings(cwd, files, alreadyRefused = new Set()) {
104
108
  });
105
109
  }
106
110
 
107
- /** Findings for `files`: the guarded trees, then the secret guard over every file. */
111
+ /** The bypass markers (R303) of `files` read from the index: an inline disable, a type-check escape, a skipped test or a swallowed failure fails at the commit. */
112
+ function bypassGuardFindings(cwd, files) {
113
+ return files.flatMap(file => {
114
+ const text = stagedText(cwd, file);
115
+ return text === null ? [] : bypassesIn(file, text).map(hit => ({ file, code: HFS_BYPASS_MARKER, message: bypassMessage(file, hit) }));
116
+ });
117
+ }
118
+
119
+ /** Findings for `files`: the guarded trees, then the secret guard and the bypass guard over every file. */
108
120
  export function judge(cwd, files) {
109
121
  const guarded = files.filter(GUARDED);
110
122
  const findings = hygieneFindings(guarded, ignoredAmong(cwd, guarded.filter(file => file.startsWith(WORK))));
111
123
  const refused = new Set(findings.filter(finding => finding.code === 'HFS_PLAINTEXT_SECRET').map(finding => finding.file));
112
- return { checked: files.length, findings: [...findings, ...secretGuardFindings(cwd, files, refused)] };
124
+ return { checked: files.length, findings: [...findings, ...secretGuardFindings(cwd, files, refused), ...bypassGuardFindings(cwd, files)] };
113
125
  }
114
126
 
115
127
  // The scripts/housekeeping/ledger-hygiene.mjs of the checkout under judgment: the root git names for `cwd`, which carries
@@ -1,15 +1,16 @@
1
1
  {{header}}
2
- # Commit gate (L0 only): work hygiene and the secrets guard of the staged files, eslint of the staged files of each side,
3
- # stylelint over the staged CSS of fe, a prettier check of the staged files. Types and the targeted specs belong to the op gate.
4
- npx starci app hygiene
2
+ # Commit gate (L0 only): work hygiene, the secrets guard and the bypass guard (no inline disable, type-check escape, skipped test or
3
+ # swallowed failure: HFS_BYPASS_MARKER) of the staged files, managed files equal to their render, eslint of the staged files of each
4
+ # side, stylelint over the staged CSS of fe, a prettier check of the staged files. Every step ends the hook when it fails: none can be
5
+ # skipped. Types and the targeted specs belong to the op gate.
6
+ npx starci app hygiene || exit $?
7
+ npx starci app sync --check || exit $?
5
8
  # NUL-delimited paths keep filenames intact; bounded batches fit the Windows command line.
6
9
  git diff --cached --name-only --diff-filter=ACMR -z --relative=be -- '*.ts' '*.mts' '*.cts' '*.js' '*.mjs' '*.cjs' |
7
10
  xargs -0 -n 50 sh -c 'if [ "$#" -gt 0 ]; then cd be && npx eslint -- "$@"; fi' sh || exit $?
8
11
  git diff --cached --name-only --diff-filter=ACMR -z --relative=fe -- '*.ts' '*.tsx' '*.mts' '*.cts' '*.js' '*.jsx' '*.mjs' '*.cjs' |
9
12
  xargs -0 -n 50 sh -c 'if [ "$#" -gt 0 ]; then cd fe && npx eslint --max-warnings=0 --no-warn-ignored -- "$@"; fi' sh || exit $?
10
- styles=$(git diff --cached --name-only --diff-filter=ACMR --relative=fe -- '*.css') || exit $?
11
- if [ -n "$styles" ]; then
12
- (cd fe && npx stylelint $styles)
13
- fi
13
+ git diff --cached --name-only --diff-filter=ACMR -z --relative=fe -- '*.css' |
14
+ xargs -0 -n 50 sh -c 'if [ "$#" -gt 0 ]; then cd fe && npx stylelint "$@"; fi' sh || exit $?
14
15
  git diff --cached --name-only --diff-filter=ACMR -z |
15
16
  xargs -0 -n 50 sh -c 'if [ "$#" -gt 0 ]; then npx prettier --check --ignore-unknown -- "$@"; fi' sh || exit $?