@marinjursic/prc-linux-arm64 0.1.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.
Files changed (264) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/bin/LICENSE +21 -0
  4. package/bin/README.md +335 -0
  5. package/bin/THIRD_PARTY_NOTICES.md +74 -0
  6. package/bin/adapters/checkov-v3.3.8.yaml +50 -0
  7. package/bin/adapters/gitleaks-v8.30.0.yaml +63 -0
  8. package/bin/adapters/grype-v0.116.1.yaml +58 -0
  9. package/bin/adapters/syft-v1.51.0.yaml +54 -0
  10. package/bin/catalog/assertions/core-repository.yaml +625 -0
  11. package/bin/catalog/assertions/iac.yaml +24 -0
  12. package/bin/catalog/assertions/supply-chain.yaml +45 -0
  13. package/bin/catalog/control-contracts.json +1 -0
  14. package/bin/catalog/control-id-registry.json +110470 -0
  15. package/bin/catalog/objectives/core-repository.yaml +243 -0
  16. package/bin/catalog/objectives/iac.yaml +13 -0
  17. package/bin/catalog/objectives/supply-chain.yaml +13 -0
  18. package/bin/catalog/profiles/api.yaml +12 -0
  19. package/bin/catalog/profiles/core-repository.yaml +49 -0
  20. package/bin/catalog/profiles/iac.yaml +18 -0
  21. package/bin/catalog/profiles/kubernetes.yaml +15 -0
  22. package/bin/catalog/profiles/quick.yaml +27 -0
  23. package/bin/catalog/profiles/supply-chain.yaml +20 -0
  24. package/bin/docs/architecture/adapters.md +380 -0
  25. package/bin/docs/architecture/agent-providers.md +188 -0
  26. package/bin/docs/architecture/applicability.md +80 -0
  27. package/bin/docs/architecture/catalog-integrity.md +85 -0
  28. package/bin/docs/architecture/evidence-and-results.md +154 -0
  29. package/bin/docs/architecture/execution-plans.md +61 -0
  30. package/bin/docs/architecture/product-contract.md +76 -0
  31. package/bin/docs/architecture/publisher-trust.md +68 -0
  32. package/bin/docs/architecture/remediation-contract.md +113 -0
  33. package/bin/docs/architecture/trust-model.md +95 -0
  34. package/bin/docs/assets/hero.svg +37 -0
  35. package/bin/docs/assets/logo.svg +13 -0
  36. package/bin/docs/assets/production-readiness-scan-demo-poster.png +0 -0
  37. package/bin/docs/assets/production-readiness-scan-demo.gif +0 -0
  38. package/bin/docs/assets/production-readiness-scan-demo.mp4 +0 -0
  39. package/bin/docs/assets/social-card.png +0 -0
  40. package/bin/docs/assets/social-card.svg +40 -0
  41. package/bin/docs/checklists/00-readiness-principle.md +17 -0
  42. package/bin/docs/checklists/01-release-foundations.md +91 -0
  43. package/bin/docs/checklists/02-product-risk-architecture.md +136 -0
  44. package/bin/docs/checklists/03-source-build-supply-chain.md +97 -0
  45. package/bin/docs/checklists/04-environments-quality-experience.md +226 -0
  46. package/bin/docs/checklists/05-application-security.md +320 -0
  47. package/bin/docs/checklists/06-data-privacy-performance.md +166 -0
  48. package/bin/docs/checklists/07-reliability-operations.md +355 -0
  49. package/bin/docs/checklists/08-maintenance-vendors-compliance.md +112 -0
  50. package/bin/docs/checklists/09-conditional-modules.md +229 -0
  51. package/bin/docs/checklists/10-evidence-and-decision.md +111 -0
  52. package/bin/docs/engineering/00-overview.md +51 -0
  53. package/bin/docs/engineering/01-governance-and-foundations.md +919 -0
  54. package/bin/docs/engineering/02-product-and-requirements.md +186 -0
  55. package/bin/docs/engineering/03-user-experience-web-and-content.md +1352 -0
  56. package/bin/docs/engineering/04-architecture-and-design.md +387 -0
  57. package/bin/docs/engineering/05-code-quality-and-implementation.md +1103 -0
  58. package/bin/docs/engineering/06-application-services-and-apis.md +476 -0
  59. package/bin/docs/engineering/07-data-and-information-lifecycle.md +1009 -0
  60. package/bin/docs/engineering/08-security-and-cryptography.md +1215 -0
  61. package/bin/docs/engineering/09-privacy-and-data-protection.md +205 -0
  62. package/bin/docs/engineering/10-verification-and-testing.md +841 -0
  63. package/bin/docs/engineering/11-developer-experience-platform-and-delivery.md +1013 -0
  64. package/bin/docs/engineering/12-operations-sre-and-support.md +795 -0
  65. package/bin/docs/engineering/13-documentation-and-knowledge.md +349 -0
  66. package/bin/docs/engineering/14-trust-safety-and-ecosystems.md +330 -0
  67. package/bin/docs/engineering/15-ai-ml-and-ai-assisted-development.md +785 -0
  68. package/bin/docs/engineering/16-specialized-domains-and-release-assurance.md +775 -0
  69. package/bin/docs/engineering/source-manifest.md +479 -0
  70. package/bin/docs/guides/ai-assisted-review.md +61 -0
  71. package/bin/docs/guides/getting-started.md +78 -0
  72. package/bin/docs/index.md +66 -0
  73. package/bin/docs/prompts/evidence-challenge.md +26 -0
  74. package/bin/docs/prompts/full-readiness-review.md +34 -0
  75. package/bin/docs/prompts/release-diff-review.md +31 -0
  76. package/bin/docs/records/evidence-record.md +42 -0
  77. package/bin/docs/records/go-no-go-decision.md +63 -0
  78. package/bin/docs/records/release-assessment.md +124 -0
  79. package/bin/docs/records/risk-exception.md +64 -0
  80. package/bin/docs/references.md +52 -0
  81. package/bin/docs/scanner/ai-control-review.md +208 -0
  82. package/bin/docs/scanner/benchmarks.md +122 -0
  83. package/bin/docs/scanner/cli-contract.md +130 -0
  84. package/bin/docs/scanner/configuration.md +101 -0
  85. package/bin/docs/scanner/control-contracts.md +47 -0
  86. package/bin/docs/scanner/core-repository.md +62 -0
  87. package/bin/docs/scanner/diff-and-invalidation.md +79 -0
  88. package/bin/docs/scanner/doctor.md +71 -0
  89. package/bin/docs/scanner/getting-started.md +355 -0
  90. package/bin/docs/scanner/go-http-timeouts.md +96 -0
  91. package/bin/docs/scanner/infrastructure-policy.md +64 -0
  92. package/bin/docs/scanner/kubernetes-workloads.md +63 -0
  93. package/bin/docs/scanner/mcp-agent-integration.md +138 -0
  94. package/bin/docs/scanner/openapi-contracts.md +75 -0
  95. package/bin/docs/scanner/private-key-armor.md +44 -0
  96. package/bin/docs/scanner/releases.md +160 -0
  97. package/bin/docs/scanner/remediation.md +273 -0
  98. package/bin/docs/scanner/risk-exceptions.md +52 -0
  99. package/bin/docs/scanner/security-walkthrough.md +236 -0
  100. package/bin/docs/scanner/state-and-history.md +113 -0
  101. package/bin/docs/scanner/supply-chain.md +132 -0
  102. package/bin/docs/scanner/test-discovery.md +60 -0
  103. package/bin/docs/stylesheets/extra.css +183 -0
  104. package/bin/fixtures/benchmarks/core-native/suite-comprehensive.yaml +302 -0
  105. package/bin/fixtures/benchmarks/core-native/suite.yaml +59 -0
  106. package/bin/fixtures/benchmarks/core-native/targets/baseline/README.md +3 -0
  107. package/bin/fixtures/benchmarks/core-native/targets/baseline/app.go +1 -0
  108. package/bin/fixtures/benchmarks/core-native/targets/conflict-template/app.js +5 -0
  109. package/bin/fixtures/benchmarks/core-native/targets/container-risky-template/Dockerfile +2 -0
  110. package/bin/fixtures/benchmarks/core-native/targets/container-valid/Dockerfile +2 -0
  111. package/bin/fixtures/benchmarks/core-native/targets/dependency-lock-missing/package.json +5 -0
  112. package/bin/fixtures/benchmarks/core-native/targets/dependency-lock-present/package-lock.json +6 -0
  113. package/bin/fixtures/benchmarks/core-native/targets/dependency-lock-present/package.json +5 -0
  114. package/bin/fixtures/benchmarks/core-native/targets/empty-manifest-template/package.json +1 -0
  115. package/bin/fixtures/benchmarks/core-native/targets/final-newline-template/app.py +1 -0
  116. package/bin/fixtures/benchmarks/core-native/targets/foundation-present/.github/CODEOWNERS +1 -0
  117. package/bin/fixtures/benchmarks/core-native/targets/foundation-present/.github/dependabot.yml +6 -0
  118. package/bin/fixtures/benchmarks/core-native/targets/foundation-present/.github/workflows/validate.yml +15 -0
  119. package/bin/fixtures/benchmarks/core-native/targets/foundation-present/CODE_OF_CONDUCT.md +3 -0
  120. package/bin/fixtures/benchmarks/core-native/targets/foundation-present/CONTRIBUTING.md +3 -0
  121. package/bin/fixtures/benchmarks/core-native/targets/foundation-present/LICENSE +1 -0
  122. package/bin/fixtures/benchmarks/core-native/targets/foundation-present/README.md +3 -0
  123. package/bin/fixtures/benchmarks/core-native/targets/foundation-present/SECURITY.md +3 -0
  124. package/bin/fixtures/benchmarks/core-native/targets/foundation-present/package-lock.json +6 -0
  125. package/bin/fixtures/benchmarks/core-native/targets/foundation-present/package.json +7 -0
  126. package/bin/fixtures/benchmarks/core-native/targets/foundation-present/tests/example.test.js +3 -0
  127. package/bin/fixtures/benchmarks/core-native/targets/go-http-server-timeout-risky-template/go.mod +3 -0
  128. package/bin/fixtures/benchmarks/core-native/targets/go-http-server-timeout-risky-template/server.go +18 -0
  129. package/bin/fixtures/benchmarks/core-native/targets/go-http-timeout-malformed-template/client.go +3 -0
  130. package/bin/fixtures/benchmarks/core-native/targets/go-http-timeout-malformed-template/go.mod +3 -0
  131. package/bin/fixtures/benchmarks/core-native/targets/go-http-timeout-risky-template/client.go +7 -0
  132. package/bin/fixtures/benchmarks/core-native/targets/go-http-timeout-risky-template/go.mod +3 -0
  133. package/bin/fixtures/benchmarks/core-native/targets/go-http-timeout-safe/client.go +22 -0
  134. package/bin/fixtures/benchmarks/core-native/targets/go-http-timeout-safe/go.mod +3 -0
  135. package/bin/fixtures/benchmarks/core-native/targets/go-http-timeout-safe/hazards_test.go +8 -0
  136. package/bin/fixtures/benchmarks/core-native/targets/kubernetes-risky-template/deployment.yaml +27 -0
  137. package/bin/fixtures/benchmarks/core-native/targets/kubernetes-valid/deployment.yaml +26 -0
  138. package/bin/fixtures/benchmarks/core-native/targets/openapi-operation-ids-risky-template/openapi.yaml +17 -0
  139. package/bin/fixtures/benchmarks/core-native/targets/openapi-operation-responses-risky-template/openapi.yaml +11 -0
  140. package/bin/fixtures/benchmarks/core-native/targets/openapi-root-malformed-template/openapi.yaml +5 -0
  141. package/bin/fixtures/benchmarks/core-native/targets/openapi-root-risky-template/openapi.yaml +5 -0
  142. package/bin/fixtures/benchmarks/core-native/targets/openapi-root-valid/openapi.yaml +17 -0
  143. package/bin/fixtures/benchmarks/core-native/targets/package-test-command/app.js +3 -0
  144. package/bin/fixtures/benchmarks/core-native/targets/package-test-command/package.json +7 -0
  145. package/bin/fixtures/benchmarks/core-native/targets/package-test-placeholder/app.js +3 -0
  146. package/bin/fixtures/benchmarks/core-native/targets/package-test-placeholder/package.json +7 -0
  147. package/bin/fixtures/benchmarks/core-native/targets/private-key-template/deploy.pem +3 -0
  148. package/bin/fixtures/benchmarks/core-native/targets/readme-missing/fixture.txt +1 -0
  149. package/bin/fixtures/benchmarks/core-native/targets/runtime-missing/package-lock.json +6 -0
  150. package/bin/fixtures/benchmarks/core-native/targets/runtime-missing/package.json +4 -0
  151. package/bin/fixtures/benchmarks/core-native/targets/terraform-locked/.terraform.lock.hcl +3 -0
  152. package/bin/fixtures/benchmarks/core-native/targets/terraform-locked/main.tf +7 -0
  153. package/bin/fixtures/benchmarks/core-native/targets/terraform-unlocked-template/.terraform.lock.hcl +3 -0
  154. package/bin/fixtures/benchmarks/core-native/targets/terraform-unlocked-template/main.tf +7 -0
  155. package/bin/fixtures/benchmarks/core-native/targets/test-declaration-valid/app.py +2 -0
  156. package/bin/fixtures/benchmarks/core-native/targets/test-declaration-valid/tests/test_app.py +5 -0
  157. package/bin/fixtures/benchmarks/core-native/targets/test-path-without-declaration/app.py +2 -0
  158. package/bin/fixtures/benchmarks/core-native/targets/test-path-without-declaration/tests/test_app.py +1 -0
  159. package/bin/fixtures/benchmarks/core-native/targets/workflow-malformed/.github/workflows/validate.yml +1 -0
  160. package/bin/fixtures/benchmarks/core-native/targets/workflow-no-jobs/.github/workflows/empty.yml +9 -0
  161. package/bin/fixtures/benchmarks/core-native/targets/workflow-risky/.github/workflows/risky.yml +10 -0
  162. package/bin/fixtures/benchmarks/core-native/targets/workflow-valid/.github/workflows/validate.yml +14 -0
  163. package/bin/packs/core-foundation.yaml +25 -0
  164. package/bin/packs/core-native.yaml +59 -0
  165. package/bin/prc +0 -0
  166. package/bin/schemas/adapter-execution-v0.1.schema.json +101 -0
  167. package/bin/schemas/adapter-execution-v0.2.schema.json +128 -0
  168. package/bin/schemas/adapter-execution.schema.json +145 -0
  169. package/bin/schemas/adapter-fixture-report.schema.json +59 -0
  170. package/bin/schemas/adapter-fixture-suite.schema.json +104 -0
  171. package/bin/schemas/adapter-manifest-v0.1.schema.json +55 -0
  172. package/bin/schemas/adapter-manifest-v0.2.schema.json +122 -0
  173. package/bin/schemas/adapter-manifest-v0.3.schema.json +172 -0
  174. package/bin/schemas/adapter-manifest.schema.json +299 -0
  175. package/bin/schemas/adapter-message.schema.json +136 -0
  176. package/bin/schemas/adapter-registry-report.schema.json +13 -0
  177. package/bin/schemas/adapter-registry.schema.json +47 -0
  178. package/bin/schemas/agent-execution-v0.1.schema.json +26 -0
  179. package/bin/schemas/agent-execution.schema.json +26 -0
  180. package/bin/schemas/agent-failure-v0.1.schema.json +102 -0
  181. package/bin/schemas/agent-failure.schema.json +102 -0
  182. package/bin/schemas/agent-output-v0.1.schema.json +36 -0
  183. package/bin/schemas/agent-output.schema.json +36 -0
  184. package/bin/schemas/agent-task-v0.1.schema.json +44 -0
  185. package/bin/schemas/agent-task.schema.json +46 -0
  186. package/bin/schemas/assertion-catalog.schema.json +69 -0
  187. package/bin/schemas/benchmark-report.schema.json +94 -0
  188. package/bin/schemas/benchmark-suite.schema.json +116 -0
  189. package/bin/schemas/catalog-bundle.schema.json +27 -0
  190. package/bin/schemas/catalog-manifest.schema.json +23 -0
  191. package/bin/schemas/checkov-iac-policy-report.schema.json +82 -0
  192. package/bin/schemas/control-contracts.schema.json +44 -0
  193. package/bin/schemas/control-review-output.schema.json +51 -0
  194. package/bin/schemas/doctor.schema.json +53 -0
  195. package/bin/schemas/evidence-v0.1.schema.json +21 -0
  196. package/bin/schemas/evidence.schema.json +21 -0
  197. package/bin/schemas/finding-v0.1.schema.json +70 -0
  198. package/bin/schemas/finding.schema.json +70 -0
  199. package/bin/schemas/fix-contract-v0.1.schema.json +35 -0
  200. package/bin/schemas/fix-contract-v0.2.schema.json +46 -0
  201. package/bin/schemas/fix-contract-v0.3.schema.json +49 -0
  202. package/bin/schemas/fix-contract.schema.json +49 -0
  203. package/bin/schemas/grype-vulnerability-report.schema.json +88 -0
  204. package/bin/schemas/history.schema.json +37 -0
  205. package/bin/schemas/invalidation.schema.json +86 -0
  206. package/bin/schemas/inventory-v0.1.schema.json +42 -0
  207. package/bin/schemas/inventory-v0.2.schema.json +95 -0
  208. package/bin/schemas/inventory-v0.3.schema.json +139 -0
  209. package/bin/schemas/inventory.schema.json +139 -0
  210. package/bin/schemas/objective-catalog.schema.json +62 -0
  211. package/bin/schemas/pack-report.schema.json +16 -0
  212. package/bin/schemas/pack.schema.json +53 -0
  213. package/bin/schemas/plan-v0.1.schema.json +31 -0
  214. package/bin/schemas/plan-v0.2.schema.json +32 -0
  215. package/bin/schemas/plan-v0.3.schema.json +44 -0
  216. package/bin/schemas/plan-v0.4.schema.json +48 -0
  217. package/bin/schemas/plan-v0.5.schema.json +49 -0
  218. package/bin/schemas/plan-v0.6.schema.json +137 -0
  219. package/bin/schemas/plan.schema.json +137 -0
  220. package/bin/schemas/profile.schema.json +42 -0
  221. package/bin/schemas/project-config.schema.json +128 -0
  222. package/bin/schemas/release-manifest-v0.1.schema.json +86 -0
  223. package/bin/schemas/release-manifest-v0.2.schema.json +146 -0
  224. package/bin/schemas/release-manifest-v0.3.schema.json +146 -0
  225. package/bin/schemas/release-manifest.schema.json +6 -0
  226. package/bin/schemas/remediation-candidate-v0.1.schema.json +51 -0
  227. package/bin/schemas/remediation-candidate-v0.2.schema.json +51 -0
  228. package/bin/schemas/remediation-candidate-v0.3.schema.json +51 -0
  229. package/bin/schemas/remediation-candidate-v0.4.schema.json +69 -0
  230. package/bin/schemas/remediation-candidate.schema.json +69 -0
  231. package/bin/schemas/remediation-run-v0.1.schema.json +69 -0
  232. package/bin/schemas/remediation-run-v0.2.schema.json +78 -0
  233. package/bin/schemas/remediation-run-v0.3.schema.json +86 -0
  234. package/bin/schemas/remediation-run-v0.4.schema.json +86 -0
  235. package/bin/schemas/remediation-run-v0.5.schema.json +131 -0
  236. package/bin/schemas/remediation-run-v0.6.schema.json +143 -0
  237. package/bin/schemas/remediation-run-v0.7.schema.json +160 -0
  238. package/bin/schemas/remediation-run-v0.8.schema.json +161 -0
  239. package/bin/schemas/remediation-run.schema.json +161 -0
  240. package/bin/schemas/risk-exception-verification.schema.json +17 -0
  241. package/bin/schemas/risk-exception.schema.json +137 -0
  242. package/bin/schemas/run-result-v0.1.schema.json +54 -0
  243. package/bin/schemas/run-result-v0.10.schema.json +64 -0
  244. package/bin/schemas/run-result-v0.11.schema.json +146 -0
  245. package/bin/schemas/run-result-v0.2.schema.json +60 -0
  246. package/bin/schemas/run-result-v0.3.schema.json +52 -0
  247. package/bin/schemas/run-result-v0.4.schema.json +52 -0
  248. package/bin/schemas/run-result-v0.5.schema.json +60 -0
  249. package/bin/schemas/run-result-v0.6.schema.json +61 -0
  250. package/bin/schemas/run-result-v0.7.schema.json +61 -0
  251. package/bin/schemas/run-result-v0.8.schema.json +61 -0
  252. package/bin/schemas/run-result-v0.9.schema.json +77 -0
  253. package/bin/schemas/run-result.schema.json +165 -0
  254. package/bin/schemas/signature-verification.schema.json +22 -0
  255. package/bin/schemas/signature.schema.json +18 -0
  256. package/bin/schemas/state-check-v0.1.schema.json +27 -0
  257. package/bin/schemas/state-check.schema.json +28 -0
  258. package/bin/schemas/trust-store.schema.json +50 -0
  259. package/bin/schemas/verification-execution-v0.1.schema.json +105 -0
  260. package/bin/schemas/verification-execution.schema.json +105 -0
  261. package/bin/schemas/version-v0.1.schema.json +27 -0
  262. package/bin/schemas/version.schema.json +27 -0
  263. package/manifest.json +9 -0
  264. package/package.json +28 -0
@@ -0,0 +1,273 @@
1
+ # Bounded isolated remediation
2
+
3
+ The experimental `remediate` command supports two deterministic fixers:
4
+
5
+ - `PRC-A-CORE-014` appends one line-feed byte to each recognized source file
6
+ that lacks one; and
7
+ - `PRC-A-CORE-022` clears group-write and other-write permission bits while
8
+ preserving every file byte and all other permission bits.
9
+
10
+ Neither fixer executes target code, calls a model, uses the network, edits the
11
+ original workspace, or performs version-control operations.
12
+
13
+ The README-presence assertion is deliberately R2. Writing useful project
14
+ documentation requires project-specific judgment, so the scanner does not create
15
+ a placeholder README and claim the finding is fixed.
16
+
17
+ ## Create an isolated candidate
18
+
19
+ Choose a new destination outside the target tree. Its parent must already exist,
20
+ and the destination itself must not exist.
21
+
22
+ ```bash
23
+ ./prc remediate \
24
+ --catalog-root /path/to/production-readiness-checklist \
25
+ --target /path/to/project \
26
+ --config /path/to/project/production-readiness.yaml \
27
+ --assertion PRC-A-CORE-014 \
28
+ --candidate-dir /safe/path/prc-candidate \
29
+ --max-files 20 \
30
+ --max-changed-lines 20
31
+ ```
32
+
33
+ The command exits `0` only when the candidate passes every acceptance check. A
34
+ validated but rejected candidate is still printed and exits `8`. Invalid input
35
+ exits `3`; a policy-denied remediation exits `5`. Use
36
+ `--format json` for the versioned `prc.remediation-candidate/v0.4` record.
37
+
38
+ With `--config`, the exact canonical configuration digest and project identity
39
+ are recorded in the fix contract. The configured profile is mandatory,
40
+ `remediation.enabled` must be true, and command-line file or line limits cannot
41
+ raise the configured ceilings. The configured attempt ceiling is recorded even
42
+ though this command performs exactly one attempt. Scanner defaults, configured
43
+ protected paths, and the configuration file itself are unioned into the guard
44
+ set. Baseline, candidate, and final source-integrity scans all rebind the same
45
+ configuration.
46
+
47
+ ## What acceptance verifies
48
+
49
+ The scanner creates a content-addressed fix contract with the baseline run,
50
+ inventory, exact canonical finding ID and stable finding fingerprint, allowed
51
+ paths, protected paths, network denial, one-attempt limit, and file and line
52
+ budgets. After applying the fix in the copy, it:
53
+
54
+ 1. inventories the candidate from fresh bytes;
55
+ 2. walks the raw candidate tree so excluded directories cannot hide additions;
56
+ 3. rejects additions, deletions, symlinks, non-regular entries,
57
+ protected-path changes, and any change outside the allowlist;
58
+ 4. verifies the fixer's exact byte-and-mode postcondition: one appended
59
+ line-feed with the mode unchanged, or bytes unchanged with only group-write
60
+ and other-write bits cleared;
61
+ 5. rescans the candidate and requires the target assertion to pass; and
62
+ 6. requires every assertion that passed in the baseline to remain passing; and
63
+ 7. re-inventories the original target and requires it to remain byte-for-byte
64
+ and mode-for-mode identical to the baseline.
65
+
66
+ The candidate directory is preserved for review. Acceptance is permission to
67
+ inspect or continue testing that isolated candidate; it is not authorization to
68
+ merge, deploy, release, accept risk, or claim that the full profile is satisfied.
69
+
70
+ ## Run the bounded remediation loop
71
+
72
+ Without a provider, `prc fix` repeatedly applies only the registered R1 fixers.
73
+ Each accepted candidate becomes the source of a new sibling candidate, so fixes
74
+ compose without changing the original project. The candidate root must be a new
75
+ path outside the target tree. The scanner validates that destination first but
76
+ does not create it until an eligible attempt has passed task, source, policy,
77
+ and budget preflight.
78
+
79
+ ```bash
80
+ export OPENAI_API_KEY='your-provider-key'
81
+ ./prc fix \
82
+ --catalog-root /path/to/production-readiness-checklist \
83
+ --target /path/to/project \
84
+ --config /path/to/project/production-readiness.yaml \
85
+ --candidate-root /safe/path/prc-remediation-run \
86
+ --max-attempts 3 \
87
+ --max-files 20 \
88
+ --max-changed-lines 200 \
89
+ --max-duration-seconds 1800 \
90
+ --format json > remediation-run.json
91
+ ```
92
+
93
+ The loop evaluates findings in profile order and stops predictably when it has
94
+ closed all eligible findings, a cumulative budget is exhausted, a provider
95
+ cannot return a candidate, or an independently checked candidate is rejected.
96
+ File and changed-line usage accumulates across accepted candidates. One
97
+ wall-clock budget spans planning, provider execution, candidate generation, and
98
+ verification. It is propagated as a hard deadline to provider and verifier
99
+ child processes and checked at scanner phase boundaries; a synchronous
100
+ candidate operation that returns after the deadline is preserved but rejected,
101
+ never accepted. Command-line values cannot raise limits declared in project
102
+ configuration. Go contexts propagate deadline cancellation, and commands
103
+ started with `CommandContext` are interrupted when that context completes
104
+ ([context package](https://pkg.go.dev/context),
105
+ [os/exec package](https://pkg.go.dev/os/exec)).
106
+
107
+ The `prc.remediation-run/v0.9` report records every actual attempt, including
108
+ proposals rejected before candidate creation. Each attempt binds its sequence,
109
+ mode, exact finding and fingerprint, scanner-owned task, before and after
110
+ inventory digests, provider execution or failure and candidate when present, timestamps,
111
+ outcome, machine-readable reason code, and exact scanner rejection reason. The
112
+ scanner verifies this linkage before computing the run content ID. The report
113
+ also preserves every candidate, provider transcript digest, cumulative budget
114
+ usage, final fresh assessment, final isolated workspace, and a reason code for
115
+ every unresolved result. Its embedded v0.9 scan result preserves adapter
116
+ resolution provenance; frozen v0.3 through v0.7 remediation schemas retain their
117
+ version-pinned dependency graphs. Every unresolved failure includes its
118
+ canonical finding ID and stable fingerprint. Its terminal states are:
119
+
120
+ - `profile_satisfied`: every required result in the selected profile passed;
121
+ - `machine_work_complete`: no registered deterministic R1 failure remains, but
122
+ manual evidence, blocked checks, or higher-risk work can still remain;
123
+ - `stopped_by_policy_or_budget`: an eligible fix could not run within policy;
124
+ - `candidate_rejected`: independent acceptance rejected an attempted fix;
125
+ - `provider_stopped`: the provider returned `unable` or `needs_escalation`
126
+ without a patch; or
127
+ - `provider_failed`: scanner preflight, transcript persistence, process,
128
+ timeout, output-bound, postflight-integrity, or output-protocol validation
129
+ failed and the loop did not retry.
130
+
131
+ Exit status `0` is reserved for `profile_satisfied`. A no-go gate exits `1`,
132
+ incomplete or blocked assessment work and `provider_stopped` exit `2`, a policy
133
+ or budget stop exits `5`, provider failure exits `4`, and candidate rejection
134
+ exits `8`. Caller cancellation retains exit `7` while preserving its failure
135
+ record.
136
+ `machine_work_complete` is not a production-readiness claim. The default loop
137
+ does not invoke an agent. No loop mode runs project commands, deploys, merges,
138
+ or performs version-control operations.
139
+
140
+ ## Opt in to one scanner-planned R2 task
141
+
142
+ `prc fix --provider` connects the bounded loop to the read-only Codex or Claude
143
+ Code provider adapter. This is not general repository autonomy. The current
144
+ task planner supports only a failing `PRC-A-CORE-010` test-discovery assertion:
145
+ it selects one bounded source file, derives a small allowlist of new test paths,
146
+ binds the exact triggering finding into the sealed task, and asks for exactly
147
+ one non-vacuous test file. Every other R2 finding remains
148
+ `no_safe_agent_task` until it has a dedicated planner and sufficiently strong
149
+ verification.
150
+
151
+ ```bash
152
+ ./prc fix \
153
+ --catalog-root /path/to/production-readiness-checklist \
154
+ --target /path/to/project \
155
+ --config /path/to/project/production-readiness.yaml \
156
+ --candidate-root /safe/path/prc-remediation-run \
157
+ --provider codex \
158
+ --allow-remote-source-processing \
159
+ --verifier-runtime docker \
160
+ --verifier-image registry.example/prc/python-verifier@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
161
+ --max-attempts 3 \
162
+ --max-duration-seconds 1800 \
163
+ --format json > remediation-run.json
164
+ ```
165
+
166
+ The remote-processing flag is mandatory because the sealed prompt contains the
167
+ selected source file. High-confidence secret-like material in that input causes
168
+ a policy stop before the candidate root or provider output directory is created;
169
+ the error identifies only the source path and detector family. The provider
170
+ receives no source-workspace access, shell, network tool, MCP server, secret,
171
+ edit tool, or candidate workspace. Its output
172
+ directory is private and separate from both source and candidate. Each provider
173
+ attempt preserves `agent-task.json`, bounded stdout/stderr transcripts, their
174
+ digests, the executable digest, and the schema digest. A proposal is parsed and
175
+ applied by the scanner exactly once in a fresh candidate, then passes the same
176
+ structural, anti-gaming, target-assertion, regression, and source-integrity
177
+ checks as `remediate-proposal`.
178
+
179
+ `--verifier-image` is mandatory with `--provider`. The reference must include an
180
+ explicit registry and immutable SHA-256 digest, and the image must already be
181
+ present because the runner passes `--pull=never`. The provider and repository
182
+ cannot choose or alter the image, command, or limits. The scanner infers one
183
+ supported command solely from the sealed source path: `go test ./...` for Go,
184
+ `python -m pytest -q` for Python, or `node --test` for plain JavaScript. The
185
+ scanner never invokes package scripts. TypeScript proposal planning remains
186
+ fail-closed because no scanner-owned verifier is registered for that ecosystem.
187
+ Because verification is network-denied and starts with empty scratch caches, the
188
+ selected image must already contain the required toolchain and test runner, and
189
+ the candidate must vendor or otherwise carry every dependency it needs. The
190
+ project does not yet publish a canonical verifier image; operators are
191
+ responsible for reviewing and pinning one for each supported ecosystem.
192
+
193
+ The candidate is mounted read-only into a read-only container with no network,
194
+ all Linux capabilities dropped, `no-new-privileges`, the caller's non-root
195
+ numeric user, bounded CPU, memory and swap, processes, file descriptors,
196
+ scratch space, time, stdout, and stderr. These flags implement documented
197
+ [Docker runtime isolation and resource controls](https://docs.docker.com/engine/containers/run/).
198
+ The output record contains hashes and byte counts rather than raw test output,
199
+ binds the configured candidate identity separately from its raw workspace-byte
200
+ inventory, and verifies that the candidate bytes did not change during the
201
+ run. A test failure, timeout, output limit, unavailable runtime or image, or
202
+ integrity change rejects the candidate; none is converted to a pass.
203
+
204
+ If invocation fails before a valid provider output exists, the scanner writes a
205
+ content-addressed `prc.agent-failure/v0.1` record. It uses a scanner-authored
206
+ safe reason, links the sealed task and provider identities, distinguishes the
207
+ failure stage and reason code, and records whichever bounded transcripts were
208
+ successfully persisted. The failed attempt consumes one attempt, is terminal,
209
+ and is never retried automatically.
210
+
211
+ Current acceptance reconstructs the proposed test before candidate creation,
212
+ requires a conventionally collectable declaration and a recognized behavioral
213
+ failure check, and establishes that the test was added without weakening
214
+ existing tests or regressing prior scanner passes. It then runs the supported
215
+ scanner-owned test command in the isolated verifier and requires exit status
216
+ zero. Go documents `go test ./...` as package-list mode over packages below the
217
+ current directory, and a failing Go test returns a nonzero status
218
+ ([Go command reference](https://go.dev/cmd/go/)). Passing the suite proves only
219
+ that the configured command passed in that image; it does not prove complete
220
+ behavioral coverage. Broader R2 autonomy stays disabled until each task has an
221
+ assertion-specific behavioral contract and verifier.
222
+
223
+ ## Apply one validated R2 proposal
224
+
225
+ `remediate-proposal` is the scanner-owned bridge from a validated Codex or
226
+ Claude Code `suggest` result to an isolated candidate. It never asks the provider
227
+ to edit files and never executes provider-authored commands. The source task must
228
+ still match the current workspace inventory, the assertion must be classified
229
+ R2, its exact finding ID and stable fingerprint must still match a freshly
230
+ reproduced failure, and the candidate destination must be new and outside the
231
+ source tree. The v0.3 fix contract records both the task's triggering finding
232
+ ID and the freshly verified baseline finding ID so the provider handoff remains
233
+ auditable end to end.
234
+
235
+ ```bash
236
+ ./prc remediate-proposal \
237
+ --catalog-root /path/to/production-readiness-checklist \
238
+ --target /path/to/project \
239
+ --config /path/to/project/production-readiness.yaml \
240
+ --provider codex \
241
+ --task /safe/path/task.json \
242
+ --output /safe/path/validated-provider-output.json \
243
+ --candidate-dir /safe/path/prc-r2-candidate \
244
+ --verifier-runtime docker \
245
+ --verifier-image registry.example/prc/python-verifier@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef \
246
+ --max-files 20 \
247
+ --max-changed-lines 200
248
+ ```
249
+
250
+ The strict internal unified-diff parser supports exact-context modification and
251
+ mode-`0644` text-file addition. It rejects deletions, renames, copies, binary or
252
+ mode changes, CRLF patch encoding, non-newline markers, malformed coordinates,
253
+ context mismatches, unlisted or protected paths, and budget overruns before
254
+ acceptance. A conservative anti-gaming pass also rejects changes to existing test
255
+ or specification files, newly introduced suppression or skip directives,
256
+ constant assertions, empty Go tests, test-shaped files without a collectable
257
+ declaration, and invocation-only tests without a recognized behavioral failure
258
+ check. Language-aware payload rules also reject generated tests that request
259
+ process or shell execution, network clients, environment or secret access,
260
+ filesystem mutation or absolute-path reads, dynamic evaluation, deserialization
261
+ execution, or long encoded payloads before creating a candidate. New focused
262
+ local assertions remain permitted. The payload audit is deliberately
263
+ conservative and syntactic; the independent sandbox remains the containment
264
+ boundary for obfuscation or parser gaps. The raw-tree, byte, mode, target assertion, baseline
265
+ regression, and source-integrity audits then run from fresh inventories.
266
+
267
+ Current R2 acceptance proves the declared deterministic scanner postcondition,
268
+ structural anti-gaming checks, scanner non-regression envelope, and successful
269
+ execution of the registered sandbox command. The anti-gaming checks catch known
270
+ unsafe patch shapes, and the test execution proves the suite passed; neither
271
+ alone proves that a new test is behaviorally sufficient. Broader code-changing
272
+ autonomy still requires task-specific verification and stronger behavioral
273
+ assertions before it can be enabled by policy.
@@ -0,0 +1,52 @@
1
+ # Signed risk exceptions
2
+
3
+ A risk exception is an accountable human decision about one exact failed
4
+ finding. It is not a scanner result, cannot turn a failure into a pass, and
5
+ does not change the run's terminal state. The scanner has no command that
6
+ creates, approves, or signs an exception.
7
+
8
+ The `prc.risk-exception/v0.1` record binds:
9
+
10
+ - the immutable run, inventory, profile, project, commit, artifact, and
11
+ environment scope;
12
+ - the exact finding ID, stable fingerprint, assertion, and controls;
13
+ - distinct requester, risk owner, and independent reviewer identities;
14
+ - likelihood, impact, rationale, and worst credible outcome;
15
+ - compensating controls with content-addressed evidence references;
16
+ - monitoring, containment response, remediation owner, plan, and due date; and
17
+ - UTC approval and automatic expiry no more than 366 days apart.
18
+
19
+ Verification rejects a missing or non-failing finding, scope drift,
20
+ self-approval, duplicate reviewers, future approval, expired decision,
21
+ unbounded duration, unsigned edits, revoked keys, or a key without the
22
+ `risk-exception` scope. The signature must have been issued after approval and
23
+ before verification.
24
+
25
+ ## Verify against immutable history
26
+
27
+ The bound run must already exist in the private scanner state store. Loading it
28
+ through the history store revalidates its nested plan, inventory, findings,
29
+ evidence, adapter executions, and content identities before exception
30
+ verification:
31
+
32
+ ```bash
33
+ prc exception verify \
34
+ --file /path/to/PRC-EXC-001.yaml \
35
+ --state-dir /path/to/private-state \
36
+ --trust-store /path/to/risk-owner-keys.yaml \
37
+ --signature /path/to/PRC-EXC-001.signature.yaml \
38
+ --verified-at 2026-08-23T13:00:00Z \
39
+ --format json
40
+ ```
41
+
42
+ The output disposition is `accepted_risk_exception`, but its `gate_effect`
43
+ always states that the finding remains failed and the scanner terminal state
44
+ is unchanged. A release process may present that signed decision to accountable
45
+ people; general agent remediation and scanner policy cannot consume it as a
46
+ Pass or silently suppress the finding.
47
+
48
+ The machine contracts are `risk-exception.schema.json` and
49
+ `risk-exception-verification.schema.json`. Compensating evidence references
50
+ are digests, not proof by themselves; the approving workflow remains
51
+ responsible for retaining and independently authenticating the referenced
52
+ evidence.
@@ -0,0 +1,236 @@
1
+ # Safe start-to-finish scanner walkthrough
2
+
3
+ This page explains what happens from installation through a finished report,
4
+ what can go wrong at each step, and what the scanner does about it. Safe
5
+ behavior should not depend on knowing security jargon.
6
+
7
+ ## 1. Choose one exact release
8
+
9
+ Find a `scanner-vX.Y.Z` release in this repository and use that exact version.
10
+ Do not copy a similar package name from a search result.
11
+
12
+ For a Node project:
13
+
14
+ ```bash
15
+ npm install --save-dev --save-exact --ignore-scripts --no-audit --no-fund @marinjursic/prc@X.Y.Z
16
+ ```
17
+
18
+ What this changes:
19
+
20
+ - npm adds the exact scanner version to `devDependencies`;
21
+ - npm installs the small launcher and one matching native package;
22
+ - npm writes or updates `package-lock.json`; and
23
+ - npm does not run package install hooks because `--ignore-scripts` is present.
24
+
25
+ What could be attacked:
26
+
27
+ - A misspelled name could install somebody else's package. Use the exact scoped
28
+ name `@marinjursic/prc` from this repository.
29
+ - A floating version such as `latest` can change between machines. Use the exact
30
+ release number and commit the lock file.
31
+ - Any package manager or registry can be compromised. Check the release's npm
32
+ provenance and compare the version with the GitHub release before trusting
33
+ it. The first npm publication also needs a one-time human bootstrap, which is
34
+ clearly documented rather than hidden in automation.
35
+ - Install hooks are a common place for unwanted code. The scanner packages have
36
+ no hooks, no third-party JavaScript runtime dependencies, and the command
37
+ disables hooks anyway.
38
+
39
+ The npm launcher never downloads a binary. It reads the exact platform manifest,
40
+ checks the packaged native binary's SHA-256, and starts that file directly
41
+ without a shell. It does not fall back to a program named `prc` on `PATH`.
42
+
43
+ ## 2. Add the easy command
44
+
45
+ Add this one line to the existing `scripts` object in `package.json`:
46
+
47
+ ```json
48
+ {
49
+ "scripts": {
50
+ "scan": "prc scan"
51
+ }
52
+ }
53
+ ```
54
+
55
+ The shortest repeatable command is:
56
+
57
+ ```bash
58
+ npm run scan
59
+ ```
60
+
61
+ For the stricter run, use `npm run --ignore-scripts scan`; the named `scan`
62
+ script runs, but local `prescan` and `postscan` hooks do not. If you do not want
63
+ to edit `package.json`, use this after the exact package is already installed:
64
+
65
+ ```bash
66
+ npm exec --offline --no -- prc scan
67
+ ```
68
+
69
+ `--offline --no` makes a missing local command fail instead of asking to fetch
70
+ something from the registry. `npm scan` is not valid npm syntax for a custom
71
+ command.
72
+
73
+ ## 3. Build a safe inventory
74
+
75
+ The scanner reads the target tree and records file paths, sizes, modes, hashes,
76
+ recognized project facts, exclusions, and Git identity. It does not run the
77
+ project's package manager, build, tests, scripts, hooks, containers, or code.
78
+
79
+ A hostile repository might contain links that point outside the project, huge
80
+ files, changing files, strange Git configuration, invalid text, or generated
81
+ trees designed to waste time. The inventory therefore:
82
+
83
+ - never follows repository symlinks;
84
+ - uses entry-count, per-file, and total-byte limits;
85
+ - checks a file again after reading it;
86
+ - runs Git with a small scanner-owned configuration and scopes status to the
87
+ target worktree;
88
+ - excludes only clear caches, generated output, scanner state, and Git internals;
89
+ - records every exclusion and limit instead of silently calling the scan
90
+ complete; and
91
+ - stops on unsafe or changing input instead of guessing.
92
+
93
+ ## 4. Run the local checks
94
+
95
+ The normal profile currently has 40 narrow checks. They cover exact repository
96
+ facts such as a usable lock file, workflow parsing, pinned action references,
97
+ private-key armor, selected Kubernetes fields, OpenAPI structure, and direct Go
98
+ HTTP helper calls.
99
+
100
+ Parsers can have bugs, and one file pattern does not prove a broad engineering
101
+ promise. Each parser has input limits and returns an error or incomplete result
102
+ when it cannot safely decide. A narrow passing check produces only its narrow
103
+ evidence. It does not turn a large linked control into a complete Pass.
104
+
105
+ For example, finding `README.md` proves only that a nonempty root README exists.
106
+ It does not prove the instructions are correct. Detecting
107
+ `pull_request_target` asks for security review; trigger presence alone is not
108
+ reported as proof of a vulnerability. The six-hour workflow timeout is a named
109
+ value in the selected core profile, not a claim that every project must use the
110
+ same limit.
111
+
112
+ ## 5. Include all 10,042 controls honestly
113
+
114
+ Every complete report contains every registered control and its exact control
115
+ contract. The generated contracts say what kind of evidence appears necessary,
116
+ whether complete inventory or a project threshold is needed, whether the rule
117
+ looks compound or negative, and what must be shown for Not Applicable.
118
+
119
+ All generated contracts are marked `generated_unreviewed`. They route future
120
+ work; they are not 10,042 approved automatic tests. Broad controls remain
121
+ `needs_review`, `blocked`, or `partially_verified` until the right evidence
122
+ exists. This is how the scanner uses every rule without inventing thousands of
123
+ false passes.
124
+
125
+ The full proposed acceptance review for every control is split into bounded
126
+ parts under `research/control-acceptance-criteria/`. Its `README.md` is the
127
+ index. A control owner must still approve and test a contract before it can
128
+ become a trusted automatic check.
129
+
130
+ ## 6. Write the report
131
+
132
+ By default the scanner writes one private HTML file outside the target project
133
+ and prints its exact path. It creates a new file and never overwrites an old
134
+ one. The target bytes and file modes are checked before and after the scan in
135
+ the test suite.
136
+
137
+ The terminal uses green for Pass, red for Fail, yellow for blocked or manual
138
+ work, and plain text when output is redirected. The report separates:
139
+
140
+ - the result of the 40-check local profile;
141
+ - the state of the full 10,042-control catalog;
142
+ - verified findings and exact evidence;
143
+ - controls that still need proof; and
144
+ - inventory limits and exclusions.
145
+
146
+ Reports can contain project names, paths, evidence summaries, and optional AI
147
+ review text. Treat them as project data. Store them in a private location and do
148
+ not upload them automatically.
149
+
150
+ ## 7. Optional AI review
151
+
152
+ A normal scan never contacts Codex, Claude, or another remote model. Sign in
153
+ through the scanner once, then use the short AI option:
154
+
155
+ ```bash
156
+ prc login codex
157
+ prc full codex
158
+ ```
159
+
160
+ Use `claude` in both commands for Claude Code. The login is kept in a private
161
+ scanner-only directory; normal provider settings, sessions, instructions, plugins,
162
+ hooks, and MCP servers are not loaded. `--ai` is also explicit permission to
163
+ send bounded, screened source excerpts to the chosen provider. Supported
164
+ temporary API-key environment variables and the longer
165
+ `--review-provider`/`--allow-remote-source-processing` form remain available.
166
+ `prc full codex` is the short spelling of `prc scan --ai codex`.
167
+
168
+ Before the provider starts, the scanner makes a private snapshot of bounded text
169
+ excerpts. It skips sensitive names and known key or token shapes, gives the
170
+ provider no target path, and marks repository text as untrusted data. Output
171
+ must cite a path and line that was actually shown. A valid location is recorded
172
+ as `snapshot_location_validated`, while the claim remains
173
+ `advisory_unverified`; a real line can still be irrelevant or misunderstood.
174
+ Missing, omitted, runtime, legal, company, or human evidence stays a limitation.
175
+
176
+ Prompt injection is still possible whenever untrusted text reaches a model.
177
+ The provider gets no general shell, source-reading, write, browser, web, or MCP
178
+ tool. Codex gets only subagent coordination for full review; Claude gets only
179
+ its Agent tool. The coordinator is required to create one separate subagent per
180
+ rule. The scanner checks the final schema, task ID, order, paths, lines, sizes,
181
+ and completeness, but current provider output does not give it trustworthy
182
+ proof that the provider really made every requested internal subagent call. A
183
+ provider that ignores the task can therefore produce only rejected or untrusted
184
+ advice, never verified evidence.
185
+
186
+ The local provider program itself is a bigger trust boundary. A malicious
187
+ `codex` or `claude` executable runs as your OS user and could ignore command
188
+ flags. The scanner hashes it and isolates configuration and environment, but it
189
+ cannot make a malicious executable safe. Install the official CLI, inspect its
190
+ path with `prc doctor`, and use a separate OS account or stronger outer sandbox
191
+ on a sensitive computer. The remote provider also receives the approved
192
+ excerpts and may charge money. Start with one rule.
193
+
194
+ AI output is advice only. It cannot change the local result, create a verified
195
+ Pass, make the final Not Applicable decision, or fix a file.
196
+
197
+ ## 8. Optional fixes
198
+
199
+ `prc scan` has no path to the fix code. Fixing starts only with the separate
200
+ `prc fix` command.
201
+
202
+ The fix system copies the target into a new private sibling candidate. It never
203
+ edits the original project. Deterministic fixes are limited to scanner-owned
204
+ changes with exact checks. The current AI path supports only one planned
205
+ missing-test task; the provider returns an untrusted patch proposal and never
206
+ edits a candidate itself.
207
+
208
+ A proposed fix might try to escape its path list, weaken tests, add a skip or
209
+ suppress a finding. The scanner rejects protected paths, unapproved files,
210
+ change-size limits, known test weakening, constant or empty tests, command
211
+ requests, policy changes, and capability expansion. It applies an accepted
212
+ proposal once to a fresh candidate, rescans fresh bytes, and runs a pinned,
213
+ network-denied verifier container for the supported test command.
214
+
215
+ The container runtime and verifier image are also trusted dependencies. The
216
+ image must already exist, use an immutable digest, and contain its dependencies;
217
+ the scanner never pulls it during the fix. Even a successful candidate is not
218
+ merged, committed, deployed, or called production ready. A person reviews the
219
+ candidate and decides what to keep.
220
+
221
+ ## 9. Read the final state correctly
222
+
223
+ `profile_satisfied` means the selected executable profile has current acceptable
224
+ evidence. It does not mean all 10,042 broad controls passed or that no bug exists.
225
+ `needs_review`, `environment_blocked`, `no_go`, `machine_work_complete`, and
226
+ similar states keep the missing decision or evidence visible.
227
+
228
+ The safe end of a normal run is therefore a report, not an automatic rewrite:
229
+
230
+ ```text
231
+ Scan mode: report only; no fixes were applied.
232
+ Detailed report: /private/path/example-api-91c2....html
233
+ ```
234
+
235
+ Open that file, start with red failures and no-go findings, then review yellow
236
+ blocked/manual items. Green means only the exact displayed check passed.
@@ -0,0 +1,113 @@
1
+ # Durable state and run history
2
+
3
+ When `--state-dir` is supplied, a scan writes immutable canonical JSON records
4
+ and transactionally indexes their metadata in `state.sqlite`:
5
+
6
+ ```text
7
+ prc-state/
8
+ ├── state.sqlite
9
+ ├── artifacts/
10
+ │ └── sha256/ab/<artifact-sha256>
11
+ ├── evidence/
12
+ │ └── ab/<evidence-id>.json
13
+ └── runs/
14
+ └── <run-id>.json
15
+ ```
16
+
17
+ Native artifacts are immutable raw bytes addressed by their declared SHA-256.
18
+ Before writing a payload, the store verifies that the run declares the same
19
+ digest and byte count, recomputes the digest, and refuses a different payload
20
+ at an existing path. Generic adapter artifact descriptors and deliberately
21
+ ephemeral sensitive reports do not authorize payload persistence.
22
+
23
+ The JSON records are authoritative. SQLite is a query index that can be rebuilt
24
+ from those content-addressed records; it never replaces evidence or changes an
25
+ assessment. Indexing verifies every run and evidence identity against its
26
+ canonical record before one transaction updates runs, results, fingerprinted
27
+ findings, finding locations and evidence links, evidence metadata, inventory
28
+ files, inventory facts, relationships, and the audit event.
29
+
30
+ ## Create private state
31
+
32
+ Scanner evidence can contain sensitive paths and findings. Keep state outside
33
+ the target repository on a local filesystem and restrict it to the current user:
34
+
35
+ ```bash
36
+ mkdir -m 0700 /safe/local/path/prc-state
37
+
38
+ ./prc scan \
39
+ --target /path/to/project \
40
+ --catalog-root /path/to/production-readiness-checklist \
41
+ --state-dir /safe/local/path/prc-state \
42
+ --format json \
43
+ --exit-policy never
44
+ ```
45
+
46
+ The scanner creates a missing state root with mode `0700` and the database with
47
+ mode `0600`. It rejects a pre-existing state root accessible by group or other
48
+ users. Windows relies on platform access controls because POSIX mode bits are not
49
+ available.
50
+
51
+ The initial store uses a full-synchronous rollback journal, a five-second busy
52
+ timeout, immediate write transactions, strict tables, and connection-level
53
+ foreign-key enforcement. WAL is deliberately not enabled: SQLite documents that
54
+ [WAL requires all users to be on one host and does not work on network
55
+ filesystems](https://www.sqlite.org/wal.html). A remote or shared filesystem is
56
+ not a supported state location even with the rollback journal.
57
+
58
+ ## List indexed runs
59
+
60
+ ```bash
61
+ ./prc history list \
62
+ --state-dir /safe/local/path/prc-state \
63
+ --limit 20
64
+ ```
65
+
66
+ Exact filters are available for `--target-name`, `--profile`, and
67
+ `--terminal-state`. JSON output conforms to `prc.history/v0.1`:
68
+
69
+ ```bash
70
+ ./prc history list \
71
+ --state-dir /safe/local/path/prc-state \
72
+ --target-name project \
73
+ --format json > history.json
74
+ ```
75
+
76
+ Counts preserve distinct states: Pass, Fail, and unresolved/blocked results are
77
+ never averaged into a score.
78
+
79
+ ## Load a canonical run
80
+
81
+ ```bash
82
+ ./prc history show \
83
+ --state-dir /safe/local/path/prc-state \
84
+ --format json \
85
+ <run-id>
86
+ ```
87
+
88
+ `history show` obtains the record path from the index, rejects absolute,
89
+ traversing, or symlink-escaping paths, loads the immutable JSON, and recomputes
90
+ its run identity before returning it. A missing, modified, or mismatched record
91
+ is an error; the database is never treated as sufficient proof by itself.
92
+
93
+ The implementation enables foreign keys explicitly because SQLite does not
94
+ guarantee they are enabled by default, and its integrity audit uses both
95
+ [`PRAGMA integrity_check`](https://www.sqlite.org/pragma.html#pragma_integrity_check)
96
+ and `PRAGMA foreign_key_check`.
97
+
98
+ Run both checks and obtain indexed record counts with:
99
+
100
+ ```bash
101
+ ./prc history check \
102
+ --state-dir /safe/local/path/prc-state \
103
+ --format json
104
+ ```
105
+
106
+ A successful JSON response conforms to `prc.state-check/v0.2`. It includes a
107
+ separate finding count; the frozen v0.1 schema remains available for archived
108
+ outputs. Corruption or a
109
+ foreign-key violation is an error and never produces an `integrity: ok` report.
110
+
111
+ Use [diff-aware evidence invalidation](diff-and-invalidation.md) to compare one
112
+ of these canonical runs to a current target without treating the SQLite index
113
+ as assessment authority.