@dzhechkov/p-replicator 1.13.2 → 1.13.3

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/.dz-manifest.json CHANGED
@@ -109,7 +109,7 @@
109
109
  },
110
110
  {
111
111
  "path": "package.json",
112
- "sha256": "c9186f299be209dd8aecd28229225dece4fdb76e6750a0d43c31ae19cbeda387"
112
+ "sha256": "09d9074650a09fe7715324b47211685755777381c8219cdecb0bfbc4d562bd0f"
113
113
  },
114
114
  {
115
115
  "path": "scripts/check-pipeline-gaps.sh",
@@ -149,7 +149,7 @@
149
149
  },
150
150
  {
151
151
  "path": "src/utils.js",
152
- "sha256": "86ed569a58e07f5aa2d31f6b932019345bc33abc00f5185601eb1f6ef9ce3815"
152
+ "sha256": "90d7b12ca01b7ee2cfee6aac68ca11431fa1a507ddfbac155c5d9802d9d91a1e"
153
153
  },
154
154
  {
155
155
  "path": "templates/.claude/agents/doc-validator.md",
@@ -201,7 +201,7 @@
201
201
  },
202
202
  {
203
203
  "path": "templates/.claude/commands/replicate.md",
204
- "sha256": "165d7b3c0606be6817893b53cbfc5ca55c7b81cbe35cbdd0dccf8679d702e81a"
204
+ "sha256": "f176d8ec871459b5a8d2111b8527331f34340d6e169da8cc7792953e3e334774"
205
205
  },
206
206
  {
207
207
  "path": "templates/.claude/commands/run.md",
@@ -231,9 +231,13 @@
231
231
  "path": "templates/.claude/hooks/check-canon.cjs",
232
232
  "sha256": "99e6bff9b0078eb2ec23f7df98b7ac06c894f9018eba4a8c358e8f92e5ec7b06"
233
233
  },
234
+ {
235
+ "path": "templates/.claude/hooks/check-dangling-refs.cjs",
236
+ "sha256": "8f012876b1af110a1093319d36a2f84208a15780dbb8abb5a43eb4aeb8f76865"
237
+ },
234
238
  {
235
239
  "path": "templates/.claude/hooks/check-docs-complete.cjs",
236
- "sha256": "27c05c2adcedc806e395b30b455243193a4fbd0968ce96e415679e1f78db951a"
240
+ "sha256": "0f516df0882c9da53d166a1b4e30ff1fc37bd5a2027c7e5fbdab6cba116ca828"
237
241
  },
238
242
  {
239
243
  "path": "templates/.claude/hooks/check-embed-contract.cjs",
@@ -305,7 +309,7 @@
305
309
  },
306
310
  {
307
311
  "path": "templates/.claude/hooks/statusline.cjs",
308
- "sha256": "50c08decec3e80ed325f50d7b062fbe0add47e8594002fcc165248492242ab56"
312
+ "sha256": "bac385da01dd9f1548d0db48a2acdada5e89a7822a7f0ecfb61cb74ff4cda138"
309
313
  },
310
314
  {
311
315
  "path": "templates/.claude/hooks/write-insight.cjs",
@@ -313,11 +317,11 @@
313
317
  },
314
318
  {
315
319
  "path": "templates/.claude/rules/cost-of-detection-ladder.md",
316
- "sha256": "f15309ee8f1494478ff7678380dbe8fc8eecd154be36d57c9090cd17126a07da"
320
+ "sha256": "d2e7da3d56c8d4c6d1aa58e793fa0d5eecd65a5c01be38dfa0dc434273306838"
317
321
  },
318
322
  {
319
323
  "path": "templates/.claude/rules/docker-ports.md",
320
- "sha256": "59eb430f29dd762e8b76ad6d1177fe8b5b250de007856c743387cb88ee157942"
324
+ "sha256": "a9e5bb9a797ea4ef4c0671cee2cbec95f2557f8b9e1d20b84bbcee7ce4c21162"
321
325
  },
322
326
  {
323
327
  "path": "templates/.claude/rules/embeddable-widget.md",
@@ -325,7 +329,7 @@
325
329
  },
326
330
  {
327
331
  "path": "templates/.claude/rules/feature-lifecycle.md",
328
- "sha256": "4e926f84f244feb6824114a0624733738669c93e0508693fa2afa4e9a35c2aa3"
332
+ "sha256": "a7d0adf6bc63b942d3dec339b3ae68972c3dedc0b48a91d27653309c7da7f11f"
329
333
  },
330
334
  {
331
335
  "path": "templates/.claude/rules/git-workflow.md",
@@ -353,7 +357,7 @@
353
357
  },
354
358
  {
355
359
  "path": "templates/.claude/rules/replicate-pipeline.md",
356
- "sha256": "13bf073273820addeb87167402495b2f683cefac70a9f6cb07b6e054b1851e0f"
360
+ "sha256": "9c4bbaa9ac628ec5d4e44d3ace6eec0b5bd602b5dccc5d36f123d73be448f159"
357
361
  },
358
362
  {
359
363
  "path": "templates/.claude/rules/skill-interface-protocol.md",
@@ -381,7 +385,7 @@
381
385
  },
382
386
  {
383
387
  "path": "templates/.claude/skills/brutal-honesty-review/resources/assessment-rubrics.md",
384
- "sha256": "dac09c91c765e2211799cc230738fb72a966f47511edb872306a906e49640cbe"
388
+ "sha256": "b64894e1ddf8b9da7f2f146c737d35215e7281e3d8be10891d4a9b8aa2bd6d07"
385
389
  },
386
390
  {
387
391
  "path": "templates/.claude/skills/brutal-honesty-review/resources/review-template.md",
@@ -465,7 +469,7 @@
465
469
  },
466
470
  {
467
471
  "path": "templates/.claude/skills/cc-toolkit-generator-enhanced/references/security-patterns-library.md",
468
- "sha256": "5f1d650c426cbd2c9536b385306605ea62a5a520ee4566d23ca7254409c672a5"
472
+ "sha256": "4a7fae9ea1870c30b71c923fd5d3626a8926c5e960209fad709f4b8e0534fc80"
469
473
  },
470
474
  {
471
475
  "path": "templates/.claude/skills/cc-toolkit-generator-enhanced/references/templates/automation-commands.md",
@@ -869,7 +873,7 @@
869
873
  },
870
874
  {
871
875
  "path": "tests/snapshot/baseline.json",
872
- "sha256": "2e442fcb5f39de9f94c2284d385368f2e984bb17998556c41ac9f4f676a6134e"
876
+ "sha256": "31801798e099c5e43e60de29c3487a586fe6b906b2135ea1060861567d36fdfb"
873
877
  },
874
878
  {
875
879
  "path": "tests/snapshot/templates.test.js",
@@ -901,12 +905,16 @@
901
905
  },
902
906
  {
903
907
  "path": "tests/unit/capture-source-path.test.js",
904
- "sha256": "771ee1bb495fe4a60b2fa58cc8009e52610c38145059532d3e158581fdb66d93"
908
+ "sha256": "cce205634906882d7b8dc9c54dbbfc89abcafe59dd0ff5d0a9ef595e8e1c5356"
905
909
  },
906
910
  {
907
911
  "path": "tests/unit/check-canon.test.js",
908
912
  "sha256": "df1aad467e0ed38471dad55547c1af6115ec9daaa5c40e9142e4ce67fedcb1bf"
909
913
  },
914
+ {
915
+ "path": "tests/unit/check-dangling-refs.test.js",
916
+ "sha256": "8571d325047e0624d273b2058ca55732360ede48e433750a86aa79b3aba9b273"
917
+ },
910
918
  {
911
919
  "path": "tests/unit/check-docs-complete.test.js",
912
920
  "sha256": "2c6f16a61f0876f637ac492d5fb2af1ea35ad00161fd1468446ea0d08cd97f4b"
@@ -1029,11 +1037,11 @@
1029
1037
  },
1030
1038
  {
1031
1039
  "path": "tests/unit/guard-honest-input-meta.test.js",
1032
- "sha256": "b8e6513e09e774b83b2f05ac42d35c4849ef81b58e600e442dd22cf1071d02f3"
1040
+ "sha256": "5996879d9fdf6e194f40b32fff525bf9f257bbfb90719438e21850b15150ded1"
1033
1041
  },
1034
1042
  {
1035
1043
  "path": "tests/unit/honest-failure-rules.test.js",
1036
- "sha256": "176115fafdca146eff0ebf87361fe6d0f26c7c3621cda03da0140ab72ba9f1ac"
1044
+ "sha256": "f42d66af4e430e5915b7e8daec9bb2c9a5df9f43960863443ec0076d99f6ad67"
1037
1045
  },
1038
1046
  {
1039
1047
  "path": "tests/unit/hooks-project-anchored.test.js",
@@ -1065,7 +1073,11 @@
1065
1073
  },
1066
1074
  {
1067
1075
  "path": "tests/unit/negative-conclusion-gate.test.js",
1068
- "sha256": "7ffbcfdf638941511dc78c048d5056812e63af203cdf7c9bc757a22540cca14e"
1076
+ "sha256": "6c6a470d22d12ff46301c4ae61ba7a2563c4ff8a3a2d5b3a84c81c6b8c11b067"
1077
+ },
1078
+ {
1079
+ "path": "tests/unit/optional-doc-idiom.test.js",
1080
+ "sha256": "f25338f5928e9d1cba82cdc88506d46256f2b567d7524f159512cb8e06b21f06"
1069
1081
  },
1070
1082
  {
1071
1083
  "path": "tests/unit/pipeline-file-ownership.test.js",
@@ -1073,7 +1085,7 @@
1073
1085
  },
1074
1086
  {
1075
1087
  "path": "tests/unit/quote-provenance.test.js",
1076
- "sha256": "e9f50ec67b8dde73d609c1df6bbeafa7eaf23f3ae62785362b57d09e3b7e6c70"
1088
+ "sha256": "a6e5416318e22107e728e8800716d4697ff4b8edf00f6fc16019754afe03bbb1"
1077
1089
  },
1078
1090
  {
1079
1091
  "path": "tests/unit/roadmap-one-schema.test.js",
@@ -1117,7 +1129,7 @@
1117
1129
  },
1118
1130
  {
1119
1131
  "path": "tests/unit/traceability-negative-fixture.test.js",
1120
- "sha256": "abc54e0e00138ecc6d75e0cbc496cbd888cd97b1ed567b7d23557f0674b5c161"
1132
+ "sha256": "f27e812e6ea45e3cc5b21a531e0b3e95517ad7419431ed4fa8dd27628d33faff"
1121
1133
  },
1122
1134
  {
1123
1135
  "path": "tests/unit/utils.test.js",
@@ -1126,8 +1138,12 @@
1126
1138
  {
1127
1139
  "path": "tests/unit/validation-gate-teeth.test.js",
1128
1140
  "sha256": "d4f42a26b67b2fa1dfa8db9984c301a7d7e91657e5e2cdabb1bab307c766138d"
1141
+ },
1142
+ {
1143
+ "path": "tests/unit/verdict-vocabulary.test.js",
1144
+ "sha256": "55982f29de66852d085b561195b495d348a649079f5799658de3b43b697d0532"
1129
1145
  }
1130
1146
  ]
1131
1147
  },
1132
- "signature": "3K1btPFoe+6u7Nk2opxXnAGF/NbPIv3vow6HbjRyiaCvDUVAUf/KLukvcH9uxbz9eZlTilznynFrRLZmEpj5Dw=="
1148
+ "signature": "DsIFOeT4ntNvUrhbFwpDHt7FDAAAq0dlLrVkPqSmxOmk8sER5xd7d2L7OvMEeaFFzfobe6IYFNtJlv5ISvtiCA=="
1133
1149
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dzhechkov/p-replicator",
3
- "version": "1.13.2",
3
+ "version": "1.13.3",
4
4
  "description": "P-Replicator — Claude Code toolkit for AI-assisted product development (Vibe Coding). Full /replicate pipeline, 10 modular skills (880K+ chars), /harvest knowledge extraction, swarm agents, quality gates, security patterns, cross-project learning.",
5
5
  "main": "src/cli.js",
6
6
  "bin": {
@@ -73,11 +73,12 @@
73
73
  "access": "public"
74
74
  },
75
75
  "scripts": {
76
- "test": "node --test tests/unit/honest-failure-rules.test.js tests/unit/generator-swarm-contract.test.js tests/unit/check-swarm-receipts.test.js tests/unit/check-embed-contract.test.js tests/unit/check-model-cost.test.js tests/unit/check-canon.test.js tests/unit/check-file-ownership.test.js tests/unit/check-source-version.test.js tests/unit/check-handoff-manifest.test.js tests/unit/check-external-deps.test.js tests/unit/check-metric-source.test.js tests/unit/negative-conclusion-gate.test.js tests/unit/check-webhook-contract.test.js tests/unit/check-job-contract.test.js tests/unit/detection-ladder-contract.test.js tests/unit/detection-ladder-registry.test.js tests/unit/utils.test.js tests/unit/adr-scanner-contract.test.js tests/unit/sparc-reconciliation.test.js tests/unit/pipeline-file-ownership.test.js tests/unit/validation-gate-teeth.test.js tests/unit/hooks-project-anchored.test.js tests/unit/insights-dz-delegation.test.js tests/unit/statusline-two-roots.test.js tests/unit/external-dependency-check.test.js tests/unit/spec-pseudocode-traceability.test.js tests/unit/sync-templates-guard.test.js tests/unit/db-port-rule.test.js tests/unit/roadmap-one-schema.test.js tests/unit/hooks-report-failures.test.js tests/unit/growth-module-b2b-gate.test.js tests/unit/detect-parse-anchor.test.js tests/unit/statusline-honest-labels.test.js tests/unit/autocommit-deletion.test.js tests/unit/check-ports.test.js tests/unit/doctor-insight-flow.test.js tests/unit/adr-decision-coverage.test.js tests/unit/growth-requirements-bridge.test.js tests/unit/check-growth-trace.test.js tests/unit/check-look-trace.test.js tests/unit/check-look-origin.test.js tests/unit/quote-provenance.test.js tests/unit/guard-honest-input-meta.test.js tests/unit/look-phase-contract.test.js tests/unit/capture-source-path.test.js tests/unit/growth-gate-conditional.test.js tests/unit/module-copy-identity.test.js tests/unit/growth-axes-and-compliance.test.js tests/unit/skill-paths-prebaked.test.js tests/unit/check-docs-complete.test.js tests/unit/check-review-contract.test.js tests/unit/absence-is-not-emptiness.test.js tests/unit/guard-forms.test.js tests/unit/generated-guard-templates.test.js tests/unit/shipped-suite-context.test.js tests/unit/assess-scripts.test.js tests/unit/insights-docs-tell-the-truth.test.js tests/unit/insights-writer.test.js tests/unit/check-pipeline-gaps.test.js tests/unit/traceability-machine-ids.test.js tests/unit/traceability-completion-gate.test.js tests/unit/traceability-negative-fixture.test.js tests/e2e/lifecycle.test.js tests/e2e/feature-contour.test.js tests/e2e/packed-insights-writer.test.js tests/snapshot/templates.test.js",
77
- "test:unit": "node --test tests/unit/honest-failure-rules.test.js tests/unit/generator-swarm-contract.test.js tests/unit/check-swarm-receipts.test.js tests/unit/check-embed-contract.test.js tests/unit/check-model-cost.test.js tests/unit/check-canon.test.js tests/unit/check-file-ownership.test.js tests/unit/check-source-version.test.js tests/unit/check-handoff-manifest.test.js tests/unit/check-external-deps.test.js tests/unit/check-metric-source.test.js tests/unit/negative-conclusion-gate.test.js tests/unit/check-webhook-contract.test.js tests/unit/check-job-contract.test.js tests/unit/detection-ladder-contract.test.js tests/unit/detection-ladder-registry.test.js tests/unit/utils.test.js tests/unit/adr-scanner-contract.test.js tests/unit/sparc-reconciliation.test.js tests/unit/pipeline-file-ownership.test.js tests/unit/validation-gate-teeth.test.js tests/unit/hooks-project-anchored.test.js tests/unit/insights-dz-delegation.test.js tests/unit/statusline-two-roots.test.js tests/unit/external-dependency-check.test.js tests/unit/spec-pseudocode-traceability.test.js tests/unit/sync-templates-guard.test.js tests/unit/db-port-rule.test.js tests/unit/roadmap-one-schema.test.js tests/unit/hooks-report-failures.test.js tests/unit/growth-module-b2b-gate.test.js tests/unit/detect-parse-anchor.test.js tests/unit/statusline-honest-labels.test.js tests/unit/autocommit-deletion.test.js tests/unit/check-ports.test.js tests/unit/doctor-insight-flow.test.js tests/unit/adr-decision-coverage.test.js tests/unit/growth-requirements-bridge.test.js tests/unit/check-growth-trace.test.js tests/unit/check-look-trace.test.js tests/unit/check-look-origin.test.js tests/unit/quote-provenance.test.js tests/unit/guard-honest-input-meta.test.js tests/unit/look-phase-contract.test.js tests/unit/capture-source-path.test.js tests/unit/growth-gate-conditional.test.js tests/unit/module-copy-identity.test.js tests/unit/growth-axes-and-compliance.test.js tests/unit/skill-paths-prebaked.test.js tests/unit/check-docs-complete.test.js tests/unit/check-review-contract.test.js tests/unit/absence-is-not-emptiness.test.js tests/unit/guard-forms.test.js tests/unit/generated-guard-templates.test.js tests/unit/shipped-suite-context.test.js tests/unit/assess-scripts.test.js tests/unit/insights-docs-tell-the-truth.test.js tests/unit/insights-writer.test.js tests/unit/check-pipeline-gaps.test.js tests/unit/traceability-machine-ids.test.js tests/unit/traceability-completion-gate.test.js tests/unit/traceability-negative-fixture.test.js",
76
+ "test": "node --test tests/unit/honest-failure-rules.test.js tests/unit/generator-swarm-contract.test.js tests/unit/check-swarm-receipts.test.js tests/unit/check-embed-contract.test.js tests/unit/check-model-cost.test.js tests/unit/check-canon.test.js tests/unit/check-file-ownership.test.js tests/unit/check-source-version.test.js tests/unit/check-handoff-manifest.test.js tests/unit/check-external-deps.test.js tests/unit/check-metric-source.test.js tests/unit/negative-conclusion-gate.test.js tests/unit/check-webhook-contract.test.js tests/unit/check-job-contract.test.js tests/unit/detection-ladder-contract.test.js tests/unit/detection-ladder-registry.test.js tests/unit/utils.test.js tests/unit/adr-scanner-contract.test.js tests/unit/sparc-reconciliation.test.js tests/unit/pipeline-file-ownership.test.js tests/unit/validation-gate-teeth.test.js tests/unit/hooks-project-anchored.test.js tests/unit/insights-dz-delegation.test.js tests/unit/statusline-two-roots.test.js tests/unit/external-dependency-check.test.js tests/unit/spec-pseudocode-traceability.test.js tests/unit/sync-templates-guard.test.js tests/unit/db-port-rule.test.js tests/unit/roadmap-one-schema.test.js tests/unit/hooks-report-failures.test.js tests/unit/growth-module-b2b-gate.test.js tests/unit/detect-parse-anchor.test.js tests/unit/statusline-honest-labels.test.js tests/unit/autocommit-deletion.test.js tests/unit/check-ports.test.js tests/unit/doctor-insight-flow.test.js tests/unit/adr-decision-coverage.test.js tests/unit/growth-requirements-bridge.test.js tests/unit/check-growth-trace.test.js tests/unit/check-look-trace.test.js tests/unit/check-look-origin.test.js tests/unit/quote-provenance.test.js tests/unit/guard-honest-input-meta.test.js tests/unit/look-phase-contract.test.js tests/unit/growth-gate-conditional.test.js tests/unit/module-copy-identity.test.js tests/unit/growth-axes-and-compliance.test.js tests/unit/skill-paths-prebaked.test.js tests/unit/check-docs-complete.test.js tests/unit/check-review-contract.test.js tests/unit/absence-is-not-emptiness.test.js tests/unit/guard-forms.test.js tests/unit/generated-guard-templates.test.js tests/unit/shipped-suite-context.test.js tests/unit/assess-scripts.test.js tests/unit/insights-docs-tell-the-truth.test.js tests/unit/insights-writer.test.js tests/unit/check-pipeline-gaps.test.js tests/unit/traceability-machine-ids.test.js tests/unit/traceability-completion-gate.test.js tests/unit/traceability-negative-fixture.test.js tests/e2e/lifecycle.test.js tests/e2e/feature-contour.test.js tests/e2e/packed-insights-writer.test.js tests/snapshot/templates.test.js tests/unit/optional-doc-idiom.test.js tests/unit/verdict-vocabulary.test.js tests/unit/check-dangling-refs.test.js test/mutation-registry-freshness.test.js",
77
+ "test:unit": "node --test tests/unit/honest-failure-rules.test.js tests/unit/generator-swarm-contract.test.js tests/unit/check-swarm-receipts.test.js tests/unit/check-embed-contract.test.js tests/unit/check-model-cost.test.js tests/unit/check-canon.test.js tests/unit/check-file-ownership.test.js tests/unit/check-source-version.test.js tests/unit/check-handoff-manifest.test.js tests/unit/check-external-deps.test.js tests/unit/check-metric-source.test.js tests/unit/negative-conclusion-gate.test.js tests/unit/check-webhook-contract.test.js tests/unit/check-job-contract.test.js tests/unit/detection-ladder-contract.test.js tests/unit/detection-ladder-registry.test.js tests/unit/utils.test.js tests/unit/adr-scanner-contract.test.js tests/unit/sparc-reconciliation.test.js tests/unit/pipeline-file-ownership.test.js tests/unit/validation-gate-teeth.test.js tests/unit/hooks-project-anchored.test.js tests/unit/insights-dz-delegation.test.js tests/unit/statusline-two-roots.test.js tests/unit/external-dependency-check.test.js tests/unit/spec-pseudocode-traceability.test.js tests/unit/sync-templates-guard.test.js tests/unit/db-port-rule.test.js tests/unit/roadmap-one-schema.test.js tests/unit/hooks-report-failures.test.js tests/unit/growth-module-b2b-gate.test.js tests/unit/detect-parse-anchor.test.js tests/unit/statusline-honest-labels.test.js tests/unit/autocommit-deletion.test.js tests/unit/check-ports.test.js tests/unit/doctor-insight-flow.test.js tests/unit/adr-decision-coverage.test.js tests/unit/growth-requirements-bridge.test.js tests/unit/check-growth-trace.test.js tests/unit/check-look-trace.test.js tests/unit/check-look-origin.test.js tests/unit/quote-provenance.test.js tests/unit/guard-honest-input-meta.test.js tests/unit/look-phase-contract.test.js tests/unit/growth-gate-conditional.test.js tests/unit/module-copy-identity.test.js tests/unit/growth-axes-and-compliance.test.js tests/unit/skill-paths-prebaked.test.js tests/unit/check-docs-complete.test.js tests/unit/check-review-contract.test.js tests/unit/absence-is-not-emptiness.test.js tests/unit/guard-forms.test.js tests/unit/generated-guard-templates.test.js tests/unit/shipped-suite-context.test.js tests/unit/assess-scripts.test.js tests/unit/insights-docs-tell-the-truth.test.js tests/unit/insights-writer.test.js tests/unit/check-pipeline-gaps.test.js tests/unit/traceability-machine-ids.test.js tests/unit/traceability-completion-gate.test.js tests/unit/traceability-negative-fixture.test.js tests/unit/optional-doc-idiom.test.js tests/unit/verdict-vocabulary.test.js tests/unit/check-dangling-refs.test.js",
78
78
  "test:e2e": "node --test tests/e2e/lifecycle.test.js tests/e2e/packed-insights-writer.test.js",
79
79
  "test:snapshot": "node --test tests/snapshot/templates.test.js",
80
80
  "test:doctor": "node bin/cli.js doctor",
81
- "snapshot:baseline": "node tests/snapshot/update-baseline.js"
81
+ "snapshot:baseline": "node tests/snapshot/update-baseline.js",
82
+ "test:browser": "node --test tests/unit/capture-source-path.test.js"
82
83
  }
83
84
  }
package/sbom.json CHANGED
@@ -279,7 +279,7 @@
279
279
  },
280
280
  {
281
281
  "name": "dz:canonical-json-sha256-v2",
282
- "value": "c9186f299be209dd8aecd28229225dece4fdb76e6750a0d43c31ae19cbeda387"
282
+ "value": "09d9074650a09fe7715324b47211685755777381c8219cdecb0bfbc4d562bd0f"
283
283
  }
284
284
  ]
285
285
  },
@@ -379,7 +379,7 @@
379
379
  "hashes": [
380
380
  {
381
381
  "alg": "SHA-256",
382
- "content": "86ed569a58e07f5aa2d31f6b932019345bc33abc00f5185601eb1f6ef9ce3815"
382
+ "content": "90d7b12ca01b7ee2cfee6aac68ca11431fa1a507ddfbac155c5d9802d9d91a1e"
383
383
  }
384
384
  ]
385
385
  },
@@ -509,7 +509,7 @@
509
509
  "hashes": [
510
510
  {
511
511
  "alg": "SHA-256",
512
- "content": "165d7b3c0606be6817893b53cbfc5ca55c7b81cbe35cbdd0dccf8679d702e81a"
512
+ "content": "f176d8ec871459b5a8d2111b8527331f34340d6e169da8cc7792953e3e334774"
513
513
  }
514
514
  ]
515
515
  },
@@ -583,13 +583,23 @@
583
583
  }
584
584
  ]
585
585
  },
586
+ {
587
+ "type": "file",
588
+ "name": "templates/.claude/hooks/check-dangling-refs.cjs",
589
+ "hashes": [
590
+ {
591
+ "alg": "SHA-256",
592
+ "content": "8f012876b1af110a1093319d36a2f84208a15780dbb8abb5a43eb4aeb8f76865"
593
+ }
594
+ ]
595
+ },
586
596
  {
587
597
  "type": "file",
588
598
  "name": "templates/.claude/hooks/check-docs-complete.cjs",
589
599
  "hashes": [
590
600
  {
591
601
  "alg": "SHA-256",
592
- "content": "27c05c2adcedc806e395b30b455243193a4fbd0968ce96e415679e1f78db951a"
602
+ "content": "0f516df0882c9da53d166a1b4e30ff1fc37bd5a2027c7e5fbdab6cba116ca828"
593
603
  }
594
604
  ]
595
605
  },
@@ -769,7 +779,7 @@
769
779
  "hashes": [
770
780
  {
771
781
  "alg": "SHA-256",
772
- "content": "50c08decec3e80ed325f50d7b062fbe0add47e8594002fcc165248492242ab56"
782
+ "content": "bac385da01dd9f1548d0db48a2acdada5e89a7822a7f0ecfb61cb74ff4cda138"
773
783
  }
774
784
  ]
775
785
  },
@@ -789,7 +799,7 @@
789
799
  "hashes": [
790
800
  {
791
801
  "alg": "SHA-256",
792
- "content": "f15309ee8f1494478ff7678380dbe8fc8eecd154be36d57c9090cd17126a07da"
802
+ "content": "d2e7da3d56c8d4c6d1aa58e793fa0d5eecd65a5c01be38dfa0dc434273306838"
793
803
  }
794
804
  ]
795
805
  },
@@ -799,7 +809,7 @@
799
809
  "hashes": [
800
810
  {
801
811
  "alg": "SHA-256",
802
- "content": "59eb430f29dd762e8b76ad6d1177fe8b5b250de007856c743387cb88ee157942"
812
+ "content": "a9e5bb9a797ea4ef4c0671cee2cbec95f2557f8b9e1d20b84bbcee7ce4c21162"
803
813
  }
804
814
  ]
805
815
  },
@@ -819,7 +829,7 @@
819
829
  "hashes": [
820
830
  {
821
831
  "alg": "SHA-256",
822
- "content": "4e926f84f244feb6824114a0624733738669c93e0508693fa2afa4e9a35c2aa3"
832
+ "content": "a7d0adf6bc63b942d3dec339b3ae68972c3dedc0b48a91d27653309c7da7f11f"
823
833
  }
824
834
  ]
825
835
  },
@@ -889,7 +899,7 @@
889
899
  "hashes": [
890
900
  {
891
901
  "alg": "SHA-256",
892
- "content": "13bf073273820addeb87167402495b2f683cefac70a9f6cb07b6e054b1851e0f"
902
+ "content": "9c4bbaa9ac628ec5d4e44d3ace6eec0b5bd602b5dccc5d36f123d73be448f159"
893
903
  }
894
904
  ]
895
905
  },
@@ -959,7 +969,7 @@
959
969
  "hashes": [
960
970
  {
961
971
  "alg": "SHA-256",
962
- "content": "dac09c91c765e2211799cc230738fb72a966f47511edb872306a906e49640cbe"
972
+ "content": "b64894e1ddf8b9da7f2f146c737d35215e7281e3d8be10891d4a9b8aa2bd6d07"
963
973
  }
964
974
  ]
965
975
  },
@@ -1169,7 +1179,7 @@
1169
1179
  "hashes": [
1170
1180
  {
1171
1181
  "alg": "SHA-256",
1172
- "content": "5f1d650c426cbd2c9536b385306605ea62a5a520ee4566d23ca7254409c672a5"
1182
+ "content": "4a7fae9ea1870c30b71c923fd5d3626a8926c5e960209fad709f4b8e0534fc80"
1173
1183
  }
1174
1184
  ]
1175
1185
  },
@@ -2179,7 +2189,7 @@
2179
2189
  "hashes": [
2180
2190
  {
2181
2191
  "alg": "SHA-256",
2182
- "content": "2e442fcb5f39de9f94c2284d385368f2e984bb17998556c41ac9f4f676a6134e"
2192
+ "content": "31801798e099c5e43e60de29c3487a586fe6b906b2135ea1060861567d36fdfb"
2183
2193
  }
2184
2194
  ]
2185
2195
  },
@@ -2259,7 +2269,7 @@
2259
2269
  "hashes": [
2260
2270
  {
2261
2271
  "alg": "SHA-256",
2262
- "content": "771ee1bb495fe4a60b2fa58cc8009e52610c38145059532d3e158581fdb66d93"
2272
+ "content": "cce205634906882d7b8dc9c54dbbfc89abcafe59dd0ff5d0a9ef595e8e1c5356"
2263
2273
  }
2264
2274
  ]
2265
2275
  },
@@ -2273,6 +2283,16 @@
2273
2283
  }
2274
2284
  ]
2275
2285
  },
2286
+ {
2287
+ "type": "file",
2288
+ "name": "tests/unit/check-dangling-refs.test.js",
2289
+ "hashes": [
2290
+ {
2291
+ "alg": "SHA-256",
2292
+ "content": "8571d325047e0624d273b2058ca55732360ede48e433750a86aa79b3aba9b273"
2293
+ }
2294
+ ]
2295
+ },
2276
2296
  {
2277
2297
  "type": "file",
2278
2298
  "name": "tests/unit/check-docs-complete.test.js",
@@ -2579,7 +2599,7 @@
2579
2599
  "hashes": [
2580
2600
  {
2581
2601
  "alg": "SHA-256",
2582
- "content": "b8e6513e09e774b83b2f05ac42d35c4849ef81b58e600e442dd22cf1071d02f3"
2602
+ "content": "5996879d9fdf6e194f40b32fff525bf9f257bbfb90719438e21850b15150ded1"
2583
2603
  }
2584
2604
  ]
2585
2605
  },
@@ -2589,7 +2609,7 @@
2589
2609
  "hashes": [
2590
2610
  {
2591
2611
  "alg": "SHA-256",
2592
- "content": "176115fafdca146eff0ebf87361fe6d0f26c7c3621cda03da0140ab72ba9f1ac"
2612
+ "content": "f42d66af4e430e5915b7e8daec9bb2c9a5df9f43960863443ec0076d99f6ad67"
2593
2613
  }
2594
2614
  ]
2595
2615
  },
@@ -2669,7 +2689,17 @@
2669
2689
  "hashes": [
2670
2690
  {
2671
2691
  "alg": "SHA-256",
2672
- "content": "7ffbcfdf638941511dc78c048d5056812e63af203cdf7c9bc757a22540cca14e"
2692
+ "content": "6c6a470d22d12ff46301c4ae61ba7a2563c4ff8a3a2d5b3a84c81c6b8c11b067"
2693
+ }
2694
+ ]
2695
+ },
2696
+ {
2697
+ "type": "file",
2698
+ "name": "tests/unit/optional-doc-idiom.test.js",
2699
+ "hashes": [
2700
+ {
2701
+ "alg": "SHA-256",
2702
+ "content": "f25338f5928e9d1cba82cdc88506d46256f2b567d7524f159512cb8e06b21f06"
2673
2703
  }
2674
2704
  ]
2675
2705
  },
@@ -2689,7 +2719,7 @@
2689
2719
  "hashes": [
2690
2720
  {
2691
2721
  "alg": "SHA-256",
2692
- "content": "e9f50ec67b8dde73d609c1df6bbeafa7eaf23f3ae62785362b57d09e3b7e6c70"
2722
+ "content": "a6e5416318e22107e728e8800716d4697ff4b8edf00f6fc16019754afe03bbb1"
2693
2723
  }
2694
2724
  ]
2695
2725
  },
@@ -2799,7 +2829,7 @@
2799
2829
  "hashes": [
2800
2830
  {
2801
2831
  "alg": "SHA-256",
2802
- "content": "abc54e0e00138ecc6d75e0cbc496cbd888cd97b1ed567b7d23557f0674b5c161"
2832
+ "content": "f27e812e6ea45e3cc5b21a531e0b3e95517ad7419431ed4fa8dd27628d33faff"
2803
2833
  }
2804
2834
  ]
2805
2835
  },
@@ -2822,6 +2852,16 @@
2822
2852
  "content": "d4f42a26b67b2fa1dfa8db9984c301a7d7e91657e5e2cdabb1bab307c766138d"
2823
2853
  }
2824
2854
  ]
2855
+ },
2856
+ {
2857
+ "type": "file",
2858
+ "name": "tests/unit/verdict-vocabulary.test.js",
2859
+ "hashes": [
2860
+ {
2861
+ "alg": "SHA-256",
2862
+ "content": "55982f29de66852d085b561195b495d348a649079f5799658de3b43b697d0532"
2863
+ }
2864
+ ]
2825
2865
  }
2826
2866
  ]
2827
2867
  }
package/src/utils.js CHANGED
@@ -354,6 +354,7 @@ const COMPONENTS = {
354
354
  'write-insight': 'Validate and append one harvest insight to the project Markdown carrier',
355
355
  'check-ports': 'Enforce docker-ports Правило №0 against a real compose (invoke deliberately; exits 0/1/2)',
356
356
  'check-growth-trace': 'Did the M5 growth seed reach docs/Specification.md (invoke deliberately; exits 0/1/2)',
357
+ 'check-dangling-refs': 'Does shipped prose reference a file that does not exist? (invoke deliberately; exits 0 within baseline, 1 above it, 2 when .claude is absent)',
357
358
  'check-look-trace': 'Did the Phase-0.5 source-look seed reach docs/Specification.md (invoke deliberately; exits 0/1/2)',
358
359
  'check-look-origin': 'Did a third-party-analysis HYPOTHESIS row reach Specification.md without dated live confirmation (invoke deliberately; exits 0/1/2)',
359
360
  'check-review-contract': 'Does review-report.md answer every AC id, disclose the reviewer family and name the spec revision it judged (exits 0/1/2)',
@@ -343,7 +343,15 @@ Security Pattern: # If external integrations
343
343
  server_side: "No key storage on backend"
344
344
  ```
345
345
 
346
- **Mode:** MANUAL (checkpoint at each phase inside sparc-prd-mini)
346
+ **Mode:** MANUAL checkpoint at each phase inside `sparc-prd-mini`.
347
+
348
+ > **Решение владельца 2026-09-03: MANUAL остаётся.** Ночью 2026-09-03 строка была изменена на AUTO
349
+ > как устранение противоречия: навык `sparc-prd-mini` объявляет AUTO своим режимом по умолчанию
350
+ > (`SKILL.md:35`), а эта команда навязывала MANUAL. Противоречие реально, но владелец разрешил его
351
+ > в другую сторону: остановки на фазах — не накладной расход, а точки, где он может отказаться от
352
+ > рамки до того, как она станет кодом. ИЗМЕРЕНО, чтобы цена решения была известна: остановок до
353
+ > первой строки кода тринадцать — пять в этом файле и восемь внутри навыка. Их сохраняют
354
+ > сознательно.
347
355
 
348
356
  **Output location:** `docs/` directory (NOT `/output/` — write directly into the project)
349
357
 
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ /**
4
+ * check-dangling-refs.cjs — текст ссылается на файл, которого нет?
5
+ *
6
+ * NOT an event hook. Как `check-look-trace.cjs` и соседи, лежит здесь потому, что каталог уже несёт
7
+ * простые утилиты на Node; в `settings.json` он не зарегистрирован и потому вправе отказывать
8
+ * ненулевым кодом.
9
+ *
10
+ * ─── ЗАЧЕМ ───────────────────────────────────────────────────────────────────
11
+ * Один класс дефекта ловился вручную минимум четыре раза: список хуков называл 4 из 8; таблица
12
+ * говорила «Rules 5» при шести; справка обещала 18 видов отказа при 17 в массиве; путь вывода
13
+ * называл каталог, которого не бывает. Форма всегда одна — ТЕКСТ ССЫЛАЕТСЯ НА ОБЪЕКТ, КОТОРОГО НЕТ,
14
+ * и ни одна застава об этом не спрашивала. `verify` спросить не может по построению: он обходит
15
+ * зарегистрированные КОМПОНЕНТЫ и проверяет их наличие, то есть идёт от объекта к тексту, а не от
16
+ * текста к объекту.
17
+ *
18
+ * ─── ЧТО ОН ДЕЛАЕТ, И ЧЕГО НЕ ДЕЛАЕТ ─────────────────────────────────────────
19
+ * Обходит отгружаемые `*.md`, вытаскивает ссылки вида `` `.claude/<путь>` `` на файлы с известными
20
+ * расширениями и проверяет существование цели. Он НЕ разбирает прозу и НЕ угадывает намерение:
21
+ * ссылка засчитывается, только если она в обратных кавычках и оканчивается на расширение из списка.
22
+ * Ссылка на каталог не проверяется вовсе — каталог может создаваться в работе.
23
+ *
24
+ * ─── ПОЧЕМУ БАЗА, А НЕ ПРОСТО ОТКАЗ ──────────────────────────────────────────
25
+ * ИЗМЕРЕНО 2026-09-03 на свежем дереве: 58 висячих ссылок в 23 файлах, и они не появляются после
26
+ * `init` — проверено на пустом проекте. Отказать на всех значило бы отказать каждому проекту прямо
27
+ * сейчас, то есть выключить заставу в первый же день. Поэтому база ЗАКРЕПЛЕНА числом и может только
28
+ * УМЕНЬШАТЬСЯ: новая висячая ссылка даёт отказ, а починка старой обязана уменьшить базу, иначе
29
+ * тест краснеет. Это тот же приём, которым в пакете уже ретирован `Final_Summary.md`: сообщаем,
30
+ * пока не решили, но фиксируем состояние датой и не даём ему ухудшаться.
31
+ *
32
+ * Коды: 0 — не хуже базы · 1 — база превышена (названы новые) · 2 — не удалось установить.
33
+ */
34
+
35
+ const fs = require('node:fs');
36
+ const path = require('node:path');
37
+
38
+ /** ИЗМЕРЕНО 2026-09-03 на снимке дерева; может только уменьшаться. */
39
+ const BASELINE = 58;
40
+
41
+ const REF = /`(\.claude\/[A-Za-z0-9_\-./]+\.(?:cjs|mjs|js|sh|md|json|yaml|yml))`/g;
42
+
43
+ function walk(dir) {
44
+ return fs.readdirSync(dir, { withFileTypes: true }).flatMap((e) => {
45
+ const p = path.join(dir, e.name);
46
+ return e.isDirectory() ? walk(p) : [p];
47
+ });
48
+ }
49
+
50
+ /** Pure half: given a root holding `.claude/`, return every dangling reference found. */
51
+ function danglingRefs(root) {
52
+ const base = path.join(root, '.claude');
53
+ if (!fs.existsSync(base)) return null; // не установлено — код 2, а не «чисто»
54
+ const out = [];
55
+ for (const file of walk(base)) {
56
+ if (!file.endsWith('.md')) continue;
57
+ const src = fs.readFileSync(file, 'utf8');
58
+ let m;
59
+ while ((m = REF.exec(src))) {
60
+ const target = path.join(root, m[1]);
61
+ if (!fs.existsSync(target)) out.push({ from: path.relative(root, file), to: m[1] });
62
+ }
63
+ }
64
+ return out;
65
+ }
66
+
67
+ function main(argv) {
68
+ const root = argv[2] || process.cwd();
69
+ const found = danglingRefs(root);
70
+ if (found === null) {
71
+ console.error(`НЕ УСТАНОВЛЕНО: каталог .claude не найден в ${root} — проверка не выполнялась, и это не «чисто»`);
72
+ return 2;
73
+ }
74
+ const unique = [...new Set(found.map((f) => `${f.from} → ${f.to}`))];
75
+ if (unique.length > BASELINE) {
76
+ console.error(`❌ висячих ссылок ${unique.length} при базе ${BASELINE} — текст обещает файлы, которых нет:`);
77
+ unique.slice(0, 20).forEach((u) => console.error(` ${u}`));
78
+ if (unique.length > 20) console.error(` … и ещё ${unique.length - 20}`);
79
+ return 1;
80
+ }
81
+ console.log(`✅ висячих ссылок ${unique.length}, база ${BASELINE} — не хуже. Проверено файлов: ${walk(path.join(root, '.claude')).filter((f) => f.endsWith('.md')).length}`);
82
+ if (unique.length < BASELINE) {
83
+ console.log(` База устарела в лучшую сторону: опустите BASELINE до ${unique.length}, чтобы достижение закрепилось.`);
84
+ }
85
+ return 0;
86
+ }
87
+
88
+ module.exports = { danglingRefs, BASELINE, REF };
89
+ if (require.main === module) process.exit(main(process.argv));
@@ -43,7 +43,14 @@ const DOCS = [
43
43
  // practice — and blocking on it would have refused every project that ran like that one.
44
44
  // The discrepancy is filed; until it is settled this reports rather than refuses.
45
45
  { file: 'Final_Summary.md', optional: true, expected: true },
46
+ // Both entries below were made optional with no recorded reason — the gap the dated-receipt
47
+ // guard (`tests/unit/optional-doc-idiom.test.js`) found. What would SETTLE it is unmeasured:
48
+ // whether real projects produce them. So `expected` is deliberately NOT set on either — calling
49
+ // them expected asserts something nobody measured, calling them dispensable retires a promise
50
+ // silently. The receipts record the state; they do not resolve it.
51
+ // MEASURED 2026-09-03: promised twice by `commands/replicate.md`, required by nothing here.
46
52
  { file: 'C4_Diagrams.md', optional: true },
53
+ // MEASURED 2026-09-03: promised SEVEN times by `commands/replicate.md`, required by nothing here.
47
54
  { file: 'ADR.md', optional: true },
48
55
  ];
49
56
 
@@ -245,7 +245,7 @@ function parseExpectedToolkit() {
245
245
  commandsExpected: 11,
246
246
  agentsExpected: 4, // pre-shipped only (project agents are extra)
247
247
  rulesExpected: 13, // pre-shipped only (project rules are extra)
248
- hooksExpected: 25, // 4 event hooks + statusline + state-update + writer + 15 checks + 1 capture
248
+ hooksExpected: 26, // 4 event hooks + statusline + state-update + writer + 15 checks + 1 capture
249
249
  };
250
250
  }
251
251
 
@@ -62,9 +62,9 @@ directly—for example, a static grep cannot establish runtime resilience.
62
62
  Every safeguard must connect the reason for the property to an observable signal, a recurring trigger,
63
63
  and a response. Record it with this shape:
64
64
 
65
- | Cause / property | Observable signal | Check kind | Layer | Trigger / cadence | Reaction | Owner |
66
- |---|---|---|---|---|---|---|
67
- | Why the constraint exists | What changes when it is violated | How it is observed | Where it is enforced | When it runs | What happens on failure | Who acts |
65
+ | Cause / property | Observable signal | Check kind | Layer | Scope — what it does NOT cover | Trigger / cadence | Reaction | Owner |
66
+ |---|---|---|---|---|---|---|---|
67
+ | Why the constraint exists | What changes when it is violated | How it is observed | Where it is enforced | The boundary, stated so nobody has to infer it | When it runs | What happens on failure | | Who acts |
68
68
 
69
69
  **Reaction must name a concrete action.** Valid reactions include: block or return the change, repair
70
70
  the practice or implementation, escalate to the named owner, or revisit the decision explicitly.
@@ -77,7 +77,12 @@ A blank cell, “note the warning,” or “the reviewer decides” does not clo
77
77
  3. Select a check kind that can observe that signal.
78
78
  4. Place the check on the strongest layer that can express it reliably.
79
79
  5. Define its trigger or cadence, concrete Reaction, and owner.
80
- 6. Test that the safeguard fires on a deliberately bad input before trusting the happy path.
80
+ 6. Test that the safeguard FIRES on a deliberately bad input and, in the same breath, that it
81
+ stays CLEAN on a correct and COMPLETE one. Both halves or neither: a guard proven only to fire is
82
+ indistinguishable from one that fires at everything, and a guard proven only to pass is
83
+ indistinguishable from one that cannot see. The two cases are cheap together and worthless apart.
84
+ 7. State the check's SCOPE — what it does not look at. Every guard has a boundary, and a boundary
85
+ left unsaid is read by the next person as "covers everything".
81
86
 
82
87
  ## Anti-pattern: “the critic/reviewer will catch it”
83
88
 
@@ -94,3 +99,31 @@ may complement the check for semantics; it must not carry a deterministic invari
94
99
  The same property written only as “remember to include the file” would sit on Layer 5 and could fail
95
100
  silently. The artifact test observes the real distribution boundary and defines what happens when it
96
101
  breaks.
102
+
103
+ ---
104
+
105
+ ## A guard that cannot fail is not on Layer 1 — it is decoration
106
+
107
+ A check earns its layer by what it does on BAD input, not by existing. A guard nobody ever saw refuse
108
+ is indistinguishable from a guard that cannot refuse, and the two are told apart by one act: feed it
109
+ the thing it exists to catch and watch it go red.
110
+
111
+ **The rule.** Every guard you add ships with a case that makes it FAIL. Not a case that exercises it —
112
+ a case that would pass if the guard were deleted, and fails because it is there.
113
+
114
+ Three ways a guard silently cannot fail, all of them observed:
115
+
116
+ | How it dies | What it looks like | How to tell |
117
+ |---|---|---|
118
+ | Its predicate matches nothing | green forever, no findings ever | inject the exact shape it names; it must go red |
119
+ | It is never invoked | green because it never ran | grep the pipeline for its invocation and for consumption of its exit code |
120
+ | It refuses on absence | red always, for a reason unrelated to the defect | run it on known-good input; it must go green |
121
+
122
+ **The honest half of this rule.** No mechanism in this package enforces it. There is no meta-test
123
+ walking every guard and demanding a failing case beside it. Until such a test exists, this rule lives
124
+ on **Layer 4** — it works when someone reads it and applies it, and lapses silently when nobody does.
125
+ Writing it here does not make it Layer 1; only the meta-test would.
126
+
127
+ That admission is the point. A rule that overstates its own layer is exactly the defect it warns
128
+ about: a Layer-4 habit wearing Layer-1 clothes, which is the worst outcome the ladder describes,
129
+ because it buys the confidence of a deterministic check while keeping the reliability of a reminder.