avorelo 0.3.8 → 0.4.0-rc.2

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 (394) hide show
  1. package/LICENSE +16 -23
  2. package/README.md +62 -72
  3. package/bin/avorelo +9 -0
  4. package/package.json +147 -139
  5. package/scripts/README.md +40 -0
  6. package/scripts/avorelo-session-collision-guard.js +540 -0
  7. package/scripts/avorelo-workstream-preflight.js +918 -0
  8. package/scripts/cco-dashboard.js +346 -0
  9. package/scripts/cco-posttooluse.js +504 -0
  10. package/scripts/cco-pretooluse.js +381 -0
  11. package/scripts/cco-status.js +540 -0
  12. package/scripts/cco-stop.js +77 -0
  13. package/scripts/cco-userprompt-submit.js +83 -0
  14. package/scripts/lib/activation/account-state.js +37 -0
  15. package/scripts/lib/activation/activate-command.js +114 -0
  16. package/scripts/lib/activation/activation-runner.js +607 -0
  17. package/scripts/lib/activation/activation-self-healing.js +481 -0
  18. package/scripts/lib/activation/activation-state.js +96 -0
  19. package/scripts/lib/activation/activation-summary.js +241 -0
  20. package/scripts/lib/activation/adapters/claude-code.js +77 -0
  21. package/scripts/lib/activation/adapters/codex-cli.js +52 -0
  22. package/scripts/lib/activation/adapters/cursor.js +37 -0
  23. package/scripts/lib/activation/adapters/github-agent.js +39 -0
  24. package/scripts/lib/activation/adapters/terminal.js +42 -0
  25. package/scripts/lib/activation/adapters/vscode.js +39 -0
  26. package/scripts/lib/activation/adapters/windsurf.js +37 -0
  27. package/scripts/lib/activation/ai-surface-detector.js +151 -0
  28. package/scripts/lib/activation/connect-account.js +145 -0
  29. package/scripts/lib/activation/detect-environment.js +75 -0
  30. package/scripts/lib/activation/detect-hosts.js +62 -0
  31. package/scripts/lib/activation/format-activation-output.js +109 -0
  32. package/scripts/lib/activation/next-action.js +43 -0
  33. package/scripts/lib/activation/repair-engine.js +219 -0
  34. package/scripts/lib/activation/run-entry.js +346 -0
  35. package/scripts/lib/activation-distribution-readiness.js +507 -0
  36. package/scripts/lib/adapter-conformance.js +176 -0
  37. package/scripts/lib/adapter-readiness.js +428 -0
  38. package/scripts/lib/adapter-safety-boundaries.js +335 -0
  39. package/scripts/lib/adapter-technical-readiness-gate.js +205 -0
  40. package/scripts/lib/agent-access-governance.js +455 -0
  41. package/scripts/lib/agent-activation-readiness.js +878 -0
  42. package/scripts/lib/agent-enforcement.js +765 -0
  43. package/scripts/lib/agent-evolution-loop.js +479 -0
  44. package/scripts/lib/agent-policy-profile.js +210 -0
  45. package/scripts/lib/agent-security/action-evaluator.js +507 -0
  46. package/scripts/lib/agent-security/adapter-registry.js +98 -0
  47. package/scripts/lib/agent-security/auto-policy.js +139 -0
  48. package/scripts/lib/agent-security/bounded-scan.js +93 -0
  49. package/scripts/lib/agent-security/enforcement-adapter.js +174 -0
  50. package/scripts/lib/agent-security/enforcement-engine.js +1129 -0
  51. package/scripts/lib/agent-security/file-write-adapter.js +183 -0
  52. package/scripts/lib/agent-security/file-write-rules.js +178 -0
  53. package/scripts/lib/agent-security/index.js +3342 -0
  54. package/scripts/lib/agent-security/instruction-risk.js +181 -0
  55. package/scripts/lib/agent-security/mcp-action-adapter.js +185 -0
  56. package/scripts/lib/agent-security/mcp-action-rules.js +184 -0
  57. package/scripts/lib/agent-security/package-action-adapter.js +175 -0
  58. package/scripts/lib/agent-security/package-action-rules.js +233 -0
  59. package/scripts/lib/agent-security/performance.js +148 -0
  60. package/scripts/lib/agent-security/permission-minimizer.js +403 -0
  61. package/scripts/lib/agent-security/scan-cache.js +74 -0
  62. package/scripts/lib/agent-security/source-trust.js +146 -0
  63. package/scripts/lib/ai-efficiency-dogfood-pack.js +437 -0
  64. package/scripts/lib/ai-efficiency-eval.js +207 -0
  65. package/scripts/lib/ai-efficiency-guard-contract.js +209 -0
  66. package/scripts/lib/ai-efficiency-measured-value.js +106 -0
  67. package/scripts/lib/ai-install-prompt.js +293 -0
  68. package/scripts/lib/ai-task-inference.js +155 -0
  69. package/scripts/lib/ai-value-ledger.js +121 -0
  70. package/scripts/lib/ai-value-proof-table.js +151 -0
  71. package/scripts/lib/ai-work-efficiency-routing.js +623 -0
  72. package/scripts/lib/ai-workspace-hygiene.js +1499 -0
  73. package/scripts/lib/alpha-activation.js +520 -0
  74. package/scripts/lib/alpha-feedback.js +263 -0
  75. package/scripts/lib/alpha-readiness-gate.js +332 -0
  76. package/scripts/lib/anti-gaming.js +169 -0
  77. package/scripts/lib/artifact-health.js +431 -0
  78. package/scripts/lib/artifact-receipt-hygiene.js +619 -0
  79. package/scripts/lib/attribution.js +180 -0
  80. package/scripts/lib/audit.js +289 -0
  81. package/scripts/lib/avorelo-skill-registry.js +810 -0
  82. package/scripts/lib/batch-jobs.js +71 -0
  83. package/scripts/lib/brain-pack.js +578 -0
  84. package/scripts/lib/brand-boundary.js +424 -0
  85. package/scripts/lib/brand.js +74 -0
  86. package/scripts/lib/browser-capability.js +1048 -0
  87. package/scripts/lib/browser-proof-governed-workflow.js +1020 -0
  88. package/scripts/lib/browser-proof-preflight.js +321 -0
  89. package/scripts/lib/cache-readiness.js +296 -0
  90. package/scripts/lib/canonical-reentry.js +162 -0
  91. package/scripts/lib/capability-contract-validator.js +177 -0
  92. package/scripts/lib/capability-hygiene.js +504 -0
  93. package/scripts/lib/capability-intake-quarantine.js +789 -0
  94. package/scripts/lib/capability-kernel-registry.js +566 -0
  95. package/scripts/lib/capability-kernel.js +202 -0
  96. package/scripts/lib/capability-manifest.js +255 -0
  97. package/scripts/lib/capability-outcome-normalizer.js +104 -0
  98. package/scripts/lib/capability-packs.js +314 -0
  99. package/scripts/lib/capability-recommender.js +513 -0
  100. package/scripts/lib/capability-registry.js +1062 -0
  101. package/scripts/lib/carry-forward-surfacing.js +194 -0
  102. package/scripts/lib/ccusage-adapter.js +188 -0
  103. package/scripts/lib/claude-session-evidence/index.js +1027 -0
  104. package/scripts/lib/cli-output-sanitizer.js +118 -0
  105. package/scripts/lib/company-loop.js +1149 -0
  106. package/scripts/lib/config.js +641 -0
  107. package/scripts/lib/context-acquisition-plan.js +359 -0
  108. package/scripts/lib/context-authority-rules.js +138 -0
  109. package/scripts/lib/context-budget-guard.js +170 -0
  110. package/scripts/lib/context-budget-scanner.js +257 -0
  111. package/scripts/lib/context-budget.js +167 -0
  112. package/scripts/lib/context-claim-safety.js +116 -0
  113. package/scripts/lib/context-compiler.js +236 -0
  114. package/scripts/lib/context-optimizer.js +715 -0
  115. package/scripts/lib/context-packet.js +121 -0
  116. package/scripts/lib/context-receipt.js +57 -0
  117. package/scripts/lib/context-reduction-plan.js +179 -0
  118. package/scripts/lib/context-safety.js +88 -0
  119. package/scripts/lib/context-savings-engine.js +158 -0
  120. package/scripts/lib/context-source-registry.js +393 -0
  121. package/scripts/lib/context-task-profiles.js +147 -0
  122. package/scripts/lib/cost-abuse-guard.js +975 -0
  123. package/scripts/lib/cost-evidence.js +287 -0
  124. package/scripts/lib/cost-to-outcome-signals.js +639 -0
  125. package/scripts/lib/cross-host-install-plan.js +308 -0
  126. package/scripts/lib/cross-host-install-readiness.js +242 -0
  127. package/scripts/lib/cross-host-value-flow.js +268 -0
  128. package/scripts/lib/dashboard.js +1056 -0
  129. package/scripts/lib/data-permissions-guard.js +1187 -0
  130. package/scripts/lib/deployment-environment-guard.js +1236 -0
  131. package/scripts/lib/design-partner-feedback.js +346 -0
  132. package/scripts/lib/dogfood-evidence-freshness.js +567 -0
  133. package/scripts/lib/efficiency-receipt.js +354 -0
  134. package/scripts/lib/entitlements.js +100 -0
  135. package/scripts/lib/execution-packet.js +559 -0
  136. package/scripts/lib/execution-route-governor.js +179 -0
  137. package/scripts/lib/experimentation-events.js +547 -0
  138. package/scripts/lib/external-capability-compliance.js +107 -0
  139. package/scripts/lib/external-readiness/ai-visibility/ai-visibility-runner.js +322 -0
  140. package/scripts/lib/external-readiness/calibration/benchmark-site-catalog.js +121 -0
  141. package/scripts/lib/external-readiness/calibration/completion-gate.js +112 -0
  142. package/scripts/lib/external-readiness/calibration/real-site-benchmark-runner.js +284 -0
  143. package/scripts/lib/external-readiness/drift-detector.js +100 -0
  144. package/scripts/lib/external-readiness/endpoint-prober.js +332 -0
  145. package/scripts/lib/external-readiness/external-readiness-runner.js +112 -0
  146. package/scripts/lib/external-readiness/full-agent-readiness-scorer.js +220 -0
  147. package/scripts/lib/external-readiness/golden-path-runner.js +333 -0
  148. package/scripts/lib/external-readiness/inside-out-runner.js +118 -0
  149. package/scripts/lib/external-readiness/proof-receipt-writer.js +112 -0
  150. package/scripts/lib/external-readiness/safe-fix-executor.js +117 -0
  151. package/scripts/lib/external-readiness/skills/category-boundary-guard.js +30 -0
  152. package/scripts/lib/external-readiness/skills/pmm-positioning-guard.js +69 -0
  153. package/scripts/lib/external-readiness/skills/safe-fix-policy.js +35 -0
  154. package/scripts/lib/external-user-simulation.js +166 -0
  155. package/scripts/lib/failure-recovery-readiness.js +81 -0
  156. package/scripts/lib/failure-recovery.js +419 -0
  157. package/scripts/lib/feedback-intelligence.js +537 -0
  158. package/scripts/lib/feedback-signals.js +205 -0
  159. package/scripts/lib/file-integrity.js +68 -0
  160. package/scripts/lib/fsx.js +129 -0
  161. package/scripts/lib/full-readiness-gate.js +451 -0
  162. package/scripts/lib/governed-action-exposure-primitives.js +1514 -0
  163. package/scripts/lib/governed-exposure-planner.js +186 -0
  164. package/scripts/lib/governed-workspace-hygiene.js +946 -0
  165. package/scripts/lib/guard-suite-common.js +412 -0
  166. package/scripts/lib/guidance-builder.js +174 -0
  167. package/scripts/lib/hook-apply.js +1075 -0
  168. package/scripts/lib/hook-baseline.js +310 -0
  169. package/scripts/lib/hook-config-preview.js +275 -0
  170. package/scripts/lib/hook-contracts.js +290 -0
  171. package/scripts/lib/hook-safety-boundary-readiness.js +80 -0
  172. package/scripts/lib/host-capability-matrix.js +351 -0
  173. package/scripts/lib/host-support-context.js +254 -0
  174. package/scripts/lib/http-hook-action.js +538 -0
  175. package/scripts/lib/install-ai-readiness.js +84 -0
  176. package/scripts/lib/install-intake-risk.js +1051 -0
  177. package/scripts/lib/install-journey-intelligence.js +329 -0
  178. package/scripts/lib/intervention-guidance.js +57 -0
  179. package/scripts/lib/known-limitations.js +115 -0
  180. package/scripts/lib/l8-path-truth.js +146 -0
  181. package/scripts/lib/launch-hardening-gate.js +436 -0
  182. package/scripts/lib/launch-readiness.js +635 -0
  183. package/scripts/lib/learning-experimentation-foundation.js +1484 -0
  184. package/scripts/lib/learning-memory.js +686 -0
  185. package/scripts/lib/lifecycle-hooks.js +982 -0
  186. package/scripts/lib/local-package-smoke.js +436 -0
  187. package/scripts/lib/local-pricing.js +299 -0
  188. package/scripts/lib/mcp-enforcement.js +311 -0
  189. package/scripts/lib/mcp-least-privilege-policy.js +303 -0
  190. package/scripts/lib/mcp-tool-inventory.js +388 -0
  191. package/scripts/lib/mcp-tool-risk.js +0 -0
  192. package/scripts/lib/memory.js +335 -0
  193. package/scripts/lib/metrics.js +699 -0
  194. package/scripts/lib/micro-proof.js +133 -0
  195. package/scripts/lib/model-work-class-routing.js +79 -0
  196. package/scripts/lib/next-run-context.js +436 -0
  197. package/scripts/lib/next-run-continuity.js +1207 -0
  198. package/scripts/lib/observability-recovery-guard.js +1030 -0
  199. package/scripts/lib/operating-value.js +1662 -0
  200. package/scripts/lib/optimization-v3.js +122 -0
  201. package/scripts/lib/orchestration/adapters/_shared.js +49 -0
  202. package/scripts/lib/orchestration/adapters/aider.js +18 -0
  203. package/scripts/lib/orchestration/adapters/claude-code.js +35 -0
  204. package/scripts/lib/orchestration/adapters/codex.js +35 -0
  205. package/scripts/lib/orchestration/adapters/gemini-cli.js +18 -0
  206. package/scripts/lib/orchestration/adapters/git.js +25 -0
  207. package/scripts/lib/orchestration/adapters/index.js +31 -0
  208. package/scripts/lib/orchestration/adapters/lm-studio.js +18 -0
  209. package/scripts/lib/orchestration/adapters/ollama.js +18 -0
  210. package/scripts/lib/orchestration/adapters/opencode.js +18 -0
  211. package/scripts/lib/orchestration/adapters/openrouter.js +18 -0
  212. package/scripts/lib/orchestration/adapters/test-runner.js +25 -0
  213. package/scripts/lib/orchestration/cli.js +438 -0
  214. package/scripts/lib/orchestration/execution-manager.js +279 -0
  215. package/scripts/lib/orchestration/handoff.js +314 -0
  216. package/scripts/lib/orchestration/index.js +456 -0
  217. package/scripts/lib/orchestration/inventory.js +47 -0
  218. package/scripts/lib/orchestration/model-discovery.js +498 -0
  219. package/scripts/lib/orchestration/model-profiler.js +170 -0
  220. package/scripts/lib/orchestration/model-profiles.js +252 -0
  221. package/scripts/lib/orchestration/model-refresh-policy.js +72 -0
  222. package/scripts/lib/orchestration/proof-writer.js +349 -0
  223. package/scripts/lib/orchestration/provider-discovery/aider.js +49 -0
  224. package/scripts/lib/orchestration/provider-discovery/claude-code.js +56 -0
  225. package/scripts/lib/orchestration/provider-discovery/codex.js +49 -0
  226. package/scripts/lib/orchestration/provider-discovery/common.js +186 -0
  227. package/scripts/lib/orchestration/provider-discovery/gemini.js +106 -0
  228. package/scripts/lib/orchestration/provider-discovery/lm-studio.js +118 -0
  229. package/scripts/lib/orchestration/provider-discovery/models-dev.js +12 -0
  230. package/scripts/lib/orchestration/provider-discovery/ollama.js +100 -0
  231. package/scripts/lib/orchestration/provider-discovery/opencode.js +47 -0
  232. package/scripts/lib/orchestration/provider-discovery/openrouter.js +44 -0
  233. package/scripts/lib/orchestration/risk-classifier.js +130 -0
  234. package/scripts/lib/orchestration/routing-policy.js +486 -0
  235. package/scripts/lib/orchestration/settings.js +95 -0
  236. package/scripts/lib/orchestration/state.js +165 -0
  237. package/scripts/lib/orchestration/verification-manager.js +138 -0
  238. package/scripts/lib/outcome-evidence-stack.js +1083 -0
  239. package/scripts/lib/output-profiles.js +146 -0
  240. package/scripts/lib/package-content-audit.js +368 -0
  241. package/scripts/lib/package-runtime.js +278 -0
  242. package/scripts/lib/plan-surface.js +53 -0
  243. package/scripts/lib/plans.js +2327 -0
  244. package/scripts/lib/policy-provider.js +27 -0
  245. package/scripts/lib/prelaunch-activation-readiness.js +409 -0
  246. package/scripts/lib/prelaunch-evidence-store.js +816 -0
  247. package/scripts/lib/prelaunch-intelligence.js +869 -0
  248. package/scripts/lib/pricing-experiment.js +118 -0
  249. package/scripts/lib/pro-moment-events.js +77 -0
  250. package/scripts/lib/pro-moment-state.js +227 -0
  251. package/scripts/lib/pro-moments.js +1216 -0
  252. package/scripts/lib/product-home-receipt.js +1790 -0
  253. package/scripts/lib/product-learning-events.js +696 -0
  254. package/scripts/lib/production-confidence-control-tower.js +1209 -0
  255. package/scripts/lib/production-confidence.js +1858 -0
  256. package/scripts/lib/project-profile.js +555 -0
  257. package/scripts/lib/prompt-compiler-plan.js +94 -0
  258. package/scripts/lib/prompt-compiler.js +280 -0
  259. package/scripts/lib/prompt-lint.js +32 -0
  260. package/scripts/lib/prompt-suggestions.js +52 -0
  261. package/scripts/lib/proof-canonical.js +398 -0
  262. package/scripts/lib/proof-drilldown.js +383 -0
  263. package/scripts/lib/proof-e2e/promise-completion.js +141 -0
  264. package/scripts/lib/proof-e2e/promise-dashboard-claims.js +135 -0
  265. package/scripts/lib/proof-e2e/promise-local-proof.js +156 -0
  266. package/scripts/lib/proof-e2e/promise-provider-neutral.js +136 -0
  267. package/scripts/lib/proof-e2e/promise-registry.js +219 -0
  268. package/scripts/lib/proof-e2e/promise-security-trust.js +141 -0
  269. package/scripts/lib/proof-e2e/promise-skills-risk.js +163 -0
  270. package/scripts/lib/proof-e2e/promise-token-savings.js +112 -0
  271. package/scripts/lib/proof-e2e/promise-work-management.js +126 -0
  272. package/scripts/lib/proof-events.js +342 -0
  273. package/scripts/lib/proof-history.js +243 -0
  274. package/scripts/lib/proof-metrics.js +296 -0
  275. package/scripts/lib/proof-outcome-evidence.js +134 -0
  276. package/scripts/lib/proof-receipt.js +335 -0
  277. package/scripts/lib/proof-record.js +461 -0
  278. package/scripts/lib/proof-savings-report.js +1549 -0
  279. package/scripts/lib/public-activation-distribution-gate.js +266 -0
  280. package/scripts/lib/public-cli.js +5631 -0
  281. package/scripts/lib/public-distribution-truth.js +211 -0
  282. package/scripts/lib/public-distribution.js +73 -0
  283. package/scripts/lib/public-install-claim-checker.js +300 -0
  284. package/scripts/lib/publish-provenance-readiness.js +287 -0
  285. package/scripts/lib/readiness-delta.js +218 -0
  286. package/scripts/lib/readiness-evidence-closure.js +196 -0
  287. package/scripts/lib/reentry-memory-capture.js +241 -0
  288. package/scripts/lib/reentry-memory-retrieval.js +302 -0
  289. package/scripts/lib/reentry-memory-status.js +147 -0
  290. package/scripts/lib/reentry-memory-store.js +183 -0
  291. package/scripts/lib/reentry-state.js +66 -0
  292. package/scripts/lib/release-candidate-bundle.js +166 -0
  293. package/scripts/lib/remediation.js +81 -0
  294. package/scripts/lib/repo-map.js +391 -0
  295. package/scripts/lib/run-action-policy.js +104 -0
  296. package/scripts/lib/run-contract-receipt.js +48 -0
  297. package/scripts/lib/run-contract.js +288 -0
  298. package/scripts/lib/run-cost-to-verified-outcome.js +87 -0
  299. package/scripts/lib/run-improvements-lifecycle.js +330 -0
  300. package/scripts/lib/run-improvements.js +789 -0
  301. package/scripts/lib/run-proof-contract.js +116 -0
  302. package/scripts/lib/run-risk-classifier.js +131 -0
  303. package/scripts/lib/run-task-classifier.js +216 -0
  304. package/scripts/lib/runtime-decision-policy.js +387 -0
  305. package/scripts/lib/safe-path-engine.js +705 -0
  306. package/scripts/lib/safe-repair.js +877 -0
  307. package/scripts/lib/safe-run-controller.js +887 -0
  308. package/scripts/lib/scope-repair-before-approval.js +865 -0
  309. package/scripts/lib/score.js +262 -0
  310. package/scripts/lib/seamless-enforcement.js +329 -0
  311. package/scripts/lib/seamless-outcome.js +689 -0
  312. package/scripts/lib/seamless-reality-gate.js +5053 -0
  313. package/scripts/lib/security-confidence/activation-safety.js +78 -0
  314. package/scripts/lib/security-confidence/adapters/adapter-contract.js +125 -0
  315. package/scripts/lib/security-confidence/adapters/mock-claude-bughunter-adapter.js +36 -0
  316. package/scripts/lib/security-confidence/adapters/mock-decepticon-adapter.js +34 -0
  317. package/scripts/lib/security-confidence/adapters/mock-mcp-scan-adapter.js +35 -0
  318. package/scripts/lib/security-confidence/adapters/mock-snyk-agent-scan-adapter.js +35 -0
  319. package/scripts/lib/security-confidence/adapters/mock-tank-adapter.js +34 -0
  320. package/scripts/lib/security-confidence/adapters/reference-registry.js +63 -0
  321. package/scripts/lib/security-confidence/auth-rbac-plan.js +39 -0
  322. package/scripts/lib/security-confidence/component-inventory.js +151 -0
  323. package/scripts/lib/security-confidence/constants.js +191 -0
  324. package/scripts/lib/security-confidence/dependency-script-risk.js +95 -0
  325. package/scripts/lib/security-confidence/evidence-hygiene.js +127 -0
  326. package/scripts/lib/security-confidence/feature-impact-classifier.js +80 -0
  327. package/scripts/lib/security-confidence/file-utils.js +161 -0
  328. package/scripts/lib/security-confidence/finding-triage.js +90 -0
  329. package/scripts/lib/security-confidence/findings.js +115 -0
  330. package/scripts/lib/security-confidence/index.js +29 -0
  331. package/scripts/lib/security-confidence/permission-budget.js +93 -0
  332. package/scripts/lib/security-confidence/redaction.js +82 -0
  333. package/scripts/lib/security-confidence/redteam-fixtures.js +53 -0
  334. package/scripts/lib/security-confidence/reference-adoption.js +229 -0
  335. package/scripts/lib/security-confidence/reference-taxonomy.js +155 -0
  336. package/scripts/lib/security-confidence/report-quality.js +99 -0
  337. package/scripts/lib/security-confidence/report-writer.js +79 -0
  338. package/scripts/lib/security-confidence/risk-classifier.js +187 -0
  339. package/scripts/lib/security-confidence/runner.js +179 -0
  340. package/scripts/lib/security-confidence/schema.js +188 -0
  341. package/scripts/lib/security-confidence/secret-safety.js +74 -0
  342. package/scripts/lib/security-confidence/security-capability-router.js +98 -0
  343. package/scripts/lib/security-confidence/web-security-smoke-plan.js +46 -0
  344. package/scripts/lib/security-risk-classifier.js +511 -0
  345. package/scripts/lib/security-scan.js +396 -0
  346. package/scripts/lib/session-context-optimizer.js +1211 -0
  347. package/scripts/lib/session-timing.js +322 -0
  348. package/scripts/lib/skill-hygiene.js +805 -0
  349. package/scripts/lib/skill-packs.js +161 -0
  350. package/scripts/lib/skills-operating-layer-v1.js +1023 -0
  351. package/scripts/lib/skills-operating-layer.js +629 -0
  352. package/scripts/lib/smallest-safe-plan.js +214 -0
  353. package/scripts/lib/smart-routing-plan.js +115 -0
  354. package/scripts/lib/smart-work-routing.js +768 -0
  355. package/scripts/lib/source-catalog.js +1022 -0
  356. package/scripts/lib/status-value-summary.js +32 -0
  357. package/scripts/lib/supply-chain-dependency-guard.js +1333 -0
  358. package/scripts/lib/supply-chain-guard.js +219 -0
  359. package/scripts/lib/support-bundle.js +561 -0
  360. package/scripts/lib/support-redaction.js +66 -0
  361. package/scripts/lib/task-continuation.js +440 -0
  362. package/scripts/lib/test-helpers.js +15 -0
  363. package/scripts/lib/tier.js +38 -0
  364. package/scripts/lib/token-context-quality-gate.js +370 -0
  365. package/scripts/lib/token-cost-capture.js +187 -0
  366. package/scripts/lib/token-cost-evidence.js +862 -0
  367. package/scripts/lib/token-cost-intelligence.js +358 -0
  368. package/scripts/lib/token-efficiency-evidence.js +213 -0
  369. package/scripts/lib/token-efficiency-map.js +110 -0
  370. package/scripts/lib/token-evidence.js +703 -0
  371. package/scripts/lib/tokenish.js +17 -0
  372. package/scripts/lib/tool-output-sandbox.js +559 -0
  373. package/scripts/lib/trust-audit.js +136 -0
  374. package/scripts/lib/unified-events.js +396 -0
  375. package/scripts/lib/upgrade-interruption-recovery.js +407 -0
  376. package/scripts/lib/usage-ledger.js +201 -0
  377. package/scripts/lib/value-ledger.js +130 -0
  378. package/scripts/lib/value-proof-calibration.js +531 -0
  379. package/scripts/lib/visual-qa.js +231 -0
  380. package/scripts/lib/voice-alpha.js +29 -0
  381. package/scripts/lib/webhook-idempotency-guard.js +990 -0
  382. package/scripts/lib/work-aware-orchestration.js +976 -0
  383. package/scripts/lib/work-control-receipts.js +577 -0
  384. package/scripts/lib/work-ledger.js +1123 -0
  385. package/scripts/lib/work-panel-preview.js +352 -0
  386. package/scripts/lib/workflow-discipline.js +280 -0
  387. package/scripts/lib/workflow-intelligence-radar.js +804 -0
  388. package/scripts/lib/workflow-signals.js +419 -0
  389. package/scripts/lib/workspace-map.js +281 -0
  390. package/scripts/lib/workspace-registry.js +1367 -0
  391. package/scripts/lib/workspace-resolver.js +542 -0
  392. package/scripts/wuz-doctor.js +315 -0
  393. package/bin/avorelo.mjs +0 -7
  394. package/dist/avorelo.mjs +0 -24678
@@ -0,0 +1,567 @@
1
+ "use strict";
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ const { nowIso, safeReadJson, safeWriteJson } = require("./fsx");
7
+
8
+ const CONTRACT = "avorelo.dogfoodEvidenceFreshness.v1";
9
+ const REPORT_DIR_REL = ".claude/cco/reports/dogfood-evidence-freshness";
10
+ const REPORT_JSON_REL = `${REPORT_DIR_REL}/latest-report.json`;
11
+
12
+ const MAX_FINDINGS = 25;
13
+ const MAX_EVIDENCE_REFS_PER_FINDING = 3;
14
+ const MAX_ARTIFACT_SIZE = 256 * 1024; // 256KB
15
+ const STALE_DAYS = 90;
16
+
17
+ // Matches a Windows drive path (C:\ or C:/dir) but NOT a URL scheme like
18
+ // http://, https://, postgresql:// — a URL has `://` (two slashes after the
19
+ // colon) and is never an absolute LOCAL path. Excluding URL schemes removes a
20
+ // false-positive class without weakening local-path detection.
21
+ const ABSOLUTE_WINDOWS_PATH_RE = /[A-Za-z]:(?:\\|\/(?!\/))/;
22
+ const ABSOLUTE_UNIX_PATH_RE = /(?:^|\s)\/(?:Users|home|tmp|var|etc)\//;
23
+ // `sk-` requires a leading non-alphanumeric boundary so it matches real API
24
+ // keys (e.g. "sk-ant-...") but NOT the "sk-" buried inside ordinary words like
25
+ // "ri[sk-]governance" or "ta[sk-]specific". Without the boundary, hyphenated
26
+ // English phrases were flagged as secrets — a false-positive class.
27
+ const SECRET_PATTERN_RE = /(?:(?<![A-Za-z0-9])sk-[A-Za-z0-9_-]{16,}|gh[ps]_[A-Za-z0-9]{12,}|npm_[A-Za-z0-9]{12,}|AKIA[0-9A-Z]{16}|(?:api[_ -]?key|token|password|secret|authorization)\s*[:=]\s*[^\s'"]{8,})/i;
28
+ // A raw dump is a SINGLE fenced code/log block of 500+ chars. The inner match
29
+ // must not cross a ``` fence — otherwise several small command blocks separated
30
+ // by prose were spuriously joined into one phantom "dump" (a false positive
31
+ // that also flagged legitimate command-example docs).
32
+ const RAW_DUMP_RE = /```(?:json|js|javascript|typescript|ts|bash|sh|log|text)\s*\n(?:(?!```)[\s\S]){500,}?\n```/;
33
+ const PR_REF_RE = /(?:PR|pull request|pull)\s*#?(\d+)/gi;
34
+ const SHA_REF_RE = /\b[0-9a-f]{7,40}\b/g;
35
+ const PASS_COUNT_RE = /(\d+)\s*(?:test|spec|assertion|check)s?\s*(?:pass|passed|passing|green)/i;
36
+
37
+ function toPosix(value) {
38
+ return String(value || "").replace(/\\/g, "/");
39
+ }
40
+
41
+ function sanitizeText(value, max = 220) {
42
+ const text = String(value || "")
43
+ .replace(/\s+/g, " ")
44
+ .replace(/(?:(?<![A-Za-z0-9])sk-[A-Za-z0-9_-]{16,}|gh[ps]_[A-Za-z0-9]{12,}|npm_[A-Za-z0-9]{12,}|AKIA[0-9A-Z]{16})/g, "[redacted-token]")
45
+ .replace(/(bearer\s+)[A-Za-z0-9._-]{8,}/ig, "$1[redacted]")
46
+ .replace(/((?:api[_ -]?key|token|password|secret|authorization)\s*[:=]\s*)([^\s'"]+)/ig, "$1[redacted]")
47
+ .trim();
48
+ if (!text) return null;
49
+ return text.length > max ? `${text.slice(0, max - 3).trimEnd()}...` : text;
50
+ }
51
+
52
+ function sanitizeRef(ref) {
53
+ const text = toPosix(String(ref || "").trim());
54
+ if (!text || text.startsWith("..")) return null;
55
+ return text;
56
+ }
57
+
58
+ function makeEvidenceRef(relPath, label) {
59
+ const base = sanitizeRef(relPath);
60
+ if (!base) return null;
61
+ const note = label ? ` (${sanitizeText(label, 80)})` : "";
62
+ return `${base}${note}`;
63
+ }
64
+
65
+ function severityRank(severity) {
66
+ if (severity === "block") return 3;
67
+ if (severity === "warn") return 2;
68
+ if (severity === "info") return 1;
69
+ return 0;
70
+ }
71
+
72
+ function isStaleDate(isoString) {
73
+ if (!isoString) return false;
74
+ try {
75
+ const d = new Date(isoString);
76
+ if (isNaN(d.getTime())) return false;
77
+ const now = Date.now();
78
+ return (now - d.getTime()) > (STALE_DAYS * 24 * 60 * 60 * 1000);
79
+ } catch {
80
+ return false;
81
+ }
82
+ }
83
+
84
+ function hasAbsolutePath(text) {
85
+ return ABSOLUTE_WINDOWS_PATH_RE.test(text) || ABSOLUTE_UNIX_PATH_RE.test(text);
86
+ }
87
+
88
+ // ── Scan dogfood docs ───────────────────────────────────────────────────────
89
+
90
+ function scanDogfoodDocs(cwd) {
91
+ const docs = [];
92
+ const dogfoodDir = path.join(cwd, "docs", "dogfood");
93
+ if (!fs.existsSync(dogfoodDir)) return docs;
94
+
95
+ try {
96
+ for (const entry of fs.readdirSync(dogfoodDir, { withFileTypes: true })) {
97
+ if (!entry.isFile()) continue;
98
+ if (!entry.name.endsWith(".md") && !entry.name.endsWith(".json")) continue;
99
+ const absPath = path.join(dogfoodDir, entry.name);
100
+ const relPath = toPosix(`docs/dogfood/${entry.name}`);
101
+ try {
102
+ const stat = fs.statSync(absPath);
103
+ if (stat.size > MAX_ARTIFACT_SIZE) {
104
+ docs.push({ relPath, content: null, oversized: true, size: stat.size });
105
+ continue;
106
+ }
107
+ const content = fs.readFileSync(absPath, "utf8");
108
+ docs.push({ relPath, content, oversized: false, size: stat.size });
109
+ } catch {
110
+ docs.push({ relPath, content: null, oversized: false, size: 0 });
111
+ }
112
+ }
113
+ } catch {}
114
+ return docs;
115
+ }
116
+
117
+ // ── Scan artifact dirs ──────────────────────────────────────────────────────
118
+
119
+ function scanArtifacts(cwd) {
120
+ const artifacts = [];
121
+ const dirs = [
122
+ "artifacts",
123
+ ".claude/cco/reports",
124
+ ".claude/cco/state",
125
+ ".claude/cco/orchestration",
126
+ ];
127
+
128
+ let fileCount = 0;
129
+ for (const dir of dirs) {
130
+ const absDir = path.join(cwd, dir);
131
+ if (!fs.existsSync(absDir)) continue;
132
+ walkJsonFiles(absDir, cwd, artifacts, fileCount, 4);
133
+ fileCount = artifacts.length;
134
+ }
135
+ return artifacts;
136
+ }
137
+
138
+ function walkJsonFiles(dirPath, cwd, artifacts, currentCount, maxDepth) {
139
+ if (maxDepth <= 0 || currentCount >= 200) return;
140
+ try {
141
+ for (const entry of fs.readdirSync(dirPath, { withFileTypes: true })) {
142
+ if (artifacts.length >= 200) return;
143
+ const absPath = path.join(dirPath, entry.name);
144
+ if (entry.isDirectory()) {
145
+ if (entry.name === "node_modules" || entry.name === ".git") continue;
146
+ walkJsonFiles(absPath, cwd, artifacts, artifacts.length, maxDepth - 1);
147
+ continue;
148
+ }
149
+ if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
150
+ const relPath = toPosix(path.relative(cwd, absPath));
151
+ try {
152
+ const stat = fs.statSync(absPath);
153
+ if (stat.size > MAX_ARTIFACT_SIZE) {
154
+ artifacts.push({ relPath, data: null, oversized: true });
155
+ continue;
156
+ }
157
+ const raw = fs.readFileSync(absPath, "utf8").replace(/^/, "");
158
+ const data = JSON.parse(raw);
159
+ artifacts.push({ relPath, data, oversized: false });
160
+ } catch {
161
+ artifacts.push({ relPath, data: null, oversized: false });
162
+ }
163
+ }
164
+ } catch {}
165
+ }
166
+
167
+ // ── Load capability manifest for coverage check ─────────────────────────────
168
+
169
+ function loadCapabilityManifest(cwd) {
170
+ try {
171
+ const reg = require("./capability-registry");
172
+ if (typeof reg.listCapabilities === "function") return reg.listCapabilities();
173
+ return [];
174
+ } catch {
175
+ return [];
176
+ }
177
+ }
178
+
179
+ // ── Core analysis ───────────────────────────────────────────────────────────
180
+
181
+ function buildDogfoodFreshnessReport(cwd = process.cwd(), options = {}) {
182
+ const limitsApplied = [];
183
+ const findings = [];
184
+ const seenCodes = new Map();
185
+
186
+ function addFinding(severity, reasonCode, title, safeNextAction, evidenceRefs) {
187
+ if (findings.length >= MAX_FINDINGS) {
188
+ if (!limitsApplied.includes("MAX_FINDINGS_REACHED")) limitsApplied.push("MAX_FINDINGS_REACHED");
189
+ return;
190
+ }
191
+ const key = `${reasonCode}:${(evidenceRefs || [])[0] || ""}`;
192
+ if (seenCodes.has(key)) return;
193
+ seenCodes.set(key, true);
194
+ findings.push({
195
+ severity,
196
+ reasonCode,
197
+ title: sanitizeText(title, 220),
198
+ safeNextAction: sanitizeText(safeNextAction, 220),
199
+ evidenceRefs: (evidenceRefs || []).slice(0, MAX_EVIDENCE_REFS_PER_FINDING).filter(Boolean),
200
+ });
201
+ }
202
+
203
+ const docs = scanDogfoodDocs(cwd);
204
+ const artifacts = scanArtifacts(cwd);
205
+ const capabilities = loadCapabilityManifest(cwd);
206
+
207
+ if (docs.length === 0 && artifacts.length === 0) {
208
+ const emptyReport = buildEmptyReport(limitsApplied);
209
+ if (options.write !== false) {
210
+ safeWriteJson(cwd, REPORT_JSON_REL, emptyReport);
211
+ }
212
+ return emptyReport;
213
+ }
214
+
215
+ let staleRefCount = 0;
216
+ let missingEvidenceCount = 0;
217
+ let unsafeEvidenceCount = 0;
218
+
219
+ // ── Check each dogfood doc ──
220
+ for (const doc of docs) {
221
+ addFinding("info", "DOGFOOD_DOC_FOUND", `Dogfood doc found: ${doc.relPath}`, "No action needed.", [makeEvidenceRef(doc.relPath, "dogfood doc")]);
222
+
223
+ if (!doc.content) continue;
224
+
225
+ // Check for absolute paths
226
+ if (hasAbsolutePath(doc.content)) {
227
+ addFinding("block", "DOGFOOD_ABSOLUTE_PATH_FOUND", `Absolute local path found in ${doc.relPath}`, "Replace absolute paths with repo-relative paths.", [makeEvidenceRef(doc.relPath, "absolute path")]);
228
+ unsafeEvidenceCount++;
229
+ }
230
+
231
+ // Check for raw dumps
232
+ if (RAW_DUMP_RE.test(doc.content)) {
233
+ addFinding("block", "DOGFOOD_RAW_DUMP_FOUND", `Large raw code/log dump found in ${doc.relPath}`, "Replace raw dumps with concise evidence summaries.", [makeEvidenceRef(doc.relPath, "raw dump")]);
234
+ unsafeEvidenceCount++;
235
+ }
236
+
237
+ // Check for secret patterns
238
+ if (SECRET_PATTERN_RE.test(doc.content)) {
239
+ addFinding("block", "DOGFOOD_SECRET_PATTERN_FOUND", `Secret-like pattern found in ${doc.relPath}`, "Remove or redact secret values.", [makeEvidenceRef(doc.relPath, "secret pattern")]);
240
+ unsafeEvidenceCount++;
241
+ }
242
+
243
+ // Check for stale PR refs
244
+ const prRefs = doc.content.matchAll(PR_REF_RE);
245
+ for (const match of prRefs) {
246
+ const prNum = parseInt(match[1], 10);
247
+ if (prNum < 100) {
248
+ addFinding("warn", "DOGFOOD_STALE_PR_REF", `Possibly stale PR #${prNum} reference in ${doc.relPath}`, "Verify PR reference is still relevant.", [makeEvidenceRef(doc.relPath, `PR #${prNum}`)]);
249
+ staleRefCount++;
250
+ }
251
+ }
252
+
253
+ // Check for pass counts without test refs
254
+ const passMatch = doc.content.match(PASS_COUNT_RE);
255
+ if (passMatch) {
256
+ addFinding("info", "DOGFOOD_PASS_COUNT_FOUND", `Pass count found in ${doc.relPath}: ${passMatch[0]}`, "Verify pass count is backed by actual test evidence.", [makeEvidenceRef(doc.relPath, "pass count")]);
257
+
258
+ // Check if there's a test file reference nearby
259
+ const hasTestRef = /(?:tests?\/|\.test\.|\.spec\.|test-runner|vitest|jest|mocha)/i.test(doc.content);
260
+ if (!hasTestRef) {
261
+ addFinding("warn", "DOGFOOD_PASS_COUNT_UNSUPPORTED", `Pass count in ${doc.relPath} has no visible test file reference`, "Add references to actual test files that produce this count.", [makeEvidenceRef(doc.relPath, "unsupported pass count")]);
262
+ missingEvidenceCount++;
263
+ }
264
+ }
265
+
266
+ // Check module refs exist
267
+ const moduleRefs = doc.content.match(/(?:scripts\/lib\/[a-z0-9-]+\.js|scripts\/[a-z0-9-]+\.js)/gi) || [];
268
+ for (const ref of [...new Set(moduleRefs)].slice(0, 10)) {
269
+ if (fs.existsSync(path.join(cwd, ref))) {
270
+ addFinding("info", "DOGFOOD_MODULE_REF_FOUND", `Module reference '${ref}' exists`, "No action needed.", [makeEvidenceRef(ref, "module")]);
271
+ } else {
272
+ addFinding("warn", "DOGFOOD_MISSING_ARTIFACT", `Referenced module '${ref}' not found in ${doc.relPath}`, "Update or remove the stale module reference.", [makeEvidenceRef(doc.relPath, `missing: ${ref}`)]);
273
+ missingEvidenceCount++;
274
+ }
275
+ }
276
+
277
+ // Check test file refs exist
278
+ const testRefs = doc.content.match(/(?:tests\/[a-z0-9-]+\.test\.js)/gi) || [];
279
+ for (const ref of [...new Set(testRefs)].slice(0, 10)) {
280
+ if (fs.existsSync(path.join(cwd, ref))) {
281
+ addFinding("info", "DOGFOOD_TEST_REF_FOUND", `Test reference '${ref}' exists`, "No action needed.", [makeEvidenceRef(ref, "test")]);
282
+ } else {
283
+ addFinding("warn", "DOGFOOD_MISSING_ARTIFACT", `Referenced test '${ref}' not found in ${doc.relPath}`, "Update or remove the stale test reference.", [makeEvidenceRef(doc.relPath, `missing: ${ref}`)]);
284
+ missingEvidenceCount++;
285
+ }
286
+ }
287
+
288
+ // Check release doc refs
289
+ const releaseRefs = doc.content.match(/(?:docs\/releases\/[a-z0-9-]+\.md)/gi) || [];
290
+ for (const ref of [...new Set(releaseRefs)].slice(0, 5)) {
291
+ if (fs.existsSync(path.join(cwd, ref))) {
292
+ addFinding("info", "DOGFOOD_RELEASE_REF_FOUND", `Release doc '${ref}' exists`, "No action needed.", [makeEvidenceRef(ref, "release doc")]);
293
+ } else {
294
+ addFinding("warn", "DOGFOOD_MISSING_ARTIFACT", `Referenced release doc '${ref}' not found in ${doc.relPath}`, "Update or remove the stale release reference.", [makeEvidenceRef(doc.relPath, `missing: ${ref}`)]);
295
+ missingEvidenceCount++;
296
+ }
297
+ }
298
+ }
299
+
300
+ // ── Check artifacts for freshness ──
301
+ for (const artifact of artifacts) {
302
+ if (!artifact.data) continue;
303
+
304
+ addFinding("info", "DOGFOOD_ARTIFACT_FOUND", `Artifact found: ${artifact.relPath}`, "No action needed.", [makeEvidenceRef(artifact.relPath, "artifact")]);
305
+
306
+ // Schema check
307
+ if (!artifact.data.schemaVersion) {
308
+ addFinding("warn", "DOGFOOD_MISSING_SCHEMA", `Artifact ${artifact.relPath} has no schemaVersion`, "Add schemaVersion to the artifact.", [makeEvidenceRef(artifact.relPath, "missing schema")]);
309
+ }
310
+
311
+ // Stale generatedAt
312
+ if (artifact.data.generatedAt && isStaleDate(artifact.data.generatedAt)) {
313
+ addFinding("warn", "DOGFOOD_STALE_ARTIFACT", `Artifact ${artifact.relPath} generatedAt is older than ${STALE_DAYS} days`, "Re-generate the artifact to refresh evidence.", [makeEvidenceRef(artifact.relPath, "stale")]);
314
+ staleRefCount++;
315
+ }
316
+ }
317
+
318
+ // ── Coverage mismatch ──
319
+ if (capabilities.length > 0 && docs.length > 0) {
320
+ const docNames = new Set(docs.map(d => d.relPath.toLowerCase()));
321
+ let coveredCount = 0;
322
+ for (const cap of capabilities) {
323
+ const capId = String(cap.id || cap.name || "").toLowerCase().replace(/_/g, "-");
324
+ const found = [...docNames].some(d => d.includes(capId));
325
+ if (found) coveredCount++;
326
+ }
327
+ const coverageRatio = capabilities.length > 0 ? coveredCount / capabilities.length : 1;
328
+ if (coverageRatio < 0.3) {
329
+ addFinding("warn", "DOGFOOD_COVERAGE_MISMATCH", `Dogfood coverage is low: ${coveredCount}/${capabilities.length} capabilities have matching dogfood docs`, "Add dogfood docs for uncovered capabilities.", []);
330
+ missingEvidenceCount++;
331
+ }
332
+ }
333
+
334
+ // ── Determine overall status ──
335
+ const hasBlock = findings.some(f => f.severity === "block");
336
+ const hasWarn = findings.some(f => f.severity === "warn");
337
+ const status = hasBlock ? "blocked" : hasWarn ? "warn" : "pass";
338
+
339
+ const warnCount = findings.filter(f => f.severity === "warn").length;
340
+ const blockCount = findings.filter(f => f.severity === "block").length;
341
+ const infoCount = findings.filter(f => f.severity === "info").length;
342
+
343
+ const safeNextAction = hasBlock
344
+ ? "Remove raw secrets, absolute paths, or code dumps from dogfood evidence before sharing."
345
+ : hasWarn
346
+ ? "Update stale references and add missing evidence links in dogfood docs."
347
+ : "Dogfood evidence is fresh and connected. Safe to proceed.";
348
+
349
+ const report = {
350
+ schemaVersion: CONTRACT,
351
+ generatedAt: nowIso(),
352
+ status,
353
+ redacted: true,
354
+ summary: {
355
+ title: "Dogfood Evidence Freshness Guard",
356
+ text: `${docs.length} docs inspected, ${artifacts.length} artifacts inspected. ${staleRefCount} stale, ${missingEvidenceCount} missing, ${unsafeEvidenceCount} unsafe.`,
357
+ findingCounts: { info: infoCount, warn: warnCount, block: blockCount },
358
+ safeNextAction,
359
+ },
360
+ surfaceEvidence: {
361
+ filesInspected: docs.length + artifacts.length,
362
+ artifactsInspected: artifacts.length,
363
+ capabilitiesInspected: capabilities.length,
364
+ limitsApplied,
365
+ },
366
+ freshnessCounts: {
367
+ docsInspected: docs.length,
368
+ artifactsInspected: artifacts.length,
369
+ staleRefCount,
370
+ missingEvidenceCount,
371
+ unsafeEvidenceCount,
372
+ },
373
+ findings: findings.sort((a, b) => severityRank(b.severity) - severityRank(a.severity)),
374
+ productHome: {
375
+ cardSource: "dogfood-evidence-freshness",
376
+ status,
377
+ found: findings.filter(f => f.severity === "warn" || f.severity === "block").map(f => sanitizeText(f.title, 120)).slice(0, 5),
378
+ fixedOrPrepared: [],
379
+ savedOrProved: staleRefCount === 0 && missingEvidenceCount === 0 ? ["Dogfood evidence is fresh and connected"] : [],
380
+ forReview: findings.filter(f => f.severity === "block").map(f => sanitizeText(f.title, 120)).slice(0, 3),
381
+ safeNextAction,
382
+ },
383
+ valueProof: {
384
+ implemented: true,
385
+ dogfooded: false,
386
+ measured: false,
387
+ measurementType: "heuristic",
388
+ publicClaimAllowed: false,
389
+ evidenceRefs: [makeEvidenceRef(REPORT_JSON_REL, "freshness report")].filter(Boolean),
390
+ caveat: "Freshness checks are heuristic-based. No test suite execution or live validation performed.",
391
+ },
392
+ limits: {
393
+ localFirst: true,
394
+ deterministicFirst: true,
395
+ modelCalls: false,
396
+ networkCalls: false,
397
+ providerCalls: false,
398
+ registryCalls: false,
399
+ rawDump: false,
400
+ autoFix: false,
401
+ },
402
+ };
403
+
404
+ if (options.write !== false) {
405
+ safeWriteJson(cwd, REPORT_JSON_REL, report);
406
+ }
407
+
408
+ return report;
409
+ }
410
+
411
+ function buildEmptyReport(limitsApplied = []) {
412
+ return {
413
+ schemaVersion: CONTRACT,
414
+ generatedAt: nowIso(),
415
+ status: "no_data",
416
+ redacted: true,
417
+ summary: {
418
+ title: "Dogfood Evidence Freshness Guard",
419
+ text: "No dogfood evidence found.",
420
+ findingCounts: { info: 0, warn: 0, block: 0 },
421
+ safeNextAction: "No dogfood evidence available. Create dogfood docs in docs/dogfood/.",
422
+ },
423
+ surfaceEvidence: {
424
+ filesInspected: 0,
425
+ artifactsInspected: 0,
426
+ capabilitiesInspected: 0,
427
+ limitsApplied,
428
+ },
429
+ freshnessCounts: {
430
+ docsInspected: 0,
431
+ artifactsInspected: 0,
432
+ staleRefCount: 0,
433
+ missingEvidenceCount: 0,
434
+ unsafeEvidenceCount: 0,
435
+ },
436
+ findings: [],
437
+ productHome: {
438
+ cardSource: "dogfood-evidence-freshness",
439
+ status: "no_data",
440
+ found: [],
441
+ fixedOrPrepared: [],
442
+ savedOrProved: [],
443
+ forReview: [],
444
+ safeNextAction: "No dogfood evidence available.",
445
+ },
446
+ valueProof: {
447
+ implemented: true,
448
+ dogfooded: false,
449
+ measured: false,
450
+ measurementType: "unavailable",
451
+ publicClaimAllowed: false,
452
+ evidenceRefs: [],
453
+ caveat: "No data to measure against.",
454
+ },
455
+ limits: {
456
+ localFirst: true,
457
+ deterministicFirst: true,
458
+ modelCalls: false,
459
+ networkCalls: false,
460
+ providerCalls: false,
461
+ registryCalls: false,
462
+ rawDump: false,
463
+ autoFix: false,
464
+ },
465
+ };
466
+ }
467
+
468
+ // ── Generate / Load / Format / Surface ──────────────────────────────────────
469
+
470
+ function generateDogfoodFreshness(cwd = process.cwd(), options = {}) {
471
+ const report = buildDogfoodFreshnessReport(cwd, options);
472
+ return { report, reportPath: path.join(cwd, REPORT_JSON_REL) };
473
+ }
474
+
475
+ function loadDogfoodFreshness(cwd = process.cwd()) {
476
+ return safeReadJson(cwd, REPORT_JSON_REL, null);
477
+ }
478
+
479
+ function formatDogfoodFreshnessText(report) {
480
+ if (!report || report.schemaVersion !== CONTRACT) {
481
+ return [
482
+ "Avorelo Dogfood Evidence Freshness Guard",
483
+ "Status: NO DATA",
484
+ "No dogfood evidence found yet.",
485
+ "Safe next action: Create dogfood docs in docs/dogfood/.",
486
+ ].join("\n");
487
+ }
488
+
489
+ const fc = report.freshnessCounts || {};
490
+ const lines = [
491
+ "Avorelo Dogfood Evidence Freshness Guard",
492
+ `Status: ${String(report.status || "no_data").toUpperCase()} · redacted=${report.redacted === true ? "yes" : "no"}`,
493
+ `Docs: ${fc.docsInspected || 0} · artifacts: ${fc.artifactsInspected || 0} · stale=${fc.staleRefCount || 0} · missing=${fc.missingEvidenceCount || 0} · unsafe=${fc.unsafeEvidenceCount || 0}`,
494
+ "Notes: local static scan only · no test execution · no doc mutation",
495
+ ];
496
+
497
+ if (Array.isArray(report.findings) && report.findings.length > 0) {
498
+ lines.push("");
499
+ lines.push("Findings:");
500
+ for (const finding of report.findings.slice(0, 5)) {
501
+ lines.push(`- [${finding.severity}] ${finding.title}${finding.evidenceRefs?.length ? ` · ${finding.evidenceRefs[0]}` : ""}`);
502
+ }
503
+ if (report.findings.length > 5) {
504
+ lines.push(` ... and ${report.findings.length - 5} more`);
505
+ }
506
+ }
507
+
508
+ lines.push("");
509
+ lines.push(`Safe next action: ${report.summary?.safeNextAction || "Review dogfood evidence freshness."}`);
510
+ return lines.join("\n");
511
+ }
512
+
513
+ function formatDogfoodFreshnessStatusLine(report) {
514
+ if (!report || report.schemaVersion !== CONTRACT) {
515
+ return "Dogfood freshness: NOT RUN · run `avorelo dogfood-freshness --text`";
516
+ }
517
+ const fc = report.freshnessCounts || {};
518
+ return `Dogfood freshness: ${String(report.status || "no_data").toUpperCase()}`
519
+ + ` · docs=${fc.docsInspected || 0}`
520
+ + ` · stale=${fc.staleRefCount || 0}`
521
+ + ` · missing=${fc.missingEvidenceCount || 0}`
522
+ + ` · next: ${sanitizeText(report.summary?.safeNextAction, 140) || "Review dogfood evidence."}`;
523
+ }
524
+
525
+ function buildDogfoodFreshnessSurface(cwd = process.cwd(), options = {}) {
526
+ const report = loadDogfoodFreshness(cwd) || (options.buildIfMissing ? buildDogfoodFreshnessReport(cwd, { write: false }) : null);
527
+ if (!report) {
528
+ return {
529
+ status: "not_run",
530
+ docsInspected: 0,
531
+ staleRefCount: 0,
532
+ missingEvidenceCount: 0,
533
+ nextBestAction: "Run `avorelo dogfood-freshness --text` to check evidence freshness.",
534
+ statusLine: "Dogfood freshness: NOT RUN · run `avorelo dogfood-freshness --text`",
535
+ showInStatus: true,
536
+ showInDashboard: true,
537
+ evidenceRef: null,
538
+ limitations: ["Local heuristic analysis only. No test execution."],
539
+ };
540
+ }
541
+
542
+ const fc = report.freshnessCounts || {};
543
+ return {
544
+ status: report.status,
545
+ docsInspected: fc.docsInspected || 0,
546
+ staleRefCount: fc.staleRefCount || 0,
547
+ missingEvidenceCount: fc.missingEvidenceCount || 0,
548
+ unsafeEvidenceCount: fc.unsafeEvidenceCount || 0,
549
+ nextBestAction: report.summary?.safeNextAction,
550
+ statusLine: formatDogfoodFreshnessStatusLine(report),
551
+ showInStatus: true,
552
+ showInDashboard: true,
553
+ evidenceRef: REPORT_JSON_REL,
554
+ limitations: ["Local heuristic analysis only. No test execution."],
555
+ };
556
+ }
557
+
558
+ module.exports = {
559
+ CONTRACT,
560
+ REPORT_JSON_REL,
561
+ buildDogfoodFreshnessReport,
562
+ generateDogfoodFreshness,
563
+ loadDogfoodFreshness,
564
+ formatDogfoodFreshnessText,
565
+ formatDogfoodFreshnessStatusLine,
566
+ buildDogfoodFreshnessSurface,
567
+ };