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,359 @@
1
+ "use strict";
2
+
3
+ // ── Context Acquisition Plan ──────────────────────────────────────────────────
4
+ //
5
+ // Determines what context to acquire for a task — without loading it all.
6
+ // Selects the minimal sufficient context strategy, budget, and fallback.
7
+ //
8
+ // Contract: avorelo.contextAcquisitionPlan.v1
9
+ //
10
+ // Strategy order:
11
+ // 1. project profile / activation facts
12
+ // 2. repo map / symbol map
13
+ // 3. selected package scope
14
+ // 4. git diff summary (if relevant)
15
+ // 5. file slices
16
+ // 6. full file (only if necessary and within budget)
17
+ // 7. fallback + warn if confidence low
18
+ //
19
+ // Non-goals: loading full repo, selecting secrets/sensitive files,
20
+ // automatic full-file fallback without reason.
21
+
22
+ const fs = require("node:fs");
23
+ const path = require("node:path");
24
+ const { nowIso } = require("./fsx");
25
+ const { appendProductLearningEvent } = require("./product-learning-events");
26
+
27
+ const CONTRACT = "avorelo.contextAcquisitionPlan.v1";
28
+ const SCHEMA_VERSION = 1;
29
+
30
+ const PLAN_DIR_REL = ".claude/cco/orchestration/context-acquisition";
31
+ const LATEST_PLAN_REL = `${PLAN_DIR_REL}/latest-plan.json`;
32
+
33
+ const DEFAULT_CONTEXT_BUDGET_TOKENS = 8000;
34
+ const MAX_CONTEXT_BUDGET_TOKENS = 16384;
35
+
36
+ // ── Task classification ───────────────────────────────────────────────────────
37
+
38
+ const TASK_PATTERNS = {
39
+ docs: /\b(docs?|documentation|readme|changelog|guide|tutorial|write up|update docs?)\b/i,
40
+ test: /\b(test|spec|jest|vitest|mocha|pytest|unit test|integration test)\b/i,
41
+ // security checked before bugfix so "fix auth vulnerability" classifies as security
42
+ security: /\b(auth(?:entication|orization)?|security|secret|password|rbac|csrf|xss|sql injection|vulnerability|privilege|injection)\b/i,
43
+ bugfix: /\b(fix|bug|broken|regression|error|crash|fail|patch)\b/i,
44
+ refactor: /\b(refactor|cleanup|clean up|restructure|rename|reorganize|simplify)\b/i,
45
+ feature: /\b(add|implement|build|create|new feature|support)\b/i,
46
+ explore: /\b(understand|explore|survey|overview|what does|explain|analyze)\b/i,
47
+ };
48
+
49
+ function classifyTask(taskText) {
50
+ if (!taskText) return "unknown";
51
+ for (const [kind, re] of Object.entries(TASK_PATTERNS)) {
52
+ if (re.test(taskText)) return kind;
53
+ }
54
+ return "unknown";
55
+ }
56
+
57
+ // ── Strategy selection ────────────────────────────────────────────────────────
58
+
59
+ function selectContextStrategy(cwd, taskText, repoMap, executionPacket, options = {}) {
60
+ const taskKind = classifyTask(taskText);
61
+ const budget = options.contextBudget || DEFAULT_CONTEXT_BUDGET_TOKENS;
62
+
63
+ const strategy = {
64
+ taskKind,
65
+ useProjectProfile: true,
66
+ useRepoMap: true,
67
+ usePackageScope: false,
68
+ useGitDiff: false,
69
+ useFileSlices: false,
70
+ useFullFiles: false,
71
+ requiresApproval: false,
72
+ conservative: false,
73
+ confidence: "medium",
74
+ qualityRisks: [],
75
+ nextAction: null,
76
+ };
77
+
78
+ // Docs task: profile + repo map only, no source
79
+ if (taskKind === "docs") {
80
+ strategy.useFileSlices = false;
81
+ strategy.useFullFiles = false;
82
+ strategy.confidence = "high";
83
+ strategy.nextAction = "Load project profile and repo map; read only doc files.";
84
+ return strategy;
85
+ }
86
+
87
+ // Security task: caution + approval
88
+ if (taskKind === "security") {
89
+ strategy.requiresApproval = true;
90
+ strategy.useFileSlices = true;
91
+ strategy.qualityRisks.push("security_sensitive: do not compress security-critical config");
92
+ strategy.confidence = "low";
93
+ strategy.nextAction = "Review selected files carefully. Approval required before proceeding.";
94
+ return strategy;
95
+ }
96
+
97
+ // Explore task: repo map first, no full dump
98
+ if (taskKind === "explore") {
99
+ strategy.useRepoMap = true;
100
+ strategy.useFileSlices = false;
101
+ strategy.useFullFiles = false;
102
+ strategy.confidence = "medium";
103
+ strategy.nextAction = "Use repo map for overview. Load slices only if specific question requires it.";
104
+ return strategy;
105
+ }
106
+
107
+ // Bug fix: repo map + slices + git diff
108
+ if (taskKind === "bugfix") {
109
+ strategy.useGitDiff = true;
110
+ strategy.useFileSlices = true;
111
+ strategy.confidence = "medium";
112
+ strategy.nextAction = "Load git diff first. Select likely relevant file slices.";
113
+ return strategy;
114
+ }
115
+
116
+ // Test / refactor / feature: slices with optional full file fallback
117
+ if (["test", "refactor", "feature"].includes(taskKind)) {
118
+ strategy.useFileSlices = true;
119
+ strategy.useFullFiles = false; // only if slice insufficient
120
+ strategy.confidence = "medium";
121
+ strategy.nextAction = "Select relevant file slices via repo map symbols.";
122
+ return strategy;
123
+ }
124
+
125
+ // Unknown: conservative
126
+ strategy.conservative = true;
127
+ strategy.useFileSlices = false;
128
+ strategy.confidence = "low";
129
+ strategy.qualityRisks.push("task_unclear: conservative context to avoid quality regression");
130
+ strategy.nextAction = "Task unclear. Use repo map only. Escalate if more context needed.";
131
+ return strategy;
132
+ }
133
+
134
+ // ── Tool/MCP tax — no-connect governor ────────────────────────────────────────
135
+ //
136
+ // Before loading an external tool/MCP, decide deterministically whether local
137
+ // evidence already suffices. Avoids the "tool tax" (loading connectors just in
138
+ // case). Advisory only (claimType heuristic) — records the decision, never hard
139
+ // blocks. Local read tools are always allowed.
140
+
141
+ const LOCAL_EVIDENCE_TOOLS = new Set(["Read", "Grep", "Glob", "LS", "NotebookRead"]);
142
+ const EXTERNAL_TOOL_RE = /^(mcp__|WebFetch|WebSearch|browser|Computer|Fetch)/i;
143
+ // Task kinds where local repo evidence is typically sufficient (no external connect).
144
+ const LOCAL_SUFFICIENT_KINDS = new Set(["docs", "explore", "refactor", "test", "bugfix"]);
145
+
146
+ function hasLocalRepoEvidence(cwd) {
147
+ try {
148
+ const mapPath = path.join(cwd, ".claude/cco/orchestration/repo-map/latest-map.json");
149
+ if (fs.existsSync(mapPath)) return true;
150
+ } catch {}
151
+ try {
152
+ // Any source files present is weak local evidence.
153
+ return fs.existsSync(path.join(cwd, "package.json")) || fs.existsSync(path.join(cwd, "scripts"));
154
+ } catch {}
155
+ return false;
156
+ }
157
+
158
+ function buildToolTaxDecision(cwd, input = {}, options = {}) {
159
+ const { toolName = "", taskText = "" } = input;
160
+ const taskKind = classifyTask(taskText);
161
+ const localEvidence =
162
+ typeof input.localEvidenceSufficient === "boolean"
163
+ ? input.localEvidenceSufficient
164
+ : hasLocalRepoEvidence(cwd);
165
+
166
+ // Local read tools never incur tool tax.
167
+ if (LOCAL_EVIDENCE_TOOLS.has(toolName)) {
168
+ return { contract: CONTRACT, toolName, taskKind, decision: "local_tool", reasonCode: "local_tool_no_tax", connect: true, claimType: "heuristic", nextAction: null, redacted: true };
169
+ }
170
+
171
+ const isExternal = EXTERNAL_TOOL_RE.test(toolName);
172
+ if (!isExternal) {
173
+ // Unknown/internal tool — allow, no tax claim.
174
+ return { contract: CONTRACT, toolName, taskKind, decision: "tool_load_required", reasonCode: "non_external_tool", connect: true, claimType: "heuristic", nextAction: null, redacted: true };
175
+ }
176
+
177
+ // External/MCP tool: avoid the connect when local evidence already covers the task.
178
+ if (localEvidence && LOCAL_SUFFICIENT_KINDS.has(taskKind)) {
179
+ return {
180
+ contract: CONTRACT,
181
+ toolName,
182
+ taskKind,
183
+ decision: "no_connect",
184
+ reasonCode: "tool_load_avoided",
185
+ connect: false,
186
+ claimType: "heuristic",
187
+ nextAction: `Local repo evidence is sufficient for a ${taskKind} task; skip loading ${toolName}.`,
188
+ redacted: true,
189
+ };
190
+ }
191
+
192
+ return {
193
+ contract: CONTRACT,
194
+ toolName,
195
+ taskKind,
196
+ decision: "tool_load_required",
197
+ reasonCode: localEvidence ? "task_needs_external_evidence" : "no_local_evidence",
198
+ connect: true,
199
+ claimType: "heuristic",
200
+ nextAction: `External evidence needed for ${taskKind || "this"} task; ${toolName} load is justified.`,
201
+ redacted: true,
202
+ };
203
+ }
204
+
205
+ // ── Plan builder ──────────────────────────────────────────────────────────────
206
+
207
+ function buildContextAcquisitionPlan(cwd, taskText, options = {}) {
208
+ const budget = options.contextBudget || DEFAULT_CONTEXT_BUDGET_TOKENS;
209
+
210
+ // Try to read repo map
211
+ let repoMap = null;
212
+ try {
213
+ const mapPath = path.join(cwd, ".claude/cco/orchestration/repo-map/latest-map.json");
214
+ if (fs.existsSync(mapPath)) {
215
+ repoMap = JSON.parse(fs.readFileSync(mapPath, "utf8"));
216
+ }
217
+ } catch {}
218
+
219
+ // Try to read execution packet
220
+ let executionPacket = null;
221
+ try {
222
+ const packetPath = path.join(cwd, ".claude/cco/orchestration/execution-packet/latest-packet.json");
223
+ if (fs.existsSync(packetPath)) {
224
+ executionPacket = JSON.parse(fs.readFileSync(packetPath, "utf8"));
225
+ }
226
+ } catch {}
227
+
228
+ const strategy = selectContextStrategy(cwd, taskText, repoMap, executionPacket, options);
229
+ const taskKind = strategy.taskKind;
230
+
231
+ // Select relevant files via repo map
232
+ let selectedFiles = [];
233
+ let selectedSymbols = [];
234
+ let fullFileFallbacks = [];
235
+
236
+ if (repoMap && strategy.useFileSlices) {
237
+ try {
238
+ const { selectLikelyRelevantFiles } = require("./repo-map");
239
+ const relevant = selectLikelyRelevantFiles(cwd, taskText, repoMap, options);
240
+ selectedFiles = relevant.slice(0, 10).map((f) => ({ path: f.path, reason: "relevance_score", estimatedTokens: f.estimatedTokens }));
241
+ selectedSymbols = relevant.flatMap((f) => (f.symbols || []).slice(0, 3)).slice(0, 20);
242
+ } catch {}
243
+ }
244
+
245
+ // Slices are symbolic; actual slicing happens in execution
246
+ const slices = strategy.useFileSlices ? selectedFiles.map((f) => ({ path: f.path, type: "slice" })) : [];
247
+
248
+ // Full file fallbacks: only listed if necessary
249
+ if (strategy.useFullFiles) {
250
+ for (const f of selectedFiles.slice(0, 3)) {
251
+ if (f.estimatedTokens && f.estimatedTokens < 2000) {
252
+ fullFileFallbacks.push({ path: f.path, reason: "small_file_full_read_safe" });
253
+ }
254
+ }
255
+ }
256
+
257
+ const contextBudget = {
258
+ targetTokens: budget,
259
+ maxTokens: MAX_CONTEXT_BUDGET_TOKENS,
260
+ estimatedSelected: selectedFiles.reduce((s, f) => s + (f.estimatedTokens || 0), 0),
261
+ withinBudget: selectedFiles.reduce((s, f) => s + (f.estimatedTokens || 0), 0) < budget,
262
+ };
263
+
264
+ const excluded = [];
265
+ if (taskKind === "docs") excluded.push({ reason: "docs_task_no_source_context_needed" });
266
+ if (strategy.conservative) excluded.push({ reason: "unknown_task_conservative" });
267
+ if (repoMap && repoMap.sensitiveExcluded > 0) excluded.push({ reason: "sensitive_files_excluded", count: repoMap.sensitiveExcluded });
268
+
269
+ return {
270
+ contract: CONTRACT,
271
+ schemaVersion: SCHEMA_VERSION,
272
+ createdAt: nowIso(),
273
+ taskSummary: taskText ? taskText.slice(0, 200) : null,
274
+ taskKind,
275
+ strategy: {
276
+ useProjectProfile: strategy.useProjectProfile,
277
+ useRepoMap: strategy.useRepoMap,
278
+ useGitDiff: strategy.useGitDiff,
279
+ useFileSlices: strategy.useFileSlices,
280
+ useFullFiles: strategy.useFullFiles,
281
+ requiresApproval: strategy.requiresApproval,
282
+ conservative: strategy.conservative,
283
+ },
284
+ selectedFiles,
285
+ selectedSymbols,
286
+ slices,
287
+ excluded,
288
+ fullFileFallbacks,
289
+ contextBudget,
290
+ confidence: strategy.confidence,
291
+ qualityRisks: strategy.qualityRisks,
292
+ nextAction: strategy.nextAction,
293
+ redacted: true,
294
+ };
295
+ }
296
+
297
+ function writeContextAcquisitionPlan(cwd, plan) {
298
+ const dir = path.join(cwd, PLAN_DIR_REL);
299
+ fs.mkdirSync(dir, { recursive: true });
300
+ const abs = path.join(cwd, LATEST_PLAN_REL);
301
+ fs.writeFileSync(abs, JSON.stringify(plan, null, 2), "utf8");
302
+ try {
303
+ appendProductLearningEvent(cwd, "context_acquisition_plan_generated", {
304
+ taskKind: plan.taskKind,
305
+ confidence: plan.confidence,
306
+ selectedFiles: plan.selectedFiles.length,
307
+ withinBudget: plan.contextBudget.withinBudget,
308
+ requiresApproval: plan.strategy.requiresApproval,
309
+ });
310
+ } catch {}
311
+ return abs;
312
+ }
313
+
314
+ function buildContextPlanSurface(cwd, options = {}) {
315
+ const abs = path.join(cwd, LATEST_PLAN_REL);
316
+ if (!fs.existsSync(abs)) {
317
+ return { status: "not_available", artifactPath: LATEST_PLAN_REL };
318
+ }
319
+ try {
320
+ const plan = JSON.parse(fs.readFileSync(abs, "utf8"));
321
+ return {
322
+ status: "available",
323
+ taskKind: plan.taskKind,
324
+ confidence: plan.confidence,
325
+ selectedFiles: plan.selectedFiles.length,
326
+ withinBudget: plan.contextBudget.withinBudget,
327
+ artifactPath: LATEST_PLAN_REL,
328
+ };
329
+ } catch {
330
+ return { status: "error", artifactPath: LATEST_PLAN_REL };
331
+ }
332
+ }
333
+
334
+ function formatContextPlanText(plan, options = {}) {
335
+ const lines = [`Context Acquisition Plan [${plan.taskKind}]`];
336
+ lines.push(` Confidence: ${plan.confidence} | Approval required: ${plan.strategy.requiresApproval}`);
337
+ lines.push(` Strategy: profile=${plan.strategy.useProjectProfile} repoMap=${plan.strategy.useRepoMap} gitDiff=${plan.strategy.useGitDiff} slices=${plan.strategy.useFileSlices} fullFile=${plan.strategy.useFullFiles}`);
338
+ if (plan.selectedFiles.length) {
339
+ lines.push(` Selected files (${plan.selectedFiles.length}): ${plan.selectedFiles.slice(0, 5).map((f) => f.path).join(", ")}`);
340
+ }
341
+ lines.push(` Budget: ~${plan.contextBudget.estimatedSelected}/${plan.contextBudget.targetTokens} tokens (${plan.contextBudget.withinBudget ? "within" : "over"} budget)`);
342
+ if (plan.qualityRisks.length) lines.push(` Quality risks: ${plan.qualityRisks.join("; ")}`);
343
+ if (plan.nextAction) lines.push(` Next: ${plan.nextAction}`);
344
+ return lines.join("\n");
345
+ }
346
+
347
+ module.exports = {
348
+ CONTRACT,
349
+ SCHEMA_VERSION,
350
+ PLAN_DIR_REL,
351
+ LATEST_PLAN_REL,
352
+ classifyTask,
353
+ selectContextStrategy,
354
+ buildToolTaxDecision,
355
+ buildContextAcquisitionPlan,
356
+ writeContextAcquisitionPlan,
357
+ buildContextPlanSurface,
358
+ formatContextPlanText,
359
+ };
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+
3
+ const AUTHORITY_ORDER = { high: 3, medium: 2, low: 1 };
4
+
5
+ const RULES = [
6
+ {
7
+ id: "release-beats-planning",
8
+ description: "Release docs beat planning docs",
9
+ apply(refs) {
10
+ return refs.map((r) => {
11
+ if (r.type === "release_doc") return { ...r, authorityBoost: 2 };
12
+ if (r.type === "planning_doc") return { ...r, authorityPenalty: 1 };
13
+ return r;
14
+ });
15
+ },
16
+ },
17
+ {
18
+ id: "dogfood-beats-claim",
19
+ description: "Dogfood artifact / proof receipt beats claim in prose",
20
+ apply(refs) {
21
+ return refs.map((r) => {
22
+ if (r.type === "proof_artifact" || r.type === "dogfood_artifact") {
23
+ return { ...r, authorityBoost: (r.authorityBoost || 0) + 1 };
24
+ }
25
+ return r;
26
+ });
27
+ },
28
+ },
29
+ {
30
+ id: "source-beats-screenshot",
31
+ description: "Current source code beats old screenshots",
32
+ apply(refs) {
33
+ return refs.map((r) => {
34
+ if (r.type === "screenshot_ref" && r.freshness !== "fresh") {
35
+ return { ...r, authorityPenalty: (r.authorityPenalty || 0) + 2 };
36
+ }
37
+ if (r.type === "source_code" || r.type === "public_web_source") {
38
+ return { ...r, authorityBoost: (r.authorityBoost || 0) + 1 };
39
+ }
40
+ return r;
41
+ });
42
+ },
43
+ },
44
+ {
45
+ id: "kernel-beats-scattered",
46
+ description: "Capability Kernel registry beats scattered assumptions",
47
+ apply(refs) {
48
+ return refs.map((r) => {
49
+ if (r.type === "capability_manifest") {
50
+ return { ...r, authorityBoost: (r.authorityBoost || 0) + 1 };
51
+ }
52
+ return r;
53
+ });
54
+ },
55
+ },
56
+ {
57
+ id: "memory-cannot-override",
58
+ description: "Reentry Memory cannot override source of truth",
59
+ apply(refs) {
60
+ return refs.map((r) => {
61
+ if (r.type === "reentry_memory") {
62
+ return { ...r, authorityPenalty: (r.authorityPenalty || 0) + 1, cannotOverride: true };
63
+ }
64
+ return r;
65
+ });
66
+ },
67
+ },
68
+ {
69
+ id: "public-needs-public-safe",
70
+ description: "Public copy needs public-safe sources",
71
+ apply(refs, context) {
72
+ if (!context || !context.requiresPublicSafe) return refs;
73
+ return refs.map((r) => {
74
+ if (r.internalOnly && !r.publicSafe) {
75
+ return { ...r, excludedByPublicSafety: true };
76
+ }
77
+ return r;
78
+ });
79
+ },
80
+ },
81
+ {
82
+ id: "evidence-refs-must-be-real",
83
+ description: "Evidence refs must point to real files",
84
+ apply(refs, context) {
85
+ const fs = require("fs");
86
+ const path = require("path");
87
+ const repoRoot = (context && context.repoRoot) || process.cwd();
88
+ return refs.map((r) => {
89
+ if (!r.evidenceRefs || !r.evidenceRefs.length) return r;
90
+ const verified = [];
91
+ for (const ev of r.evidenceRefs) {
92
+ const abs = path.join(repoRoot, ev);
93
+ try { fs.accessSync(abs); verified.push(ev); } catch { /* skip fake */ }
94
+ }
95
+ return { ...r, evidenceRefs: verified };
96
+ });
97
+ },
98
+ },
99
+ {
100
+ id: "freshness-matters",
101
+ description: "Stale sources get penalties",
102
+ apply(refs) {
103
+ return refs.map((r) => {
104
+ if (r.freshness === "stale") return { ...r, authorityPenalty: (r.authorityPenalty || 0) + 3 };
105
+ if (r.freshness === "possibly_stale") return { ...r, authorityPenalty: (r.authorityPenalty || 0) + 1 };
106
+ return r;
107
+ });
108
+ },
109
+ },
110
+ ];
111
+
112
+ function computeAuthorityScore(ref) {
113
+ const base = AUTHORITY_ORDER[ref.authority] || 1;
114
+ const boost = ref.authorityBoost || 0;
115
+ const penalty = ref.authorityPenalty || 0;
116
+ const proofBonus = (ref.evidenceRefs && ref.evidenceRefs.length > 0) ? 1 : 0;
117
+ return base + boost - penalty + proofBonus;
118
+ }
119
+
120
+ function applyAllRules(refs, context) {
121
+ let result = refs;
122
+ for (const rule of RULES) {
123
+ result = rule.apply(result, context);
124
+ }
125
+ return result;
126
+ }
127
+
128
+ function rankByAuthority(refs) {
129
+ return refs.slice().sort((a, b) => computeAuthorityScore(b) - computeAuthorityScore(a));
130
+ }
131
+
132
+ module.exports = {
133
+ AUTHORITY_ORDER,
134
+ RULES,
135
+ computeAuthorityScore,
136
+ applyAllRules,
137
+ rankByAuthority,
138
+ };
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+
6
+ const BUDGET_REL = ".claude/cco/state/context-budget.json";
7
+
8
+ const DEFAULT_BUDGETS = {
9
+ "cost-saver": {
10
+ maxContextChars: 40000,
11
+ warnAtPercent: 70,
12
+ blockAtPercent: 90,
13
+ maxToolOutputBytes: 12000,
14
+ maxSingleFileBytes: 20000,
15
+ },
16
+ balanced: {
17
+ maxContextChars: 80000,
18
+ warnAtPercent: 70,
19
+ blockAtPercent: 90,
20
+ maxToolOutputBytes: 24000,
21
+ maxSingleFileBytes: 40000,
22
+ },
23
+ quality: {
24
+ maxContextChars: 160000,
25
+ warnAtPercent: 75,
26
+ blockAtPercent: 92,
27
+ maxToolOutputBytes: 48000,
28
+ maxSingleFileBytes: 80000,
29
+ },
30
+ };
31
+
32
+ const DEFAULT_PROFILE = "balanced";
33
+
34
+ function getBudgetForProfile(profile) {
35
+ return DEFAULT_BUDGETS[profile] || DEFAULT_BUDGETS[DEFAULT_PROFILE];
36
+ }
37
+
38
+ function normalizeBudgetConfig(raw) {
39
+ if (!raw || raw.enabled === false) {
40
+ return { enabled: false };
41
+ }
42
+ const rawProfile = String(raw.profile || DEFAULT_PROFILE);
43
+ const profile = DEFAULT_BUDGETS[rawProfile] ? rawProfile : DEFAULT_PROFILE;
44
+ const base = DEFAULT_BUDGETS[profile];
45
+ return {
46
+ enabled: raw.enabled !== false,
47
+ profile,
48
+ maxContextChars: Number.isFinite(Number(raw.maxContextChars)) ? Math.max(8000, Number(raw.maxContextChars)) : base.maxContextChars,
49
+ warnAtPercent: Number.isFinite(Number(raw.warnAtPercent)) ? Math.min(99, Math.max(10, Number(raw.warnAtPercent))) : base.warnAtPercent,
50
+ blockAtPercent: Number.isFinite(Number(raw.blockAtPercent)) ? Math.min(100, Math.max(50, Number(raw.blockAtPercent))) : base.blockAtPercent,
51
+ maxToolOutputBytes: Number.isFinite(Number(raw.maxToolOutputBytes)) ? Number(raw.maxToolOutputBytes) : base.maxToolOutputBytes,
52
+ maxSingleFileBytes: Number.isFinite(Number(raw.maxSingleFileBytes)) ? Number(raw.maxSingleFileBytes) : base.maxSingleFileBytes,
53
+ };
54
+ }
55
+
56
+ function estimateChars(text) {
57
+ return typeof text === "string" ? text.length : String(text || "").length;
58
+ }
59
+
60
+ function computeBudgetState(usedChars, budget) {
61
+ const { maxContextChars, warnAtPercent, blockAtPercent } = budget;
62
+ const usedPercent = maxContextChars > 0 ? (usedChars / maxContextChars) * 100 : 0;
63
+ const isOverWarn = usedPercent >= warnAtPercent;
64
+ const isOverBlock = usedPercent >= blockAtPercent;
65
+ const remainingChars = Math.max(0, maxContextChars - usedChars);
66
+
67
+ let status = "ok";
68
+ if (isOverBlock) status = "critical";
69
+ else if (isOverWarn) status = "warn";
70
+
71
+ return {
72
+ usedChars,
73
+ maxContextChars,
74
+ usedPercent: Math.round(usedPercent * 10) / 10,
75
+ remainingChars,
76
+ status,
77
+ warnAtPercent,
78
+ blockAtPercent,
79
+ };
80
+ }
81
+
82
+ function checkToolOutputSize(outputText, budget) {
83
+ const bytes = Buffer.byteLength(String(outputText || ""), "utf8");
84
+ const isOversized = bytes > budget.maxToolOutputBytes;
85
+ return {
86
+ bytes,
87
+ maxBytes: budget.maxToolOutputBytes,
88
+ isOversized,
89
+ truncateHint: isOversized ? `Output exceeds ${budget.maxToolOutputBytes} bytes. Store out-of-band and reference by path.` : null,
90
+ };
91
+ }
92
+
93
+ function checkSingleFileSize(fileSizeBytes, budget) {
94
+ const isOversized = fileSizeBytes > budget.maxSingleFileBytes;
95
+ return {
96
+ bytes: fileSizeBytes,
97
+ maxBytes: budget.maxSingleFileBytes,
98
+ isOversized,
99
+ truncateHint: isOversized ? `File exceeds ${budget.maxSingleFileBytes} bytes. Read in chunks or summarize.` : null,
100
+ };
101
+ }
102
+
103
+ function loadBudgetState(cwd) {
104
+ try {
105
+ const p = path.join(cwd, BUDGET_REL);
106
+ return JSON.parse(fs.readFileSync(p, "utf8"));
107
+ } catch {
108
+ return null;
109
+ }
110
+ }
111
+
112
+ function saveBudgetState(cwd, state) {
113
+ const p = path.join(cwd, BUDGET_REL);
114
+ fs.mkdirSync(path.dirname(p), { recursive: true });
115
+ fs.writeFileSync(p, JSON.stringify(state, null, 2), "utf8");
116
+ }
117
+
118
+ function buildBudgetStatus(cwd, rawBudgetConfig) {
119
+ const budget = normalizeBudgetConfig(rawBudgetConfig);
120
+ if (!budget.enabled) {
121
+ return { enabled: false, status: "off" };
122
+ }
123
+
124
+ const stored = loadBudgetState(cwd);
125
+ const usedChars = stored?.usedChars || 0;
126
+ const budgetState = computeBudgetState(usedChars, budget);
127
+
128
+ const warnings = [];
129
+ if (budgetState.status === "critical") {
130
+ warnings.push(`Context at ${budgetState.usedPercent}% of limit — consider /cco-optimize or summarize large outputs.`);
131
+ } else if (budgetState.status === "warn") {
132
+ warnings.push(`Context at ${budgetState.usedPercent}% of limit — approaching budget.`);
133
+ }
134
+
135
+ return {
136
+ enabled: true,
137
+ status: budgetState.status,
138
+ usedChars: budgetState.usedChars,
139
+ maxContextChars: budgetState.maxContextChars,
140
+ usedPercent: budgetState.usedPercent,
141
+ remainingChars: budgetState.remainingChars,
142
+ warnAtPercent: budgetState.warnAtPercent,
143
+ blockAtPercent: budgetState.blockAtPercent,
144
+ warnings,
145
+ budgetPath: BUDGET_REL,
146
+ };
147
+ }
148
+
149
+ function formatBudgetStatusText(budgetStatus) {
150
+ if (!budgetStatus || !budgetStatus.enabled || budgetStatus.status === "off") return null;
151
+ const { status, usedPercent, remainingChars, warnings } = budgetStatus;
152
+ if (status === "ok" && warnings.length === 0) return null;
153
+ const lines = [`Context budget: ${usedPercent}% used, ${remainingChars} chars remaining`];
154
+ warnings.forEach((w) => lines.push(` ⚠ ${w}`));
155
+ return lines.join("\n");
156
+ }
157
+
158
+ module.exports = {
159
+ DEFAULT_BUDGETS,
160
+ getBudgetForProfile,
161
+ normalizeBudgetConfig,
162
+ estimateChars,
163
+ computeBudgetState,
164
+ checkToolOutputSize,
165
+ checkSingleFileSize,
166
+ loadBudgetState,
167
+ saveBudgetState,
168
+ buildBudgetStatus,
169
+ formatBudgetStatusText,
170
+ };