@ornexus/neocortex 4.60.66 → 4.60.68

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 (236) hide show
  1. package/dist/release-source.json +1 -1
  2. package/dist/sbom.cdx.json +1598 -1640
  3. package/install.ps1 +1 -1
  4. package/install.sh +2 -1
  5. package/package.json +10 -7
  6. package/packages/client/dist/adapters/adapter-registry.js +108 -1
  7. package/packages/client/dist/adapters/antigravity-adapter.js +77 -2
  8. package/packages/client/dist/adapters/claude-code-adapter.js +79 -3
  9. package/packages/client/dist/adapters/codex-adapter.js +80 -2
  10. package/packages/client/dist/adapters/cursor-adapter.js +115 -4
  11. package/packages/client/dist/adapters/gemini-adapter.js +71 -2
  12. package/packages/client/dist/adapters/grok-adapter.js +42 -2
  13. package/packages/client/dist/adapters/index.js +22 -1
  14. package/packages/client/dist/adapters/platform-detector.js +212 -1
  15. package/packages/client/dist/adapters/target-adapter.js +12 -0
  16. package/packages/client/dist/adapters/vscode-adapter.js +72 -2
  17. package/packages/client/dist/agent/refresh-stubs.js +417 -2
  18. package/packages/client/dist/agent/update-agent-yaml.js +102 -1
  19. package/packages/client/dist/agent/update-description.js +251 -1
  20. package/packages/client/dist/cache/crypto-utils.js +78 -1
  21. package/packages/client/dist/cache/encrypted-cache.js +108 -1
  22. package/packages/client/dist/cache/in-memory-asset-cache.js +73 -1
  23. package/packages/client/dist/cache/index.js +13 -1
  24. package/packages/client/dist/cache/protected-pi-boundary.js +44 -1
  25. package/packages/client/dist/checkpoint/checkpoint-client-reader.js +127 -2
  26. package/packages/client/dist/checkpoint/index.js +11 -1
  27. package/packages/client/dist/checkpoint/shared-checkpoint-types.js +32 -1
  28. package/packages/client/dist/cli.js +303 -3
  29. package/packages/client/dist/commands/activate.js +394 -8
  30. package/packages/client/dist/commands/architecture-answers.js +274 -7
  31. package/packages/client/dist/commands/architecture-memory-terminal.js +253 -4
  32. package/packages/client/dist/commands/architecture-non-ui-continuation.js +100 -1
  33. package/packages/client/dist/commands/architecture-root-binding.js +51 -1
  34. package/packages/client/dist/commands/cache-status.js +112 -2
  35. package/packages/client/dist/commands/config.js +88 -1
  36. package/packages/client/dist/commands/doctor.d.ts +135 -0
  37. package/packages/client/dist/commands/doctor.js +635 -0
  38. package/packages/client/dist/commands/invoke.d.ts +18 -0
  39. package/packages/client/dist/commands/invoke.js +7140 -142
  40. package/packages/client/dist/commands/legacy-epic-terminal.js +71 -1
  41. package/packages/client/dist/commands/legacy-story-branch.js +96 -1
  42. package/packages/client/dist/commands/legacy-story-pr.js +276 -1
  43. package/packages/client/dist/commands/mutation-qa-checkpoint.js +285 -5
  44. package/packages/client/dist/commands/mutation-qa-gate.js +54 -1
  45. package/packages/client/dist/commands/mutation-qa-git.js +41 -1
  46. package/packages/client/dist/commands/mutation-qa-policy.js +102 -1
  47. package/packages/client/dist/commands/mutation-qa-run.js +219 -3
  48. package/packages/client/dist/commands/mutation-qa-verdict.js +149 -1
  49. package/packages/client/dist/commands/mutation-qa.js +220 -1
  50. package/packages/client/dist/commands/native-agent.js +136 -2
  51. package/packages/client/dist/commands/planning-diagnosis.js +43 -1
  52. package/packages/client/dist/commands/planning-generation.js +53 -1
  53. package/packages/client/dist/commands/planning-memory.js +40 -1
  54. package/packages/client/dist/commands/planning-research.js +42 -1
  55. package/packages/client/dist/commands/private-session.js +75 -1
  56. package/packages/client/dist/commands/property-qa.js +139 -1
  57. package/packages/client/dist/commands/qa-control.js +16 -1
  58. package/packages/client/dist/commands/qa-scan-browser-launch.js +55 -1
  59. package/packages/client/dist/commands/qa-scan-browser-route.js +28 -1
  60. package/packages/client/dist/commands/qa-scan-capture.js +663 -5
  61. package/packages/client/dist/commands/qa-scan-discovery.js +376 -3
  62. package/packages/client/dist/commands/qa-scan-review.js +826 -5
  63. package/packages/client/dist/commands/qa-synthetic-backend-capture.js +266 -1
  64. package/packages/client/dist/commands/qa-synthetic-backend-review.js +297 -1
  65. package/packages/client/dist/commands/qa-synthetic-backend.js +340 -2
  66. package/packages/client/dist/commands/qa-synthetic-broker-port.js +85 -1
  67. package/packages/client/dist/commands/qa-synthetic-browser.js +39 -1
  68. package/packages/client/dist/commands/refactor-characterization.js +671 -21
  69. package/packages/client/dist/commands/refactor-commit.js +399 -13
  70. package/packages/client/dist/commands/refactor-control.js +142 -3
  71. package/packages/client/dist/commands/refactor-cpp-assertions.js +93 -3
  72. package/packages/client/dist/commands/refactor-review.js +283 -5
  73. package/packages/client/dist/commands/refactor-root.js +588 -7
  74. package/packages/client/dist/commands/refresh-memory.js +156 -3
  75. package/packages/client/dist/commands/shared-architecture-non-ui.js +24 -1
  76. package/packages/client/dist/commands/story-checkpoint.js +171 -1
  77. package/packages/client/dist/config/profile-directory.js +13 -1
  78. package/packages/client/dist/config/resolver-selection.js +278 -1
  79. package/packages/client/dist/config/secure-config.js +281 -12
  80. package/packages/client/dist/config.js +223 -2
  81. package/packages/client/dist/constants.js +25 -1
  82. package/packages/client/dist/context/context-collector.js +222 -2
  83. package/packages/client/dist/context/context-sanitizer.js +145 -1
  84. package/packages/client/dist/continuity/autonomous-governance.js +285 -1
  85. package/packages/client/dist/continuity/continuity-client-state-store.js +1587 -1
  86. package/packages/client/dist/continuity/invoke-hooks.js +129 -1
  87. package/packages/client/dist/continuity/migrations/001-initial-schema.js +12 -2
  88. package/packages/client/dist/continuity/migrations/002-processing-output-summary-indexes.js +12 -2
  89. package/packages/client/dist/continuity/migrations/003-headless-execution-attempts.js +12 -2
  90. package/packages/client/dist/continuity/migrations/004-outbox-delivery-state.js +12 -2
  91. package/packages/client/dist/continuity/migrations/005-bounded-headless-queue.js +12 -2
  92. package/packages/client/dist/continuity/migrations/006-native-agent-dispatches.js +10 -2
  93. package/packages/client/dist/continuity/native-agent-store.js +69 -1
  94. package/packages/client/dist/continuity/native-agent-types.js +90 -1
  95. package/packages/client/dist/continuity/outbox.js +117 -1
  96. package/packages/client/dist/continuity/runner-bootstrap-policy.js +172 -1
  97. package/packages/client/dist/continuity/sqlite-store.js +2536 -81
  98. package/packages/client/dist/effects/invoke-effect-gateways.js +62 -1
  99. package/packages/client/dist/errors/error-messages.js +228 -2
  100. package/packages/client/dist/errors/frontmatter-diagnostics.js +125 -1
  101. package/packages/client/dist/evidence/collector.js +347 -1
  102. package/packages/client/dist/evidence/index.js +1 -1
  103. package/packages/client/dist/evidence/types.js +2 -0
  104. package/packages/client/dist/fs/atomic-state-replace.js +152 -1
  105. package/packages/client/dist/generated/command-registry.generated.js +4076 -1
  106. package/packages/client/dist/generated/public-projections.generated.js +149 -1
  107. package/packages/client/dist/git/direct-yolo-c01-retry.js +138 -4
  108. package/packages/client/dist/git/direct-yolo-checkpoint.js +1234 -4
  109. package/packages/client/dist/git/git-lifecycle-step-ids.js +14 -1
  110. package/packages/client/dist/git/git-lifecycle-store.js +1938 -9
  111. package/packages/client/dist/git/legacy-story-branch-checkpoint.js +259 -9
  112. package/packages/client/dist/git/legacy-story-branch-setup.js +348 -4
  113. package/packages/client/dist/git/legacy-story-pr.js +3538 -70
  114. package/packages/client/dist/git/secure-filesystem-boundary.js +182 -5
  115. package/packages/client/dist/graph-retrieval/pre-command-hook.js +284 -1
  116. package/packages/client/dist/graph-retrieval/shared-graph-retrieval-contract.js +237 -1
  117. package/packages/client/dist/i18n/first-run.js +60 -2
  118. package/packages/client/dist/index.js +47 -1
  119. package/packages/client/dist/invocation/invoke-input.js +24 -1
  120. package/packages/client/dist/license/index.js +5 -1
  121. package/packages/client/dist/license/license-client.js +304 -1
  122. package/packages/client/dist/machine/fingerprint.js +163 -2
  123. package/packages/client/dist/machine/index.js +5 -1
  124. package/packages/client/dist/memory/project-memory-path-scope.js +62 -1
  125. package/packages/client/dist/memory/project-memory-writer.js +1007 -40
  126. package/packages/client/dist/memory/shared-project-memory-types.js +253 -2
  127. package/packages/client/dist/migrations/project-identity-capability.js +50 -1
  128. package/packages/client/dist/migrations/project-identity.js +493 -7
  129. package/packages/client/dist/migrations/state-json.js +344 -4
  130. package/packages/client/dist/policy/architecture-policy.js +184 -2
  131. package/packages/client/dist/policy/index.js +7 -1
  132. package/packages/client/dist/policy/shared-policy-types.js +38 -0
  133. package/packages/client/dist/policy/subagent-approval-policy.js +55 -1
  134. package/packages/client/dist/private-execution/clean-baseline.js +279 -2
  135. package/packages/client/dist/private-execution/codex-executor.js +574 -4
  136. package/packages/client/dist/private-execution/codex-host-runtime.js +137 -1
  137. package/packages/client/dist/private-execution/codex-lifecycle-guard.js +97 -1
  138. package/packages/client/dist/private-execution/codex-scoped-permissions.js +128 -1
  139. package/packages/client/dist/private-execution/delivery.js +410 -13
  140. package/packages/client/dist/private-execution/diagnosis-root-review.js +294 -2
  141. package/packages/client/dist/private-execution/frozen-handoff.js +19 -6
  142. package/packages/client/dist/private-execution/implementation-validation.js +106 -2
  143. package/packages/client/dist/private-execution/isolated-admission.js +1432 -23
  144. package/packages/client/dist/private-execution/isolated-session.js +725 -5
  145. package/packages/client/dist/private-execution/isolated-workspace.js +122 -1
  146. package/packages/client/dist/private-execution/pact-consumer-runtime.js +409 -3
  147. package/packages/client/dist/private-execution/pact-test-source.js +258 -1
  148. package/packages/client/dist/private-execution/pact-toolchain.js +290 -3
  149. package/packages/client/dist/private-execution/pact-write-set.js +172 -1
  150. package/packages/client/dist/private-execution/planning-diagnosis-checkpoint.js +406 -5
  151. package/packages/client/dist/private-execution/planning-generation-checkpoint.js +462 -5
  152. package/packages/client/dist/private-execution/planning-memory-checkpoint.js +139 -3
  153. package/packages/client/dist/private-execution/planning-research-checkpoint.js +325 -4
  154. package/packages/client/dist/private-execution/private-report-store.js +42 -1
  155. package/packages/client/dist/private-execution/property-test-candidate.js +103 -1
  156. package/packages/client/dist/private-execution/property-test-choices.js +147 -3
  157. package/packages/client/dist/private-execution/property-test-plan.js +271 -7
  158. package/packages/client/dist/private-execution/property-test-review.js +258 -4
  159. package/packages/client/dist/private-execution/property-test-runtime.js +372 -9
  160. package/packages/client/dist/private-execution/property-test-source.js +139 -1
  161. package/packages/client/dist/private-execution/root-checkpoint.js +80 -1
  162. package/packages/client/dist/private-execution/root-memory-git-evidence.js +135 -3
  163. package/packages/client/dist/private-execution/root-memory-recovery.js +93 -1
  164. package/packages/client/dist/private-execution/root-memory-request.js +29 -1
  165. package/packages/client/dist/private-execution/root-memory-scope.js +178 -1
  166. package/packages/client/dist/private-execution/root-memory-writer.js +102 -1
  167. package/packages/client/dist/private-execution/session-lease.js +63 -1
  168. package/packages/client/dist/private-execution/shared-private-admission-types.js +50 -1
  169. package/packages/client/dist/private-execution/shared-project-validation.js +66 -1
  170. package/packages/client/dist/private-execution/shared-root-memory-types.js +61 -1
  171. package/packages/client/dist/private-execution/ux-source-validation.js +372 -1
  172. package/packages/client/dist/private-execution/ux-write-set.js +191 -2
  173. package/packages/client/dist/resilience/circuit-breaker.js +170 -1
  174. package/packages/client/dist/resilience/degradation-manager.js +164 -1
  175. package/packages/client/dist/resilience/freshness-indicator.js +100 -1
  176. package/packages/client/dist/resilience/index.js +8 -1
  177. package/packages/client/dist/resilience/recovery-detector.js +74 -1
  178. package/packages/client/dist/resolvers/asset-resolver.js +13 -0
  179. package/packages/client/dist/resolvers/local-resolver.js +255 -8
  180. package/packages/client/dist/resolvers/remote-resolver.js +233 -1
  181. package/packages/client/dist/runner/binary.js +404 -1
  182. package/packages/client/dist/runner/cli.js +1571 -17
  183. package/packages/client/dist/runner/headless/adapters.js +49 -1
  184. package/packages/client/dist/runner/headless/claude-code-adapter.js +79 -1
  185. package/packages/client/dist/runner/headless/continuous-story-workspace.js +1628 -11
  186. package/packages/client/dist/runner/headless/epic-git-reconciliation-inventory.js +69 -1
  187. package/packages/client/dist/runner/headless/epic-merge-candidate-qa.js +110 -2
  188. package/packages/client/dist/runner/headless/epic-terminal-git-cli-adapter.js +1236 -8
  189. package/packages/client/dist/runner/headless/epic-terminal-git-runner.js +318 -2
  190. package/packages/client/dist/runner/headless/fake-adapter.js +62 -1
  191. package/packages/client/dist/runner/headless/managed-profile.js +132 -1
  192. package/packages/client/dist/runner/headless/opencode-adapter.js +145 -2
  193. package/packages/client/dist/runner/headless/prepared-story-bundle.js +43 -1
  194. package/packages/client/dist/runner/headless/resolver.js +231 -1
  195. package/packages/client/dist/runner/headless/run-yolo.js +885 -1
  196. package/packages/client/dist/runner/headless/run-yoloop.d.ts +4 -1
  197. package/packages/client/dist/runner/headless/run-yoloop.js +2574 -2
  198. package/packages/client/dist/runner/headless/types.js +574 -2
  199. package/packages/client/dist/runner/local-console.js +396 -13
  200. package/packages/client/dist/runner/portal-sync-worker.js +1487 -1
  201. package/packages/client/dist/runner/project-identity.js +106 -1
  202. package/packages/client/dist/runner/scheduler.js +995 -7
  203. package/packages/client/dist/runner-cli.js +18 -2
  204. package/packages/client/dist/state/invocation-shape.js +13 -1
  205. package/packages/client/dist/state/project-state-snapshot.js +1677 -1
  206. package/packages/client/dist/state/state-json-repair.js +785 -3
  207. package/packages/client/dist/state/structural-dag-projection.js +118 -1
  208. package/packages/client/dist/telemetry/index.js +5 -1
  209. package/packages/client/dist/telemetry/offline-queue.js +131 -1
  210. package/packages/client/dist/tier/index.js +5 -1
  211. package/packages/client/dist/tier/tier-aware-client.js +405 -1
  212. package/packages/client/dist/types/index.js +38 -1
  213. package/packages/client/dist/version.js +27 -1
  214. package/packages/client/dist/yolo/change-evidence-collector.js +126 -1
  215. package/packages/client/dist/yolo/invoke-envelope-capability.js +62 -1
  216. package/packages/client/dist/yolo/spec-envelope-collector.js +185 -5
  217. package/packages/client/dist/yoloop/discovery-hook.js +300 -2
  218. package/packages/client/dist/yoloop/index.js +8 -1
  219. package/packages/client/dist/yoloop/invoke-hooks.js +669 -12
  220. package/packages/client/dist/yoloop/shared-discover-epics.js +1007 -1
  221. package/packages/client/dist/yoloop/shared-yoloop-types.js +33 -1
  222. package/packages/client/dist/yoloop/target-normalization.js +180 -1
  223. package/packages/client/dist/yoloop/yoloop-client-state-store.js +1723 -1
  224. package/packages/shared/dist/compatibility/index.js +476 -0
  225. package/packages/shared/dist/yoloop/release-blocked.js +653 -0
  226. package/targets-stubs/antigravity/gemini.md +1 -1
  227. package/targets-stubs/antigravity/skill/SKILL.md +3 -2
  228. package/targets-stubs/claude-code/neocortex-root.agent.yaml +1 -1
  229. package/targets-stubs/claude-code/neocortex-root.md +5 -5
  230. package/targets-stubs/claude-code/neocortex.agent.yaml +1 -1
  231. package/targets-stubs/claude-code/neocortex.md +8 -9
  232. package/targets-stubs/codex/AGENTS.md +3 -3
  233. package/targets-stubs/cursor/agent.md +4 -3
  234. package/targets-stubs/gemini-cli/agent.md +5 -4
  235. package/targets-stubs/opencode/neocortex-root.md +3 -3
  236. package/targets-stubs/vscode/neocortex.agent.md +5 -4
@@ -1 +1,100 @@
1
- import{isDeepStrictEqual as d}from"node:util";import{ARCHITECTURE_NON_UI_COMMANDS as R,ARCHITECTURE_PUBLIC_COMMANDS as A,parseArchitectureNonUiScopeReceipt as y}from"./shared-architecture-non-ui.js";const a=e=>!!e&&typeof e=="object"&&!Array.isArray(e),r=R;function C(e){const t=y(e.nonUiScopeReceipt);return t&&t.targetEpicId===e.targetEpicId&&t.graphRevision===e.graphRevision&&a(e.accounting)&&t.accountingId===e.accounting.accountingId&&a(e.evidenceExpectation)&&t.rootInputSha256===e.evidenceExpectation.inputHash?t:void 0}function D(e){if(e.nonUiScopeReceipt===void 0)return A.length-1;if(!C(e))throw new Error("architecture-non-ui-scope-invalid");return r.length-1}function f(e,t,c,n){return Array.isArray(e)&&e.length===t&&e.every((i,o)=>a(i)&&i.targetEpicId===c&&i.stageCommand===r[o]&&a(i.completionEvidence)&&a(i.validationEvidence)&&i.completionEvidence.stageCommand===i.stageCommand&&i.completionEvidence.status==="succeeded"&&i.validationEvidence.stageCommand===i.stageCommand&&i.validationEvidence.status==="passed"&&i.completionEvidence.targetEpicId===c&&i.validationEvidence.targetEpicId===c&&i.completionEvidence.artifactHash===i.validationEvidence.artifactHash&&a(i.validationEvidence.isolated)&&a(i.validationEvidence.regression)&&i.validationEvidence.isolated.graphHash===n&&i.validationEvidence.regression.graphHash===n)}function H(e){const t=e.reviewDecision,c=e.completionEvidence,n=e.validationEvidence;return a(t)&&a(c)&&a(n)&&t.schemaVersion==="ArchitectureReviewDecision/1"&&t.decision==="approved"&&t.targetEpicId===e.targetEpicId&&t.graphRevision===e.graphRevision&&t.artifactHash===c.artifactHash&&t.artifactHash===n.artifactHash&&t.completionReceiptId===c.receiptId&&t.validationReceiptId===n.receiptId}function O(e,t,c=!1){const n=t.checkpoint;if(!a(n))return;const i=C(n);if(!i||i.targetEpicId!==e.targetEpicId||i.graphRevision!==e.graphRevision||!a(e.evidenceExpectation)||i.rootInputSha256!==e.evidenceExpectation.inputHash||!a(e.accounting)||i.accountingId!==e.accounting.accountingId||e.nonUiScopeReceipt!==void 0&&!d(e.nonUiScopeReceipt,i))return;const o=e.acceptedStages,s=n.acceptedStages,l=r.indexOf(String(e.currentStageCommand)),p=e.targetEpicId,u=e.graphRevision,g=S=>d(n[S],e[S]),h=e.childStatus===void 0&&e.completionEvidence===void 0&&e.validationEvidence===void 0,E=n.childStatus===void 0&&n.completionEvidence===void 0&&n.validationEvidence===void 0;if(e.currentStageCommand==="arch-design-system"&&e.continuationState==="advance"&&h&&E&&n.currentStageCommand==="arch-performance"&&n.continuationState==="advance"&&t.nextAction==="resume"&&f(o,r.indexOf("arch-performance"),p,u)&&d(s,o))return"advance";if(l<r.indexOf("arch-security")||e.nonUiScopeReceipt===void 0&&e.currentStageCommand!=="arch-security")return;if(e.continuationState==="complete"&&e.currentStageCommand==="update-memory"&&n.continuationState==="complete"&&n.currentStageCommand==="update-memory"&&t.nextAction==="complete"&&f(o,r.length,p,u)&&d(s,o)&&["childStatus","completionEvidence","validationEvidence","reviewDecision","terminalMemoryCheckpoint"].every(g)&&c)return"complete-replay";if(!f(o,l,p,u))return;if(h&&E&&["advance","delegate"].includes(String(e.continuationState))&&n.currentStageCommand===e.currentStageCommand&&n.continuationState==="delegate"&&t.nextAction==="delegate"&&d(s,o)&&g("reviewDecision"))return"delegate";const m=e.completionEvidence,v=e.validationEvidence;if(e.childStatus!=="succeeded"||!a(m)||!a(v)||m.status!=="succeeded"||v.status!=="passed"||m.stageCommand!==e.currentStageCommand||v.stageCommand!==e.currentStageCommand||m.targetEpicId!==p||v.targetEpicId!==p||m.artifactHash!==v.artifactHash)return;if(e.currentStageCommand==="arch-review"&&!H(e))return n.currentStageCommand==="arch-review"&&n.continuationState==="ask-user"&&t.nextAction==="ask-user"&&d(s,o)&&["childStatus","completionEvidence","validationEvidence"].every(g)&&d(n.questionIds,["ARCH-REVIEW-A09-APPROVAL"])&&e.reviewDecision===void 0?"ask-user":void 0;if(e.currentStageCommand==="arch-review"&&(e.continuationState!=="ask-user"||!d(e.questionIds,["ARCH-REVIEW-A09-APPROVAL"])))return;const I=[...o,{targetEpicId:p,stageCommand:e.currentStageCommand,completionEvidence:m,validationEvidence:v}];if(!(!d(s,I)||!g("reviewDecision"))){if(e.currentStageCommand==="update-memory")return n.currentStageCommand==="update-memory"&&n.continuationState==="complete"&&t.nextAction==="complete"&&["childStatus","completionEvidence","validationEvidence","terminalMemoryCheckpoint"].every(g)&&c?"complete":void 0;if(E&&n.currentStageCommand===r[l+1]&&n.continuationState==="advance"&&t.nextAction==="resume")return"advance"}}export{D as architectureMemoryPredecessorCount,O as classifyNonUiArchitectureTransition};
1
+ /** Closed client projection. Signature authenticity remains a server-only check. */
2
+ import { isDeepStrictEqual } from 'node:util';
3
+ import { ARCHITECTURE_NON_UI_COMMANDS, ARCHITECTURE_PUBLIC_COMMANDS, parseArchitectureNonUiScopeReceipt } from './shared-architecture-non-ui.js';
4
+ const obj = (x) => !!x && typeof x === 'object' && !Array.isArray(x);
5
+ const commands = ARCHITECTURE_NON_UI_COMMANDS;
6
+ function boundScope(execution) {
7
+ const scope = parseArchitectureNonUiScopeReceipt(execution.nonUiScopeReceipt);
8
+ return scope && scope.targetEpicId === execution.targetEpicId && scope.graphRevision === execution.graphRevision
9
+ && obj(execution.accounting) && scope.accountingId === execution.accounting.accountingId
10
+ && obj(execution.evidenceExpectation) && scope.rootInputSha256 === execution.evidenceExpectation.inputHash ? scope : undefined;
11
+ }
12
+ export function architectureMemoryPredecessorCount(execution) {
13
+ if (execution.nonUiScopeReceipt === undefined)
14
+ return ARCHITECTURE_PUBLIC_COMMANDS.length - 1;
15
+ if (!boundScope(execution))
16
+ throw new Error('architecture-non-ui-scope-invalid');
17
+ return commands.length - 1;
18
+ }
19
+ function prefix(rows, n, target, graph) {
20
+ return Array.isArray(rows) && rows.length === n && rows.every((r, i) => obj(r) && r.targetEpicId === target && r.stageCommand === commands[i]
21
+ && obj(r.completionEvidence) && obj(r.validationEvidence)
22
+ && r.completionEvidence.stageCommand === r.stageCommand && r.completionEvidence.status === 'succeeded'
23
+ && r.validationEvidence.stageCommand === r.stageCommand && r.validationEvidence.status === 'passed'
24
+ && r.completionEvidence.targetEpicId === target && r.validationEvidence.targetEpicId === target
25
+ && r.completionEvidence.artifactHash === r.validationEvidence.artifactHash
26
+ && obj(r.validationEvidence.isolated) && obj(r.validationEvidence.regression)
27
+ && r.validationEvidence.isolated.graphHash === graph && r.validationEvidence.regression.graphHash === graph);
28
+ }
29
+ function approvedReview(r) {
30
+ const d = r.reviewDecision, c = r.completionEvidence, v = r.validationEvidence;
31
+ return obj(d) && obj(c) && obj(v) && d.schemaVersion === 'ArchitectureReviewDecision/1' && d.decision === 'approved'
32
+ && d.targetEpicId === r.targetEpicId && d.graphRevision === r.graphRevision && d.artifactHash === c.artifactHash
33
+ && d.artifactHash === v.artifactHash && d.completionReceiptId === c.receiptId && d.validationReceiptId === v.receiptId;
34
+ }
35
+ export function classifyNonUiArchitectureTransition(request, execution, memoryReceiptValid = false) {
36
+ const checkpoint = execution.checkpoint;
37
+ if (!obj(checkpoint))
38
+ return;
39
+ const scope = boundScope(checkpoint);
40
+ if (!scope || scope.targetEpicId !== request.targetEpicId || scope.graphRevision !== request.graphRevision
41
+ || !obj(request.evidenceExpectation) || scope.rootInputSha256 !== request.evidenceExpectation.inputHash
42
+ || !obj(request.accounting) || scope.accountingId !== request.accounting.accountingId
43
+ || request.nonUiScopeReceipt !== undefined && !isDeepStrictEqual(request.nonUiScopeReceipt, scope))
44
+ return;
45
+ const old = request.acceptedStages, next = checkpoint.acceptedStages, idx = commands.indexOf(String(request.currentStageCommand));
46
+ const target = request.targetEpicId, graph = request.graphRevision;
47
+ const same = (key) => isDeepStrictEqual(checkpoint[key], request[key]);
48
+ const idle = request.childStatus === undefined && request.completionEvidence === undefined && request.validationEvidence === undefined;
49
+ const cleared = checkpoint.childStatus === undefined && checkpoint.completionEvidence === undefined && checkpoint.validationEvidence === undefined;
50
+ if (request.currentStageCommand === 'arch-design-system' && request.continuationState === 'advance' && idle && cleared
51
+ && checkpoint.currentStageCommand === 'arch-performance' && checkpoint.continuationState === 'advance'
52
+ && execution.nextAction === 'resume' && prefix(old, commands.indexOf('arch-performance'), target, graph) && isDeepStrictEqual(next, old))
53
+ return 'advance';
54
+ if (idx < commands.indexOf('arch-security'))
55
+ return;
56
+ if (request.nonUiScopeReceipt === undefined && request.currentStageCommand !== 'arch-security')
57
+ return;
58
+ if (request.continuationState === 'complete' && request.currentStageCommand === 'update-memory'
59
+ && checkpoint.continuationState === 'complete' && checkpoint.currentStageCommand === 'update-memory'
60
+ && execution.nextAction === 'complete' && prefix(old, commands.length, target, graph) && isDeepStrictEqual(next, old)
61
+ && ['childStatus', 'completionEvidence', 'validationEvidence', 'reviewDecision', 'terminalMemoryCheckpoint'].every(same)
62
+ && memoryReceiptValid)
63
+ return 'complete-replay';
64
+ if (!prefix(old, idx, target, graph))
65
+ return;
66
+ if (idle && cleared && ['advance', 'delegate'].includes(String(request.continuationState))
67
+ && checkpoint.currentStageCommand === request.currentStageCommand && checkpoint.continuationState === 'delegate'
68
+ && execution.nextAction === 'delegate' && isDeepStrictEqual(next, old) && same('reviewDecision'))
69
+ return 'delegate';
70
+ const c = request.completionEvidence, v = request.validationEvidence;
71
+ if (request.childStatus !== 'succeeded' || !obj(c) || !obj(v) || c.status !== 'succeeded' || v.status !== 'passed'
72
+ || c.stageCommand !== request.currentStageCommand || v.stageCommand !== request.currentStageCommand
73
+ || c.targetEpicId !== target || v.targetEpicId !== target || c.artifactHash !== v.artifactHash)
74
+ return;
75
+ if (request.currentStageCommand === 'arch-review' && !approvedReview(request)) {
76
+ if (checkpoint.currentStageCommand === 'arch-review' && checkpoint.continuationState === 'ask-user'
77
+ && execution.nextAction === 'ask-user' && isDeepStrictEqual(next, old)
78
+ && ['childStatus', 'completionEvidence', 'validationEvidence'].every(same)
79
+ && isDeepStrictEqual(checkpoint.questionIds, ['ARCH-REVIEW-A09-APPROVAL'])
80
+ && request.reviewDecision === undefined)
81
+ return 'ask-user';
82
+ return;
83
+ }
84
+ if (request.currentStageCommand === 'arch-review' && (request.continuationState !== 'ask-user'
85
+ || !isDeepStrictEqual(request.questionIds, ['ARCH-REVIEW-A09-APPROVAL'])))
86
+ return;
87
+ const expected = [...old, { targetEpicId: target, stageCommand: request.currentStageCommand, completionEvidence: c, validationEvidence: v }];
88
+ if (!isDeepStrictEqual(next, expected) || !same('reviewDecision'))
89
+ return;
90
+ if (request.currentStageCommand === 'update-memory') {
91
+ if (checkpoint.currentStageCommand === 'update-memory' && checkpoint.continuationState === 'complete'
92
+ && execution.nextAction === 'complete' && ['childStatus', 'completionEvidence', 'validationEvidence', 'terminalMemoryCheckpoint'].every(same)
93
+ && memoryReceiptValid)
94
+ return 'complete';
95
+ return;
96
+ }
97
+ if (cleared && checkpoint.currentStageCommand === commands[idx + 1] && checkpoint.continuationState === 'advance'
98
+ && execution.nextAction === 'resume')
99
+ return 'advance';
100
+ }
@@ -1 +1,51 @@
1
- import{createHash as f}from"node:crypto";import{execFileSync as g}from"node:child_process";import{lstatSync as u,realpathSync as n}from"node:fs";import{join as t,resolve as d}from"node:path";import{resolveClientPreFlightTrigger as v}from"../tier/tier-aware-client.js";const w=/^P[1-9][0-9]{0,11}$/,E=/^[a-f0-9]{40,64}$/;function S(s){const r=s.match(/^\s*(\*?[^\s]+)[ \t]+"[^"\n]{1,4096}"[ \t]+@docs\/epics\/epic-(P[1-9][0-9]{0,11})\.md\s*$/);return r&&v(r[1])==="arch-plan"?r[2]:void 0}function A(s,r){if(!w.test(r))throw new Error("architecture-root-epic-binding-invalid");const i=d(s),e=`docs/epics/epic-${r}.md`,a=t(i,e);try{if(n(i)!==i)throw new Error("architecture-root-epic-binding-invalid");if(n(t(i,"docs"))!==t(i,"docs")||n(t(i,"docs","epics"))!==t(i,"docs","epics")||n(a)!==a)throw new Error("architecture-root-epic-binding-invalid");const h=u(a);if(!h.isFile()||h.isSymbolicLink()||h.size>256*1024)throw new Error("architecture-root-epic-binding-invalid");const o=l=>g("git",[...l],{cwd:i,encoding:"utf8",stdio:["ignore","pipe","ignore"],maxBuffer:1024*1024}).trim();if(d(o(["rev-parse","--show-toplevel"]))!==i)throw new Error("architecture-root-epic-binding-invalid");const c=o(["rev-parse","--verify",`HEAD:${e}`]),p=o(["hash-object","--",e]),m=o(["ls-files","--stage","--",e]).match(/^100644 ([a-f0-9]{40,64}) 0\t/);if(!E.test(c)||p!==c||m?.[1]!==c)throw new Error("architecture-root-epic-binding-invalid");return f("sha256").update(`architecture-committed-epic-v1\0${r}\0${c}`).digest("hex")}catch{throw new Error("architecture-root-epic-binding-invalid")}}export{A as deriveCommittedArchitectureEpicGraphRevision,S as explicitArchitectureEpicTarget};
1
+ /**
2
+ * A first architecture root may bind only to an explicitly selected,
3
+ * committed epic. The digest is stable across stage commits but changes when
4
+ * the epic source changes; it never grants child, Git or billing authority.
5
+ */
6
+ import { createHash } from 'node:crypto';
7
+ import { execFileSync } from 'node:child_process';
8
+ import { lstatSync, realpathSync } from 'node:fs';
9
+ import { join, resolve } from 'node:path';
10
+ import { resolveClientPreFlightTrigger } from '../tier/tier-aware-client.js';
11
+ const EPIC_ID = /^P[1-9][0-9]{0,11}$/;
12
+ const OID = /^[a-f0-9]{40,64}$/;
13
+ export function explicitArchitectureEpicTarget(args) {
14
+ const match = args.match(/^\s*(\*?[^\s]+)[ \t]+"[^"\n]{1,4096}"[ \t]+@docs\/epics\/epic-(P[1-9][0-9]{0,11})\.md\s*$/);
15
+ return match && resolveClientPreFlightTrigger(match[1]) === 'arch-plan' ? match[2] : undefined;
16
+ }
17
+ export function deriveCommittedArchitectureEpicGraphRevision(projectRoot, epicId) {
18
+ if (!EPIC_ID.test(epicId))
19
+ throw new Error('architecture-root-epic-binding-invalid');
20
+ const root = resolve(projectRoot);
21
+ const relativePath = `docs/epics/epic-${epicId}.md`;
22
+ const path = join(root, relativePath);
23
+ try {
24
+ if (realpathSync(root) !== root)
25
+ throw new Error('architecture-root-epic-binding-invalid');
26
+ if (realpathSync(join(root, 'docs')) !== join(root, 'docs')
27
+ || realpathSync(join(root, 'docs', 'epics')) !== join(root, 'docs', 'epics')
28
+ || realpathSync(path) !== path)
29
+ throw new Error('architecture-root-epic-binding-invalid');
30
+ const entry = lstatSync(path);
31
+ if (!entry.isFile() || entry.isSymbolicLink() || entry.size > 256 * 1024) {
32
+ throw new Error('architecture-root-epic-binding-invalid');
33
+ }
34
+ const run = (arguments_) => execFileSync('git', [...arguments_], {
35
+ cwd: root, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'], maxBuffer: 1024 * 1024,
36
+ }).trim();
37
+ if (resolve(run(['rev-parse', '--show-toplevel'])) !== root) {
38
+ throw new Error('architecture-root-epic-binding-invalid');
39
+ }
40
+ const committed = run(['rev-parse', '--verify', `HEAD:${relativePath}`]);
41
+ const working = run(['hash-object', '--', relativePath]);
42
+ const staged = run(['ls-files', '--stage', '--', relativePath]).match(/^100644 ([a-f0-9]{40,64}) 0\t/);
43
+ if (!OID.test(committed) || working !== committed || staged?.[1] !== committed) {
44
+ throw new Error('architecture-root-epic-binding-invalid');
45
+ }
46
+ return createHash('sha256').update(`architecture-committed-epic-v1\0${epicId}\0${committed}`).digest('hex');
47
+ }
48
+ catch {
49
+ throw new Error('architecture-root-epic-binding-invalid');
50
+ }
51
+ }
@@ -1,2 +1,112 @@
1
- import{readdir as y,stat as g}from"node:fs/promises";import{join as f}from"node:path";async function T(t){const r=t.staleThresholdMs??864e5;let e=0,s=0,c=0,i=null,a=null;try{const u=(await y(t.cacheDir)).filter(l=>l.endsWith(".enc"));e=u.length;const h=Date.now();for(const l of u)try{const m=f(t.cacheDir,l),d=await g(m);s+=d.size;const n=d.mtime;(!i||n<i)&&(i=n),(!a||n>a)&&(a=n),h-n.getTime()>r&&c++}catch{}}catch{}const S=t.circuitBreaker.getState().state;let o=0;try{o=(await t.telemetryQueue.getStats()).count}catch{}return{totalEntries:e,totalSizeBytes:s,totalSizeFormatted:$(s),oldestEntry:i,newestEntry:a,staleEntries:c,circuitState:S,lastSync:a,telemetryQueueSize:o}}function B(t){return["+-------------------------------------------------+","| NEOCORTEX CACHE STATUS |","+-------------------------------------------------+",`| Total entries: ${String(t.totalEntries).padEnd(29)}|`,`| Total size: ${t.totalSizeFormatted.padEnd(29)}|`,`| Oldest entry: ${(t.oldestEntry?.toISOString()??"N/A").padEnd(29)}|`,`| Newest entry: ${(t.newestEntry?.toISOString()??"N/A").padEnd(29)}|`,`| Stale entries: ${String(t.staleEntries).padEnd(29)}|`,"|-------------------------------------------------|",`| Circuit breaker: ${t.circuitState.padEnd(29)}|`,`| Last sync: ${(t.lastSync?.toISOString()??"N/A").padEnd(29)}|`,`| Telemetry queue: ${(t.telemetryQueueSize+" events").padEnd(29)}|`,"+-------------------------------------------------+"].join(`
2
- `)}function $(t){if(t===0)return"0 B";const r=["B","KB","MB","GB"],e=Math.floor(Math.log(t)/Math.log(1024));return`${(t/Math.pow(1024,e)).toFixed(e===0?0:1)} ${r[e]}`}export{B as formatCacheStatus,T as getCacheStatus};
1
+ /**
2
+ * @license FSL-1.1
3
+ * Copyright (c) 2026 OrNexus AI
4
+ *
5
+ * This file is part of Neocortex CLI, licensed under the
6
+ * Functional Source License, Version 1.1 (FSL-1.1).
7
+ *
8
+ * Change Date: February 20, 2029
9
+ * Change License: MIT
10
+ *
11
+ * See the LICENSE file in the project root for full license text.
12
+ */
13
+ /**
14
+ * @neocortex/client - Cache Status Command
15
+ *
16
+ * Displays comprehensive cache and circuit breaker status information.
17
+ * Shows entry count, total size, age range, stale entries, circuit state,
18
+ * and telemetry queue stats.
19
+ *
20
+ * Story 42.9 - AC7
21
+ */
22
+ import { readdir, stat } from 'node:fs/promises';
23
+ import { join } from 'node:path';
24
+ // ── Implementation ──────────────────────────────────────────────────────
25
+ /**
26
+ * Gather comprehensive cache status information.
27
+ */
28
+ export async function getCacheStatus(options) {
29
+ const staleThreshold = options.staleThresholdMs ?? 86_400_000; // 24h default
30
+ let totalEntries = 0;
31
+ let totalSizeBytes = 0;
32
+ let staleEntries = 0;
33
+ let oldestEntry = null;
34
+ let newestEntry = null;
35
+ try {
36
+ const entries = await readdir(options.cacheDir);
37
+ const encFiles = entries.filter((e) => e.endsWith('.enc'));
38
+ totalEntries = encFiles.length;
39
+ const now = Date.now();
40
+ for (const file of encFiles) {
41
+ try {
42
+ const filePath = join(options.cacheDir, file);
43
+ const fileStat = await stat(filePath);
44
+ totalSizeBytes += fileStat.size;
45
+ const mtime = fileStat.mtime;
46
+ if (!oldestEntry || mtime < oldestEntry)
47
+ oldestEntry = mtime;
48
+ if (!newestEntry || mtime > newestEntry)
49
+ newestEntry = mtime;
50
+ if (now - mtime.getTime() > staleThreshold) {
51
+ staleEntries++;
52
+ }
53
+ }
54
+ catch {
55
+ // Skip files that can't be stat'd
56
+ }
57
+ }
58
+ }
59
+ catch {
60
+ // Cache directory doesn't exist or can't be read
61
+ }
62
+ const circuitState = options.circuitBreaker.getState().state;
63
+ let telemetryQueueSize = 0;
64
+ try {
65
+ const queueStats = await options.telemetryQueue.getStats();
66
+ telemetryQueueSize = queueStats.count;
67
+ }
68
+ catch {
69
+ // Queue unavailable
70
+ }
71
+ return {
72
+ totalEntries,
73
+ totalSizeBytes,
74
+ totalSizeFormatted: formatBytes(totalSizeBytes),
75
+ oldestEntry,
76
+ newestEntry,
77
+ staleEntries,
78
+ circuitState,
79
+ lastSync: newestEntry, // Most recent cache write approximates last sync
80
+ telemetryQueueSize,
81
+ };
82
+ }
83
+ /**
84
+ * Format cache status as a human-readable string for terminal output.
85
+ */
86
+ export function formatCacheStatus(info) {
87
+ const lines = [
88
+ '+-------------------------------------------------+',
89
+ '| NEOCORTEX CACHE STATUS |',
90
+ '+-------------------------------------------------+',
91
+ `| Total entries: ${String(info.totalEntries).padEnd(29)}|`,
92
+ `| Total size: ${info.totalSizeFormatted.padEnd(29)}|`,
93
+ `| Oldest entry: ${(info.oldestEntry?.toISOString() ?? 'N/A').padEnd(29)}|`,
94
+ `| Newest entry: ${(info.newestEntry?.toISOString() ?? 'N/A').padEnd(29)}|`,
95
+ `| Stale entries: ${String(info.staleEntries).padEnd(29)}|`,
96
+ '|-------------------------------------------------|',
97
+ `| Circuit breaker: ${info.circuitState.padEnd(29)}|`,
98
+ `| Last sync: ${(info.lastSync?.toISOString() ?? 'N/A').padEnd(29)}|`,
99
+ `| Telemetry queue: ${(info.telemetryQueueSize + ' events').padEnd(29)}|`,
100
+ '+-------------------------------------------------+',
101
+ ];
102
+ return lines.join('\n');
103
+ }
104
+ // ── Helpers ─────────────────────────────────────────────────────────────
105
+ function formatBytes(bytes) {
106
+ if (bytes === 0)
107
+ return '0 B';
108
+ const units = ['B', 'KB', 'MB', 'GB'];
109
+ const i = Math.floor(Math.log(bytes) / Math.log(1024));
110
+ const value = bytes / Math.pow(1024, i);
111
+ return `${value.toFixed(i === 0 ? 0 : 1)} ${units[i]}`;
112
+ }
@@ -1 +1,88 @@
1
- import{SUBAGENT_APPROVAL_EVIDENCE as d,deriveSubagentHostApprovalPolicy as v}from"../policy/subagent-approval-policy.js";import{detectPlatform as m}from"../adapters/platform-detector.js";import{ApprovalPolicyConfigError as E,getSubagentApprovalPolicy as b,resetSubagentApprovalMode as y,setSubagentApprovalMode as P}from"../config.js";function $(a,r){const t={evidence:d,...a.resolution,auditEvent:a.auditEvent?.event};return r?JSON.stringify(t,null,2):[d,`requested=${t.requestedMode}`,`effective=${t.effectiveMode}`,`source=${t.source}`,`scope=${t.scope}`,`platform=${t.platformTarget}`,`reason=${t.effectiveReason}`,`fallback=${t.fallbackMode}`,`fallbackReason=${t.fallbackReasonCode??"none"}`].join(" ")}async function w(a,r={}){const t=r.stdout??console.log,n=r.stderr??console.error;let s="status",l,i=!1,f=!1;for(let e=0;e<a.length;e+=1){const o=a[e];if(o==="--json")i=!0;else if(o==="--platform-target"){if(l=a[e+1],e+=1,!l)return n("Error: --platform-target requires a value."),1}else if(!f&&(o==="status"||o==="max"||o==="standard"||o==="disabled"||o==="reset"))s=o,f=!0;else return n("Error: expected status, max, standard, disabled, or reset."),1}const p=r.env??process.env,u=m({cwd:r.cwd??process.cwd(),env:p,targetFlag:l}),g=v(u.targetId),c={configFilePath:r.configFilePath,platformTarget:u.targetId,hostPolicy:g,now:r.now};try{const e=s==="status"?b(c):s==="reset"?y(c):P(s,c);return t($(e,i)),0}catch(e){return e instanceof E?(n(`Error: ${e.reasonCode}`),1):(n("Error: approval-policy-update-failed"),1)}}export{w as configCliHandler};
1
+ import { SUBAGENT_APPROVAL_EVIDENCE, deriveSubagentHostApprovalPolicy, } from '../policy/subagent-approval-policy.js';
2
+ import { detectPlatform } from '../adapters/platform-detector.js';
3
+ import { ApprovalPolicyConfigError, getSubagentApprovalPolicy, resetSubagentApprovalMode, setSubagentApprovalMode, } from '../config.js';
4
+ function renderResult(result, json) {
5
+ const payload = {
6
+ evidence: SUBAGENT_APPROVAL_EVIDENCE,
7
+ ...result.resolution,
8
+ auditEvent: result.auditEvent?.event,
9
+ };
10
+ if (json)
11
+ return JSON.stringify(payload, null, 2);
12
+ return [
13
+ SUBAGENT_APPROVAL_EVIDENCE,
14
+ `requested=${payload.requestedMode}`,
15
+ `effective=${payload.effectiveMode}`,
16
+ `source=${payload.source}`,
17
+ `scope=${payload.scope}`,
18
+ `platform=${payload.platformTarget}`,
19
+ `reason=${payload.effectiveReason}`,
20
+ `fallback=${payload.fallbackMode}`,
21
+ `fallbackReason=${payload.fallbackReasonCode ?? 'none'}`,
22
+ ].join(' ');
23
+ }
24
+ export async function configCliHandler(args, dependencies = {}) {
25
+ const stdout = dependencies.stdout ?? console.log;
26
+ const stderr = dependencies.stderr ?? console.error;
27
+ let action = 'status';
28
+ let platformTarget;
29
+ let json = false;
30
+ let actionSeen = false;
31
+ for (let index = 0; index < args.length; index += 1) {
32
+ const value = args[index];
33
+ if (value === '--json') {
34
+ json = true;
35
+ }
36
+ else if (value === '--platform-target') {
37
+ platformTarget = args[index + 1];
38
+ index += 1;
39
+ if (!platformTarget) {
40
+ stderr('Error: --platform-target requires a value.');
41
+ return 1;
42
+ }
43
+ }
44
+ else if (!actionSeen &&
45
+ (value === 'status' ||
46
+ value === 'max' ||
47
+ value === 'standard' ||
48
+ value === 'disabled' ||
49
+ value === 'reset')) {
50
+ action = value;
51
+ actionSeen = true;
52
+ }
53
+ else {
54
+ stderr('Error: expected status, max, standard, disabled, or reset.');
55
+ return 1;
56
+ }
57
+ }
58
+ const env = dependencies.env ?? process.env;
59
+ const detection = detectPlatform({
60
+ cwd: dependencies.cwd ?? process.cwd(),
61
+ env,
62
+ targetFlag: platformTarget,
63
+ });
64
+ const hostPolicy = deriveSubagentHostApprovalPolicy(detection.targetId);
65
+ const options = {
66
+ configFilePath: dependencies.configFilePath,
67
+ platformTarget: detection.targetId,
68
+ hostPolicy,
69
+ now: dependencies.now,
70
+ };
71
+ try {
72
+ const result = action === 'status'
73
+ ? getSubagentApprovalPolicy(options)
74
+ : action === 'reset'
75
+ ? resetSubagentApprovalMode(options)
76
+ : setSubagentApprovalMode(action, options);
77
+ stdout(renderResult(result, json));
78
+ return 0;
79
+ }
80
+ catch (error) {
81
+ if (error instanceof ApprovalPolicyConfigError) {
82
+ stderr(`Error: ${error.reasonCode}`);
83
+ return 1;
84
+ }
85
+ stderr('Error: approval-policy-update-failed');
86
+ return 1;
87
+ }
88
+ }
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Read-only compatibility and release doctor (P223.02).
3
+ *
4
+ * The release contract is owned by P223.01. This command intentionally loads
5
+ * that authority through a narrow adapter instead of copying its validator.
6
+ * The dynamic boundary keeps this dependent story buildable while P223.01 is
7
+ * integrated in parallel.
8
+ */
9
+ export declare const DOCTOR_SCHEMA_VERSION: "CompatibilityReleaseDoctor/1.0";
10
+ export declare const DOCTOR_RESPONSE_SCHEMA_VERSION: "CompatibilityDoctorResponse/1.0";
11
+ export declare const DOCTOR_EXIT_CODES: Readonly<{
12
+ readonly SUCCESS: 0;
13
+ readonly BLOCKED: 1;
14
+ readonly USAGE: 2;
15
+ }>;
16
+ export declare const DOCTOR_REASON_CODES: Readonly<{
17
+ readonly HEALTHY: "doctor-healthy";
18
+ readonly OFFLINE: "doctor-offline";
19
+ readonly SERVER_UNREACHABLE: "server-unreachable";
20
+ readonly CLIENT_TOO_OLD: "client-too-old";
21
+ readonly SERVER_TOO_OLD: "server-too-old";
22
+ readonly PROTOCOL_MISMATCH: "protocol-mismatch";
23
+ readonly SCHEMA_MISMATCH: "schema-mismatch";
24
+ readonly CAPABILITY_MISMATCH: "capability-mismatch";
25
+ readonly REGISTRY_DRIFT: "registry-drift";
26
+ readonly MALFORMED_RESPONSE: "malformed-response";
27
+ readonly AUTHORITY_UNAVAILABLE: "compatibility-authority-unavailable";
28
+ readonly RELEASE_LIFECYCLE_UNAVAILABLE: "release-lifecycle-unavailable";
29
+ readonly REQUIRED_DIMENSION_BLOCKED: "required-release-dimension-blocked";
30
+ }>;
31
+ export type DoctorMode = 'online' | 'offline';
32
+ export type DoctorOverallStatus = 'healthy' | 'degraded' | 'incompatible';
33
+ export type DoctorCompatibilityStatus = 'compatible' | 'degraded' | 'incompatible' | 'unknown';
34
+ export type DoctorSeverity = 'error' | 'warning' | 'info';
35
+ export type ReleaseTruth = true | false | 'unknown';
36
+ export type ReleaseFreshness = 'fresh' | 'stale' | 'unknown';
37
+ export type ReleaseDimensionName = 'implementationComplete' | 'betaOperable' | 'releaseReady' | 'productionPromoted';
38
+ export type DoctorAffectedDimension = ReleaseDimensionName | 'compatibility' | 'releaseLifecycle';
39
+ export interface DoctorFinding {
40
+ readonly severity: DoctorSeverity;
41
+ readonly reasonCode: string;
42
+ readonly affectedDimension: DoctorAffectedDimension;
43
+ readonly evidenceRef: string | null;
44
+ readonly remediation: string;
45
+ }
46
+ export interface DoctorReleaseDimension {
47
+ readonly value: ReleaseTruth;
48
+ readonly freshness: ReleaseFreshness;
49
+ readonly reasonCodes: readonly string[];
50
+ readonly evidenceRefs: readonly string[];
51
+ }
52
+ export interface DoctorReport {
53
+ readonly schemaVersion: typeof DOCTOR_SCHEMA_VERSION;
54
+ readonly publicSafe: true;
55
+ readonly readOnly: true;
56
+ readonly mode: DoctorMode;
57
+ readonly overall: DoctorOverallStatus;
58
+ readonly exitCode: 0 | 1;
59
+ readonly compatibility: {
60
+ readonly status: DoctorCompatibilityStatus;
61
+ readonly clientVersion: string;
62
+ readonly serverVersion: string | null;
63
+ readonly protocolVersion: string | null;
64
+ readonly schemaVersions: readonly string[];
65
+ readonly capabilityIds: readonly string[];
66
+ readonly registry: {
67
+ readonly localVersion: string;
68
+ readonly localChecksum: string;
69
+ readonly remoteVersion: string | null;
70
+ readonly remoteChecksum: string | null;
71
+ readonly status: 'matched' | 'mismatched' | 'unknown';
72
+ };
73
+ };
74
+ readonly release: {
75
+ readonly candidateId: string | null;
76
+ readonly lineageSha256: string | null;
77
+ readonly requiredDimension: ReleaseDimensionName | null;
78
+ readonly dimensions: Readonly<Record<ReleaseDimensionName, DoctorReleaseDimension>>;
79
+ };
80
+ readonly findings: readonly DoctorFinding[];
81
+ }
82
+ interface CompatibilityAuthority {
83
+ readonly createCompatibilityOffer: (input: {
84
+ readonly clientVersion: string;
85
+ readonly registryVersion: string;
86
+ readonly registryChecksum: string;
87
+ }) => unknown;
88
+ readonly isCompatibilityResultV1: (value: unknown) => boolean;
89
+ readonly validateReleaseLifecycle: (value: unknown) => {
90
+ readonly accepted: boolean;
91
+ readonly reasonCodes: readonly string[];
92
+ readonly projection?: unknown;
93
+ };
94
+ readonly createReleaseLifecycleContext?: (input: {
95
+ readonly projectId: string;
96
+ readonly candidateId: string;
97
+ readonly lineageSha256: string;
98
+ }) => unknown;
99
+ }
100
+ interface DoctorFetchResponse {
101
+ readonly ok: boolean;
102
+ readonly status: number;
103
+ text(): Promise<string>;
104
+ }
105
+ type DoctorFetch = (url: string, init: RequestInit) => Promise<DoctorFetchResponse>;
106
+ export interface DoctorDependencies {
107
+ readonly fetch?: DoctorFetch;
108
+ readonly loadCompatibilityAuthority?: () => Promise<CompatibilityAuthority | null>;
109
+ readonly getClientVersion?: () => string;
110
+ readonly collectReleaseContext?: (projectRoot: string, authority: CompatibilityAuthority) => unknown | null;
111
+ readonly env?: Readonly<Record<string, string | undefined>>;
112
+ readonly stdout?: (message: string) => void;
113
+ readonly stderr?: (message: string) => void;
114
+ }
115
+ interface ParsedDoctorArgs {
116
+ readonly mode: DoctorMode;
117
+ readonly json: boolean;
118
+ readonly serverUrl: string;
119
+ readonly requiredDimension: ReleaseDimensionName | null;
120
+ /** Local-only selection root. It is never serialized or rendered. */
121
+ readonly projectRoot: string;
122
+ }
123
+ export declare function parseDoctorArgs(args: readonly string[], env?: Readonly<Record<string, string | undefined>>): ParsedDoctorArgs;
124
+ /** P223.01 integration seam. No fallback validator is maintained here. */
125
+ export declare function loadSharedCompatibilityAuthority(): Promise<CompatibilityAuthority | null>;
126
+ /**
127
+ * Resolve the current project to an opaque selector without repairing or
128
+ * writing state. Git output is consumed locally and only domain-separated
129
+ * hashes plus the already-public project ID cross the network boundary.
130
+ */
131
+ export declare function collectLocalReleaseLifecycleContext(projectRoot: string, authority: CompatibilityAuthority): unknown | null;
132
+ export declare function runDoctor(options: ParsedDoctorArgs, dependencies?: DoctorDependencies): Promise<DoctorReport>;
133
+ export declare function renderDoctorReport(report: DoctorReport): string;
134
+ export declare function doctorCliHandler(args: readonly string[], dependencies?: DoctorDependencies): Promise<number>;
135
+ export {};