@dzhechkov/p-replicator 1.9.0 → 1.10.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/.dz-manifest.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "files": [
6
6
  {
7
7
  "path": "CHANGELOG.md",
8
- "sha256": "57b20e3bfd20ed2a97f783d77af52bb6c74ceff5466cacb20ddb058c0a344c48"
8
+ "sha256": "63092c71ea7153d562c26db68f2774f233b7c5d37e78e4e3cdfaa1546c42668d"
9
9
  },
10
10
  {
11
11
  "path": "KNOWN_LIMITATIONS.md",
@@ -109,7 +109,7 @@
109
109
  },
110
110
  {
111
111
  "path": "package.json",
112
- "sha256": "195281e31da3a3e5ecde1b7087ec5904f35d8f2639e6270f2d8ae685adcfa0c5"
112
+ "sha256": "0cc3dc1f4a07a4e5f3ac3f3a1981dc1766302fbbe3ed5818b04c806d4c476059"
113
113
  },
114
114
  {
115
115
  "path": "src/cli.js",
@@ -117,7 +117,7 @@
117
117
  },
118
118
  {
119
119
  "path": "src/commands/doctor.js",
120
- "sha256": "0cbd703649882cca4e484bf696b384291780ba760b7895a3ed2bdc1005ef2e4c"
120
+ "sha256": "566a8cf554420fbbb734705de283f04d40048ee3eb38f1877304d2cc5e56a47f"
121
121
  },
122
122
  {
123
123
  "path": "src/commands/init.js",
@@ -137,11 +137,11 @@
137
137
  },
138
138
  {
139
139
  "path": "src/commands/verify.js",
140
- "sha256": "e6d56e7471825b1bacd0e9dbc85d6c9428547c08ea604c348247e258a607eca0"
140
+ "sha256": "18f5442af9b3a549dfb284cd0d8aef83ba973bd34a3a04e7c656262baebb0e57"
141
141
  },
142
142
  {
143
143
  "path": "src/utils.js",
144
- "sha256": "d4fc297e21682290c15aa64499190ee49b7aa62e69d527c2b5332fffad02f401"
144
+ "sha256": "43f6abbf447478bae423bce742cfbdace1725946621925eb2ffb3a3ab5b3379e"
145
145
  },
146
146
  {
147
147
  "path": "templates/.claude/agents/doc-validator.md",
@@ -181,7 +181,7 @@
181
181
  },
182
182
  {
183
183
  "path": "templates/.claude/commands/myinsights.md",
184
- "sha256": "2e73e822384f976383d9c3313940888b9853f1781d2c39a2fb89825f221149dc"
184
+ "sha256": "93258a3340f99a0f14b374746ae2934b01d7cefe06d575434868eb98da2d854a"
185
185
  },
186
186
  {
187
187
  "path": "templates/.claude/commands/next.md",
@@ -217,7 +217,7 @@
217
217
  },
218
218
  {
219
219
  "path": "templates/.claude/hooks/check-docs-complete.cjs",
220
- "sha256": "13eca8ab8f18325031ca707baa2f7068f8c05484f8e4b12d4129a1023cc7a478"
220
+ "sha256": "27c05c2adcedc806e395b30b455243193a4fbd0968ce96e415679e1f78db951a"
221
221
  },
222
222
  {
223
223
  "path": "templates/.claude/hooks/check-growth-trace.cjs",
@@ -225,7 +225,7 @@
225
225
  },
226
226
  {
227
227
  "path": "templates/.claude/hooks/check-ports.cjs",
228
- "sha256": "e5f2d2bd8899df27c2dfedf76128467becae1868210eb8525a1bad2869a8c78f"
228
+ "sha256": "1813aa60e4d15c5f6ce54a9b3471c3772efe60c332316183c7ad8f5b619f2169"
229
229
  },
230
230
  {
231
231
  "path": "templates/.claude/hooks/session-insights.cjs",
@@ -237,7 +237,7 @@
237
237
  },
238
238
  {
239
239
  "path": "templates/.claude/hooks/statusline.cjs",
240
- "sha256": "948edf98ccabaa4e2dc59078435fb444639aa740baa08967d3a78067e4de3416"
240
+ "sha256": "465190ab21610357094fd6eba188ba9f7086dc5a933568f40a7f7c715ccd6745"
241
241
  },
242
242
  {
243
243
  "path": "templates/.claude/rules/docker-ports.md",
@@ -293,11 +293,11 @@
293
293
  },
294
294
  {
295
295
  "path": "templates/.claude/skills/brutal-honesty-review/scripts/assess-code.sh",
296
- "sha256": "7e9722c1533f1b7d1a9d11a7add13ac12a2a5f0acfc0ed2cdede2bcf0dab788f"
296
+ "sha256": "2b10d2972b1379adde9a68ddf8bcdb399b7d65075e458a54523ffd8d99ddc746"
297
297
  },
298
298
  {
299
299
  "path": "templates/.claude/skills/brutal-honesty-review/scripts/assess-tests.sh",
300
- "sha256": "8c6444bdb5ce97e49223cdaa6b1c58ac8fcec710cd6ee8d56de9bc677379bd88"
300
+ "sha256": "d33e760a0739e9291f6087adf189f01eb7c4a1136d9128390dd6e3ad8eadda6f"
301
301
  },
302
302
  {
303
303
  "path": "templates/.claude/skills/brutal-honesty-review/scripts/validate-config.json",
@@ -377,7 +377,7 @@
377
377
  },
378
378
  {
379
379
  "path": "templates/.claude/skills/cc-toolkit-generator-enhanced/references/templates/ddd-hooks-commands.md",
380
- "sha256": "d70a0c4977d322602c35c53bf04880177b5dd8f0de2b339d68a0f55993903745"
380
+ "sha256": "8398f2493434db101476300e514a34bf8124a51eb732cf81923f9a5b5a3d5db4"
381
381
  },
382
382
  {
383
383
  "path": "templates/.claude/skills/cc-toolkit-generator-enhanced/references/templates/ddd-skills.md",
@@ -701,7 +701,7 @@
701
701
  },
702
702
  {
703
703
  "path": "tests/snapshot/baseline.json",
704
- "sha256": "0d5af8aadd98bf1f5f07a02b9d6d7a5dd243d4263a5b03de1a249fdaa5111a56"
704
+ "sha256": "333e554a3840fd02e0e230efe4852bb490beded41f6024c65849060780eebdee"
705
705
  },
706
706
  {
707
707
  "path": "tests/snapshot/templates.test.js",
@@ -711,6 +711,10 @@
711
711
  "path": "tests/snapshot/update-baseline.js",
712
712
  "sha256": "1f50d0c2ec86f1c865ee6ed8c59725e57c397d487b7a24baf051dc5d4b294459"
713
713
  },
714
+ {
715
+ "path": "tests/unit/absence-is-not-emptiness.test.js",
716
+ "sha256": "6c7c1c8086461eac16415ebcccea081d3169212826f23e835cf109d741dd6ac3"
717
+ },
714
718
  {
715
719
  "path": "tests/unit/adr-decision-coverage.test.js",
716
720
  "sha256": "34f9bf0700b4c45fb905f606567f2a6d3ba152f8f1db29f479963667b298ede4"
@@ -719,13 +723,17 @@
719
723
  "path": "tests/unit/adr-scanner-contract.test.js",
720
724
  "sha256": "08c8b7d862ae0ddcd72116462458b71d3fe29b09cbaf08fa6a824e22ad6985c8"
721
725
  },
726
+ {
727
+ "path": "tests/unit/assess-scripts.test.js",
728
+ "sha256": "b16b015dc28cd5b1d85a8ec0ae54768af1787d2d26e9e5b495c8f791aaa2043f"
729
+ },
722
730
  {
723
731
  "path": "tests/unit/autocommit-deletion.test.js",
724
732
  "sha256": "87ebe50e164cfa3aeda3d4f04e6b6aa98ab8af44711cbeb94252d770c07ad8ad"
725
733
  },
726
734
  {
727
735
  "path": "tests/unit/check-docs-complete.test.js",
728
- "sha256": "0dbc15c1077c9c02766cfa9b1eb357b30b59639f2fa91003e44e3c6485da3e7b"
736
+ "sha256": "2c6f16a61f0876f637ac492d5fb2af1ea35ad00161fd1468446ea0d08cd97f4b"
729
737
  },
730
738
  {
731
739
  "path": "tests/unit/check-growth-trace.test.js",
@@ -733,7 +741,7 @@
733
741
  },
734
742
  {
735
743
  "path": "tests/unit/check-ports.test.js",
736
- "sha256": "72d9eeaa8c47d83fba867722f4b8efc8d079e2d9649e1a20abff46571c2f6f15"
744
+ "sha256": "d8e2e1f22dadb40fbb03ffbd25ed945fa85fe7b5d49fe0f3597cfc3facc2c118"
737
745
  },
738
746
  {
739
747
  "path": "tests/unit/db-port-rule.test.js",
@@ -747,6 +755,10 @@
747
755
  "path": "tests/unit/external-dependency-check.test.js",
748
756
  "sha256": "d85109f8e86648d61fc17d0128e9d4881950a70641c246e667d7e54ffc1f0273"
749
757
  },
758
+ {
759
+ "path": "tests/unit/generated-guard-templates.test.js",
760
+ "sha256": "928ddb625cc1bbc7dd145992c9a37373da93ae314f39391c67ad7ed064e2c940"
761
+ },
750
762
  {
751
763
  "path": "tests/unit/growth-axes-and-compliance.test.js",
752
764
  "sha256": "88e4d8c7ae278c46dfce4d89fcbd1dee49c0b545ebc07e459306bfdc70567048"
@@ -763,6 +775,10 @@
763
775
  "path": "tests/unit/growth-requirements-bridge.test.js",
764
776
  "sha256": "2f560a16f1757df46d5d52e5d29a7aad3e4c327cd07ea9cc69240c7dd1c93f2a"
765
777
  },
778
+ {
779
+ "path": "tests/unit/guard-forms.test.js",
780
+ "sha256": "61a219a7748e0b56bc4207eee107815a4b4111fbebd41b68f6d390130506cd42"
781
+ },
766
782
  {
767
783
  "path": "tests/unit/hooks-project-anchored.test.js",
768
784
  "sha256": "2fa5b44982d72701d7a8486ac24ee3a91c6fa6123ef7303a0e065bf1e60987d7"
@@ -771,9 +787,13 @@
771
787
  "path": "tests/unit/hooks-report-failures.test.js",
772
788
  "sha256": "35d3fca74c22e1bc88b6fbb25f172b66a21561a947e2b6e90a366d5a854376b8"
773
789
  },
790
+ {
791
+ "path": "tests/unit/insights-docs-tell-the-truth.test.js",
792
+ "sha256": "d73ebce2f729911cad452897883b3d55d69e19613c7c1fc7c9bcfa3b5569fc1b"
793
+ },
774
794
  {
775
795
  "path": "tests/unit/module-copy-identity.test.js",
776
- "sha256": "a1269ad9f68a38faa7710fc63ce850feacb2304996b85ef38237b222815a3532"
796
+ "sha256": "69a63e511cef4d6cb7ea5669b61746f2fc8af22273bc76539cb304bd27e49de9"
777
797
  },
778
798
  {
779
799
  "path": "tests/unit/pipeline-file-ownership.test.js",
@@ -783,6 +803,10 @@
783
803
  "path": "tests/unit/roadmap-one-schema.test.js",
784
804
  "sha256": "3e7ac9dbc9796a791fc95c43b4346c6da2455f3c0ace45bbc440502c5957d3dc"
785
805
  },
806
+ {
807
+ "path": "tests/unit/shipped-suite-context.test.js",
808
+ "sha256": "fd6128505f3272aa7349d21d18a2494eaa8e5e2397ee85047f9828471c99d721"
809
+ },
786
810
  {
787
811
  "path": "tests/unit/skill-paths-prebaked.test.js",
788
812
  "sha256": "efb13ca5d2fa68f3186e5af4142509d260d7cf63c902f59e915110bb550887df"
@@ -805,7 +829,7 @@
805
829
  },
806
830
  {
807
831
  "path": "tests/unit/sync-templates-guard.test.js",
808
- "sha256": "75e8e0d0d2dfc16f14c586d399b5c9c075cc3a0494c558fe39d8528516185cfe"
832
+ "sha256": "e4fc7687dcf37d17bf2a059d3248c8c00526c104f6a0f6e104fa9ca6e00039ae"
809
833
  },
810
834
  {
811
835
  "path": "tests/unit/utils.test.js",
@@ -817,5 +841,5 @@
817
841
  }
818
842
  ]
819
843
  },
820
- "signature": "OMtz2uZJ+oSOZn3pdPDukLfw/5FD68SgFh/weBKRMzNGQyuBjh7L0durZEyaLu1T0pbbQ+WTQ1eEAi48cGCjBg=="
844
+ "signature": "ZKPYreIIzuZR6WoZ0J8IBCnwHmSC51tyVihIl3MfZKhVry+nKGokIl0bLu6eKxzGSI0rfDwKfBUPZKHv0iMbDg=="
821
845
  }
package/CHANGELOG.md CHANGED
@@ -5,6 +5,55 @@ All notable changes to `@dzhechkov/p-replicator` are documented here.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.10.0] - 2026-08-27
9
+
10
+ **Every guard in this package can now be shown to fail — and three that could not, now can.**
11
+ MINOR: no pre-shipped contract change, but the exit-code semantics of two shipped scripts changed.
12
+
13
+ ### Fixed — guards that could not refuse
14
+
15
+ - **`check-ports.cjs` resolved one path in two frames of reference.** A relative argument was
16
+ re-applied by docker, so `check-ports.cjs projects/01` reported
17
+ `…/projects/01/projects/01/docker-compose.yml`. Worse, it fired BEFORE docker parsed the file and
18
+ so MASKED real config errors, and the cure it printed was the invocation that SUCCEEDS. Two edits:
19
+ absolutise at the boundary, and delete the `cwd:` override — measured to buy nothing on Compose v2+.
20
+ - **The generated aggregate guard was false-green on 3 of 4 inputs**, and the generator writes it
21
+ into every bootstrapped project. Four declarations minified onto ONE line reported OK; so did a
22
+ missing file; so did an **unsubstituted `{{…}}` placeholder — forever**. Now 0/1/2, counting
23
+ occurrences rather than lines.
24
+ - **`assess-code.sh` and `assess-tests.sh` printed red verdicts and exited 0**, while a nonexistent
25
+ path exited 1 — blindness outranked findings. Now 1 on findings, 2 on could-not-check. Detection
26
+ unchanged.
27
+ - **`verify` and `doctor` were blind to an EMPTY file.** 31 artifacts truncated to zero bytes and
28
+ both reported clean; a zero-byte `settings.json` — no hooks wired at all — got a checkmark.
29
+ Three states now, reported as three.
30
+
31
+ ### Added
32
+
33
+ - **`dz mutation-gate` enrolment** — `test/mutation-registry.json`, six entries, every mutation
34
+ demonstrated red by hand before the registry was trusted. Gate: 6/6 PROVEN.
35
+ - **`tests/unit/guard-forms.test.js`** — a layer-1 refusal of five shell shapes that make a guard
36
+ unable to fail. It caught the aggregate guard, and later confirmed its own fix: inventory 2 → 0.
37
+ - **`check-docs-complete.cjs`** at the Phase 1→2 boundary, with a confidence split: `{{…}}` and
38
+ TODO/TBD/XXX block; bracketed prose is NAMED but never blocks, because it cannot be told from a
39
+ mermaid label — and blocking on it refused every project the bundled skill generates.
40
+
41
+ ### Changed — honesty in shipped documents
42
+
43
+ - `myinsights.md` no longer claims insights are injected "when their tags match the current task".
44
+ The hook runs at `SessionStart`, before anything has been said, so there is no task to match
45
+ against; it injects the three most recent entries. The reason and the consequence are both stated,
46
+ and a test pins the document to the code.
47
+ - The insights carrier now reports THREE states — not started / zero entries / N recorded — in
48
+ `doctor`, `verify` and the statusline. Absent and empty rendering identically is what let 27
49
+ recorded insights become 0 across four real projects with every surface reporting fine.
50
+
51
+ ### Verified differently this time
52
+
53
+ The shipped suite now runs from a TARBALL, not only locally: **288/296 exit 1 → 311/311 exit 0**.
54
+ Two tests are monorepo-only by construction and skip loudly outside it — permitted only because a
55
+ guard asserts they RUN inside, so the skip is provably not taken where it matters.
56
+
8
57
  ## [1.9.0] - 2026-08-27
9
58
 
10
59
  **MINOR — hooks 8 → 9** (`check-docs-complete`). After `update`, `doctor` and `verify` expect the new count.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dzhechkov/p-replicator",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
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": {
@@ -20,8 +20,8 @@
20
20
  ],
21
21
  "scripts": {
22
22
  "prepublishOnly": "node --test tests/snapshot/templates.test.js && node ../../../scripts/prepublish-gate.mjs",
23
- "test": "node --test 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/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/adr-decision-coverage.test.js tests/unit/growth-requirements-bridge.test.js tests/unit/check-growth-trace.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/e2e/lifecycle.test.js tests/snapshot/templates.test.js",
24
- "test:unit": "node --test 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/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/adr-decision-coverage.test.js tests/unit/growth-requirements-bridge.test.js tests/unit/check-growth-trace.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",
23
+ "test": "node --test 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/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/adr-decision-coverage.test.js tests/unit/growth-requirements-bridge.test.js tests/unit/check-growth-trace.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/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/e2e/lifecycle.test.js tests/snapshot/templates.test.js",
24
+ "test:unit": "node --test 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/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/adr-decision-coverage.test.js tests/unit/growth-requirements-bridge.test.js tests/unit/check-growth-trace.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/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",
25
25
  "test:e2e": "node --test tests/e2e/lifecycle.test.js",
26
26
  "test:snapshot": "node --test tests/snapshot/templates.test.js",
27
27
  "test:doctor": "node bin/cli.js doctor",
package/sbom.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "hashes": [
16
16
  {
17
17
  "alg": "SHA-256",
18
- "content": "57b20e3bfd20ed2a97f783d77af52bb6c74ceff5466cacb20ddb058c0a344c48"
18
+ "content": "63092c71ea7153d562c26db68f2774f233b7c5d37e78e4e3cdfaa1546c42668d"
19
19
  }
20
20
  ]
21
21
  },
@@ -275,7 +275,7 @@
275
275
  "hashes": [
276
276
  {
277
277
  "alg": "SHA-256",
278
- "content": "195281e31da3a3e5ecde1b7087ec5904f35d8f2639e6270f2d8ae685adcfa0c5"
278
+ "content": "0cc3dc1f4a07a4e5f3ac3f3a1981dc1766302fbbe3ed5818b04c806d4c476059"
279
279
  }
280
280
  ]
281
281
  },
@@ -295,7 +295,7 @@
295
295
  "hashes": [
296
296
  {
297
297
  "alg": "SHA-256",
298
- "content": "0cbd703649882cca4e484bf696b384291780ba760b7895a3ed2bdc1005ef2e4c"
298
+ "content": "566a8cf554420fbbb734705de283f04d40048ee3eb38f1877304d2cc5e56a47f"
299
299
  }
300
300
  ]
301
301
  },
@@ -345,7 +345,7 @@
345
345
  "hashes": [
346
346
  {
347
347
  "alg": "SHA-256",
348
- "content": "e6d56e7471825b1bacd0e9dbc85d6c9428547c08ea604c348247e258a607eca0"
348
+ "content": "18f5442af9b3a549dfb284cd0d8aef83ba973bd34a3a04e7c656262baebb0e57"
349
349
  }
350
350
  ]
351
351
  },
@@ -355,7 +355,7 @@
355
355
  "hashes": [
356
356
  {
357
357
  "alg": "SHA-256",
358
- "content": "d4fc297e21682290c15aa64499190ee49b7aa62e69d527c2b5332fffad02f401"
358
+ "content": "43f6abbf447478bae423bce742cfbdace1725946621925eb2ffb3a3ab5b3379e"
359
359
  }
360
360
  ]
361
361
  },
@@ -455,7 +455,7 @@
455
455
  "hashes": [
456
456
  {
457
457
  "alg": "SHA-256",
458
- "content": "2e73e822384f976383d9c3313940888b9853f1781d2c39a2fb89825f221149dc"
458
+ "content": "93258a3340f99a0f14b374746ae2934b01d7cefe06d575434868eb98da2d854a"
459
459
  }
460
460
  ]
461
461
  },
@@ -545,7 +545,7 @@
545
545
  "hashes": [
546
546
  {
547
547
  "alg": "SHA-256",
548
- "content": "13eca8ab8f18325031ca707baa2f7068f8c05484f8e4b12d4129a1023cc7a478"
548
+ "content": "27c05c2adcedc806e395b30b455243193a4fbd0968ce96e415679e1f78db951a"
549
549
  }
550
550
  ]
551
551
  },
@@ -565,7 +565,7 @@
565
565
  "hashes": [
566
566
  {
567
567
  "alg": "SHA-256",
568
- "content": "e5f2d2bd8899df27c2dfedf76128467becae1868210eb8525a1bad2869a8c78f"
568
+ "content": "1813aa60e4d15c5f6ce54a9b3471c3772efe60c332316183c7ad8f5b619f2169"
569
569
  }
570
570
  ]
571
571
  },
@@ -595,7 +595,7 @@
595
595
  "hashes": [
596
596
  {
597
597
  "alg": "SHA-256",
598
- "content": "948edf98ccabaa4e2dc59078435fb444639aa740baa08967d3a78067e4de3416"
598
+ "content": "465190ab21610357094fd6eba188ba9f7086dc5a933568f40a7f7c715ccd6745"
599
599
  }
600
600
  ]
601
601
  },
@@ -735,7 +735,7 @@
735
735
  "hashes": [
736
736
  {
737
737
  "alg": "SHA-256",
738
- "content": "7e9722c1533f1b7d1a9d11a7add13ac12a2a5f0acfc0ed2cdede2bcf0dab788f"
738
+ "content": "2b10d2972b1379adde9a68ddf8bcdb399b7d65075e458a54523ffd8d99ddc746"
739
739
  }
740
740
  ]
741
741
  },
@@ -745,7 +745,7 @@
745
745
  "hashes": [
746
746
  {
747
747
  "alg": "SHA-256",
748
- "content": "8c6444bdb5ce97e49223cdaa6b1c58ac8fcec710cd6ee8d56de9bc677379bd88"
748
+ "content": "d33e760a0739e9291f6087adf189f01eb7c4a1136d9128390dd6e3ad8eadda6f"
749
749
  }
750
750
  ]
751
751
  },
@@ -945,7 +945,7 @@
945
945
  "hashes": [
946
946
  {
947
947
  "alg": "SHA-256",
948
- "content": "d70a0c4977d322602c35c53bf04880177b5dd8f0de2b339d68a0f55993903745"
948
+ "content": "8398f2493434db101476300e514a34bf8124a51eb732cf81923f9a5b5a3d5db4"
949
949
  }
950
950
  ]
951
951
  },
@@ -1755,7 +1755,7 @@
1755
1755
  "hashes": [
1756
1756
  {
1757
1757
  "alg": "SHA-256",
1758
- "content": "0d5af8aadd98bf1f5f07a02b9d6d7a5dd243d4263a5b03de1a249fdaa5111a56"
1758
+ "content": "333e554a3840fd02e0e230efe4852bb490beded41f6024c65849060780eebdee"
1759
1759
  }
1760
1760
  ]
1761
1761
  },
@@ -1779,6 +1779,16 @@
1779
1779
  }
1780
1780
  ]
1781
1781
  },
1782
+ {
1783
+ "type": "file",
1784
+ "name": "tests/unit/absence-is-not-emptiness.test.js",
1785
+ "hashes": [
1786
+ {
1787
+ "alg": "SHA-256",
1788
+ "content": "6c7c1c8086461eac16415ebcccea081d3169212826f23e835cf109d741dd6ac3"
1789
+ }
1790
+ ]
1791
+ },
1782
1792
  {
1783
1793
  "type": "file",
1784
1794
  "name": "tests/unit/adr-decision-coverage.test.js",
@@ -1799,6 +1809,16 @@
1799
1809
  }
1800
1810
  ]
1801
1811
  },
1812
+ {
1813
+ "type": "file",
1814
+ "name": "tests/unit/assess-scripts.test.js",
1815
+ "hashes": [
1816
+ {
1817
+ "alg": "SHA-256",
1818
+ "content": "b16b015dc28cd5b1d85a8ec0ae54768af1787d2d26e9e5b495c8f791aaa2043f"
1819
+ }
1820
+ ]
1821
+ },
1802
1822
  {
1803
1823
  "type": "file",
1804
1824
  "name": "tests/unit/autocommit-deletion.test.js",
@@ -1815,7 +1835,7 @@
1815
1835
  "hashes": [
1816
1836
  {
1817
1837
  "alg": "SHA-256",
1818
- "content": "0dbc15c1077c9c02766cfa9b1eb357b30b59639f2fa91003e44e3c6485da3e7b"
1838
+ "content": "2c6f16a61f0876f637ac492d5fb2af1ea35ad00161fd1468446ea0d08cd97f4b"
1819
1839
  }
1820
1840
  ]
1821
1841
  },
@@ -1835,7 +1855,7 @@
1835
1855
  "hashes": [
1836
1856
  {
1837
1857
  "alg": "SHA-256",
1838
- "content": "72d9eeaa8c47d83fba867722f4b8efc8d079e2d9649e1a20abff46571c2f6f15"
1858
+ "content": "d8e2e1f22dadb40fbb03ffbd25ed945fa85fe7b5d49fe0f3597cfc3facc2c118"
1839
1859
  }
1840
1860
  ]
1841
1861
  },
@@ -1869,6 +1889,16 @@
1869
1889
  }
1870
1890
  ]
1871
1891
  },
1892
+ {
1893
+ "type": "file",
1894
+ "name": "tests/unit/generated-guard-templates.test.js",
1895
+ "hashes": [
1896
+ {
1897
+ "alg": "SHA-256",
1898
+ "content": "928ddb625cc1bbc7dd145992c9a37373da93ae314f39391c67ad7ed064e2c940"
1899
+ }
1900
+ ]
1901
+ },
1872
1902
  {
1873
1903
  "type": "file",
1874
1904
  "name": "tests/unit/growth-axes-and-compliance.test.js",
@@ -1909,6 +1939,16 @@
1909
1939
  }
1910
1940
  ]
1911
1941
  },
1942
+ {
1943
+ "type": "file",
1944
+ "name": "tests/unit/guard-forms.test.js",
1945
+ "hashes": [
1946
+ {
1947
+ "alg": "SHA-256",
1948
+ "content": "61a219a7748e0b56bc4207eee107815a4b4111fbebd41b68f6d390130506cd42"
1949
+ }
1950
+ ]
1951
+ },
1912
1952
  {
1913
1953
  "type": "file",
1914
1954
  "name": "tests/unit/hooks-project-anchored.test.js",
@@ -1929,13 +1969,23 @@
1929
1969
  }
1930
1970
  ]
1931
1971
  },
1972
+ {
1973
+ "type": "file",
1974
+ "name": "tests/unit/insights-docs-tell-the-truth.test.js",
1975
+ "hashes": [
1976
+ {
1977
+ "alg": "SHA-256",
1978
+ "content": "d73ebce2f729911cad452897883b3d55d69e19613c7c1fc7c9bcfa3b5569fc1b"
1979
+ }
1980
+ ]
1981
+ },
1932
1982
  {
1933
1983
  "type": "file",
1934
1984
  "name": "tests/unit/module-copy-identity.test.js",
1935
1985
  "hashes": [
1936
1986
  {
1937
1987
  "alg": "SHA-256",
1938
- "content": "a1269ad9f68a38faa7710fc63ce850feacb2304996b85ef38237b222815a3532"
1988
+ "content": "69a63e511cef4d6cb7ea5669b61746f2fc8af22273bc76539cb304bd27e49de9"
1939
1989
  }
1940
1990
  ]
1941
1991
  },
@@ -1959,6 +2009,16 @@
1959
2009
  }
1960
2010
  ]
1961
2011
  },
2012
+ {
2013
+ "type": "file",
2014
+ "name": "tests/unit/shipped-suite-context.test.js",
2015
+ "hashes": [
2016
+ {
2017
+ "alg": "SHA-256",
2018
+ "content": "fd6128505f3272aa7349d21d18a2494eaa8e5e2397ee85047f9828471c99d721"
2019
+ }
2020
+ ]
2021
+ },
1962
2022
  {
1963
2023
  "type": "file",
1964
2024
  "name": "tests/unit/skill-paths-prebaked.test.js",
@@ -2015,7 +2075,7 @@
2015
2075
  "hashes": [
2016
2076
  {
2017
2077
  "alg": "SHA-256",
2018
- "content": "75e8e0d0d2dfc16f14c586d399b5c9c075cc3a0494c558fe39d8528516185cfe"
2078
+ "content": "e4fc7687dcf37d17bf2a059d3248c8c00526c104f6a0f6e104fa9ca6e00039ae"
2019
2079
  }
2020
2080
  ]
2021
2081
  },
@@ -6,7 +6,7 @@ const { execFileSync } = require('child_process');
6
6
  const {
7
7
  green, red, yellow, cyan, bold, dim,
8
8
  info, success, warn, error: logError,
9
- readManifest, fileExists,
9
+ readManifest, fileExists, artifactState,
10
10
  MANIFEST_FILE, COMPONENTS,
11
11
  } = require('../utils');
12
12
 
@@ -29,6 +29,22 @@ function run(options) {
29
29
  function fail(msg) { console.log(` ${red('\u2717')} ${msg}`); issues++; }
30
30
  function hint(msg) { console.log(` ${yellow('!')} ${msg}`); warnings++; }
31
31
 
32
+ /**
33
+ * One reporter for every component, because a two-way branch cannot say three things.
34
+ *
35
+ * The first version of this change swapped the CONDITION to artifactState and left the else
36
+ * branch intact, so a whitespace-only artifact was reported as "missing" — the exact collapse
37
+ * AR-4 forbids. And settings.json and the hooks were still on fileExists, so a ZERO-BYTE
38
+ * settings.json (no hooks wired at all) and a zero-byte hook both received a checkmark.
39
+ */
40
+ function reportArtifact(label, filePath, missingNote) {
41
+ const state = artifactState(filePath);
42
+ if (state === 'present') { pass(label); return; }
43
+ if (state === 'empty') { fail(`${label} \u2014 EMPTY, cannot load`); return; }
44
+ fail(`${label} \u2014 missing${missingNote ? ' (' + missingNote + ')' : ''}`);
45
+ }
46
+
47
+
32
48
  console.log(bold('P-Replicator \u2014 Health Check'));
33
49
  console.log('');
34
50
 
@@ -59,11 +75,7 @@ function run(options) {
59
75
  console.log(bold(`Skills (expected ${EXPECTED_SKILLS.length}):`));
60
76
  for (const skill of EXPECTED_SKILLS) {
61
77
  const skillPath = path.join(claudeDir, 'skills', skill, 'SKILL.md');
62
- if (fileExists(skillPath)) {
63
- pass(skill);
64
- } else {
65
- fail(`${skill} \u2014 SKILL.md missing`);
66
- }
78
+ reportArtifact(skill, skillPath, 'SKILL.md');
67
79
  }
68
80
  console.log('');
69
81
 
@@ -71,11 +83,7 @@ function run(options) {
71
83
  console.log(bold(`Commands (expected ${EXPECTED_COMMANDS.length}):`));
72
84
  for (const cmd of EXPECTED_COMMANDS) {
73
85
  const cmdPath = path.join(claudeDir, 'commands', `${cmd}.md`);
74
- if (fileExists(cmdPath)) {
75
- pass(`/${cmd}`);
76
- } else {
77
- fail(`/${cmd} \u2014 ${cmd}.md missing`);
78
- }
86
+ reportArtifact(`/${cmd}`, cmdPath, undefined);
79
87
  }
80
88
  console.log('');
81
89
 
@@ -83,11 +91,7 @@ function run(options) {
83
91
  console.log(bold(`Agents (expected ${EXPECTED_AGENTS.length}):`));
84
92
  for (const agent of EXPECTED_AGENTS) {
85
93
  const agentPath = path.join(claudeDir, 'agents', `${agent}.md`);
86
- if (fileExists(agentPath)) {
87
- pass(agent);
88
- } else {
89
- fail(`${agent} \u2014 ${agent}.md missing`);
90
- }
94
+ reportArtifact(agent, agentPath, undefined);
91
95
  }
92
96
  console.log('');
93
97
 
@@ -95,22 +99,14 @@ function run(options) {
95
99
  console.log(bold(`Rules (expected ${EXPECTED_RULES.length}):`));
96
100
  for (const rule of EXPECTED_RULES) {
97
101
  const rulePath = path.join(claudeDir, 'rules', `${rule}.md`);
98
- if (fileExists(rulePath)) {
99
- pass(rule);
100
- } else {
101
- fail(`${rule} \u2014 ${rule}.md missing`);
102
- }
102
+ reportArtifact(rule, rulePath, undefined);
103
103
  }
104
104
  console.log('');
105
105
 
106
106
  // ── 6b) Settings (hooks config) ─────────────────────────────────────────
107
107
  console.log(bold('Hooks (settings.json):'));
108
108
  const settingsPath = path.join(claudeDir, 'settings.json');
109
- if (fileExists(settingsPath)) {
110
- pass('settings.json');
111
- } else {
112
- fail('settings.json — missing (SessionStart + Stop hooks not configured)');
113
- }
109
+ reportArtifact('settings.json', settingsPath, 'SessionStart + Stop hooks not configured');
114
110
  console.log('');
115
111
 
116
112
  // ── 6c) Hook scripts (cross-platform Node, v1.4.1+) ─────────────────────
@@ -119,11 +115,7 @@ function run(options) {
119
115
  console.log(bold(`Hook scripts (expected ${hookKeys.length}):`));
120
116
  for (const hook of hookKeys) {
121
117
  const hookPath = path.join(claudeDir, 'hooks', `${hook}.cjs`);
122
- if (fileExists(hookPath)) {
123
- pass(`${hook}.cjs`);
124
- } else {
125
- fail(`${hook}.cjs — missing (referenced by settings.json)`);
126
- }
118
+ reportArtifact(`${hook}.cjs`, hookPath, 'referenced by settings.json');
127
119
  }
128
120
  console.log('');
129
121
  }
@@ -148,6 +140,26 @@ function run(options) {
148
140
  }
149
141
  console.log('');
150
142
 
143
+ // ── The insights carrier: THREE states, and none of them fails ───────────
144
+ //
145
+ // A project that has recorded no insight is a NEW project, and a check that refuses a new project
146
+ // is a check people disable — taking the real signal with it. The defect was never the emptiness:
147
+ // it was that ABSENT and EMPTY rendered identically, so a carrier that had never been created
148
+ // looked exactly like one being used and found empty. MEASURED across four real projects on one
149
+ // machine: 11 -> 10 -> 6 -> 0 insights, with every surface reporting OK throughout.
150
+ const insightsIndex = path.join(claudeDir, 'insights', 'index.md');
151
+ const insightsState = artifactState(insightsIndex);
152
+ if (insightsState === 'missing') {
153
+ hint('insights carrier: NOT STARTED — no .claude/insights/index.md. Record one with /myinsights');
154
+ } else if (insightsState === 'empty') {
155
+ hint('insights carrier: EXISTS but holds ZERO entries — nothing is injected at SessionStart');
156
+ } else {
157
+ const entries = (fs.readFileSync(insightsIndex, 'utf-8')
158
+ .match(/^##\s+\d{4}-\d{2}-\d{2}/gm) || []).length;
159
+ pass('insights carrier: ' + entries + ' entr' + (entries === 1 ? 'y' : 'ies') + ' recorded');
160
+ }
161
+ console.log('');
162
+
151
163
  // ── 8) Summary ──────────────────────────────────────────────────────────
152
164
  console.log(bold('\u2500'.repeat(50)));
153
165
  if (issues === 0 && warnings === 0) {