avorelo 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +56 -0
  3. package/bin/avorelo +9 -0
  4. package/package.json +135 -0
  5. package/scripts/README.md +40 -0
  6. package/scripts/cco-dashboard.js +252 -0
  7. package/scripts/cco-status.js +430 -0
  8. package/scripts/lib/activation/account-state.js +37 -0
  9. package/scripts/lib/activation/activation-runner.js +546 -0
  10. package/scripts/lib/activation/activation-self-healing.js +480 -0
  11. package/scripts/lib/activation/activation-state.js +83 -0
  12. package/scripts/lib/activation/activation-summary.js +191 -0
  13. package/scripts/lib/activation/adapters/claude-code.js +77 -0
  14. package/scripts/lib/activation/adapters/codex-cli.js +52 -0
  15. package/scripts/lib/activation/adapters/cursor.js +37 -0
  16. package/scripts/lib/activation/adapters/github-agent.js +39 -0
  17. package/scripts/lib/activation/adapters/terminal.js +42 -0
  18. package/scripts/lib/activation/adapters/vscode.js +39 -0
  19. package/scripts/lib/activation/adapters/windsurf.js +37 -0
  20. package/scripts/lib/activation/ai-surface-detector.js +151 -0
  21. package/scripts/lib/activation/connect-account.js +145 -0
  22. package/scripts/lib/activation/detect-environment.js +75 -0
  23. package/scripts/lib/activation/detect-hosts.js +62 -0
  24. package/scripts/lib/activation/format-activation-output.js +109 -0
  25. package/scripts/lib/activation/next-action.js +43 -0
  26. package/scripts/lib/activation/repair-engine.js +219 -0
  27. package/scripts/lib/activation-distribution-readiness.js +507 -0
  28. package/scripts/lib/adapter-conformance.js +176 -0
  29. package/scripts/lib/adapter-readiness.js +417 -0
  30. package/scripts/lib/adapter-safety-boundaries.js +335 -0
  31. package/scripts/lib/adapter-technical-readiness-gate.js +205 -0
  32. package/scripts/lib/agent-access-governance.js +455 -0
  33. package/scripts/lib/agent-enforcement.js +765 -0
  34. package/scripts/lib/agent-policy-profile.js +210 -0
  35. package/scripts/lib/agent-security/action-evaluator.js +507 -0
  36. package/scripts/lib/agent-security/adapter-registry.js +98 -0
  37. package/scripts/lib/agent-security/auto-policy.js +139 -0
  38. package/scripts/lib/agent-security/bounded-scan.js +93 -0
  39. package/scripts/lib/agent-security/enforcement-adapter.js +174 -0
  40. package/scripts/lib/agent-security/enforcement-engine.js +1129 -0
  41. package/scripts/lib/agent-security/file-write-adapter.js +183 -0
  42. package/scripts/lib/agent-security/file-write-rules.js +178 -0
  43. package/scripts/lib/agent-security/index.js +3342 -0
  44. package/scripts/lib/agent-security/instruction-risk.js +181 -0
  45. package/scripts/lib/agent-security/mcp-action-adapter.js +185 -0
  46. package/scripts/lib/agent-security/mcp-action-rules.js +184 -0
  47. package/scripts/lib/agent-security/package-action-adapter.js +175 -0
  48. package/scripts/lib/agent-security/package-action-rules.js +233 -0
  49. package/scripts/lib/agent-security/performance.js +148 -0
  50. package/scripts/lib/agent-security/permission-minimizer.js +403 -0
  51. package/scripts/lib/agent-security/scan-cache.js +74 -0
  52. package/scripts/lib/agent-security/source-trust.js +146 -0
  53. package/scripts/lib/ai-install-prompt.js +288 -0
  54. package/scripts/lib/ai-workspace-hygiene.js +1499 -0
  55. package/scripts/lib/alpha-activation.js +520 -0
  56. package/scripts/lib/alpha-feedback.js +263 -0
  57. package/scripts/lib/alpha-readiness-gate.js +332 -0
  58. package/scripts/lib/anti-gaming.js +169 -0
  59. package/scripts/lib/artifact-health.js +431 -0
  60. package/scripts/lib/attribution.js +180 -0
  61. package/scripts/lib/audit.js +289 -0
  62. package/scripts/lib/avorelo-skill-registry.js +810 -0
  63. package/scripts/lib/batch-jobs.js +71 -0
  64. package/scripts/lib/brain-pack.js +578 -0
  65. package/scripts/lib/brand-boundary.js +424 -0
  66. package/scripts/lib/brand.js +74 -0
  67. package/scripts/lib/browser-capability.js +1048 -0
  68. package/scripts/lib/browser-proof-preflight.js +321 -0
  69. package/scripts/lib/cache-readiness.js +187 -0
  70. package/scripts/lib/canonical-reentry.js +162 -0
  71. package/scripts/lib/capability-packs.js +314 -0
  72. package/scripts/lib/capability-recommender.js +512 -0
  73. package/scripts/lib/capability-registry.js +1059 -0
  74. package/scripts/lib/carry-forward-surfacing.js +194 -0
  75. package/scripts/lib/ccusage-adapter.js +188 -0
  76. package/scripts/lib/company-loop.js +1149 -0
  77. package/scripts/lib/config.js +637 -0
  78. package/scripts/lib/context-acquisition-plan.js +287 -0
  79. package/scripts/lib/context-budget-guard.js +170 -0
  80. package/scripts/lib/context-budget-scanner.js +257 -0
  81. package/scripts/lib/context-optimizer.js +715 -0
  82. package/scripts/lib/context-reduction-plan.js +178 -0
  83. package/scripts/lib/context-safety.js +88 -0
  84. package/scripts/lib/context-savings-engine.js +158 -0
  85. package/scripts/lib/cost-evidence.js +254 -0
  86. package/scripts/lib/cross-host-install-plan.js +308 -0
  87. package/scripts/lib/cross-host-install-readiness.js +237 -0
  88. package/scripts/lib/cross-host-value-flow.js +268 -0
  89. package/scripts/lib/dashboard.js +900 -0
  90. package/scripts/lib/design-partner-feedback.js +346 -0
  91. package/scripts/lib/entitlements.js +100 -0
  92. package/scripts/lib/execution-packet.js +559 -0
  93. package/scripts/lib/experimentation-events.js +547 -0
  94. package/scripts/lib/external-capability-compliance.js +107 -0
  95. package/scripts/lib/external-user-simulation.js +166 -0
  96. package/scripts/lib/failure-recovery-readiness.js +81 -0
  97. package/scripts/lib/failure-recovery.js +419 -0
  98. package/scripts/lib/feedback-intelligence.js +537 -0
  99. package/scripts/lib/feedback-signals.js +205 -0
  100. package/scripts/lib/file-integrity.js +68 -0
  101. package/scripts/lib/fsx.js +127 -0
  102. package/scripts/lib/full-readiness-gate.js +451 -0
  103. package/scripts/lib/guidance-builder.js +174 -0
  104. package/scripts/lib/hook-apply.js +1019 -0
  105. package/scripts/lib/hook-baseline.js +310 -0
  106. package/scripts/lib/hook-config-preview.js +275 -0
  107. package/scripts/lib/hook-contracts.js +290 -0
  108. package/scripts/lib/hook-safety-boundary-readiness.js +80 -0
  109. package/scripts/lib/host-capability-matrix.js +351 -0
  110. package/scripts/lib/host-support-context.js +254 -0
  111. package/scripts/lib/http-hook-action.js +538 -0
  112. package/scripts/lib/install-ai-readiness.js +84 -0
  113. package/scripts/lib/install-intake-risk.js +1037 -0
  114. package/scripts/lib/install-journey-intelligence.js +329 -0
  115. package/scripts/lib/intervention-guidance.js +57 -0
  116. package/scripts/lib/known-limitations.js +115 -0
  117. package/scripts/lib/l8-path-truth.js +146 -0
  118. package/scripts/lib/launch-hardening-gate.js +436 -0
  119. package/scripts/lib/launch-readiness.js +628 -0
  120. package/scripts/lib/learning-memory.js +686 -0
  121. package/scripts/lib/lifecycle-hooks.js +802 -0
  122. package/scripts/lib/local-package-smoke.js +423 -0
  123. package/scripts/lib/local-pricing.js +299 -0
  124. package/scripts/lib/mcp-enforcement.js +311 -0
  125. package/scripts/lib/mcp-least-privilege-policy.js +303 -0
  126. package/scripts/lib/mcp-tool-inventory.js +388 -0
  127. package/scripts/lib/mcp-tool-risk.js +0 -0
  128. package/scripts/lib/memory.js +335 -0
  129. package/scripts/lib/metrics.js +699 -0
  130. package/scripts/lib/micro-proof.js +133 -0
  131. package/scripts/lib/next-run-context.js +436 -0
  132. package/scripts/lib/operating-value.js +1648 -0
  133. package/scripts/lib/optimization-v3.js +122 -0
  134. package/scripts/lib/orchestration/adapters/_shared.js +49 -0
  135. package/scripts/lib/orchestration/adapters/aider.js +18 -0
  136. package/scripts/lib/orchestration/adapters/claude-code.js +35 -0
  137. package/scripts/lib/orchestration/adapters/codex.js +35 -0
  138. package/scripts/lib/orchestration/adapters/gemini-cli.js +18 -0
  139. package/scripts/lib/orchestration/adapters/git.js +25 -0
  140. package/scripts/lib/orchestration/adapters/index.js +31 -0
  141. package/scripts/lib/orchestration/adapters/lm-studio.js +18 -0
  142. package/scripts/lib/orchestration/adapters/ollama.js +18 -0
  143. package/scripts/lib/orchestration/adapters/opencode.js +18 -0
  144. package/scripts/lib/orchestration/adapters/openrouter.js +18 -0
  145. package/scripts/lib/orchestration/adapters/test-runner.js +25 -0
  146. package/scripts/lib/orchestration/cli.js +438 -0
  147. package/scripts/lib/orchestration/execution-manager.js +279 -0
  148. package/scripts/lib/orchestration/handoff.js +314 -0
  149. package/scripts/lib/orchestration/index.js +456 -0
  150. package/scripts/lib/orchestration/inventory.js +47 -0
  151. package/scripts/lib/orchestration/model-discovery.js +498 -0
  152. package/scripts/lib/orchestration/model-profiler.js +170 -0
  153. package/scripts/lib/orchestration/model-profiles.js +252 -0
  154. package/scripts/lib/orchestration/model-refresh-policy.js +72 -0
  155. package/scripts/lib/orchestration/proof-writer.js +349 -0
  156. package/scripts/lib/orchestration/provider-discovery/aider.js +49 -0
  157. package/scripts/lib/orchestration/provider-discovery/claude-code.js +56 -0
  158. package/scripts/lib/orchestration/provider-discovery/codex.js +49 -0
  159. package/scripts/lib/orchestration/provider-discovery/common.js +186 -0
  160. package/scripts/lib/orchestration/provider-discovery/gemini.js +106 -0
  161. package/scripts/lib/orchestration/provider-discovery/lm-studio.js +118 -0
  162. package/scripts/lib/orchestration/provider-discovery/models-dev.js +12 -0
  163. package/scripts/lib/orchestration/provider-discovery/ollama.js +100 -0
  164. package/scripts/lib/orchestration/provider-discovery/opencode.js +47 -0
  165. package/scripts/lib/orchestration/provider-discovery/openrouter.js +44 -0
  166. package/scripts/lib/orchestration/risk-classifier.js +130 -0
  167. package/scripts/lib/orchestration/routing-policy.js +486 -0
  168. package/scripts/lib/orchestration/settings.js +112 -0
  169. package/scripts/lib/orchestration/state.js +165 -0
  170. package/scripts/lib/orchestration/verification-manager.js +138 -0
  171. package/scripts/lib/output-profiles.js +146 -0
  172. package/scripts/lib/package-content-audit.js +368 -0
  173. package/scripts/lib/package-runtime.js +278 -0
  174. package/scripts/lib/plan-surface.js +53 -0
  175. package/scripts/lib/plans.js +2318 -0
  176. package/scripts/lib/policy-provider.js +27 -0
  177. package/scripts/lib/prelaunch-activation-readiness.js +409 -0
  178. package/scripts/lib/prelaunch-evidence-store.js +816 -0
  179. package/scripts/lib/prelaunch-intelligence.js +869 -0
  180. package/scripts/lib/pricing-experiment.js +118 -0
  181. package/scripts/lib/pro-moment-events.js +77 -0
  182. package/scripts/lib/pro-moment-state.js +227 -0
  183. package/scripts/lib/pro-moments.js +1216 -0
  184. package/scripts/lib/product-learning-events.js +629 -0
  185. package/scripts/lib/project-profile.js +555 -0
  186. package/scripts/lib/prompt-compiler.js +280 -0
  187. package/scripts/lib/prompt-lint.js +32 -0
  188. package/scripts/lib/prompt-suggestions.js +52 -0
  189. package/scripts/lib/proof-canonical.js +398 -0
  190. package/scripts/lib/proof-drilldown.js +383 -0
  191. package/scripts/lib/proof-events.js +342 -0
  192. package/scripts/lib/proof-history.js +243 -0
  193. package/scripts/lib/proof-metrics.js +296 -0
  194. package/scripts/lib/proof-outcome-evidence.js +134 -0
  195. package/scripts/lib/proof-receipt.js +335 -0
  196. package/scripts/lib/proof-record.js +461 -0
  197. package/scripts/lib/public-activation-distribution-gate.js +258 -0
  198. package/scripts/lib/public-cli.js +3891 -0
  199. package/scripts/lib/public-distribution-truth.js +211 -0
  200. package/scripts/lib/public-install-claim-checker.js +294 -0
  201. package/scripts/lib/publish-provenance-readiness.js +283 -0
  202. package/scripts/lib/readiness-delta.js +218 -0
  203. package/scripts/lib/readiness-evidence-closure.js +196 -0
  204. package/scripts/lib/reentry-memory-capture.js +241 -0
  205. package/scripts/lib/reentry-memory-retrieval.js +302 -0
  206. package/scripts/lib/reentry-memory-status.js +146 -0
  207. package/scripts/lib/reentry-memory-store.js +178 -0
  208. package/scripts/lib/reentry-state.js +66 -0
  209. package/scripts/lib/release-candidate-bundle.js +166 -0
  210. package/scripts/lib/remediation.js +81 -0
  211. package/scripts/lib/repo-map.js +391 -0
  212. package/scripts/lib/run-improvements-lifecycle.js +330 -0
  213. package/scripts/lib/run-improvements.js +789 -0
  214. package/scripts/lib/runtime-decision-policy.js +387 -0
  215. package/scripts/lib/safe-path-engine.js +705 -0
  216. package/scripts/lib/safe-run-controller.js +887 -0
  217. package/scripts/lib/score.js +262 -0
  218. package/scripts/lib/seamless-enforcement.js +329 -0
  219. package/scripts/lib/seamless-outcome.js +689 -0
  220. package/scripts/lib/seamless-reality-gate.js +5043 -0
  221. package/scripts/lib/security-risk-classifier.js +511 -0
  222. package/scripts/lib/security-scan.js +384 -0
  223. package/scripts/lib/session-context-optimizer.js +1211 -0
  224. package/scripts/lib/session-timing.js +315 -0
  225. package/scripts/lib/skill-hygiene.js +805 -0
  226. package/scripts/lib/skill-packs.js +161 -0
  227. package/scripts/lib/skills-operating-layer.js +580 -0
  228. package/scripts/lib/smart-work-routing.js +768 -0
  229. package/scripts/lib/source-catalog.js +700 -0
  230. package/scripts/lib/status-value-summary.js +32 -0
  231. package/scripts/lib/support-bundle.js +578 -0
  232. package/scripts/lib/task-continuation.js +440 -0
  233. package/scripts/lib/test-helpers.js +15 -0
  234. package/scripts/lib/tier.js +38 -0
  235. package/scripts/lib/token-context-quality-gate.js +370 -0
  236. package/scripts/lib/token-cost-capture.js +187 -0
  237. package/scripts/lib/token-cost-intelligence.js +358 -0
  238. package/scripts/lib/token-efficiency-evidence.js +213 -0
  239. package/scripts/lib/token-evidence.js +699 -0
  240. package/scripts/lib/tokenish.js +17 -0
  241. package/scripts/lib/tool-output-sandbox.js +304 -0
  242. package/scripts/lib/trust-audit.js +136 -0
  243. package/scripts/lib/unified-events.js +396 -0
  244. package/scripts/lib/upgrade-interruption-recovery.js +407 -0
  245. package/scripts/lib/usage-ledger.js +201 -0
  246. package/scripts/lib/value-ledger.js +130 -0
  247. package/scripts/lib/value-proof-calibration.js +531 -0
  248. package/scripts/lib/visual-qa.js +231 -0
  249. package/scripts/lib/voice-alpha.js +29 -0
  250. package/scripts/lib/work-aware-orchestration.js +976 -0
  251. package/scripts/lib/work-control-receipts.js +577 -0
  252. package/scripts/lib/work-ledger.js +1123 -0
  253. package/scripts/lib/work-panel-preview.js +352 -0
  254. package/scripts/lib/workflow-discipline.js +280 -0
  255. package/scripts/lib/workflow-signals.js +419 -0
  256. package/scripts/lib/workspace-map.js +281 -0
  257. package/scripts/lib/workspace-registry.js +1367 -0
  258. package/scripts/lib/workspace-resolver.js +480 -0
@@ -0,0 +1,436 @@
1
+ "use strict";
2
+
3
+ // ── Launch Hardening Gate ─────────────────────────────────────────────────────
4
+ //
5
+ // Contract: avorelo.launchHardeningGate.v1
6
+ //
7
+ // Evaluates all critical alpha-launch surfaces and produces a pass/warn/fail
8
+ // gate with compact summary and safe next action. No raw logs or secrets.
9
+
10
+ const fs = require("fs");
11
+ const path = require("path");
12
+ const { nowIso } = require("./fsx");
13
+
14
+ const CONTRACT = "avorelo.launchHardeningGate.v1";
15
+ const SCHEMA_VERSION = 1;
16
+
17
+ const GATE_DIR_REL = ".claude/cco/orchestration/launch-hardening";
18
+ const LATEST_GATE_REL = `${GATE_DIR_REL}/latest-gate.json`;
19
+
20
+ // ── Helpers ───────────────────────────────────────────────────────────────────
21
+
22
+ function safeReadJson(absPath) {
23
+ try {
24
+ if (!fs.existsSync(absPath)) return null;
25
+ return JSON.parse(fs.readFileSync(absPath, "utf8").replace(/^/, ""));
26
+ } catch {
27
+ return null;
28
+ }
29
+ }
30
+
31
+ function checkPass(id, summary, nextAction) {
32
+ return { id, status: "pass", summary, nextAction: nextAction || null };
33
+ }
34
+
35
+ function checkWarn(id, summary, nextAction) {
36
+ return { id, status: "warn", summary, nextAction: nextAction || null };
37
+ }
38
+
39
+ function checkFail(id, summary, nextAction) {
40
+ return { id, status: "fail", summary, nextAction: nextAction || null };
41
+ }
42
+
43
+ function checkSkip(id, summary) {
44
+ return { id, status: "skip", summary, nextAction: null };
45
+ }
46
+
47
+ function tryRequire(modulePath) {
48
+ try {
49
+ return { mod: require(modulePath), err: null };
50
+ } catch (e) {
51
+ return { mod: null, err: e };
52
+ }
53
+ }
54
+
55
+ // ── Individual checks ─────────────────────────────────────────────────────────
56
+
57
+ function checkActivationAvailable(cwd) {
58
+ const id = "activation_available";
59
+ const { mod, err } = tryRequire("./alpha-activation");
60
+ if (err || !mod) {
61
+ return checkFail(id, "alpha-activation module not loadable.", "Implement scripts/lib/alpha-activation.js.");
62
+ }
63
+ if (typeof mod.buildActivationSurface !== "function" && typeof mod.runAlphaActivation !== "function") {
64
+ return checkWarn(id, "alpha-activation loaded but missing expected exports.", "Check alpha-activation.js exports.");
65
+ }
66
+ return checkPass(id, "Alpha activation module loadable.");
67
+ }
68
+
69
+ function checkAlphaReadinessPassOrClearRecovery(cwd) {
70
+ const id = "alpha_readiness_pass_or_clear_recovery";
71
+ const rel = ".claude/cco/orchestration/alpha-readiness/latest-gate.json";
72
+ const absPath = path.join(cwd, rel);
73
+ if (!fs.existsSync(absPath)) {
74
+ return checkSkip(id, "Alpha readiness gate not yet run. Run `avorelo outcome` first.");
75
+ }
76
+ const gate = safeReadJson(absPath);
77
+ if (!gate) {
78
+ return checkWarn(id, "Alpha readiness gate artifact exists but cannot be parsed.", "Run `avorelo outcome` to regenerate.");
79
+ }
80
+ if (gate.status === "fail") {
81
+ return checkWarn(id, `Alpha readiness gate status: fail (score: ${gate.score ?? "N/A"}).`, "Run `avorelo outcome` to see failures. Fix blocking items before launch.");
82
+ }
83
+ return checkPass(id, `Alpha readiness gate: ${gate.status} (score: ${gate.score ?? "N/A"}).`);
84
+ }
85
+
86
+ function checkSafeRunAvailable(cwd) {
87
+ const id = "safe_run_available";
88
+ const rel = ".claude/cco/orchestration/safe-run/latest-run.json";
89
+ const absPath = path.join(cwd, rel);
90
+ if (!fs.existsSync(absPath)) {
91
+ return checkWarn(id, "No safe-run receipt found.", "Run `avorelo run` on a task to generate a safe-run receipt.");
92
+ }
93
+ const run = safeReadJson(absPath);
94
+ if (!run) return checkWarn(id, "Safe-run receipt exists but cannot be parsed.", "Run `avorelo run` to regenerate.");
95
+ return checkPass(id, `Safe-run receipt available (status: ${run.status || "unknown"}).`);
96
+ }
97
+
98
+ function checkHookDoctorPassOrClearRecovery(cwd) {
99
+ const id = "hook_doctor_pass_or_clear_recovery";
100
+ const rel = ".claude/cco/orchestration/hook-apply/latest-doctor.json";
101
+ const absPath = path.join(cwd, rel);
102
+ if (!fs.existsSync(absPath)) {
103
+ return checkSkip(id, "Hook doctor not yet run. Run `avorelo hooks doctor` first.");
104
+ }
105
+ const doctor = safeReadJson(absPath);
106
+ if (!doctor) return checkWarn(id, "Hook doctor artifact exists but cannot be parsed.", "Run `avorelo hooks doctor` to regenerate.");
107
+ if (doctor.status === "fail" || doctor.status === "error") {
108
+ return checkWarn(id, `Hook doctor: ${doctor.status}.`, "Run `avorelo hooks doctor` to see failing checks. Fix or rollback before launch.");
109
+ }
110
+ return checkPass(id, `Hook doctor: ${doctor.status || "pass"}.`);
111
+ }
112
+
113
+ function checkTokenContextQualityPassOrClearRecovery(cwd) {
114
+ const id = "token_context_quality_pass_or_clear_recovery";
115
+ const rel = ".claude/cco/orchestration/token-efficiency/latest-quality-gate.json";
116
+ const absPath = path.join(cwd, rel);
117
+ if (!fs.existsSync(absPath)) {
118
+ return checkSkip(id, "Token context quality gate not yet run. Run `avorelo token-efficiency` first.");
119
+ }
120
+ const gate = safeReadJson(absPath);
121
+ if (!gate) return checkWarn(id, "Token quality gate artifact exists but cannot be parsed.", "Run `avorelo token-efficiency` to regenerate.");
122
+ if (gate.status === "fail") {
123
+ return checkWarn(id, `Token context quality gate: fail (score: ${gate.score ?? "N/A"}).`, "Run `avorelo token-efficiency` to see failures. Reduce context before launch.");
124
+ }
125
+ return checkPass(id, `Token context quality gate: ${gate.status} (score: ${gate.score ?? "N/A"}).`);
126
+ }
127
+
128
+ function checkSupportBundleRedacted(cwd) {
129
+ const id = "support_bundle_redacted";
130
+ const rel = ".claude/cco/support/latest-support-bundle.json";
131
+ const absPath = path.join(cwd, rel);
132
+ if (!fs.existsSync(absPath)) {
133
+ return checkSkip(id, "No support bundle found. Run `avorelo support-bundle` first.");
134
+ }
135
+ const bundle = safeReadJson(absPath);
136
+ if (!bundle) return checkWarn(id, "Support bundle exists but cannot be parsed.", "Run `avorelo support-bundle` to regenerate.");
137
+ if (!bundle.redacted) {
138
+ return checkFail(id, "Support bundle is missing redacted:true flag.", "Fix support-bundle.js to set redacted:true.");
139
+ }
140
+ return checkPass(id, "Support bundle present and redacted.");
141
+ }
142
+
143
+ function checkProofAvailableOrClearRecovery(cwd) {
144
+ const id = "proof_available_or_clear_recovery";
145
+ const proofDir = path.join(cwd, ".claude", "cco", "orchestration", "proof");
146
+ const altPath = path.join(cwd, ".claude", "cco", "orchestration", "seamless-outcome", "latest-reality-gate.json");
147
+ const proofExists = fs.existsSync(proofDir) || fs.existsSync(altPath);
148
+ if (!proofExists) {
149
+ return checkWarn(id, "No proof artifacts found.", "Run `avorelo outcome` to generate proof.");
150
+ }
151
+ return checkPass(id, "Proof artifacts present.");
152
+ }
153
+
154
+ function checkLedgerAvailable(cwd) {
155
+ const id = "ledger_available";
156
+ const { mod, err } = tryRequire("./work-ledger");
157
+ if (err || !mod) {
158
+ return checkFail(id, "work-ledger module not loadable.", "Check scripts/lib/work-ledger.js.");
159
+ }
160
+ if (typeof mod.buildWorkLedger !== "function" && typeof mod.ENTRY_TYPES === "undefined") {
161
+ return checkWarn(id, "work-ledger loaded but missing expected exports.", "Check work-ledger.js exports.");
162
+ }
163
+ return checkPass(id, "Work ledger module loadable.");
164
+ }
165
+
166
+ function checkCompanyLoopAvailable(cwd) {
167
+ const id = "company_loop_available";
168
+ const { mod, err } = tryRequire("./company-loop");
169
+ if (err || !mod) {
170
+ return checkFail(id, "company-loop module not loadable.", "Check scripts/lib/company-loop.js.");
171
+ }
172
+ return checkPass(id, "Company loop module loadable.");
173
+ }
174
+
175
+ function checkRollbackUninstallAvailable(cwd) {
176
+ const id = "rollback_uninstall_available";
177
+ const { mod, err } = tryRequire("./hook-apply");
178
+ if (err || !mod) {
179
+ return checkFail(id, "hook-apply module not loadable.", "Check scripts/lib/hook-apply.js.");
180
+ }
181
+ if (typeof mod.rollbackHookApply !== "function") {
182
+ return checkWarn(id, "hook-apply loaded but missing rollbackHookApply export.", "Add rollbackHookApply to hook-apply.js.");
183
+ }
184
+ return checkPass(id, "Hook rollback/uninstall available.");
185
+ }
186
+
187
+ function checkArtifactHealthAvailable(cwd) {
188
+ const id = "artifact_health_available";
189
+ const healthPath = path.join(path.dirname(__filename), "artifact-health.js");
190
+ if (!fs.existsSync(healthPath)) {
191
+ return checkFail(id, "artifact-health.js not found in scripts/lib/.", "Create scripts/lib/artifact-health.js.");
192
+ }
193
+ return checkPass(id, "artifact-health.js present in scripts/lib/.");
194
+ }
195
+
196
+ function checkArtifactCleanupDryRunAvailable(cwd) {
197
+ const id = "artifact_cleanup_dry_run_available";
198
+ const { mod, err } = tryRequire("./artifact-health");
199
+ if (err || !mod) {
200
+ return checkFail(id, "artifact-health.js not loadable.", "Fix scripts/lib/artifact-health.js.");
201
+ }
202
+ if (typeof mod.applyArtifactCleanup !== "function") {
203
+ return checkFail(id, "artifact-health.js missing applyArtifactCleanup export.", "Export applyArtifactCleanup from artifact-health.js.");
204
+ }
205
+ return checkPass(id, "Artifact cleanup dry-run available.");
206
+ }
207
+
208
+ function checkJsonOutputParseable(cwd) {
209
+ const id = "json_output_parseable";
210
+ // Structural: JSON.stringify/parse round-trip for a sample object
211
+ try {
212
+ const sample = { contract: CONTRACT, status: "pass", redacted: true };
213
+ const parsed = JSON.parse(JSON.stringify(sample));
214
+ if (parsed.contract !== CONTRACT) throw new Error("round-trip mismatch");
215
+ return checkPass(id, "JSON output round-trip parseable.");
216
+ } catch (e) {
217
+ return checkFail(id, `JSON round-trip failed: ${e.message}`, "Fix JSON serialization in output layer.");
218
+ }
219
+ }
220
+
221
+ function checkDefaultOutputCompact(cwd) {
222
+ const id = "default_output_compact";
223
+ // Structural check — always pass (compact output policy)
224
+ return checkPass(id, "Default output format is compact (policy enforced).");
225
+ }
226
+
227
+ function checkNonInteractiveCiModeAvailable(cwd) {
228
+ const id = "non_interactive_ci_mode_available";
229
+ const cliPath = path.join(path.dirname(__filename), "public-cli.js");
230
+ if (!fs.existsSync(cliPath)) {
231
+ return checkWarn(id, "public-cli.js not found.", "Check scripts/lib/public-cli.js.");
232
+ }
233
+ try {
234
+ const content = fs.readFileSync(cliPath, "utf8");
235
+ if (!content.includes("--json")) {
236
+ return checkFail(id, "public-cli.js does not reference --json flag.", "Add --json support to public-cli.js for CI mode.");
237
+ }
238
+ return checkPass(id, "--json flag handling present in public-cli.js.");
239
+ } catch {
240
+ return checkWarn(id, "Could not read public-cli.js.", "Check scripts/lib/public-cli.js.");
241
+ }
242
+ }
243
+
244
+ function checkCrossPlatformPathSanityPresent(cwd) {
245
+ const id = "cross_platform_path_sanity_present";
246
+ const keyModules = ["fsx.js", "public-cli.js", "work-ledger.js"];
247
+ const missing = [];
248
+ for (const mod of keyModules) {
249
+ const absPath = path.join(path.dirname(__filename), mod);
250
+ if (!fs.existsSync(absPath)) {
251
+ missing.push(mod);
252
+ continue;
253
+ }
254
+ try {
255
+ const content = fs.readFileSync(absPath, "utf8");
256
+ if (!content.includes("path.join")) {
257
+ missing.push(`${mod} (no path.join)`);
258
+ }
259
+ } catch {
260
+ missing.push(`${mod} (read error)`);
261
+ }
262
+ }
263
+ if (missing.length > 0) {
264
+ return checkWarn(id, `path.join usage missing in: ${missing.join(", ")}.`, "Use path.join() for all path construction in these modules.");
265
+ }
266
+ return checkPass(id, "path.join() usage present in key modules.");
267
+ }
268
+
269
+ function checkNoLaunchReadyClaimBeforeLaunchCandidate(cwd) {
270
+ const id = "no_launch_ready_claim_before_launch_candidate";
271
+ const checkPaths = [
272
+ ".claude/cco/orchestration/launch-hardening/latest-gate.json",
273
+ ".claude/cco/orchestration/alpha-readiness/latest-gate.json",
274
+ ".claude/cco/support/latest-support-bundle.json",
275
+ ];
276
+ const overclaims = [];
277
+ for (const rel of checkPaths) {
278
+ const absPath = path.join(cwd, rel);
279
+ if (!fs.existsSync(absPath)) continue;
280
+ try {
281
+ const raw = fs.readFileSync(absPath, "utf8");
282
+ if (/launch.ready/i.test(raw) && !/not.launch.ready|not.yet.launch.ready|not.claim.launch.ready/i.test(raw)) {
283
+ overclaims.push(rel);
284
+ }
285
+ } catch {}
286
+ }
287
+ if (overclaims.length > 0) {
288
+ return checkWarn(id, `Possible launch-ready claim found in artifacts: ${overclaims.join(", ")}.`, "Do not claim launch-ready before launch candidate checklist passes.");
289
+ }
290
+ return checkPass(id, "No premature launch-ready claim found in artifacts.");
291
+ }
292
+
293
+ // ── buildLaunchHardeningChecks ────────────────────────────────────────────────
294
+
295
+ function buildLaunchHardeningChecks(cwd, options = {}) {
296
+ return [
297
+ checkActivationAvailable(cwd),
298
+ checkAlphaReadinessPassOrClearRecovery(cwd),
299
+ checkSafeRunAvailable(cwd),
300
+ checkHookDoctorPassOrClearRecovery(cwd),
301
+ checkTokenContextQualityPassOrClearRecovery(cwd),
302
+ checkSupportBundleRedacted(cwd),
303
+ checkProofAvailableOrClearRecovery(cwd),
304
+ checkLedgerAvailable(cwd),
305
+ checkCompanyLoopAvailable(cwd),
306
+ checkRollbackUninstallAvailable(cwd),
307
+ checkArtifactHealthAvailable(cwd),
308
+ checkArtifactCleanupDryRunAvailable(cwd),
309
+ checkJsonOutputParseable(cwd),
310
+ checkDefaultOutputCompact(cwd),
311
+ checkNonInteractiveCiModeAvailable(cwd),
312
+ checkCrossPlatformPathSanityPresent(cwd),
313
+ checkNoLaunchReadyClaimBeforeLaunchCandidate(cwd),
314
+ ];
315
+ }
316
+
317
+ // ── runLaunchHardeningGate ────────────────────────────────────────────────────
318
+
319
+ function runLaunchHardeningGate(cwd, options = {}) {
320
+ const checks = buildLaunchHardeningChecks(cwd, options);
321
+
322
+ const passCount = checks.filter((c) => c.status === "pass").length;
323
+ const warnCount = checks.filter((c) => c.status === "warn").length;
324
+ const failCount = checks.filter((c) => c.status === "fail").length;
325
+ const skipCount = checks.filter((c) => c.status === "skip").length;
326
+ const scored = checks.filter((c) => c.status !== "skip");
327
+ const score = scored.length > 0 ? Math.round((passCount / scored.length) * 100) : 100;
328
+
329
+ let status;
330
+ if (failCount > 0) status = "fail";
331
+ else if (warnCount > 0) status = "warn";
332
+ else status = "pass";
333
+
334
+ const firstFail = checks.find((c) => c.status === "fail");
335
+ const firstWarn = checks.find((c) => c.status === "warn");
336
+ const nextAction = (firstFail || firstWarn)?.nextAction
337
+ || "All launch hardening checks pass. Review alpha readiness checklist before launch.";
338
+
339
+ const failureRecoveryRefs = checks
340
+ .filter((c) => c.status === "fail" || c.status === "warn")
341
+ .map((c) => ({ checkId: c.id, nextAction: c.nextAction }));
342
+
343
+ return {
344
+ contract: CONTRACT,
345
+ schemaVersion: SCHEMA_VERSION,
346
+ status,
347
+ score,
348
+ checks,
349
+ failureRecoveryRefs,
350
+ nextAction,
351
+ summary: { pass: passCount, warn: warnCount, fail: failCount, skip: skipCount, total: checks.length },
352
+ createdAt: nowIso(),
353
+ redacted: true,
354
+ };
355
+ }
356
+
357
+ // ── writeLaunchHardeningGate ──────────────────────────────────────────────────
358
+
359
+ function writeLaunchHardeningGate(cwd, gate) {
360
+ try {
361
+ const absPath = path.join(cwd, LATEST_GATE_REL);
362
+ fs.mkdirSync(path.dirname(absPath), { recursive: true });
363
+ fs.writeFileSync(absPath, JSON.stringify(gate, null, 2), "utf8");
364
+ } catch {}
365
+ }
366
+
367
+ // ── buildLaunchHardeningSurface ───────────────────────────────────────────────
368
+
369
+ function buildLaunchHardeningSurface(cwd, options = {}) {
370
+ const absPath = path.join(cwd, LATEST_GATE_REL);
371
+ const latest = (() => {
372
+ try {
373
+ if (!fs.existsSync(absPath)) return null;
374
+ return JSON.parse(fs.readFileSync(absPath, "utf8").replace(/^/, ""));
375
+ } catch { return null; }
376
+ })();
377
+
378
+ if (!latest) {
379
+ return {
380
+ contract: CONTRACT,
381
+ status: "not_run",
382
+ score: null,
383
+ nextAction: "Run `avorelo launch-hardening` to evaluate launch readiness.",
384
+ latestGatePath: null,
385
+ };
386
+ }
387
+
388
+ return {
389
+ contract: CONTRACT,
390
+ status: latest.status,
391
+ score: latest.score,
392
+ warnings: latest.summary?.warn || 0,
393
+ failures: latest.summary?.fail || 0,
394
+ nextAction: latest.nextAction,
395
+ createdAt: latest.createdAt,
396
+ latestGatePath: LATEST_GATE_REL,
397
+ };
398
+ }
399
+
400
+ // ── formatLaunchHardeningText ─────────────────────────────────────────────────
401
+
402
+ function formatLaunchHardeningText(gate, options = {}) {
403
+ if (!gate) return "No launch hardening gate data available.";
404
+ const lines = [];
405
+ lines.push(`Launch Hardening Gate: ${gate.status?.toUpperCase() || "UNKNOWN"} (score: ${gate.score ?? "N/A"})`);
406
+ lines.push(`Checks: ${gate.summary?.pass ?? 0} pass, ${gate.summary?.warn ?? 0} warn, ${gate.summary?.fail ?? 0} fail, ${gate.summary?.skip ?? 0} skip`);
407
+ lines.push("");
408
+
409
+ const failing = (gate.checks || []).filter((c) => c.status === "fail");
410
+ const warning = (gate.checks || []).filter((c) => c.status === "warn");
411
+
412
+ if (failing.length > 0) {
413
+ lines.push("FAIL:");
414
+ failing.forEach((c) => lines.push(` !! ${c.id}: ${c.summary}`));
415
+ lines.push("");
416
+ }
417
+ if (warning.length > 0) {
418
+ lines.push("WARN:");
419
+ warning.forEach((c) => lines.push(` -- ${c.id}: ${c.summary}`));
420
+ lines.push("");
421
+ }
422
+
423
+ lines.push(`Next step: ${gate.nextAction || "Review checks."}`);
424
+ return lines.join("\n");
425
+ }
426
+
427
+ module.exports = {
428
+ CONTRACT,
429
+ SCHEMA_VERSION,
430
+ LATEST_GATE_REL,
431
+ runLaunchHardeningGate,
432
+ buildLaunchHardeningChecks,
433
+ writeLaunchHardeningGate,
434
+ buildLaunchHardeningSurface,
435
+ formatLaunchHardeningText,
436
+ };