clinkx 0.3.0 → 1.0.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.
- package/CHANGELOG.md +33 -0
- package/LICENSE +10 -0
- package/README.md +82 -26
- package/clinkx-workflows/dist/allowed-roots.d.ts +1 -0
- package/clinkx-workflows/dist/allowed-roots.js +5 -0
- package/clinkx-workflows/dist/allowed-roots.js.map +1 -0
- package/clinkx-workflows/dist/artifacts.d.ts +20 -1
- package/clinkx-workflows/dist/artifacts.js +38 -9
- package/clinkx-workflows/dist/artifacts.js.map +1 -1
- package/clinkx-workflows/dist/backend.d.ts +4 -0
- package/clinkx-workflows/dist/citation-check.d.ts +40 -0
- package/clinkx-workflows/dist/citation-check.js +348 -0
- package/clinkx-workflows/dist/citation-check.js.map +1 -0
- package/clinkx-workflows/dist/clink-client.d.ts +2 -1
- package/clinkx-workflows/dist/clink-client.js +17 -4
- package/clinkx-workflows/dist/clink-client.js.map +1 -1
- package/clinkx-workflows/dist/config.d.ts +145 -16
- package/clinkx-workflows/dist/config.js +384 -26
- package/clinkx-workflows/dist/config.js.map +1 -1
- package/clinkx-workflows/dist/contained-file.d.ts +172 -0
- package/clinkx-workflows/dist/contained-file.js +483 -0
- package/clinkx-workflows/dist/contained-file.js.map +1 -0
- package/clinkx-workflows/dist/context-builder-lifecycle-contract.d.ts +416 -0
- package/clinkx-workflows/dist/context-builder-lifecycle-contract.js +328 -0
- package/clinkx-workflows/dist/context-builder-lifecycle-contract.js.map +1 -0
- package/clinkx-workflows/dist/context-builder-lifecycle-router.d.ts +24 -0
- package/clinkx-workflows/dist/context-builder-lifecycle-router.js +39 -0
- package/clinkx-workflows/dist/context-builder-lifecycle-router.js.map +1 -0
- package/clinkx-workflows/dist/context-cache-key.d.ts +53 -0
- package/clinkx-workflows/dist/context-cache-key.js +91 -0
- package/clinkx-workflows/dist/context-cache-key.js.map +1 -0
- package/clinkx-workflows/dist/context-mode-resolver.d.ts +27 -0
- package/clinkx-workflows/dist/context-mode-resolver.js +126 -0
- package/clinkx-workflows/dist/context-mode-resolver.js.map +1 -0
- package/clinkx-workflows/dist/context-preflight.d.ts +184 -0
- package/clinkx-workflows/dist/context-preflight.js +91 -0
- package/clinkx-workflows/dist/context-preflight.js.map +1 -0
- package/clinkx-workflows/dist/council-expander.d.ts +1 -1
- package/clinkx-workflows/dist/council-expander.js +2 -1
- package/clinkx-workflows/dist/council-expander.js.map +1 -1
- package/clinkx-workflows/dist/dashboard/activity-contract.d.ts +165 -0
- package/clinkx-workflows/dist/dashboard/activity-contract.js +105 -0
- package/clinkx-workflows/dist/dashboard/activity-contract.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/activity-lease.d.ts +25 -0
- package/clinkx-workflows/dist/dashboard/activity-lease.js +34 -0
- package/clinkx-workflows/dist/dashboard/activity-lease.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/activity-reader.d.ts +86 -0
- package/clinkx-workflows/dist/dashboard/activity-reader.js +480 -0
- package/clinkx-workflows/dist/dashboard/activity-reader.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/api-routes.d.ts +36 -0
- package/clinkx-workflows/dist/dashboard/api-routes.js +1047 -0
- package/clinkx-workflows/dist/dashboard/api-routes.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/artifact-index.d.ts +37 -0
- package/clinkx-workflows/dist/dashboard/artifact-index.js +145 -0
- package/clinkx-workflows/dist/dashboard/artifact-index.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/auth/challenge-store.d.ts +31 -0
- package/clinkx-workflows/dist/dashboard/auth/challenge-store.js +65 -0
- package/clinkx-workflows/dist/dashboard/auth/challenge-store.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/auth/controller.d.ts +26 -0
- package/clinkx-workflows/dist/dashboard/auth/controller.js +596 -0
- package/clinkx-workflows/dist/dashboard/auth/controller.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/auth/credential-store.d.ts +60 -0
- package/clinkx-workflows/dist/dashboard/auth/credential-store.js +776 -0
- package/clinkx-workflows/dist/dashboard/auth/credential-store.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.d.ts +9 -0
- package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.js +44 -0
- package/clinkx-workflows/dist/dashboard/auth/enrollment-gate.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/auth/session-store.d.ts +17 -0
- package/clinkx-workflows/dist/dashboard/auth/session-store.js +77 -0
- package/clinkx-workflows/dist/dashboard/auth/session-store.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/auth/webauthn-service.d.ts +25 -0
- package/clinkx-workflows/dist/dashboard/auth/webauthn-service.js +71 -0
- package/clinkx-workflows/dist/dashboard/auth/webauthn-service.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/context-run-liveness.d.ts +37 -0
- package/clinkx-workflows/dist/dashboard/context-run-liveness.js +49 -0
- package/clinkx-workflows/dist/dashboard/context-run-liveness.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/context-run-reader.d.ts +222 -0
- package/clinkx-workflows/dist/dashboard/context-run-reader.js +1178 -0
- package/clinkx-workflows/dist/dashboard/context-run-reader.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/contracts.d.ts +8936 -0
- package/clinkx-workflows/dist/dashboard/contracts.js +1157 -0
- package/clinkx-workflows/dist/dashboard/contracts.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/generation.d.ts +14 -0
- package/clinkx-workflows/dist/dashboard/generation.js +41 -0
- package/clinkx-workflows/dist/dashboard/generation.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/index.d.ts +28 -0
- package/clinkx-workflows/dist/dashboard/index.js +16 -0
- package/clinkx-workflows/dist/dashboard/index.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/lazy-content.d.ts +101 -0
- package/clinkx-workflows/dist/dashboard/lazy-content.js +748 -0
- package/clinkx-workflows/dist/dashboard/lazy-content.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/progress-report-contract.d.ts +303 -0
- package/clinkx-workflows/dist/dashboard/progress-report-contract.js +221 -0
- package/clinkx-workflows/dist/dashboard/progress-report-contract.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/progress-report-reader.d.ts +50 -0
- package/clinkx-workflows/dist/dashboard/progress-report-reader.js +581 -0
- package/clinkx-workflows/dist/dashboard/progress-report-reader.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.d.ts +89 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.js +71 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-overlay.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-store.d.ts +28 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-store.js +110 -0
- package/clinkx-workflows/dist/dashboard/progress-report-status-store.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/read-model.d.ts +86 -0
- package/clinkx-workflows/dist/dashboard/read-model.js +440 -0
- package/clinkx-workflows/dist/dashboard/read-model.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/request-admission.d.ts +31 -0
- package/clinkx-workflows/dist/dashboard/request-admission.js +126 -0
- package/clinkx-workflows/dist/dashboard/request-admission.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/scanner.d.ts +75 -0
- package/clinkx-workflows/dist/dashboard/scanner.js +1110 -0
- package/clinkx-workflows/dist/dashboard/scanner.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/server-factory.d.ts +50 -0
- package/clinkx-workflows/dist/dashboard/server-factory.js +431 -0
- package/clinkx-workflows/dist/dashboard/server-factory.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-contract.d.ts +2611 -0
- package/clinkx-workflows/dist/dashboard/session-log-contract.js +480 -0
- package/clinkx-workflows/dist/dashboard/session-log-contract.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-identity.d.ts +21 -0
- package/clinkx-workflows/dist/dashboard/session-log-identity.js +101 -0
- package/clinkx-workflows/dist/dashboard/session-log-identity.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-journal.d.ts +43 -0
- package/clinkx-workflows/dist/dashboard/session-log-journal.js +522 -0
- package/clinkx-workflows/dist/dashboard/session-log-journal.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-reader.d.ts +61 -0
- package/clinkx-workflows/dist/dashboard/session-log-reader.js +378 -0
- package/clinkx-workflows/dist/dashboard/session-log-reader.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-redaction.d.ts +6 -0
- package/clinkx-workflows/dist/dashboard/session-log-redaction.js +367 -0
- package/clinkx-workflows/dist/dashboard/session-log-redaction.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/session-log-retention.d.ts +23 -0
- package/clinkx-workflows/dist/dashboard/session-log-retention.js +212 -0
- package/clinkx-workflows/dist/dashboard/session-log-retention.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/static-responses.d.ts +10 -0
- package/clinkx-workflows/dist/dashboard/static-responses.js +94 -0
- package/clinkx-workflows/dist/dashboard/static-responses.js.map +1 -0
- package/clinkx-workflows/dist/dashboard/worker-lock-observer.d.ts +28 -0
- package/clinkx-workflows/dist/dashboard/worker-lock-observer.js +241 -0
- package/clinkx-workflows/dist/dashboard/worker-lock-observer.js.map +1 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-400-normal-CDDApCn2.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-400-normal-CYLoc0-x.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-500-normal-6ng42L7E.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-500-normal-BgVn5rGT.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-600-normal-Cu4Hd6ag.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/ibm-plex-sans-latin-600-normal-CuJfVYMP.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/index-DOkMXTfB.js +25 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
- package/clinkx-workflows/dist/dashboard-ui/assets/style-ChJsn0KD.css +1 -0
- package/clinkx-workflows/dist/dashboard-ui/contracts/council-plan-review-input-v1.json +158 -0
- package/clinkx-workflows/dist/dashboard-ui/index.html +15 -0
- package/clinkx-workflows/dist/dashboard-ui/licenses/IBM-Plex-Mono-OFL.txt +93 -0
- package/clinkx-workflows/dist/dashboard-ui/licenses/IBM-Plex-Sans-OFL.txt +93 -0
- package/clinkx-workflows/dist/dashboard-ui/licenses/JetBrains-Mono-OFL.txt +93 -0
- package/clinkx-workflows/dist/dashboard-ui/licenses/NOTICE.md +32 -0
- package/clinkx-workflows/dist/dashboard-ui/theme-init.js +8 -0
- package/clinkx-workflows/dist/definition-normalizer.d.ts +19 -0
- package/clinkx-workflows/dist/definition-normalizer.js.map +1 -1
- package/clinkx-workflows/dist/delegate-validate.d.ts +78 -0
- package/clinkx-workflows/dist/delegate-validate.js +97 -0
- package/clinkx-workflows/dist/delegate-validate.js.map +1 -0
- package/clinkx-workflows/dist/engine.d.ts +141 -0
- package/clinkx-workflows/dist/engine.js +882 -28
- package/clinkx-workflows/dist/engine.js.map +1 -1
- package/clinkx-workflows/dist/errors.d.ts +2 -0
- package/clinkx-workflows/dist/errors.js.map +1 -1
- package/clinkx-workflows/dist/fingerprint.d.ts +1 -1
- package/clinkx-workflows/dist/fingerprint.js +1 -1
- package/clinkx-workflows/dist/index.d.ts +19 -0
- package/clinkx-workflows/dist/index.js +15 -0
- package/clinkx-workflows/dist/index.js.map +1 -1
- package/clinkx-workflows/dist/loader.d.ts +9 -3
- package/clinkx-workflows/dist/loader.js +92 -21
- package/clinkx-workflows/dist/loader.js.map +1 -1
- package/clinkx-workflows/dist/plan-review/admission.d.ts +160 -0
- package/clinkx-workflows/dist/plan-review/admission.js +290 -0
- package/clinkx-workflows/dist/plan-review/admission.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/context-policy.d.ts +55 -0
- package/clinkx-workflows/dist/plan-review/context-policy.js +146 -0
- package/clinkx-workflows/dist/plan-review/context-policy.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/contract.d.ts +763 -0
- package/clinkx-workflows/dist/plan-review/contract.js +289 -0
- package/clinkx-workflows/dist/plan-review/contract.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/digest.d.ts +68 -0
- package/clinkx-workflows/dist/plan-review/digest.js +241 -0
- package/clinkx-workflows/dist/plan-review/digest.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/discovery.d.ts +45 -0
- package/clinkx-workflows/dist/plan-review/discovery.js +36 -0
- package/clinkx-workflows/dist/plan-review/discovery.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/execution-contract.d.ts +298 -0
- package/clinkx-workflows/dist/plan-review/execution-contract.js +194 -0
- package/clinkx-workflows/dist/plan-review/execution-contract.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/expander.d.ts +48 -0
- package/clinkx-workflows/dist/plan-review/expander.js +243 -0
- package/clinkx-workflows/dist/plan-review/expander.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/projector.d.ts +126 -0
- package/clinkx-workflows/dist/plan-review/projector.js +437 -0
- package/clinkx-workflows/dist/plan-review/projector.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/publication.d.ts +95 -0
- package/clinkx-workflows/dist/plan-review/publication.js +182 -0
- package/clinkx-workflows/dist/plan-review/publication.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/ranking-reducer.d.ts +34 -0
- package/clinkx-workflows/dist/plan-review/ranking-reducer.js +139 -0
- package/clinkx-workflows/dist/plan-review/ranking-reducer.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/resume.d.ts +38 -0
- package/clinkx-workflows/dist/plan-review/resume.js +122 -0
- package/clinkx-workflows/dist/plan-review/resume.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/rubric.d.ts +7 -0
- package/clinkx-workflows/dist/plan-review/rubric.js +24 -0
- package/clinkx-workflows/dist/plan-review/rubric.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/run-state.d.ts +398 -0
- package/clinkx-workflows/dist/plan-review/run-state.js +183 -0
- package/clinkx-workflows/dist/plan-review/run-state.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/runtime-policy.d.ts +74 -0
- package/clinkx-workflows/dist/plan-review/runtime-policy.js +186 -0
- package/clinkx-workflows/dist/plan-review/runtime-policy.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/snapshot.d.ts +81 -0
- package/clinkx-workflows/dist/plan-review/snapshot.js +170 -0
- package/clinkx-workflows/dist/plan-review/snapshot.js.map +1 -0
- package/clinkx-workflows/dist/plan-review/stage-error.d.ts +19 -0
- package/clinkx-workflows/dist/plan-review/stage-error.js +20 -0
- package/clinkx-workflows/dist/plan-review/stage-error.js.map +1 -0
- package/clinkx-workflows/dist/post-processors/index.d.ts +20 -0
- package/clinkx-workflows/dist/post-processors/index.js +21 -0
- package/clinkx-workflows/dist/post-processors/index.js.map +1 -0
- package/clinkx-workflows/dist/prompt-budget.d.ts +7 -0
- package/clinkx-workflows/dist/prompt-budget.js +7 -1
- package/clinkx-workflows/dist/prompt-budget.js.map +1 -1
- package/clinkx-workflows/dist/reducers/index.js +2 -0
- package/clinkx-workflows/dist/reducers/index.js.map +1 -1
- package/clinkx-workflows/dist/run-lock-heartbeat.d.ts +2 -0
- package/clinkx-workflows/dist/run-lock-heartbeat.js +3 -0
- package/clinkx-workflows/dist/run-lock-heartbeat.js.map +1 -0
- package/clinkx-workflows/dist/run-summary/cards/council-plan-review.d.ts +34 -0
- package/clinkx-workflows/dist/run-summary/cards/council-plan-review.js +74 -0
- package/clinkx-workflows/dist/run-summary/cards/council-plan-review.js.map +1 -0
- package/clinkx-workflows/dist/run-summary/cards/index.js +5 -0
- package/clinkx-workflows/dist/run-summary/cards/index.js.map +1 -1
- package/clinkx-workflows/dist/run-summary.d.ts +13 -0
- package/clinkx-workflows/dist/run-summary.js +29 -1
- package/clinkx-workflows/dist/run-summary.js.map +1 -1
- package/clinkx-workflows/dist/schema.d.ts +76 -21
- package/clinkx-workflows/dist/schema.js +10 -1
- package/clinkx-workflows/dist/schema.js.map +1 -1
- package/clinkx-workflows/dist/seed-terms.d.ts +30 -0
- package/clinkx-workflows/dist/seed-terms.js +176 -0
- package/clinkx-workflows/dist/seed-terms.js.map +1 -0
- package/clinkx-workflows/dist/server.d.ts +5 -2
- package/clinkx-workflows/dist/server.js +82 -52
- package/clinkx-workflows/dist/server.js.map +1 -1
- package/clinkx-workflows/dist/shutdown.d.ts +18 -20
- package/clinkx-workflows/dist/shutdown.js +43 -61
- package/clinkx-workflows/dist/shutdown.js.map +1 -1
- package/clinkx-workflows/dist/state-schema.d.ts +38 -0
- package/clinkx-workflows/dist/state.d.ts +170 -3
- package/clinkx-workflows/dist/state.js +1275 -28
- package/clinkx-workflows/dist/state.js.map +1 -1
- package/clinkx-workflows/dist/transport.d.ts +15 -0
- package/clinkx-workflows/dist/transport.js +19 -10
- package/clinkx-workflows/dist/transport.js.map +1 -1
- package/clinkx-workflows/dist/types.d.ts +14 -2
- package/clinkx-workflows/dist/validators/council.d.ts +318 -85
- package/clinkx-workflows/dist/validators/council.js +52 -13
- package/clinkx-workflows/dist/validators/council.js.map +1 -1
- package/clinkx-workflows/dist/validators/index.d.ts +1 -0
- package/clinkx-workflows/dist/validators/index.js +3 -0
- package/clinkx-workflows/dist/validators/index.js.map +1 -1
- package/clinkx-workflows/dist/validators/plan-review.d.ts +398 -0
- package/clinkx-workflows/dist/validators/plan-review.js +316 -0
- package/clinkx-workflows/dist/validators/plan-review.js.map +1 -0
- package/clinkx-workflows/dist/workflow-receipt.js +188 -4
- package/clinkx-workflows/dist/workflow-receipt.js.map +1 -1
- package/clinkx-workflows/dist/workflow-tools.d.ts +48 -3
- package/clinkx-workflows/dist/workflow-tools.js +1402 -59
- package/clinkx-workflows/dist/workflow-tools.js.map +1 -1
- package/clinkx-workflows/dist/workspace-signature.d.ts +16 -0
- package/clinkx-workflows/dist/workspace-signature.js +388 -0
- package/clinkx-workflows/dist/workspace-signature.js.map +1 -0
- package/clinkx-workflows/templates/council/answer-specialist.txt +2 -1
- package/clinkx-workflows/templates/council/code-review-chairman.txt +13 -0
- package/clinkx-workflows/templates/council/code-review-cross-reviewer.txt +4 -1
- package/clinkx-workflows/templates/council/code-review-reviewer.txt +19 -3
- package/clinkx-workflows/templates/council/debug-debugger.txt +2 -1
- package/clinkx-workflows/templates/council/discover-analyst.txt +2 -1
- package/clinkx-workflows/templates/council/member.txt +2 -1
- package/clinkx-workflows/templates/council/plan-review-chairman.txt +68 -0
- package/clinkx-workflows/templates/council/plan-review-cross-reviewer.txt +51 -0
- package/clinkx-workflows/templates/council/plan-review-reviewer.txt +60 -0
- package/clinkx-workflows/templates/plan-review/chairman.txt +48 -0
- package/clinkx-workflows/templates/plan-review/cross-review.txt +52 -0
- package/clinkx-workflows/templates/plan-review/ranking.txt +16 -0
- package/clinkx-workflows/templates/plan-review/reviewer.txt +57 -0
- package/clinkx-workflows/workflows/council-answer.yaml +97 -8
- package/clinkx-workflows/workflows/council-code-review.yaml +103 -8
- package/clinkx-workflows/workflows/council-debug.yaml +97 -8
- package/clinkx-workflows/workflows/council-default.yaml +97 -8
- package/clinkx-workflows/workflows/council-discover.yaml +97 -8
- package/clinkx-workflows/workflows/council-plan-review.yaml +250 -0
- package/clinkx-workflows/workflows/plan-review-receipts.yaml +230 -0
- package/conf/adapters/agy.json +49 -0
- package/conf/adapters/claude.json +5 -0
- package/conf/adapters/codex-app-server.json +44 -0
- package/conf/adapters/codex.json +7 -2
- package/conf/adapters/glm.json +5 -0
- package/conf/adapters/grok.json +60 -0
- package/conf/adapters/hapi/agy.json +52 -0
- package/conf/adapters/hapi/claude.json +5 -0
- package/conf/adapters/hapi/codex.json +7 -2
- package/conf/adapters/hapi/glm.json +5 -0
- package/dist/activity-journal.d.ts +42 -0
- package/dist/activity-journal.js +381 -0
- package/dist/activity-journal.js.map +1 -0
- package/dist/allowed-roots.d.ts +41 -0
- package/dist/allowed-roots.js +125 -3
- package/dist/allowed-roots.js.map +1 -1
- package/dist/codex/activity-session-log.d.ts +14 -0
- package/dist/codex/activity-session-log.js +206 -0
- package/dist/codex/activity-session-log.js.map +1 -0
- package/dist/codex/agent-tools.d.ts +23 -0
- package/dist/codex/agent-tools.js +1270 -0
- package/dist/codex/agent-tools.js.map +1 -0
- package/dist/codex/app-server-client.d.ts +76 -0
- package/dist/codex/app-server-client.js +582 -0
- package/dist/codex/app-server-client.js.map +1 -0
- package/dist/codex/app-server-registry.d.ts +389 -0
- package/dist/codex/app-server-registry.js +1407 -0
- package/dist/codex/app-server-registry.js.map +1 -0
- package/dist/codex/client-types.d.ts +109 -0
- package/dist/codex/client-types.js +2 -0
- package/dist/codex/client-types.js.map +1 -0
- package/dist/codex/protocol.d.ts +5375 -0
- package/dist/codex/protocol.js +614 -0
- package/dist/codex/protocol.js.map +1 -0
- package/dist/codex/session.d.ts +263 -0
- package/dist/codex/session.js +466 -0
- package/dist/codex/session.js.map +1 -0
- package/dist/config.d.ts +185 -19
- package/dist/config.js +82 -16
- package/dist/config.js.map +1 -1
- package/dist/context-builder/anchors.d.ts +1 -0
- package/dist/context-builder/anchors.js +3 -0
- package/dist/context-builder/anchors.js.map +1 -1
- package/dist/context-builder/bundle.d.ts +35 -2
- package/dist/context-builder/bundle.js +342 -2417
- package/dist/context-builder/bundle.js.map +1 -1
- package/dist/context-builder/codemap.d.ts +5 -0
- package/dist/context-builder/codemap.js +387 -13
- package/dist/context-builder/codemap.js.map +1 -1
- package/dist/context-builder/config.d.ts +1 -0
- package/dist/context-builder/config.js +12 -0
- package/dist/context-builder/config.js.map +1 -1
- package/dist/context-builder/context-run-catalog.d.ts +17 -0
- package/dist/context-builder/context-run-catalog.js +99 -0
- package/dist/context-builder/context-run-catalog.js.map +1 -0
- package/dist/context-builder/delegate-packet.d.ts +37 -0
- package/dist/context-builder/delegate-packet.js +359 -67
- package/dist/context-builder/delegate-packet.js.map +1 -1
- package/dist/context-builder/delegate-validation.d.ts +10 -1
- package/dist/context-builder/delegate-validation.js +153 -41
- package/dist/context-builder/delegate-validation.js.map +1 -1
- package/dist/context-builder/delegate.d.ts +2 -0
- package/dist/context-builder/delegate.js +1 -0
- package/dist/context-builder/delegate.js.map +1 -1
- package/dist/context-builder/diagnostics.d.ts +11 -2
- package/dist/context-builder/diagnostics.js +39 -6
- package/dist/context-builder/diagnostics.js.map +1 -1
- package/dist/context-builder/discovery.d.ts +29 -1
- package/dist/context-builder/discovery.js +475 -175
- package/dist/context-builder/discovery.js.map +1 -1
- package/dist/context-builder/globs.js +10 -10
- package/dist/context-builder/globs.js.map +1 -1
- package/dist/context-builder/handler.d.ts +26 -2
- package/dist/context-builder/handler.js +1158 -2416
- package/dist/context-builder/handler.js.map +1 -1
- package/dist/context-builder/lifecycle-contract.d.ts +424 -0
- package/dist/context-builder/lifecycle-contract.js +523 -0
- package/dist/context-builder/lifecycle-contract.js.map +1 -0
- package/dist/context-builder/lifecycle-journal.d.ts +62 -0
- package/dist/context-builder/lifecycle-journal.js +88 -0
- package/dist/context-builder/lifecycle-journal.js.map +1 -0
- package/dist/context-builder/lifecycle-observer.d.ts +102 -0
- package/dist/context-builder/lifecycle-observer.js +258 -0
- package/dist/context-builder/lifecycle-observer.js.map +1 -0
- package/dist/context-builder/lifecycle-reconcile.d.ts +32 -0
- package/dist/context-builder/lifecycle-reconcile.js +191 -0
- package/dist/context-builder/lifecycle-reconcile.js.map +1 -0
- package/dist/context-builder/lifecycle-recovery.d.ts +2 -0
- package/dist/context-builder/lifecycle-recovery.js +14 -0
- package/dist/context-builder/lifecycle-recovery.js.map +1 -0
- package/dist/context-builder/path-signals.js +9 -5
- package/dist/context-builder/path-signals.js.map +1 -1
- package/dist/context-builder/progress.d.ts +3 -1
- package/dist/context-builder/progress.js +23 -0
- package/dist/context-builder/progress.js.map +1 -1
- package/dist/context-builder/receipt.d.ts +6 -4
- package/dist/context-builder/receipt.js +12 -1
- package/dist/context-builder/receipt.js.map +1 -1
- package/dist/context-builder/refine-handler.d.ts +14 -0
- package/dist/context-builder/refine-handler.js +790 -0
- package/dist/context-builder/refine-handler.js.map +1 -0
- package/dist/context-builder/review-coverage.d.ts +84 -0
- package/dist/context-builder/review-coverage.js +437 -0
- package/dist/context-builder/review-coverage.js.map +1 -0
- package/dist/context-builder/schema.d.ts +239 -1
- package/dist/context-builder/schema.js +112 -6
- package/dist/context-builder/schema.js.map +1 -1
- package/dist/context-builder/secrets.d.ts +28 -0
- package/dist/context-builder/secrets.js +1473 -44
- package/dist/context-builder/secrets.js.map +1 -1
- package/dist/context-builder/selection.d.ts +7 -3
- package/dist/context-builder/selection.js +200 -738
- package/dist/context-builder/selection.js.map +1 -1
- package/dist/context-builder/session-log-identity.d.ts +1 -0
- package/dist/context-builder/session-log-identity.js +66 -0
- package/dist/context-builder/session-log-identity.js.map +1 -0
- package/dist/context-builder/slice-range-math.d.ts +16 -0
- package/dist/context-builder/slice-range-math.js +137 -0
- package/dist/context-builder/slice-range-math.js.map +1 -0
- package/dist/context-builder/status.d.ts +22 -1
- package/dist/context-builder/status.js +59 -4
- package/dist/context-builder/status.js.map +1 -1
- package/dist/context-builder/storage.d.ts +35 -2
- package/dist/context-builder/storage.js +271 -14
- package/dist/context-builder/storage.js.map +1 -1
- package/dist/context-builder/token-estimate.d.ts +13 -2
- package/dist/context-builder/token-estimate.js +77 -4
- package/dist/context-builder/token-estimate.js.map +1 -1
- package/dist/context-builder/versions.d.ts +29 -0
- package/dist/context-builder/versions.js +30 -0
- package/dist/context-builder/versions.js.map +1 -0
- package/dist/context-builder/workflow-runner.d.ts +69 -0
- package/dist/context-builder/workflow-runner.js +1051 -0
- package/dist/context-builder/workflow-runner.js.map +1 -0
- package/dist/context-builder/write-watchdog.d.ts +14 -0
- package/dist/context-builder/write-watchdog.js +38 -0
- package/dist/context-builder/write-watchdog.js.map +1 -0
- package/dist/dashboard-adapter-catalog.d.ts +9 -0
- package/dist/dashboard-adapter-catalog.js +46 -0
- package/dist/dashboard-adapter-catalog.js.map +1 -0
- package/dist/dashboard-cli.d.ts +79 -0
- package/dist/dashboard-cli.js +585 -0
- package/dist/dashboard-cli.js.map +1 -0
- package/dist/dashboard-companion/client.d.ts +36 -0
- package/dist/dashboard-companion/client.js +210 -0
- package/dist/dashboard-companion/client.js.map +1 -0
- package/dist/dashboard-companion/config.d.ts +8 -0
- package/dist/dashboard-companion/config.js +52 -0
- package/dist/dashboard-companion/config.js.map +1 -0
- package/dist/dashboard-companion/http-proxy.d.ts +10 -0
- package/dist/dashboard-companion/http-proxy.js +234 -0
- package/dist/dashboard-companion/http-proxy.js.map +1 -0
- package/dist/dashboard-companion/protocol.d.ts +80 -0
- package/dist/dashboard-companion/protocol.js +455 -0
- package/dist/dashboard-companion/protocol.js.map +1 -0
- package/dist/dashboard-companion/standalone-assets.d.ts +12 -0
- package/dist/dashboard-companion/standalone-assets.js +72 -0
- package/dist/dashboard-companion/standalone-assets.js.map +1 -0
- package/dist/dashboard-companion/standalone-entry.d.ts +1 -0
- package/dist/dashboard-companion/standalone-entry.js +17 -0
- package/dist/dashboard-companion/standalone-entry.js.map +1 -0
- package/dist/dashboard-gateway/config.d.ts +9 -0
- package/dist/dashboard-gateway/config.js +44 -0
- package/dist/dashboard-gateway/config.js.map +1 -0
- package/dist/dashboard-gateway/index.d.ts +11 -0
- package/dist/dashboard-gateway/index.js +755 -0
- package/dist/dashboard-gateway/index.js.map +1 -0
- package/dist/dashboard-gateway/main.d.ts +1 -0
- package/dist/dashboard-gateway/main.js +25 -0
- package/dist/dashboard-gateway/main.js.map +1 -0
- package/dist/dashboard-pairing-token.d.ts +1 -0
- package/dist/dashboard-pairing-token.js +5 -0
- package/dist/dashboard-pairing-token.js.map +1 -0
- package/dist/elaris/client.d.ts +73 -0
- package/dist/elaris/client.js +825 -0
- package/dist/elaris/client.js.map +1 -0
- package/dist/elaris/config.d.ts +18 -0
- package/dist/elaris/config.js +75 -0
- package/dist/elaris/config.js.map +1 -0
- package/dist/elaris/errors.d.ts +41 -0
- package/dist/elaris/errors.js +205 -0
- package/dist/elaris/errors.js.map +1 -0
- package/dist/elaris/github-repo.d.ts +18 -0
- package/dist/elaris/github-repo.js +89 -0
- package/dist/elaris/github-repo.js.map +1 -0
- package/dist/elaris/index.d.ts +10 -0
- package/dist/elaris/index.js +11 -0
- package/dist/elaris/index.js.map +1 -0
- package/dist/elaris/redact.d.ts +89 -0
- package/dist/elaris/redact.js +423 -0
- package/dist/elaris/redact.js.map +1 -0
- package/dist/elaris/run-id.d.ts +5 -0
- package/dist/elaris/run-id.js +20 -0
- package/dist/elaris/run-id.js.map +1 -0
- package/dist/elaris/status.d.ts +45 -0
- package/dist/elaris/status.js +122 -0
- package/dist/elaris/status.js.map +1 -0
- package/dist/elaris/tool-schemas.d.ts +314 -0
- package/dist/elaris/tool-schemas.js +208 -0
- package/dist/elaris/tool-schemas.js.map +1 -0
- package/dist/elaris/tools.d.ts +73 -0
- package/dist/elaris/tools.js +1065 -0
- package/dist/elaris/tools.js.map +1 -0
- package/dist/elaris/types.d.ts +1541 -0
- package/dist/elaris/types.js +252 -0
- package/dist/elaris/types.js.map +1 -0
- package/dist/errors.d.ts +16 -0
- package/dist/errors.js +19 -0
- package/dist/errors.js.map +1 -1
- package/dist/handler.d.ts +4 -0
- package/dist/handler.js +10 -1
- package/dist/handler.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +13 -3
- package/dist/index.js.map +1 -1
- package/dist/local-clink-backend.d.ts +3 -0
- package/dist/local-clink-backend.js +4 -0
- package/dist/local-clink-backend.js.map +1 -1
- package/dist/package-info.d.ts +2 -0
- package/dist/package-info.js +18 -0
- package/dist/package-info.js.map +1 -0
- package/dist/parsers/codex-jsonl.js +48 -3
- package/dist/parsers/codex-jsonl.js.map +1 -1
- package/dist/parsers/extract.d.ts +10 -1
- package/dist/parsers/extract.js +11 -3
- package/dist/parsers/extract.js.map +1 -1
- package/dist/pipeline.d.ts +4 -0
- package/dist/pipeline.js +129 -8
- package/dist/pipeline.js.map +1 -1
- package/dist/run-dir.d.ts +24 -0
- package/dist/run-dir.js +201 -2
- package/dist/run-dir.js.map +1 -1
- package/dist/runner.d.ts +13 -0
- package/dist/runner.js +184 -15
- package/dist/runner.js.map +1 -1
- package/dist/safety.d.ts +4 -4
- package/dist/safety.js +4 -4
- package/dist/schema.d.ts +7 -7
- package/dist/server.d.ts +1 -0
- package/dist/server.js +359 -17
- package/dist/server.js.map +1 -1
- package/dist/session-log-stream.d.ts +18 -0
- package/dist/session-log-stream.js +319 -0
- package/dist/session-log-stream.js.map +1 -0
- package/package.json +46 -5
- package/conf/adapters/gemini.json +0 -44
- package/conf/adapters/hapi/gemini.json +0 -47
- package/dist/parsers/gemini-json.d.ts +0 -2
- package/dist/parsers/gemini-json.js +0 -72
- package/dist/parsers/gemini-json.js.map +0 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { isExcludedPlanPath } from "./context-policy.js";
|
|
2
|
+
import { PLAN_SNAPSHOT_BEGIN, renderPlanSnapshotBlock } from "./expander.js";
|
|
3
|
+
import { PlanReviewStageError } from "./stage-error.js";
|
|
4
|
+
const PROVIDER_STAGE_IDS = ["reviewers", "cross_review", "chairman"];
|
|
5
|
+
/**
|
|
6
|
+
* Count snapshot-block OPENINGS: the begin marker alone on its own line.
|
|
7
|
+
*
|
|
8
|
+
* Line-anchoring is load-bearing, not tidiness. All three shipped actor
|
|
9
|
+
* templates NAME this marker in their prose, inline and inside backticks, to
|
|
10
|
+
* tell the model where the plan is (`templates/plan-review/reviewer.txt:4`,
|
|
11
|
+
* `chairman.txt:17`, `cross-review.txt:10`). A raw substring count therefore
|
|
12
|
+
* scores an HONEST prompt at 2 — prose mention plus the real block — so a bare
|
|
13
|
+
* `=== 1` rule rejects every legitimate resumed retry. Only
|
|
14
|
+
* `renderPlanSnapshotBlock` puts the marker alone on a line, so line-anchoring
|
|
15
|
+
* counts real blocks and ignores prose that merely quotes the delimiter.
|
|
16
|
+
*
|
|
17
|
+
* `\r?` tolerates CRLF-normalized state. It is not an anti-evasion measure:
|
|
18
|
+
* this whole check is fail-closed integrity on HONEST state, not a boundary
|
|
19
|
+
* against someone who already owns the state directory (see below).
|
|
20
|
+
*/
|
|
21
|
+
const PLAN_SNAPSHOT_BEGIN_LINE_RE = new RegExp(`^${PLAN_SNAPSHOT_BEGIN.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\r?$`, "gm");
|
|
22
|
+
function countSnapshotBlockOpenings(haystack) {
|
|
23
|
+
return [...haystack.matchAll(PLAN_SNAPSHOT_BEGIN_LINE_RE)].length;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Bind the verified persisted bindings to the persisted normalized definition.
|
|
27
|
+
* Exact coverage is required: a missing, extra, renamed, or re-providered call
|
|
28
|
+
* is a corrupt execution contract and must fail pre-backend (D3 — no fallback,
|
|
29
|
+
* no seat substitution).
|
|
30
|
+
*/
|
|
31
|
+
export function validatePlanReviewCallBindings(definition, bindings) {
|
|
32
|
+
const byCall = new Map();
|
|
33
|
+
for (const entry of bindings) {
|
|
34
|
+
const key = `${entry.stage_id}.${entry.call_id}`;
|
|
35
|
+
if (byCall.has(key)) {
|
|
36
|
+
throw new PlanReviewStageError("execution_contract", `Persisted call bindings contain duplicate call ${key}`);
|
|
37
|
+
}
|
|
38
|
+
byCall.set(key, entry);
|
|
39
|
+
}
|
|
40
|
+
const expected = new Set();
|
|
41
|
+
for (const stageId of PROVIDER_STAGE_IDS) {
|
|
42
|
+
const stage = definition.stages.find((candidate) => candidate.id === stageId);
|
|
43
|
+
if (stage === undefined || stage.calls.length === 0) {
|
|
44
|
+
throw new PlanReviewStageError("execution_contract", `Plan-review definition has no provider calls in ${stageId}`);
|
|
45
|
+
}
|
|
46
|
+
for (const call of stage.calls) {
|
|
47
|
+
const key = `${stageId}.${call.id}`;
|
|
48
|
+
expected.add(key);
|
|
49
|
+
const entry = byCall.get(key);
|
|
50
|
+
if (entry === undefined) {
|
|
51
|
+
throw new PlanReviewStageError("execution_contract", `Persisted call bindings are missing call ${key}`);
|
|
52
|
+
}
|
|
53
|
+
if (entry.cli_name !== call.cli_name) {
|
|
54
|
+
throw new PlanReviewStageError("execution_contract", `Persisted call binding provider mismatch for ${key}: ${entry.cli_name} != ${call.cli_name}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const key of byCall.keys()) {
|
|
59
|
+
if (!expected.has(key)) {
|
|
60
|
+
throw new PlanReviewStageError("execution_contract", `Persisted call bindings reference unknown call ${key}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return byCall;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Validate persisted retry identity AND D9 before any provider/backend is created.
|
|
67
|
+
*
|
|
68
|
+
* ## Why the prompt is checked here and not left to the definition
|
|
69
|
+
*
|
|
70
|
+
* `WorkflowEngine.buildCallInput` replays a persisted prepared input verbatim —
|
|
71
|
+
* `structuredClone(resumedInput)` with only `cli_name` re-pinned. The expanded
|
|
72
|
+
* DEFINITION is not what reaches an actor on a resumed retry, so asserting D9
|
|
73
|
+
* against the definition proves nothing about that dispatch. The plan text now
|
|
74
|
+
* lives in the prompt bytes, which means the prompt is the D9 surface and this
|
|
75
|
+
* is the seam that must hold it: it already runs on the resume path, before any
|
|
76
|
+
* backend is created.
|
|
77
|
+
*
|
|
78
|
+
* A LEGITIMATE persisted input always passes, because `buildCallInput` appended
|
|
79
|
+
* the bound snapshot block at original dispatch and persisted that exact prompt.
|
|
80
|
+
* So this rejects only state that was tampered with, hand-written, or carried
|
|
81
|
+
* over from a different plan revision.
|
|
82
|
+
*
|
|
83
|
+
* ## What this check ESTABLISHES — and what it does not
|
|
84
|
+
*
|
|
85
|
+
* It establishes exactly two things: the verified snapshot block is the prompt's
|
|
86
|
+
* SUFFIX, and no other block opens before it. POSITION is what makes this exact.
|
|
87
|
+
* Mere presence is satisfied by a prompt carrying the verified block beside a
|
|
88
|
+
* second, different plan revision — the resumed dispatch replays the whole
|
|
89
|
+
* persisted prompt, so an actor would see both and could not know which binds.
|
|
90
|
+
* The suffix rule rejects a revision appended AFTER the verified block; the
|
|
91
|
+
* prefix scan rejects one spliced in BEFORE it.
|
|
92
|
+
*
|
|
93
|
+
* Both rules are stated against what `buildCallInput` actually composes —
|
|
94
|
+
* `renderedPrompt + renderPlanSnapshotBlock(text)` — so every honest persisted
|
|
95
|
+
* input passes BY CONSTRUCTION rather than by luck, including one rendered from
|
|
96
|
+
* the shipped templates, whose prose quotes the delimiter inline.
|
|
97
|
+
*
|
|
98
|
+
* It does NOT establish prompt EXCLUSIVITY, and must not be read as doing so.
|
|
99
|
+
* Raw plan text appended WITHOUT delimiters is not detectable here: there is no
|
|
100
|
+
* way to distinguish it from legitimate instruction prose, and pretending
|
|
101
|
+
* otherwise would republish precisely the kind of unbacked claim this file's
|
|
102
|
+
* surrounding work exists to delete. What bounds that residue is the trust
|
|
103
|
+
* model, not this function: plan review is TRUSTED-INPUT-ONLY, and an actor who
|
|
104
|
+
* can rewrite `state.json` to append a plan can equally rewrite it
|
|
105
|
+
* self-consistently. This is a fail-closed integrity check on honest state, not
|
|
106
|
+
* a boundary against an adversary who already owns the state directory.
|
|
107
|
+
*
|
|
108
|
+
* ## What is NOT checked, and why
|
|
109
|
+
*
|
|
110
|
+
* NOT `absolute_file_paths === []`. That is true of the expanded call
|
|
111
|
+
* DEFINITION, and there it is load-bearing. It is NOT true of a dispatched
|
|
112
|
+
* input: the engine composes `absolute_file_paths` from anonymized peer
|
|
113
|
+
* artifacts (cross-review, chairman) plus `absolute_file_paths_from:
|
|
114
|
+
* [context_files, context_bundle_files]` — the caller's repo evidence
|
|
115
|
+
* (`workflows/plan-review-receipts.yaml:124,147,196`). Requiring an empty list
|
|
116
|
+
* would reject every legitimate cross-review and chairman resume. The honest
|
|
117
|
+
* file-side invariant is the one the policy already defines: no attached path
|
|
118
|
+
* may be the original plan or any plan-workspace `PLAN.md`.
|
|
119
|
+
*/
|
|
120
|
+
export function validatePlanReviewPreparedInputPolicy(preparedInputs, bindingsByCall, input = {}) {
|
|
121
|
+
for (const [callKey, prepared] of preparedInputs) {
|
|
122
|
+
// Unbound calls are not actors. The only unbound call in a plan-review
|
|
123
|
+
// definition is `ranking_analysis`, the in-process deterministic reducer —
|
|
124
|
+
// the exact set the expander declines to inline a snapshot into. D9 governs
|
|
125
|
+
// what an ACTOR receives; nothing is spawned here.
|
|
126
|
+
const binding = bindingsByCall.get(callKey);
|
|
127
|
+
if (binding === undefined) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (prepared["cli_name"] !== binding.cli_name) {
|
|
131
|
+
throw new PlanReviewStageError("execution_contract", `Persisted prepared input provider mismatch for ${callKey}`);
|
|
132
|
+
}
|
|
133
|
+
// Fail closed. A caller that cannot supply the verified snapshot cannot
|
|
134
|
+
// establish D9 for this dispatch, and dispatching anyway would republish a
|
|
135
|
+
// claim nothing backs.
|
|
136
|
+
if (input.snapshotText === undefined || input.contextPolicy === undefined) {
|
|
137
|
+
throw new PlanReviewStageError("execution_contract", `Persisted prepared input for ${callKey} cannot be checked against the ` +
|
|
138
|
+
"verified plan snapshot and context policy (D9): both are required " +
|
|
139
|
+
"whenever a bound call replays a persisted prompt");
|
|
140
|
+
}
|
|
141
|
+
const prompt = prepared["prompt"];
|
|
142
|
+
const verifiedBlock = renderPlanSnapshotBlock(input.snapshotText);
|
|
143
|
+
// POSITIONAL, not merely present. `buildCallInput` composes an actor prompt
|
|
144
|
+
// as exactly `renderedPrompt + renderPlanSnapshotBlock(text)` and persists
|
|
145
|
+
// that string (`engine.ts:1906-1908`), so the verified block is the prompt's
|
|
146
|
+
// SUFFIX by construction — every honest persisted input satisfies this.
|
|
147
|
+
// Requiring the suffix (rather than `.includes`) is what rejects a second
|
|
148
|
+
// revision appended AFTER the verified one.
|
|
149
|
+
if (typeof prompt !== "string" || !prompt.endsWith(verifiedBlock)) {
|
|
150
|
+
throw new PlanReviewStageError("execution_contract", `Persisted prepared input for ${callKey} does not end with the verified plan ` +
|
|
151
|
+
"snapshot block (D9). A resumed retry dispatches its persisted prompt verbatim, " +
|
|
152
|
+
"so a prompt that does not close with the bound snapshot would review a plan " +
|
|
153
|
+
"this run never verified, or would carry text appended after it.", "schema_mismatch");
|
|
154
|
+
}
|
|
155
|
+
// The suffix check alone still admits a SECOND, different revision spliced
|
|
156
|
+
// in BEFORE the verified block: the actor would receive two candidate plans
|
|
157
|
+
// and no way to tell which binds. So no block may open anywhere but the
|
|
158
|
+
// suffix. Scanning only the prefix is deliberate — the verified block's own
|
|
159
|
+
// body is digest-verified plan text, and a plan that legitimately quotes the
|
|
160
|
+
// delimiter on its own line must not brick an honest run.
|
|
161
|
+
const prefix = prompt.slice(0, prompt.length - verifiedBlock.length);
|
|
162
|
+
const strayBlocks = countSnapshotBlockOpenings(prefix);
|
|
163
|
+
if (strayBlocks !== 0) {
|
|
164
|
+
throw new PlanReviewStageError("execution_contract", `Persisted prepared input for ${callKey} opens ${String(strayBlocks)} plan ` +
|
|
165
|
+
"snapshot block(s) before the verified one; exactly one block, at the end, " +
|
|
166
|
+
"is permitted (D9). A prompt with a second block would dispatch a plan " +
|
|
167
|
+
"revision beside the verified one.", "schema_mismatch");
|
|
168
|
+
}
|
|
169
|
+
const attached = prepared["absolute_file_paths"];
|
|
170
|
+
if (attached !== undefined) {
|
|
171
|
+
if (!Array.isArray(attached)) {
|
|
172
|
+
throw new PlanReviewStageError("execution_contract", `Persisted prepared input for ${callKey} has a non-array absolute_file_paths`, "schema_mismatch");
|
|
173
|
+
}
|
|
174
|
+
for (const path of attached) {
|
|
175
|
+
if (typeof path !== "string") {
|
|
176
|
+
throw new PlanReviewStageError("execution_contract", `Persisted prepared input for ${callKey} has a non-string absolute_file_paths entry`, "schema_mismatch");
|
|
177
|
+
}
|
|
178
|
+
if (isExcludedPlanPath(input.contextPolicy, path)) {
|
|
179
|
+
throw new PlanReviewStageError("execution_contract", `Persisted prepared input for ${callKey} attaches force-excluded plan path ${path} ` +
|
|
180
|
+
"(D9/A-7): the verified snapshot is the only plan text an actor may receive.", "schema_mismatch");
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=runtime-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-policy.js","sourceRoot":"","sources":["../../src/plan-review/runtime-policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A-6 — immutable plan snapshot discipline.
|
|
3
|
+
*
|
|
4
|
+
* The whole point is that `plan_file` is read EXACTLY ONCE, through one
|
|
5
|
+
* no-follow handle, and never again: every actor (and every resume) is served
|
|
6
|
+
* the runtime-owned canonical copy. That closes the path/digest TOCTOU — a
|
|
7
|
+
* swap of `plan_file` after admission cannot change what the reviewers saw,
|
|
8
|
+
* because nothing re-reads it.
|
|
9
|
+
*/
|
|
10
|
+
/** Run-relative location of the runtime-owned canonical plan snapshot. */
|
|
11
|
+
export declare const PLAN_SNAPSHOT_RELPATH: string;
|
|
12
|
+
export declare const MAX_PLAN_SNAPSHOT_BYTES = 524288;
|
|
13
|
+
/** Run-relative location of the persisted normalized execution contract. */
|
|
14
|
+
export declare const EXECUTION_CONTRACT_RELPATH: string;
|
|
15
|
+
/** Hard cap for both initial serialization and resume reads. */
|
|
16
|
+
export declare const MAX_EXECUTION_CONTRACT_BYTES = 262144;
|
|
17
|
+
export interface ReadCanonicalPlanSnapshotInput {
|
|
18
|
+
readonly planFile: string;
|
|
19
|
+
readonly allowedRoots: readonly string[];
|
|
20
|
+
/** The caller's claimed checkpoint-text-v1 digest, re-verified here. */
|
|
21
|
+
readonly claimedDigest: string;
|
|
22
|
+
}
|
|
23
|
+
export interface MaterializePlanSnapshotInput extends ReadCanonicalPlanSnapshotInput {
|
|
24
|
+
readonly runDir: string;
|
|
25
|
+
}
|
|
26
|
+
export interface MaterializedPlanSnapshot {
|
|
27
|
+
readonly relPath: string;
|
|
28
|
+
readonly absolutePath: string;
|
|
29
|
+
/** SHA-256 of the snapshot file bytes (corruption check). */
|
|
30
|
+
readonly sha256: string;
|
|
31
|
+
/** checkpoint-text-v1 digest of the canonical bytes (identity). */
|
|
32
|
+
readonly planDigest: string;
|
|
33
|
+
readonly bytes: number;
|
|
34
|
+
/** The canonical snapshot TEXT — what the expander inlines (A-6/D9). */
|
|
35
|
+
readonly text: string;
|
|
36
|
+
}
|
|
37
|
+
/** The verified canonical plan, held in memory and not yet persisted. */
|
|
38
|
+
export interface CanonicalPlanSnapshot {
|
|
39
|
+
readonly canonicalBytes: Buffer;
|
|
40
|
+
readonly planDigest: string;
|
|
41
|
+
readonly text: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Read `plan_file` EXACTLY ONCE (contained, no-follow, regular-file only),
|
|
45
|
+
* canonicalize it, and verify the caller's claimed digest — without writing
|
|
46
|
+
* anything.
|
|
47
|
+
*
|
|
48
|
+
* The read is split from the write because the expander now inlines the
|
|
49
|
+
* snapshot TEXT into every actor's prompt (D9), so the verified text must exist
|
|
50
|
+
* before the run's definition is composed, while the run directory that holds
|
|
51
|
+
* the persisted copy cannot exist until the state store creates it. Splitting
|
|
52
|
+
* keeps `plan_file` read once and keeps the digest verified BEFORE the text is
|
|
53
|
+
* used for anything.
|
|
54
|
+
*
|
|
55
|
+
* Failure classes map to the plan's post-state pre-seat stages:
|
|
56
|
+
* - containment / symlink / non-regular / unreadable / invalid text → `snapshot`
|
|
57
|
+
* - canonical digest ≠ claimed digest → `digest`
|
|
58
|
+
*/
|
|
59
|
+
export declare function readCanonicalPlanSnapshot(input: ReadCanonicalPlanSnapshotInput): Promise<CanonicalPlanSnapshot>;
|
|
60
|
+
/** Copy already-verified canonical bytes into the runtime-owned run directory. */
|
|
61
|
+
export declare function persistCanonicalPlanSnapshot(runDir: string, canonical: CanonicalPlanSnapshot): Promise<MaterializedPlanSnapshot>;
|
|
62
|
+
/** Read + verify + persist in one step. The composition callers used before. */
|
|
63
|
+
export declare function materializePlanSnapshot(input: MaterializePlanSnapshotInput): Promise<MaterializedPlanSnapshot>;
|
|
64
|
+
/**
|
|
65
|
+
* Re-verify the persisted snapshot from run-owned storage alone. Used on resume:
|
|
66
|
+
* it re-reads the SNAPSHOT (never `plan_file`) through the contained no-follow
|
|
67
|
+
* reader and recomputes both the file hash and the checkpoint digest.
|
|
68
|
+
*
|
|
69
|
+
* Returns the verified snapshot rather than discarding the bytes it already
|
|
70
|
+
* read. Resume needs the canonical TEXT — it is the only thing a persisted
|
|
71
|
+
* prepared input's prompt can be checked against (D9), and the check must run
|
|
72
|
+
* before any provider exists. Returning it here keeps the snapshot read ONCE:
|
|
73
|
+
* re-reading it at the validation seam would reopen a D9-class TOCTOU between
|
|
74
|
+
* verification and use.
|
|
75
|
+
*/
|
|
76
|
+
export declare function verifyPersistedPlanSnapshot(runDir: string, relPath: string, expectedSha256: string, expectedPlanDigest: string): Promise<CanonicalPlanSnapshot>;
|
|
77
|
+
/** Persist the normalized execution contract into runtime-owned storage. */
|
|
78
|
+
export declare function writeExecutionContractSnapshot(runDir: string, contract: unknown): Promise<{
|
|
79
|
+
relPath: string;
|
|
80
|
+
sha256: string;
|
|
81
|
+
}>;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A-6 — immutable plan snapshot discipline.
|
|
3
|
+
*
|
|
4
|
+
* The whole point is that `plan_file` is read EXACTLY ONCE, through one
|
|
5
|
+
* no-follow handle, and never again: every actor (and every resume) is served
|
|
6
|
+
* the runtime-owned canonical copy. That closes the path/digest TOCTOU — a
|
|
7
|
+
* swap of `plan_file` after admission cannot change what the reviewers saw,
|
|
8
|
+
* because nothing re-reads it.
|
|
9
|
+
*/
|
|
10
|
+
import { createHash } from "node:crypto";
|
|
11
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
12
|
+
import { dirname, join } from "node:path";
|
|
13
|
+
import { ContainedFilePolicyError, readContainedAbsoluteFile, readContainedRelativeFile, } from "../contained-file.js";
|
|
14
|
+
import { CheckpointTextError, computeCheckpointDigest } from "./digest.js";
|
|
15
|
+
import { PlanReviewStageError } from "./stage-error.js";
|
|
16
|
+
/** Run-relative location of the runtime-owned canonical plan snapshot. */
|
|
17
|
+
export const PLAN_SNAPSHOT_RELPATH = join("plan-review", "plan.snapshot.md");
|
|
18
|
+
export const MAX_PLAN_SNAPSHOT_BYTES = 524_288;
|
|
19
|
+
/** Run-relative location of the persisted normalized execution contract. */
|
|
20
|
+
export const EXECUTION_CONTRACT_RELPATH = join("plan-review", "execution-contract.json");
|
|
21
|
+
/** Hard cap for both initial serialization and resume reads. */
|
|
22
|
+
export const MAX_EXECUTION_CONTRACT_BYTES = 262_144;
|
|
23
|
+
function sha256Hex(bytes) {
|
|
24
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The generic containment error names allowed roots without saying WHICH roots,
|
|
28
|
+
* which reads as `CLINKX_ALLOWED_ROOTS` — but plan_file is bound to the
|
|
29
|
+
* workflows workspace root alone. Name the root that actually applies.
|
|
30
|
+
*
|
|
31
|
+
* Only allowed-roots rejections get the hint; a symlink/non-regular rejection
|
|
32
|
+
* from the same error class is not a roots problem. Gated on the STRUCTURED
|
|
33
|
+
* `reason` discriminator rather than message wording: substring-matching the
|
|
34
|
+
* message coupled this hint to prose that is free to be reworded, and would
|
|
35
|
+
* false-positive on any path whose own name happens to contain the phrase.
|
|
36
|
+
*/
|
|
37
|
+
function planRootHint(err) {
|
|
38
|
+
if (err.reason !== "outside_allowed_roots")
|
|
39
|
+
return "";
|
|
40
|
+
return (" — plan_file must live under the workflows workspace root" +
|
|
41
|
+
" (CLINKX_WORKFLOWS_WORKSPACE_ROOT, defaulting to the server's process.cwd())." +
|
|
42
|
+
" CLINKX_ALLOWED_ROOTS is NOT consulted for plan_file and cannot widen plan-source admission.");
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Read `plan_file` EXACTLY ONCE (contained, no-follow, regular-file only),
|
|
46
|
+
* canonicalize it, and verify the caller's claimed digest — without writing
|
|
47
|
+
* anything.
|
|
48
|
+
*
|
|
49
|
+
* The read is split from the write because the expander now inlines the
|
|
50
|
+
* snapshot TEXT into every actor's prompt (D9), so the verified text must exist
|
|
51
|
+
* before the run's definition is composed, while the run directory that holds
|
|
52
|
+
* the persisted copy cannot exist until the state store creates it. Splitting
|
|
53
|
+
* keeps `plan_file` read once and keeps the digest verified BEFORE the text is
|
|
54
|
+
* used for anything.
|
|
55
|
+
*
|
|
56
|
+
* Failure classes map to the plan's post-state pre-seat stages:
|
|
57
|
+
* - containment / symlink / non-regular / unreadable / invalid text → `snapshot`
|
|
58
|
+
* - canonical digest ≠ claimed digest → `digest`
|
|
59
|
+
*/
|
|
60
|
+
export async function readCanonicalPlanSnapshot(input) {
|
|
61
|
+
let raw;
|
|
62
|
+
try {
|
|
63
|
+
const read = await readContainedAbsoluteFile(input.allowedRoots, input.planFile, { wantBytes: true, requireRegular: true, maxBytes: MAX_PLAN_SNAPSHOT_BYTES });
|
|
64
|
+
raw = read.bytes;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
if (err instanceof ContainedFilePolicyError) {
|
|
68
|
+
throw new PlanReviewStageError("snapshot", `${err.message}${planRootHint(err)}`, "invalid_output");
|
|
69
|
+
}
|
|
70
|
+
throw new PlanReviewStageError("snapshot", `plan_file could not be read: ${err instanceof Error ? err.message : String(err)}`, "no_artifact");
|
|
71
|
+
}
|
|
72
|
+
let canonical;
|
|
73
|
+
let planDigest;
|
|
74
|
+
try {
|
|
75
|
+
const computed = computeCheckpointDigest(raw);
|
|
76
|
+
canonical = computed.canonicalBytes;
|
|
77
|
+
planDigest = computed.digest;
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
if (err instanceof CheckpointTextError) {
|
|
81
|
+
throw new PlanReviewStageError("snapshot", `plan_file is not valid checkpoint-text-v1 input: ${err.message}`, "invalid_output");
|
|
82
|
+
}
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
// checkpoint-text-v1 appends a final LF when absent. Bound the canonical
|
|
86
|
+
// bytes that are persisted and resumed, not merely the raw source bytes.
|
|
87
|
+
if (canonical.byteLength > MAX_PLAN_SNAPSHOT_BYTES) {
|
|
88
|
+
throw new PlanReviewStageError("snapshot", `canonical plan snapshot exceeds ${String(MAX_PLAN_SNAPSHOT_BYTES)} bytes`, "invalid_output");
|
|
89
|
+
}
|
|
90
|
+
if (planDigest !== input.claimedDigest) {
|
|
91
|
+
throw new PlanReviewStageError("digest", `plan_file digest ${planDigest} does not match the bound plan_review.digest ${input.claimedDigest}`, "schema_mismatch");
|
|
92
|
+
}
|
|
93
|
+
return { canonicalBytes: canonical, planDigest, text: canonical.toString("utf-8") };
|
|
94
|
+
}
|
|
95
|
+
/** Copy already-verified canonical bytes into the runtime-owned run directory. */
|
|
96
|
+
export async function persistCanonicalPlanSnapshot(runDir, canonical) {
|
|
97
|
+
const absolutePath = join(runDir, PLAN_SNAPSHOT_RELPATH);
|
|
98
|
+
await mkdir(dirname(absolutePath), { recursive: true });
|
|
99
|
+
// `wx` — the snapshot is written exactly once per run and never overwritten.
|
|
100
|
+
await writeFile(absolutePath, canonical.canonicalBytes, { flag: "wx" });
|
|
101
|
+
return {
|
|
102
|
+
relPath: PLAN_SNAPSHOT_RELPATH,
|
|
103
|
+
absolutePath,
|
|
104
|
+
sha256: sha256Hex(canonical.canonicalBytes),
|
|
105
|
+
planDigest: canonical.planDigest,
|
|
106
|
+
bytes: canonical.canonicalBytes.byteLength,
|
|
107
|
+
text: canonical.text,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/** Read + verify + persist in one step. The composition callers used before. */
|
|
111
|
+
export async function materializePlanSnapshot(input) {
|
|
112
|
+
return await persistCanonicalPlanSnapshot(input.runDir, await readCanonicalPlanSnapshot(input));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Re-verify the persisted snapshot from run-owned storage alone. Used on resume:
|
|
116
|
+
* it re-reads the SNAPSHOT (never `plan_file`) through the contained no-follow
|
|
117
|
+
* reader and recomputes both the file hash and the checkpoint digest.
|
|
118
|
+
*
|
|
119
|
+
* Returns the verified snapshot rather than discarding the bytes it already
|
|
120
|
+
* read. Resume needs the canonical TEXT — it is the only thing a persisted
|
|
121
|
+
* prepared input's prompt can be checked against (D9), and the check must run
|
|
122
|
+
* before any provider exists. Returning it here keeps the snapshot read ONCE:
|
|
123
|
+
* re-reading it at the validation seam would reopen a D9-class TOCTOU between
|
|
124
|
+
* verification and use.
|
|
125
|
+
*/
|
|
126
|
+
export async function verifyPersistedPlanSnapshot(runDir, relPath, expectedSha256, expectedPlanDigest) {
|
|
127
|
+
let bytes;
|
|
128
|
+
try {
|
|
129
|
+
const read = await readContainedRelativeFile(runDir, relPath, {
|
|
130
|
+
wantBytes: true,
|
|
131
|
+
requireRegular: true,
|
|
132
|
+
maxBytes: MAX_PLAN_SNAPSHOT_BYTES,
|
|
133
|
+
});
|
|
134
|
+
bytes = read.bytes;
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
throw new PlanReviewStageError("snapshot", `Persisted plan snapshot at ${relPath} is unreadable: ${err instanceof Error ? err.message : String(err)}`, err instanceof ContainedFilePolicyError ? "invalid_output" : "no_artifact");
|
|
138
|
+
}
|
|
139
|
+
if (sha256Hex(bytes) !== expectedSha256) {
|
|
140
|
+
throw new PlanReviewStageError("snapshot", `Persisted plan snapshot at ${relPath} failed its hash check`, "schema_mismatch");
|
|
141
|
+
}
|
|
142
|
+
// Recompute the checkpoint digest from the persisted bytes rather than trust
|
|
143
|
+
// the recorded value: the snapshot must still BE the bound plan revision.
|
|
144
|
+
let canonicalBytes;
|
|
145
|
+
let planDigest;
|
|
146
|
+
try {
|
|
147
|
+
const computed = computeCheckpointDigest(bytes);
|
|
148
|
+
canonicalBytes = computed.canonicalBytes;
|
|
149
|
+
planDigest = computed.digest;
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
throw new PlanReviewStageError("snapshot", `Persisted plan snapshot at ${relPath} is not canonical checkpoint text: ${err instanceof Error ? err.message : String(err)}`, "invalid_output");
|
|
153
|
+
}
|
|
154
|
+
if (planDigest !== expectedPlanDigest) {
|
|
155
|
+
throw new PlanReviewStageError("digest", `Persisted plan snapshot digest ${planDigest} does not match the bound digest ${expectedPlanDigest}`, "schema_mismatch");
|
|
156
|
+
}
|
|
157
|
+
return { canonicalBytes, planDigest, text: canonicalBytes.toString("utf-8") };
|
|
158
|
+
}
|
|
159
|
+
/** Persist the normalized execution contract into runtime-owned storage. */
|
|
160
|
+
export async function writeExecutionContractSnapshot(runDir, contract) {
|
|
161
|
+
const absolutePath = join(runDir, EXECUTION_CONTRACT_RELPATH);
|
|
162
|
+
const bytes = Buffer.from(`${JSON.stringify(contract, null, 2)}\n`, "utf-8");
|
|
163
|
+
if (bytes.byteLength > MAX_EXECUTION_CONTRACT_BYTES) {
|
|
164
|
+
throw new PlanReviewStageError("execution_contract", `serialized execution contract exceeds ${String(MAX_EXECUTION_CONTRACT_BYTES)} bytes`, "invalid_output");
|
|
165
|
+
}
|
|
166
|
+
await mkdir(dirname(absolutePath), { recursive: true });
|
|
167
|
+
await writeFile(absolutePath, bytes, { flag: "wx" });
|
|
168
|
+
return { relPath: EXECUTION_CONTRACT_RELPATH, sha256: sha256Hex(bytes) };
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/plan-review/snapshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { PlanReviewErrorReasonSchema } from "./contract.js";
|
|
3
|
+
import type { CouncilPlanReviewErrorSchema } from "./publication.js";
|
|
4
|
+
export type PlanReviewErrorStage = z.infer<typeof CouncilPlanReviewErrorSchema>["stage"];
|
|
5
|
+
export type PlanReviewErrorReason = z.infer<typeof PlanReviewErrorReasonSchema>;
|
|
6
|
+
/**
|
|
7
|
+
* A post-state, pre-seat plan-review failure.
|
|
8
|
+
*
|
|
9
|
+
* `stage` — NOT `reason` — is what disambiguates which check failed, because the
|
|
10
|
+
* seat `error.reason` enum has no dedicated snapshot/digest member (see the
|
|
11
|
+
* plan's §Error surface). Carrying the stage on the throw is what lets the
|
|
12
|
+
* caller record `RunState.status=failed` and later surface a bounded
|
|
13
|
+
* `council-plan-review-error-v1` inline; it is never a result sidecar.
|
|
14
|
+
*/
|
|
15
|
+
export declare class PlanReviewStageError extends Error {
|
|
16
|
+
readonly stage: PlanReviewErrorStage;
|
|
17
|
+
readonly reason: PlanReviewErrorReason;
|
|
18
|
+
constructor(stage: PlanReviewErrorStage, message: string, reason?: PlanReviewErrorReason);
|
|
19
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A post-state, pre-seat plan-review failure.
|
|
3
|
+
*
|
|
4
|
+
* `stage` — NOT `reason` — is what disambiguates which check failed, because the
|
|
5
|
+
* seat `error.reason` enum has no dedicated snapshot/digest member (see the
|
|
6
|
+
* plan's §Error surface). Carrying the stage on the throw is what lets the
|
|
7
|
+
* caller record `RunState.status=failed` and later surface a bounded
|
|
8
|
+
* `council-plan-review-error-v1` inline; it is never a result sidecar.
|
|
9
|
+
*/
|
|
10
|
+
export class PlanReviewStageError extends Error {
|
|
11
|
+
stage;
|
|
12
|
+
reason;
|
|
13
|
+
constructor(stage, message, reason = "internal_error") {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = "PlanReviewStageError";
|
|
16
|
+
this.stage = stage;
|
|
17
|
+
this.reason = reason;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=stage-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stage-error.js","sourceRoot":"","sources":["../../src/plan-review/stage-error.ts"],"names":[],"mappings":"AAUA;;;;;;;;GAQG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IACpC,KAAK,CAAuB;IAC5B,MAAM,CAAwB;IAEvC,YACE,KAA2B,EAC3B,OAAe,EACf,SAAgC,gBAAgB;QAEhD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-processor registry for deterministic transforms applied to a validated
|
|
3
|
+
* call output BEFORE it is persisted as an artifact.
|
|
4
|
+
*
|
|
5
|
+
* A call opts in via `post_processor: <name>` in its workflow definition. The
|
|
6
|
+
* engine looks the name up here after JSON validation; if found, the returned
|
|
7
|
+
* value replaces `validated` before the artifact is written. Unknown names fail
|
|
8
|
+
* fast: the loader's static validation (`validatePostProcessors`) throws at
|
|
9
|
+
* workflow load time, and the engine also throws as defense-in-depth if an
|
|
10
|
+
* unregistered name ever reaches execution.
|
|
11
|
+
*/
|
|
12
|
+
/** Inputs available to a post-processor. */
|
|
13
|
+
export type PostProcessorContext = {
|
|
14
|
+
allowlist: Set<string>;
|
|
15
|
+
schemaId: string;
|
|
16
|
+
};
|
|
17
|
+
/** A post-processor transforms a validated artifact value deterministically. */
|
|
18
|
+
export type PostProcessorFn = (validated: unknown, ctx: PostProcessorContext) => unknown;
|
|
19
|
+
export declare function getPostProcessor(id: string): PostProcessorFn | undefined;
|
|
20
|
+
export declare function registerPostProcessor(id: string, fn: PostProcessorFn): void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-processor registry for deterministic transforms applied to a validated
|
|
3
|
+
* call output BEFORE it is persisted as an artifact.
|
|
4
|
+
*
|
|
5
|
+
* A call opts in via `post_processor: <name>` in its workflow definition. The
|
|
6
|
+
* engine looks the name up here after JSON validation; if found, the returned
|
|
7
|
+
* value replaces `validated` before the artifact is written. Unknown names fail
|
|
8
|
+
* fast: the loader's static validation (`validatePostProcessors`) throws at
|
|
9
|
+
* workflow load time, and the engine also throws as defense-in-depth if an
|
|
10
|
+
* unregistered name ever reaches execution.
|
|
11
|
+
*/
|
|
12
|
+
import { citationCheck } from "../citation-check.js";
|
|
13
|
+
const registry = new Map();
|
|
14
|
+
registry.set("citation_check", citationCheck);
|
|
15
|
+
export function getPostProcessor(id) {
|
|
16
|
+
return registry.get(id);
|
|
17
|
+
}
|
|
18
|
+
export function registerPostProcessor(id, fn) {
|
|
19
|
+
registry.set(id, fn);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/post-processors/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAWrD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAC;AACpD,QAAQ,CAAC,GAAG,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;AAE9C,MAAM,UAAU,gBAAgB,CAAC,EAAU;IACzC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EAAU,EAAE,EAAmB;IACnE,QAAQ,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AACvB,CAAC"}
|
|
@@ -26,6 +26,13 @@ export interface PromptBudgetInput {
|
|
|
26
26
|
readonly reserveBytes?: number | undefined;
|
|
27
27
|
readonly maxBytes?: number | undefined;
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Reserve margin for child-side prompt assembly overhead, applied to every
|
|
31
|
+
* dispatched call whose caller supplies no explicit `reserveBytes` (nothing
|
|
32
|
+
* currently does). Exported so a pre-dispatch guard can DERIVE the same reserve
|
|
33
|
+
* the engine will actually bill rather than re-literal it and drift.
|
|
34
|
+
*/
|
|
35
|
+
export declare const DEFAULT_RESERVE_BYTES = 100000;
|
|
29
36
|
export declare function estimatePromptBudget(input: PromptBudgetInput): PromptBudgetEstimate;
|
|
30
37
|
export declare function createPathContributor(label: string, path: string, kind: "context" | "file" | "image"): PromptBudgetContributor;
|
|
31
38
|
export declare function enforcePromptBudget(estimate: PromptBudgetEstimate): void;
|
|
@@ -8,7 +8,13 @@
|
|
|
8
8
|
import { statSync } from "node:fs";
|
|
9
9
|
import { getMaxPromptBytes } from "./config.js";
|
|
10
10
|
import { WorkflowError } from "./errors.js";
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Reserve margin for child-side prompt assembly overhead, applied to every
|
|
13
|
+
* dispatched call whose caller supplies no explicit `reserveBytes` (nothing
|
|
14
|
+
* currently does). Exported so a pre-dispatch guard can DERIVE the same reserve
|
|
15
|
+
* the engine will actually bill rather than re-literal it and drift.
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_RESERVE_BYTES = 100_000;
|
|
12
18
|
export function estimatePromptBudget(input) {
|
|
13
19
|
const contributors = [
|
|
14
20
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-budget.js","sourceRoot":"","sources":["../src/prompt-budget.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA0B5C,MAAM,qBAAqB,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"prompt-budget.js","sourceRoot":"","sources":["../src/prompt-budget.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Reducers run in place of LLM calls when a call specifies a `reducer` ID.
|
|
5
5
|
*/
|
|
6
|
+
import { planReviewRankingReducer } from "../plan-review/ranking-reducer.js";
|
|
6
7
|
import { councilRankingReducer } from "../ranking-reducer.js";
|
|
7
8
|
const registry = new Map();
|
|
8
9
|
registry.set("council_ranking_v1", councilRankingReducer);
|
|
10
|
+
registry.set("plan_review_ranking_v1", planReviewRankingReducer);
|
|
9
11
|
export function getReducer(id) {
|
|
10
12
|
return registry.get(id);
|
|
11
13
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reducers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAI9D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;AAC9C,QAAQ,CAAC,GAAG,CAAC,oBAAoB,EAAE,qBAAqB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reducers/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAI9D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;AAC9C,QAAQ,CAAC,GAAG,CAAC,oBAAoB,EAAE,qBAAqB,CAAC,CAAC;AAC1D,QAAQ,CAAC,GAAG,CAAC,wBAAwB,EAAE,wBAAwB,CAAC,CAAC;AAEjE,MAAM,UAAU,UAAU,CAAC,EAAU;IACnC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-lock-heartbeat.js","sourceRoot":"","sources":["../src/run-lock-heartbeat.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,MAAM,CAAC,MAAM,iCAAiC,GAAG,MAAM,CAAC"}
|