smol-symphony 0.2.0 → 0.3.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/AGENTS.md +41 -22
- package/DESIGN.md +494 -273
- package/README.md +109 -57
- package/SPEC.md +33 -24
- package/WORKFLOW.minimal.yaml +34 -0
- package/{WORKFLOW.template.md → WORKFLOW.template.yaml} +409 -256
- package/WORKFLOW.yaml +487 -0
- package/assets/skills/symphony-issues/SKILL.md +136 -0
- package/assets/symphony-mise.system.toml +68 -0
- package/dist/src/bin/symphony.js +30 -0
- package/dist/src/bin/symphony.js.map +1 -0
- package/dist/src/core/actions/context.js +109 -0
- package/dist/src/core/actions/context.js.map +1 -0
- package/dist/{actions/parsing.js → src/core/actions/parse.js} +33 -114
- package/dist/src/core/actions/parse.js.map +1 -0
- package/dist/src/core/actions/plan.js +197 -0
- package/dist/src/core/actions/plan.js.map +1 -0
- package/dist/src/core/actions/predicates.js +111 -0
- package/dist/src/core/actions/predicates.js.map +1 -0
- package/dist/src/core/actions/run-fold.js +248 -0
- package/dist/src/core/actions/run-fold.js.map +1 -0
- package/dist/src/core/actions/template.js +118 -0
- package/dist/src/core/actions/template.js.map +1 -0
- package/dist/src/core/cli/args.js +116 -0
- package/dist/src/core/cli/args.js.map +1 -0
- package/dist/src/core/coerce.js +75 -0
- package/dist/src/core/coerce.js.map +1 -0
- package/dist/src/core/credential/account-id.js +20 -0
- package/dist/src/core/credential/account-id.js.map +1 -0
- package/dist/src/core/credential/adapter-config.js +136 -0
- package/dist/src/core/credential/adapter-config.js.map +1 -0
- package/dist/src/core/credential/availability.js +98 -0
- package/dist/src/core/credential/availability.js.map +1 -0
- package/dist/src/core/credential/extract.js +228 -0
- package/dist/src/core/credential/extract.js.map +1 -0
- package/dist/src/core/credential/fake-creds.js +171 -0
- package/dist/src/core/credential/fake-creds.js.map +1 -0
- package/dist/src/core/credential/identity.js +125 -0
- package/dist/src/core/credential/identity.js.map +1 -0
- package/dist/src/core/credential/shape.js +230 -0
- package/dist/src/core/credential/shape.js.map +1 -0
- package/dist/src/core/credential/strings.js +15 -0
- package/dist/src/core/credential/strings.js.map +1 -0
- package/dist/src/core/doctor/checks.js +303 -0
- package/dist/src/core/doctor/checks.js.map +1 -0
- package/dist/src/core/git/result.js +107 -0
- package/dist/src/core/git/result.js.map +1 -0
- package/dist/src/core/http/decisions.js +225 -0
- package/dist/src/core/http/decisions.js.map +1 -0
- package/dist/{http.js → src/core/http/render.js} +472 -738
- package/dist/src/core/http/render.js.map +1 -0
- package/dist/{http-handlers.js → src/core/http/routes.js} +52 -87
- package/dist/src/core/http/routes.js.map +1 -0
- package/dist/src/core/http/views.js +181 -0
- package/dist/src/core/http/views.js.map +1 -0
- package/dist/src/core/image/managed-image.js +95 -0
- package/dist/src/core/image/managed-image.js.map +1 -0
- package/dist/src/core/issue/file.js +149 -0
- package/dist/src/core/issue/file.js.map +1 -0
- package/dist/src/core/issue/parse.js +210 -0
- package/dist/src/core/issue/parse.js.map +1 -0
- package/dist/src/core/mcp/dispatch.js +239 -0
- package/dist/src/core/mcp/dispatch.js.map +1 -0
- package/dist/src/core/mcp/post-move.js +92 -0
- package/dist/src/core/mcp/post-move.js.map +1 -0
- package/dist/src/core/mcp/protocol.js +293 -0
- package/dist/src/core/mcp/protocol.js.map +1 -0
- package/dist/src/core/mcp/url.js +162 -0
- package/dist/src/core/mcp/url.js.map +1 -0
- package/dist/src/core/path.js +63 -0
- package/dist/src/core/path.js.map +1 -0
- package/dist/src/core/reconcile/image-decide.js +48 -0
- package/dist/src/core/reconcile/image-decide.js.map +1 -0
- package/dist/src/core/reconcile/ledger.js +142 -0
- package/dist/src/core/reconcile/ledger.js.map +1 -0
- package/dist/src/core/reconcile/pr-classify.js +62 -0
- package/dist/src/core/reconcile/pr-classify.js.map +1 -0
- package/dist/{reconciler → src/core/reconcile}/pr-decide.js +25 -12
- package/dist/src/core/reconcile/pr-decide.js.map +1 -0
- package/dist/src/core/reconcile/pr-loop.js +161 -0
- package/dist/src/core/reconcile/pr-loop.js.map +1 -0
- package/dist/src/core/reconcile/pr-notes.js +35 -0
- package/dist/src/core/reconcile/pr-notes.js.map +1 -0
- package/dist/src/core/reconcile/vm-decide.js +70 -0
- package/dist/src/core/reconcile/vm-decide.js.map +1 -0
- package/dist/src/core/reconcile/vm-reap.js +207 -0
- package/dist/src/core/reconcile/vm-reap.js.map +1 -0
- package/dist/src/core/reconcile/workspace-decide.js +162 -0
- package/dist/src/core/reconcile/workspace-decide.js.map +1 -0
- package/dist/src/core/runlog/summary.js +231 -0
- package/dist/src/core/runlog/summary.js.map +1 -0
- package/dist/src/core/runner/dispatch-config.js +95 -0
- package/dist/src/core/runner/dispatch-config.js.map +1 -0
- package/dist/src/core/runner/injection.js +61 -0
- package/dist/src/core/runner/injection.js.map +1 -0
- package/dist/src/core/runner/mise.js +210 -0
- package/dist/src/core/runner/mise.js.map +1 -0
- package/dist/src/core/runner/prompt.js +720 -0
- package/dist/src/core/runner/prompt.js.map +1 -0
- package/dist/src/core/runner/turn.js +242 -0
- package/dist/src/core/runner/turn.js.map +1 -0
- package/dist/src/core/runner/vm-plan.js +390 -0
- package/dist/src/core/runner/vm-plan.js.map +1 -0
- package/dist/src/core/schedule/admission.js +123 -0
- package/dist/src/core/schedule/admission.js.map +1 -0
- package/dist/src/core/schedule/circuit-breaker.js +111 -0
- package/dist/src/core/schedule/circuit-breaker.js.map +1 -0
- package/dist/src/core/schedule/eligibility.js +83 -0
- package/dist/src/core/schedule/eligibility.js.map +1 -0
- package/dist/src/core/schedule/reconcile-issue.js +82 -0
- package/dist/src/core/schedule/reconcile-issue.js.map +1 -0
- package/dist/src/core/schedule/retry.js +96 -0
- package/dist/src/core/schedule/retry.js.map +1 -0
- package/dist/src/core/schedule/sleep-cycle.js +133 -0
- package/dist/src/core/schedule/sleep-cycle.js.map +1 -0
- package/dist/src/core/schedule/slots.js +124 -0
- package/dist/src/core/schedule/slots.js.map +1 -0
- package/dist/src/core/schedule/tick.js +553 -0
- package/dist/src/core/schedule/tick.js.map +1 -0
- package/dist/src/core/schedule/token-fold.js +181 -0
- package/dist/src/core/schedule/token-fold.js.map +1 -0
- package/dist/src/core/state-resolve.js +86 -0
- package/dist/src/core/state-resolve.js.map +1 -0
- package/dist/src/core/vm-guards.js +278 -0
- package/dist/src/core/vm-guards.js.map +1 -0
- package/dist/src/core/workflow/derive.js +107 -0
- package/dist/src/core/workflow/derive.js.map +1 -0
- package/dist/src/core/workflow/parse.js +687 -0
- package/dist/src/core/workflow/parse.js.map +1 -0
- package/dist/src/core/workflow/prompt-probe.js +78 -0
- package/dist/src/core/workflow/prompt-probe.js.map +1 -0
- package/dist/src/core/workflow/validate.js +189 -0
- package/dist/src/core/workflow/validate.js.map +1 -0
- package/dist/src/core/workspace-key.js +19 -0
- package/dist/src/core/workspace-key.js.map +1 -0
- package/dist/src/shell/actions-runner.js +356 -0
- package/dist/src/shell/actions-runner.js.map +1 -0
- package/dist/src/shell/adapter/adapter-registry.js +45 -0
- package/dist/src/shell/adapter/adapter-registry.js.map +1 -0
- package/dist/src/shell/adapter/clock-random.js +96 -0
- package/dist/src/shell/adapter/clock-random.js.map +1 -0
- package/dist/src/shell/adapter/gondolin-dispatch-helpers.js +158 -0
- package/dist/src/shell/adapter/gondolin-dispatch-helpers.js.map +1 -0
- package/dist/src/shell/adapter/gondolin-dispatch.js +385 -0
- package/dist/src/shell/adapter/gondolin-dispatch.js.map +1 -0
- package/dist/src/shell/adapter/gondolin-image-converter.js +233 -0
- package/dist/src/shell/adapter/gondolin-image-converter.js.map +1 -0
- package/dist/src/shell/adapter/gondolin-image-fetch.js +180 -0
- package/dist/src/shell/adapter/gondolin-image-fetch.js.map +1 -0
- package/dist/src/shell/adapter/launcher-asset.js +57 -0
- package/dist/src/shell/adapter/launcher-asset.js.map +1 -0
- package/dist/src/shell/adapter/mise-config-asset.js +65 -0
- package/dist/src/shell/adapter/mise-config-asset.js.map +1 -0
- package/dist/src/shell/adapter/workflow-loader.js +304 -0
- package/dist/src/shell/adapter/workflow-loader.js.map +1 -0
- package/dist/src/shell/cli/doctor.js +268 -0
- package/dist/src/shell/cli/doctor.js.map +1 -0
- package/dist/src/shell/effect-interpreter-families.js +314 -0
- package/dist/src/shell/effect-interpreter-families.js.map +1 -0
- package/dist/src/shell/effect-interpreter.js +29 -0
- package/dist/src/shell/effect-interpreter.js.map +1 -0
- package/dist/src/shell/interp/acp-frame.js +137 -0
- package/dist/src/shell/interp/acp-frame.js.map +1 -0
- package/dist/src/shell/interp/acp-ws-conn.js +320 -0
- package/dist/src/shell/interp/acp-ws-conn.js.map +1 -0
- package/dist/src/shell/interp/acp-ws-frames.js +159 -0
- package/dist/src/shell/interp/acp-ws-frames.js.map +1 -0
- package/dist/src/shell/interp/acp-ws.js +197 -0
- package/dist/src/shell/interp/acp-ws.js.map +1 -0
- package/dist/src/shell/interp/acp.js +319 -0
- package/dist/src/shell/interp/acp.js.map +1 -0
- package/dist/src/shell/interp/credential-defaults.js +128 -0
- package/dist/src/shell/interp/credential-defaults.js.map +1 -0
- package/dist/src/shell/interp/credential-hooks.js +149 -0
- package/dist/src/shell/interp/credential-hooks.js.map +1 -0
- package/dist/src/shell/interp/credential-registry.js +226 -0
- package/dist/src/shell/interp/credential-registry.js.map +1 -0
- package/dist/src/shell/interp/credential.js +103 -0
- package/dist/src/shell/interp/credential.js.map +1 -0
- package/dist/src/shell/interp/gh.js +163 -0
- package/dist/src/shell/interp/gh.js.map +1 -0
- package/dist/src/shell/interp/git.js +28 -0
- package/dist/src/shell/interp/git.js.map +1 -0
- package/dist/src/shell/interp/log.js +213 -0
- package/dist/src/shell/interp/log.js.map +1 -0
- package/dist/src/shell/interp/process.js +178 -0
- package/dist/src/shell/interp/process.js.map +1 -0
- package/dist/src/shell/interp/runlog.js +193 -0
- package/dist/src/shell/interp/runlog.js.map +1 -0
- package/dist/src/shell/interp/timer.js +64 -0
- package/dist/src/shell/interp/timer.js.map +1 -0
- package/dist/src/shell/interp/tracker-disk.js +99 -0
- package/dist/src/shell/interp/tracker-disk.js.map +1 -0
- package/dist/src/shell/interp/tracker-parse.js +71 -0
- package/dist/src/shell/interp/tracker-parse.js.map +1 -0
- package/dist/src/shell/interp/tracker-scan.js +238 -0
- package/dist/src/shell/interp/tracker-scan.js.map +1 -0
- package/dist/src/shell/interp/tracker-write.js +91 -0
- package/dist/src/shell/interp/tracker-write.js.map +1 -0
- package/dist/src/shell/interp/tracker.js +41 -0
- package/dist/src/shell/interp/tracker.js.map +1 -0
- package/dist/src/shell/interp/tty.js +48 -0
- package/dist/src/shell/interp/tty.js.map +1 -0
- package/dist/src/shell/interp/vm.js +199 -0
- package/dist/src/shell/interp/vm.js.map +1 -0
- package/dist/src/shell/interp/workspace.js +310 -0
- package/dist/src/shell/interp/workspace.js.map +1 -0
- package/dist/src/shell/main-acp.js +78 -0
- package/dist/src/shell/main-acp.js.map +1 -0
- package/dist/src/shell/main-adapters.js +222 -0
- package/dist/src/shell/main-adapters.js.map +1 -0
- package/dist/src/shell/main-credential.js +122 -0
- package/dist/src/shell/main-credential.js.map +1 -0
- package/dist/src/shell/main-doctor.js +22 -0
- package/dist/src/shell/main-doctor.js.map +1 -0
- package/dist/src/shell/main-entry.js +46 -0
- package/dist/src/shell/main-entry.js.map +1 -0
- package/dist/src/shell/main-http-csrf.js +45 -0
- package/dist/src/shell/main-http-csrf.js.map +1 -0
- package/dist/src/shell/main-http-handler.js +389 -0
- package/dist/src/shell/main-http-handler.js.map +1 -0
- package/dist/src/shell/main-http-mcp.js +122 -0
- package/dist/src/shell/main-http-mcp.js.map +1 -0
- package/dist/src/shell/main-http-views.js +253 -0
- package/dist/src/shell/main-http-views.js.map +1 -0
- package/dist/src/shell/main-http.js +76 -0
- package/dist/src/shell/main-http.js.map +1 -0
- package/dist/src/shell/main-loops.js +130 -0
- package/dist/src/shell/main-loops.js.map +1 -0
- package/dist/src/shell/main-mcp.js +129 -0
- package/dist/src/shell/main-mcp.js.map +1 -0
- package/dist/src/shell/main-orchestrator.js +120 -0
- package/dist/src/shell/main-orchestrator.js.map +1 -0
- package/dist/src/shell/main-preflight.js +43 -0
- package/dist/src/shell/main-preflight.js.map +1 -0
- package/dist/src/shell/main-reconcilers-helpers.js +244 -0
- package/dist/src/shell/main-reconcilers-helpers.js.map +1 -0
- package/dist/src/shell/main-reconcilers-pr.js +148 -0
- package/dist/src/shell/main-reconcilers-pr.js.map +1 -0
- package/dist/src/shell/main-reconcilers.js +225 -0
- package/dist/src/shell/main-reconcilers.js.map +1 -0
- package/dist/src/shell/main-runner.js +355 -0
- package/dist/src/shell/main-runner.js.map +1 -0
- package/dist/src/shell/main-scaffold.js +116 -0
- package/dist/src/shell/main-scaffold.js.map +1 -0
- package/dist/src/shell/main-shutdown.js +115 -0
- package/dist/src/shell/main-shutdown.js.map +1 -0
- package/dist/src/shell/main-startup.js +48 -0
- package/dist/src/shell/main-startup.js.map +1 -0
- package/dist/src/shell/main-substrates.js +43 -0
- package/dist/src/shell/main-substrates.js.map +1 -0
- package/dist/src/shell/main.js +385 -0
- package/dist/src/shell/main.js.map +1 -0
- package/dist/src/shell/orchestrator-feedback.js +69 -0
- package/dist/src/shell/orchestrator-feedback.js.map +1 -0
- package/dist/src/shell/orchestrator-image.js +167 -0
- package/dist/src/shell/orchestrator-image.js.map +1 -0
- package/dist/src/shell/orchestrator-loop.js +468 -0
- package/dist/src/shell/orchestrator-loop.js.map +1 -0
- package/dist/src/shell/orchestrator-reconcile.js +36 -0
- package/dist/src/shell/orchestrator-reconcile.js.map +1 -0
- package/dist/src/shell/reconciler-loop.js +228 -0
- package/dist/src/shell/reconciler-loop.js.map +1 -0
- package/dist/src/shell/runner-loop-turn.js +301 -0
- package/dist/src/shell/runner-loop-turn.js.map +1 -0
- package/dist/src/shell/runner-loop.js +338 -0
- package/dist/src/shell/runner-loop.js.map +1 -0
- package/dist/src/shell/server/http.js +208 -0
- package/dist/src/shell/server/http.js.map +1 -0
- package/dist/src/shell/server/mcp-runtime-effects.js +237 -0
- package/dist/src/shell/server/mcp-runtime-effects.js.map +1 -0
- package/dist/src/shell/server/mcp-runtime.js +99 -0
- package/dist/src/shell/server/mcp-runtime.js.map +1 -0
- package/dist/src/shell/workspace-key.js +14 -0
- package/dist/src/shell/workspace-key.js.map +1 -0
- package/dist/src/types/acp.js +8 -0
- package/dist/src/types/acp.js.map +1 -0
- package/dist/src/types/actions/plan.js +6 -0
- package/dist/src/types/actions/plan.js.map +1 -0
- package/dist/src/types/actions/predicates.js +6 -0
- package/dist/src/types/actions/predicates.js.map +1 -0
- package/dist/src/types/actions/run-fold.js +8 -0
- package/dist/src/types/actions/run-fold.js.map +1 -0
- package/dist/src/types/actions.js +7 -0
- package/dist/src/types/actions.js.map +1 -0
- package/dist/src/types/adapter/clock-random.js +4 -0
- package/dist/src/types/adapter/clock-random.js.map +1 -0
- package/dist/src/types/adapter/gondolin-image-converter.js +5 -0
- package/dist/src/types/adapter/gondolin-image-converter.js.map +1 -0
- package/dist/src/types/adapter/gondolin-image-fetch.js +5 -0
- package/dist/src/types/adapter/gondolin-image-fetch.js.map +1 -0
- package/dist/src/types/adapter/workflow-loader.js +4 -0
- package/dist/src/types/adapter/workflow-loader.js.map +1 -0
- package/dist/src/types/cli/args.js +8 -0
- package/dist/src/types/cli/args.js.map +1 -0
- package/dist/src/types/config.js +8 -0
- package/dist/src/types/config.js.map +1 -0
- package/dist/src/types/credential-interp.js +6 -0
- package/dist/src/types/credential-interp.js.map +1 -0
- package/dist/src/types/credentials.js +10 -0
- package/dist/src/types/credentials.js.map +1 -0
- package/dist/src/types/doctor.js +7 -0
- package/dist/src/types/doctor.js.map +1 -0
- package/dist/src/types/domain.js +7 -0
- package/dist/src/types/domain.js.map +1 -0
- package/dist/src/types/effect.js +15 -0
- package/dist/src/types/effect.js.map +1 -0
- package/dist/src/types/errors.js +39 -0
- package/dist/src/types/errors.js.map +1 -0
- package/dist/src/types/http/decisions.js +6 -0
- package/dist/src/types/http/decisions.js.map +1 -0
- package/dist/src/types/http/render.js +10 -0
- package/dist/src/types/http/render.js.map +1 -0
- package/dist/src/types/http/views.js +6 -0
- package/dist/src/types/http/views.js.map +1 -0
- package/dist/src/types/http.js +9 -0
- package/dist/src/types/http.js.map +1 -0
- package/dist/src/types/image/managed-image.js +7 -0
- package/dist/src/types/image/managed-image.js.map +1 -0
- package/dist/src/types/interp/effect-interpreter.js +8 -0
- package/dist/src/types/interp/effect-interpreter.js.map +1 -0
- package/dist/src/types/interp/tracker.js +7 -0
- package/dist/src/types/interp/tracker.js.map +1 -0
- package/dist/src/types/issue/file.js +6 -0
- package/dist/src/types/issue/file.js.map +1 -0
- package/dist/src/types/issue/parse.js +8 -0
- package/dist/src/types/issue/parse.js.map +1 -0
- package/dist/src/types/main-acp.js +13 -0
- package/dist/src/types/main-acp.js.map +1 -0
- package/dist/src/types/main-adapters.js +5 -0
- package/dist/src/types/main-adapters.js.map +1 -0
- package/dist/src/types/main-credential.js +21 -0
- package/dist/src/types/main-credential.js.map +1 -0
- package/dist/src/types/main-doctor.js +6 -0
- package/dist/src/types/main-doctor.js.map +1 -0
- package/dist/src/types/main-http-handler.js +12 -0
- package/dist/src/types/main-http-handler.js.map +1 -0
- package/dist/src/types/main-http.js +5 -0
- package/dist/src/types/main-http.js.map +1 -0
- package/dist/src/types/main-loops.js +5 -0
- package/dist/src/types/main-loops.js.map +1 -0
- package/dist/src/types/main-mcp.js +12 -0
- package/dist/src/types/main-mcp.js.map +1 -0
- package/dist/src/types/main-orchestrator.js +5 -0
- package/dist/src/types/main-orchestrator.js.map +1 -0
- package/dist/src/types/main-reconcilers.js +11 -0
- package/dist/src/types/main-reconcilers.js.map +1 -0
- package/dist/src/types/main-runner.js +13 -0
- package/dist/src/types/main-runner.js.map +1 -0
- package/dist/src/types/main-startup.js +5 -0
- package/dist/src/types/main-startup.js.map +1 -0
- package/dist/src/types/main-substrates.js +5 -0
- package/dist/src/types/main-substrates.js.map +1 -0
- package/dist/src/types/mcp/dispatch.js +4 -0
- package/dist/src/types/mcp/dispatch.js.map +1 -0
- package/dist/src/types/mcp/post-move.js +7 -0
- package/dist/src/types/mcp/post-move.js.map +1 -0
- package/dist/src/types/mcp.js +9 -0
- package/dist/src/types/mcp.js.map +1 -0
- package/dist/src/types/ports.js +12 -0
- package/dist/src/types/ports.js.map +1 -0
- package/dist/src/types/reconcile/image-decide.js +5 -0
- package/dist/src/types/reconcile/image-decide.js.map +1 -0
- package/dist/src/types/reconcile/ledger.js +7 -0
- package/dist/src/types/reconcile/ledger.js.map +1 -0
- package/dist/src/types/reconcile/pr-loop.js +8 -0
- package/dist/src/types/reconcile/pr-loop.js.map +1 -0
- package/dist/src/types/reconcile/vm-reap.js +8 -0
- package/dist/src/types/reconcile/vm-reap.js.map +1 -0
- package/dist/src/types/reconcile/workspace-decide.js +7 -0
- package/dist/src/types/reconcile/workspace-decide.js.map +1 -0
- package/dist/src/types/reconcile.js +9 -0
- package/dist/src/types/reconcile.js.map +1 -0
- package/dist/src/types/runlog.js +7 -0
- package/dist/src/types/runlog.js.map +1 -0
- package/dist/src/types/runner/actions-runner.js +12 -0
- package/dist/src/types/runner/actions-runner.js.map +1 -0
- package/dist/src/types/runner/gondolin-dispatch.js +5 -0
- package/dist/src/types/runner/gondolin-dispatch.js.map +1 -0
- package/dist/src/types/runner/injection.js +6 -0
- package/dist/src/types/runner/injection.js.map +1 -0
- package/dist/src/types/runner/runner-loop.js +5 -0
- package/dist/src/types/runner/runner-loop.js.map +1 -0
- package/dist/src/types/runner/turn.js +4 -0
- package/dist/src/types/runner/turn.js.map +1 -0
- package/dist/src/types/runner/vm-plan.js +4 -0
- package/dist/src/types/runner/vm-plan.js.map +1 -0
- package/dist/src/types/runtime.js +9 -0
- package/dist/src/types/runtime.js.map +1 -0
- package/dist/src/types/schedule/admission.js +7 -0
- package/dist/src/types/schedule/admission.js.map +1 -0
- package/dist/src/types/schedule/circuit-breaker.js +2 -0
- package/dist/src/types/schedule/circuit-breaker.js.map +1 -0
- package/dist/src/types/schedule/eligibility.js +9 -0
- package/dist/src/types/schedule/eligibility.js.map +1 -0
- package/dist/src/types/schedule/orchestrator-loop.js +10 -0
- package/dist/src/types/schedule/orchestrator-loop.js.map +1 -0
- package/dist/src/types/schedule/sleep-cycle.js +4 -0
- package/dist/src/types/schedule/sleep-cycle.js.map +1 -0
- package/dist/src/types/schedule/slots.js +8 -0
- package/dist/src/types/schedule/slots.js.map +1 -0
- package/dist/src/types/schedule/tick.js +9 -0
- package/dist/src/types/schedule/tick.js.map +1 -0
- package/dist/src/types/server/mcp-runtime.js +8 -0
- package/dist/src/types/server/mcp-runtime.js.map +1 -0
- package/dist/src/types/workflow/parse.js +4 -0
- package/dist/src/types/workflow/parse.js.map +1 -0
- package/dist/tests/core/account-id.test.js +35 -0
- package/dist/tests/core/account-id.test.js.map +1 -0
- package/dist/tests/core/actions-parse.test.js +176 -0
- package/dist/tests/core/actions-parse.test.js.map +1 -0
- package/dist/tests/core/adapter-config.test.js +133 -0
- package/dist/tests/core/adapter-config.test.js.map +1 -0
- package/dist/tests/core/admission.test.js +215 -0
- package/dist/tests/core/admission.test.js.map +1 -0
- package/dist/tests/core/args.test.js +132 -0
- package/dist/tests/core/args.test.js.map +1 -0
- package/dist/tests/core/availability.test.js +62 -0
- package/dist/tests/core/availability.test.js.map +1 -0
- package/dist/tests/core/checks.test.js +395 -0
- package/dist/tests/core/checks.test.js.map +1 -0
- package/dist/tests/core/circuit-breaker.test.js +172 -0
- package/dist/tests/core/circuit-breaker.test.js.map +1 -0
- package/dist/tests/core/coerce.test.js +87 -0
- package/dist/tests/core/coerce.test.js.map +1 -0
- package/dist/tests/core/context.test.js +228 -0
- package/dist/tests/core/context.test.js.map +1 -0
- package/dist/tests/core/decisions.test.js +310 -0
- package/dist/tests/core/decisions.test.js.map +1 -0
- package/dist/tests/core/derive.test.js +205 -0
- package/dist/tests/core/derive.test.js.map +1 -0
- package/dist/tests/core/dispatch-config.test.js +164 -0
- package/dist/tests/core/dispatch-config.test.js.map +1 -0
- package/dist/tests/core/dispatch.test.js +302 -0
- package/dist/tests/core/dispatch.test.js.map +1 -0
- package/dist/tests/core/eligibility.test.js +163 -0
- package/dist/tests/core/eligibility.test.js.map +1 -0
- package/dist/tests/core/extract.test.js +139 -0
- package/dist/tests/core/extract.test.js.map +1 -0
- package/dist/tests/core/fake-creds.test.js +134 -0
- package/dist/tests/core/fake-creds.test.js.map +1 -0
- package/dist/tests/core/file.test.js +197 -0
- package/dist/tests/core/file.test.js.map +1 -0
- package/dist/tests/core/git-result.test.js +113 -0
- package/dist/tests/core/git-result.test.js.map +1 -0
- package/dist/tests/core/identity.test.js +180 -0
- package/dist/tests/core/identity.test.js.map +1 -0
- package/dist/tests/core/image-decide.test.js +59 -0
- package/dist/tests/core/image-decide.test.js.map +1 -0
- package/dist/tests/core/injection.test.js +163 -0
- package/dist/tests/core/injection.test.js.map +1 -0
- package/dist/tests/core/ledger.test.js +218 -0
- package/dist/tests/core/ledger.test.js.map +1 -0
- package/dist/tests/core/managed-image.test.js +68 -0
- package/dist/tests/core/managed-image.test.js.map +1 -0
- package/dist/tests/core/mise.test.js +138 -0
- package/dist/tests/core/mise.test.js.map +1 -0
- package/dist/tests/core/parse.test.js +174 -0
- package/dist/tests/core/parse.test.js.map +1 -0
- package/dist/tests/core/path.test.js +50 -0
- package/dist/tests/core/path.test.js.map +1 -0
- package/dist/tests/core/plan.test.js +218 -0
- package/dist/tests/core/plan.test.js.map +1 -0
- package/dist/tests/core/post-move.test.js +162 -0
- package/dist/tests/core/post-move.test.js.map +1 -0
- package/dist/tests/core/pr-classify.test.js +117 -0
- package/dist/tests/core/pr-classify.test.js.map +1 -0
- package/dist/tests/core/pr-decide.test.js +298 -0
- package/dist/tests/core/pr-decide.test.js.map +1 -0
- package/dist/tests/core/pr-loop.test.js +301 -0
- package/dist/tests/core/pr-loop.test.js.map +1 -0
- package/dist/tests/core/pr-notes.test.js +165 -0
- package/dist/tests/core/pr-notes.test.js.map +1 -0
- package/dist/tests/core/predicates.test.js +154 -0
- package/dist/tests/core/predicates.test.js.map +1 -0
- package/dist/tests/core/prompt.test.js +189 -0
- package/dist/tests/core/prompt.test.js.map +1 -0
- package/dist/tests/core/protocol.test.js +195 -0
- package/dist/tests/core/protocol.test.js.map +1 -0
- package/dist/tests/core/reconcile-issue.test.js +116 -0
- package/dist/tests/core/reconcile-issue.test.js.map +1 -0
- package/dist/tests/core/render.test.js +549 -0
- package/dist/tests/core/render.test.js.map +1 -0
- package/dist/tests/core/retry.test.js +186 -0
- package/dist/tests/core/retry.test.js.map +1 -0
- package/dist/tests/core/routes.test.js +247 -0
- package/dist/tests/core/routes.test.js.map +1 -0
- package/dist/tests/core/run-fold.test.js +299 -0
- package/dist/tests/core/run-fold.test.js.map +1 -0
- package/dist/tests/core/shape.test.js +185 -0
- package/dist/tests/core/shape.test.js.map +1 -0
- package/dist/tests/core/sleep-cycle.test.js +150 -0
- package/dist/tests/core/sleep-cycle.test.js.map +1 -0
- package/dist/tests/core/slots.test.js +201 -0
- package/dist/tests/core/slots.test.js.map +1 -0
- package/dist/tests/core/state-resolve.test.js +80 -0
- package/dist/tests/core/state-resolve.test.js.map +1 -0
- package/dist/tests/core/summary.test.js +200 -0
- package/dist/tests/core/summary.test.js.map +1 -0
- package/dist/tests/core/template.test.js +116 -0
- package/dist/tests/core/template.test.js.map +1 -0
- package/dist/tests/core/tick.test.js +558 -0
- package/dist/tests/core/tick.test.js.map +1 -0
- package/dist/tests/core/token-fold.test.js +176 -0
- package/dist/tests/core/token-fold.test.js.map +1 -0
- package/dist/tests/core/turn.test.js +388 -0
- package/dist/tests/core/turn.test.js.map +1 -0
- package/dist/tests/core/url.test.js +118 -0
- package/dist/tests/core/url.test.js.map +1 -0
- package/dist/tests/core/validate.test.js +247 -0
- package/dist/tests/core/validate.test.js.map +1 -0
- package/dist/tests/core/views.test.js +252 -0
- package/dist/tests/core/views.test.js.map +1 -0
- package/dist/tests/core/vm-decide.test.js +110 -0
- package/dist/tests/core/vm-decide.test.js.map +1 -0
- package/dist/tests/core/vm-guards.test.js +153 -0
- package/dist/tests/core/vm-guards.test.js.map +1 -0
- package/dist/tests/core/vm-plan.test.js +332 -0
- package/dist/tests/core/vm-plan.test.js.map +1 -0
- package/dist/tests/core/vm-reap.test.js +196 -0
- package/dist/tests/core/vm-reap.test.js.map +1 -0
- package/dist/tests/core/workflow-parse.test.js +493 -0
- package/dist/tests/core/workflow-parse.test.js.map +1 -0
- package/dist/tests/core/workspace-decide.test.js +236 -0
- package/dist/tests/core/workspace-decide.test.js.map +1 -0
- package/dist/tests/helpers/fixtures.js +167 -0
- package/dist/tests/helpers/fixtures.js.map +1 -0
- package/dist/tests/shell/acp-substrate.test.js +101 -0
- package/dist/tests/shell/acp-substrate.test.js.map +1 -0
- package/dist/tests/shell/actions-runner-push.test.js +203 -0
- package/dist/tests/shell/actions-runner-push.test.js.map +1 -0
- package/dist/tests/shell/credential-hooks.test.js +36 -0
- package/dist/tests/shell/credential-hooks.test.js.map +1 -0
- package/dist/tests/shell/credential-registry.test.js +165 -0
- package/dist/tests/shell/credential-registry.test.js.map +1 -0
- package/dist/tests/shell/credential-substrate.test.js +179 -0
- package/dist/tests/shell/credential-substrate.test.js.map +1 -0
- package/dist/tests/shell/dockerfile-mise-pin.test.js +51 -0
- package/dist/tests/shell/dockerfile-mise-pin.test.js.map +1 -0
- package/dist/tests/shell/doctor.test.js +101 -0
- package/dist/tests/shell/doctor.test.js.map +1 -0
- package/dist/tests/shell/effect-vm-create.test.js +52 -0
- package/dist/tests/shell/effect-vm-create.test.js.map +1 -0
- package/dist/tests/shell/gh-port.test.js +63 -0
- package/dist/tests/shell/gh-port.test.js.map +1 -0
- package/dist/tests/shell/gondolin-dispatch-guard.test.js +144 -0
- package/dist/tests/shell/gondolin-dispatch-guard.test.js.map +1 -0
- package/dist/tests/shell/gondolin-dispatch-shquote.test.js +168 -0
- package/dist/tests/shell/gondolin-dispatch-shquote.test.js.map +1 -0
- package/dist/tests/shell/gondolin-image-converter.test.js +208 -0
- package/dist/tests/shell/gondolin-image-converter.test.js.map +1 -0
- package/dist/tests/shell/gondolin-image-fetch.test.js +93 -0
- package/dist/tests/shell/gondolin-image-fetch.test.js.map +1 -0
- package/dist/tests/shell/http-handler.test.js +608 -0
- package/dist/tests/shell/http-handler.test.js.map +1 -0
- package/dist/tests/shell/http-server.test.js +53 -0
- package/dist/tests/shell/http-server.test.js.map +1 -0
- package/dist/tests/shell/mcp-runtime.test.js +366 -0
- package/dist/tests/shell/mcp-runtime.test.js.map +1 -0
- package/dist/tests/shell/mise-config-asset.test.js +87 -0
- package/dist/tests/shell/mise-config-asset.test.js.map +1 -0
- package/dist/tests/shell/orchestrator-loop.test.js +583 -0
- package/dist/tests/shell/orchestrator-loop.test.js.map +1 -0
- package/dist/tests/shell/reconciler-passes.test.js +314 -0
- package/dist/tests/shell/reconciler-passes.test.js.map +1 -0
- package/dist/tests/shell/runner-loop-turn.test.js +97 -0
- package/dist/tests/shell/runner-loop-turn.test.js.map +1 -0
- package/dist/tests/shell/runner-slice.test.js +536 -0
- package/dist/tests/shell/runner-slice.test.js.map +1 -0
- package/dist/tests/shell/scaffold.test.js +65 -0
- package/dist/tests/shell/scaffold.test.js.map +1 -0
- package/dist/tests/shell/tick-config.test.js +83 -0
- package/dist/tests/shell/tick-config.test.js.map +1 -0
- package/dist/tests/shell/tracker-parse-dates.test.js +44 -0
- package/dist/tests/shell/tracker-parse-dates.test.js.map +1 -0
- package/dist/tests/shell/tracker-write-issue.test.js +154 -0
- package/dist/tests/shell/tracker-write-issue.test.js.map +1 -0
- package/dist/tests/shell/workflow-prompt-split.test.js +208 -0
- package/dist/tests/shell/workflow-prompt-split.test.js.map +1 -0
- package/dist/tests/shell/workspace-live-config.test.js +140 -0
- package/dist/tests/shell/workspace-live-config.test.js.map +1 -0
- package/package.json +21 -9
- package/patches/@earendil-works+gondolin+0.12.0.patch +173 -0
- package/prompts/Reflect.md +91 -0
- package/prompts/Review.md +97 -0
- package/prompts/Todo.md +96 -0
- package/prompts/_footer.md +41 -0
- package/prompts/_preamble.md +42 -0
- package/prompts-minimal/Todo.md +26 -0
- package/scripts/postinstall.mjs +63 -0
- package/scripts/vm-agent.mjs +312 -90
- package/WORKFLOW.md +0 -744
- package/dist/acp-bridge.js +0 -324
- package/dist/acp-bridge.js.map +0 -1
- package/dist/actions/cache.js +0 -191
- package/dist/actions/cache.js.map +0 -1
- package/dist/actions/effects.js +0 -41
- package/dist/actions/effects.js.map +0 -1
- package/dist/actions/executor.js +0 -570
- package/dist/actions/executor.js.map +0 -1
- package/dist/actions/index.js +0 -13
- package/dist/actions/index.js.map +0 -1
- package/dist/actions/parsing.js.map +0 -1
- package/dist/actions/predicate-env.js +0 -27
- package/dist/actions/predicate-env.js.map +0 -1
- package/dist/actions/predicates.js +0 -49
- package/dist/actions/predicates.js.map +0 -1
- package/dist/actions/templating.js +0 -66
- package/dist/actions/templating.js.map +0 -1
- package/dist/actions/types.js +0 -15
- package/dist/actions/types.js.map +0 -1
- package/dist/agent/acp.js +0 -473
- package/dist/agent/acp.js.map +0 -1
- package/dist/agent/adapter-names.js +0 -159
- package/dist/agent/adapter-names.js.map +0 -1
- package/dist/agent/adapters.js +0 -511
- package/dist/agent/adapters.js.map +0 -1
- package/dist/agent/credential-extractors.js +0 -342
- package/dist/agent/credential-extractors.js.map +0 -1
- package/dist/agent/credential-secrets.js +0 -628
- package/dist/agent/credential-secrets.js.map +0 -1
- package/dist/agent/credential-ticker.js +0 -57
- package/dist/agent/credential-ticker.js.map +0 -1
- package/dist/agent/gondolin-creds-staging.js +0 -356
- package/dist/agent/gondolin-creds-staging.js.map +0 -1
- package/dist/agent/gondolin-dispatch.js +0 -375
- package/dist/agent/gondolin-dispatch.js.map +0 -1
- package/dist/agent/gondolin.js +0 -124
- package/dist/agent/gondolin.js.map +0 -1
- package/dist/agent/runner-decisions.js +0 -134
- package/dist/agent/runner-decisions.js.map +0 -1
- package/dist/agent/runner.js +0 -1456
- package/dist/agent/runner.js.map +0 -1
- package/dist/agent/tool-call-summary.js +0 -102
- package/dist/agent/tool-call-summary.js.map +0 -1
- package/dist/agent/vm-acp-mapping.js +0 -73
- package/dist/agent/vm-acp-mapping.js.map +0 -1
- package/dist/agent/vm-guards.js +0 -262
- package/dist/agent/vm-guards.js.map +0 -1
- package/dist/agent/vm-port.js +0 -22
- package/dist/agent/vm-port.js.map +0 -1
- package/dist/agent/vm-process-registry.js +0 -79
- package/dist/agent/vm-process-registry.js.map +0 -1
- package/dist/bin/cli-args.js +0 -105
- package/dist/bin/cli-args.js.map +0 -1
- package/dist/bin/symphony.js +0 -794
- package/dist/bin/symphony.js.map +0 -1
- package/dist/errors.js +0 -15
- package/dist/errors.js.map +0 -1
- package/dist/http-disk.js +0 -135
- package/dist/http-disk.js.map +0 -1
- package/dist/http-handlers.js.map +0 -1
- package/dist/http.js.map +0 -1
- package/dist/issues.js +0 -178
- package/dist/issues.js.map +0 -1
- package/dist/logging.js +0 -203
- package/dist/logging.js.map +0 -1
- package/dist/mcp.js +0 -706
- package/dist/mcp.js.map +0 -1
- package/dist/memory.js +0 -85
- package/dist/memory.js.map +0 -1
- package/dist/orchestrator-decisions.js +0 -331
- package/dist/orchestrator-decisions.js.map +0 -1
- package/dist/orchestrator.js +0 -1569
- package/dist/orchestrator.js.map +0 -1
- package/dist/prompt.js +0 -65
- package/dist/prompt.js.map +0 -1
- package/dist/reconciler/cache.js +0 -65
- package/dist/reconciler/cache.js.map +0 -1
- package/dist/reconciler/index.js +0 -448
- package/dist/reconciler/index.js.map +0 -1
- package/dist/reconciler/ledger.js +0 -131
- package/dist/reconciler/ledger.js.map +0 -1
- package/dist/reconciler/pr-adapters.js +0 -174
- package/dist/reconciler/pr-adapters.js.map +0 -1
- package/dist/reconciler/pr-decide.js.map +0 -1
- package/dist/reconciler/pr.js +0 -422
- package/dist/reconciler/pr.js.map +0 -1
- package/dist/reconciler/types.js +0 -12
- package/dist/reconciler/types.js.map +0 -1
- package/dist/reconciler/vm.js +0 -243
- package/dist/reconciler/vm.js.map +0 -1
- package/dist/reconciler/workspace-defaults.js +0 -83
- package/dist/reconciler/workspace-defaults.js.map +0 -1
- package/dist/reconciler/workspace.js +0 -272
- package/dist/reconciler/workspace.js.map +0 -1
- package/dist/runlog.js +0 -403
- package/dist/runlog.js.map +0 -1
- package/dist/scaffold.js +0 -165
- package/dist/scaffold.js.map +0 -1
- package/dist/trackers/local.js +0 -445
- package/dist/trackers/local.js.map +0 -1
- package/dist/trackers/types.js +0 -10
- package/dist/trackers/types.js.map +0 -1
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
- package/dist/util/clock.js +0 -12
- package/dist/util/clock.js.map +0 -1
- package/dist/util/crypto.js +0 -25
- package/dist/util/crypto.js.map +0 -1
- package/dist/util/frontmatter.js +0 -70
- package/dist/util/frontmatter.js.map +0 -1
- package/dist/util/fs-issues.js +0 -22
- package/dist/util/fs-issues.js.map +0 -1
- package/dist/util/process.js +0 -152
- package/dist/util/process.js.map +0 -1
- package/dist/util/workspace-key.js +0 -10
- package/dist/util/workspace-key.js.map +0 -1
- package/dist/workflow-loader.js +0 -147
- package/dist/workflow-loader.js.map +0 -1
- package/dist/workflow.js +0 -822
- package/dist/workflow.js.map +0 -1
- package/dist/workspace-types.js +0 -8
- package/dist/workspace-types.js.map +0 -1
- package/dist/workspace.js +0 -443
- package/dist/workspace.js.map +0 -1
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// FCIS rewrite — PURE builder of the guest fake-creds file set (placeholders only).
|
|
2
|
+
//
|
|
3
|
+
// Ported faithfully from the reference `src/agent/gondolin-creds-staging.ts`
|
|
4
|
+
// (`buildGondolinFakeCreds`, `buildClaudeFiles`, `buildCodexFiles`).
|
|
5
|
+
//
|
|
6
|
+
// This is the credential-MODEL half of the Gondolin backend: there is NO proxy
|
|
7
|
+
// server and NO base-URL injection. The in-VM client dials its REAL upstream in
|
|
8
|
+
// its NATIVE mode with a token-shaped PLACEHOLDER as its bearer; Gondolin
|
|
9
|
+
// substitutes the real access token into the outbound request at egress
|
|
10
|
+
// (TLS-MITM) by EXACT string match on the `Authorization` header. So the bearer
|
|
11
|
+
// the guest sends MUST equal the placeholder Gondolin holds — we therefore stage
|
|
12
|
+
// `input.placeholder` VERBATIM as the staged file's bearer field (claude
|
|
13
|
+
// `claudeAiOauth.accessToken`, codex `tokens.access_token`/`id_token`). The real
|
|
14
|
+
// refresh/durable token NEVER enters the guest (the invariant).
|
|
15
|
+
//
|
|
16
|
+
// FCIS shape: in the reference the only IO was reading the host `~/.claude.json`
|
|
17
|
+
// and `~/.codex/auth.json` for the NON-SECRET identity/metadata (oauthAccount
|
|
18
|
+
// UUIDs; codex account_id / auth_mode / last_refresh). In this clean-room rewrite
|
|
19
|
+
// that IO lives in the SHELL: the shell reads + extracts the already-validated
|
|
20
|
+
// `ClaudeIdentity` / `CodexIdentity` and hands them to this core as plain data.
|
|
21
|
+
// This module is 100% synchronous, has ZERO IO, and imports ONLY from src/types.
|
|
22
|
+
//
|
|
23
|
+
// Defense-in-depth (codex review, HIGH, preserved from the reference): even
|
|
24
|
+
// though the shell extractor is expected to validate, this STAGING chokepoint
|
|
25
|
+
// re-validates the codex `accountId` (must be a UUID — a real token/`sk-…`/JWT
|
|
26
|
+
// never matches), `authMode` (closed set), and `lastRefresh` (ISO-timestamp
|
|
27
|
+
// shape) before embedding them into the staged auth.json. A token-shaped value is
|
|
28
|
+
// OMITTED regardless of which producer handed it to us.
|
|
29
|
+
// SHARED account_id guard (codex review HIGH) — the ONE definition. Re-exported
|
|
30
|
+
// so this module's importers keep their specifier.
|
|
31
|
+
import { validAccountId } from './account-id.js';
|
|
32
|
+
export { validAccountId };
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Constants (mirrors the reference guest paths + magic values).
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Guest paths the fake native creds land at (the VM runs as root). These mirror
|
|
37
|
+
// the runner's `stageAdapterExtras` guest paths so a client finds its creds in
|
|
38
|
+
// exactly the place its native mode looks.
|
|
39
|
+
const CLAUDE_CREDENTIALS_GUEST_PATH = '/root/.claude/.credentials.json';
|
|
40
|
+
const CLAUDE_CONFIG_GUEST_PATH = '/root/.claude.json';
|
|
41
|
+
const CODEX_AUTH_GUEST_PATH = '/root/.codex/auth.json';
|
|
42
|
+
// Creds files are 0600.
|
|
43
|
+
const CRED_FILE_MODE = 0o600;
|
|
44
|
+
// Far-future expiry (2100-01-01T00:00:00Z, ms since epoch) so the claude client
|
|
45
|
+
// never proactively refreshes the placeholder (a refresh attempt would be
|
|
46
|
+
// egress-blocked and is pure waste). Matches the spike's `4102444800000`.
|
|
47
|
+
const FAR_FUTURE_MS = 4_102_444_800_000;
|
|
48
|
+
// A junk refresh token: token-SHAPED but explicitly never a real token. The guest
|
|
49
|
+
// has nothing to rotate (the real refresh token stays host-side).
|
|
50
|
+
const JUNK_REFRESH = 'JUNK-PLACEHOLDER-REFRESH-not-a-real-token';
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Validation guards (defense-in-depth; SHARED, codex review HIGH).
|
|
53
|
+
// `validAccountId` + its UUID_RE live in ./account-id.js (imported above).
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
/** codex auth modes are a tiny closed set. */
|
|
56
|
+
const KNOWN_AUTH_MODES = new Set(['chatgpt', 'apikey']);
|
|
57
|
+
/** `last_refresh` is an ISO-8601 timestamp: digits + `-:.TZ+`, bounded length. */
|
|
58
|
+
const ISO_TIMESTAMP_RE = /^[0-9T:.Z+-]{1,40}$/;
|
|
59
|
+
function validAuthMode(v) {
|
|
60
|
+
return v !== null && KNOWN_AUTH_MODES.has(v) ? v : null;
|
|
61
|
+
}
|
|
62
|
+
function validLastRefresh(v) {
|
|
63
|
+
return v !== null && ISO_TIMESTAMP_RE.test(v) ? v : null;
|
|
64
|
+
}
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Entry point.
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
/**
|
|
69
|
+
* Build the fake native creds + env additions for `input.adapter`. The
|
|
70
|
+
* placeholder (a fake, token-shaped value) is what the guest sees as its bearer;
|
|
71
|
+
* Gondolin substitutes the real token at egress by EXACT string match. The
|
|
72
|
+
* returned `env` is always the single-entry `{ [secretName]: placeholder }` so a
|
|
73
|
+
* client reading its bearer from env (not a file) still gets the placeholder.
|
|
74
|
+
*
|
|
75
|
+
* 100% synchronous, pure: identity inputs (`claudeIdentity`/`codexIdentity`) are
|
|
76
|
+
* supplied already-resolved by the shell. No IO.
|
|
77
|
+
*/
|
|
78
|
+
export function buildGondolinFakeCreds(input) {
|
|
79
|
+
const env = { [input.secretName]: input.placeholder };
|
|
80
|
+
switch (input.adapter) {
|
|
81
|
+
case 'claude':
|
|
82
|
+
return { files: buildClaudeFiles(input.placeholder, input.claudeIdentity), env };
|
|
83
|
+
case 'codex':
|
|
84
|
+
return { files: buildCodexFiles(input.placeholder, input.codexIdentity), env };
|
|
85
|
+
default: {
|
|
86
|
+
// Exhaustive over AcpAdapterId (closed union claude|codex): the compiler
|
|
87
|
+
// proves `input.adapter` is `never` here. Kept as a total function.
|
|
88
|
+
const unreachable = input.adapter;
|
|
89
|
+
throw new Error(`buildGondolinFakeCreds: unhandled adapter ${String(unreachable)}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
// Per-adapter builders.
|
|
95
|
+
// ---------------------------------------------------------------------------
|
|
96
|
+
/**
|
|
97
|
+
* claude fake `~/.claude/.credentials.json` = `{ claudeAiOauth: { accessToken:
|
|
98
|
+
* <placeholder>, refreshToken: <junk>, expiresAt: <far future ms> } }` (spike B5).
|
|
99
|
+
* Far-future expiry ⇒ no proactive refresh. ALSO stage the scrubbed
|
|
100
|
+
* `~/.claude.json` identity (oauthAccount UUIDs only — the real accountUuid /
|
|
101
|
+
* organizationUuid are identifiers, NOT secrets) when one is supplied; absent
|
|
102
|
+
* identity is non-fatal (best-effort).
|
|
103
|
+
*/
|
|
104
|
+
export function buildClaudeFiles(placeholder, identity) {
|
|
105
|
+
const credsContent = JSON.stringify({
|
|
106
|
+
claudeAiOauth: {
|
|
107
|
+
accessToken: placeholder,
|
|
108
|
+
refreshToken: JUNK_REFRESH,
|
|
109
|
+
expiresAt: FAR_FUTURE_MS,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
const files = [credFile(CLAUDE_CREDENTIALS_GUEST_PATH, credsContent)];
|
|
113
|
+
if (identity !== null) {
|
|
114
|
+
const configContent = JSON.stringify({
|
|
115
|
+
hasCompletedOnboarding: true,
|
|
116
|
+
oauthAccount: { accountUuid: identity.accountUuid, organizationUuid: identity.organizationUuid },
|
|
117
|
+
projects: {},
|
|
118
|
+
});
|
|
119
|
+
files.push(credFile(CLAUDE_CONFIG_GUEST_PATH, configContent));
|
|
120
|
+
}
|
|
121
|
+
return files;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* codex fake `~/.codex/auth.json`, shaped to be COMPLETE for codex 0.135.
|
|
125
|
+
*
|
|
126
|
+
* codex 0.135's local auth manager runs a COMPLETENESS check on auth.json BEFORE
|
|
127
|
+
* it will send the `Authorization` bearer. A too-minimal `{ tokens: {…} }` is
|
|
128
|
+
* judged "credentials incomplete" → no bearer → 401 → blocked refresh → refusal.
|
|
129
|
+
* The proven-working shape (spike C7) carries the non-secret top-level
|
|
130
|
+
* completeness fields `auth_mode` + `last_refresh` (and `OPENAI_API_KEY: null`)
|
|
131
|
+
* alongside the tokens block.
|
|
132
|
+
*
|
|
133
|
+
* SAFETY-FIRST: we do NOT spread any host auth.json into the staged file. We
|
|
134
|
+
* read ONLY an ALLOWLIST of non-secret metadata (supplied as `CodexIdentity`) and
|
|
135
|
+
* BUILD a fresh object from scratch, re-validating each field at this chokepoint
|
|
136
|
+
* (defense-in-depth). The placeholder is staged as both `access_token` (codex's
|
|
137
|
+
* bearer; Gondolin substitutes the real token at egress) and `id_token`; the
|
|
138
|
+
* refresh token is JUNK; `account_id` is the non-secret routing identifier.
|
|
139
|
+
*/
|
|
140
|
+
export function buildCodexFiles(placeholder, identity) {
|
|
141
|
+
// Re-validate at this STAGING chokepoint: a custom/buggy/hostile producer could
|
|
142
|
+
// hand us a non-UUID `accountId` (or out-of-allowlist `authMode`/`lastRefresh`).
|
|
143
|
+
// The shared guards run again so a token-shaped value is OMITTED from the staged
|
|
144
|
+
// auth.json regardless of which producer made it.
|
|
145
|
+
const accountId = validAccountId(identity?.accountId ?? null);
|
|
146
|
+
const authMode = validAuthMode(identity?.authMode ?? null);
|
|
147
|
+
const lastRefresh = validLastRefresh(identity?.lastRefresh ?? null);
|
|
148
|
+
const tokens = {
|
|
149
|
+
access_token: placeholder,
|
|
150
|
+
id_token: placeholder,
|
|
151
|
+
refresh_token: JUNK_REFRESH,
|
|
152
|
+
...(accountId !== null ? { account_id: accountId } : {}),
|
|
153
|
+
};
|
|
154
|
+
// Top-level non-secret completeness fields. `OPENAI_API_KEY: null` mirrors the
|
|
155
|
+
// host (codex stores the OAuth tokens block, NOT an api key); `auth_mode` /
|
|
156
|
+
// `last_refresh` are the markers codex 0.135's completeness check requires.
|
|
157
|
+
const auth = {
|
|
158
|
+
OPENAI_API_KEY: null,
|
|
159
|
+
...(authMode !== null ? { auth_mode: authMode } : {}),
|
|
160
|
+
tokens,
|
|
161
|
+
...(lastRefresh !== null ? { last_refresh: lastRefresh } : {}),
|
|
162
|
+
};
|
|
163
|
+
return [credFile(CODEX_AUTH_GUEST_PATH, JSON.stringify(auth))];
|
|
164
|
+
}
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// Helpers.
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
function credFile(guestPath, content) {
|
|
169
|
+
return { guestPath, content, mode: CRED_FILE_MODE };
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=fake-creds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-creds.js","sourceRoot":"","sources":["../../../../src/core/credential/fake-creds.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// FCIS rewrite — pure host-identity EXTRACTORS over already-parsed JSON.
|
|
2
|
+
//
|
|
3
|
+
// Functional core: every export is a pure, SYNCHRONOUS (data) -> data function —
|
|
4
|
+
// no IO, no async/Promise, no clock/random, no node: imports; imports ONLY
|
|
5
|
+
// src/types. Ports the PURE half of src/agent/gondolin-creds-staging.ts verbatim
|
|
6
|
+
// in behavior. The original READ the host files itself; a pure core cannot touch
|
|
7
|
+
// fs/os, so the read is a `credential.read_identity` Effect the shell interprets,
|
|
8
|
+
// handing the PARSED JSON (or null when missing/malformed) to these extractors.
|
|
9
|
+
//
|
|
10
|
+
// SECURITY INVARIANT (codex review): the codex auth.json bytes the shell parses DO
|
|
11
|
+
// contain real tokens. These extractors read ONLY non-secret identity by an
|
|
12
|
+
// explicit key allowlist (claude oauthAccount UUIDs; codex `tokens.account_id` /
|
|
13
|
+
// top-level `auth_mode` / `last_refresh`) and NEVER touch
|
|
14
|
+
// `tokens.{access,id,refresh}_token` / a real `OPENAI_API_KEY`. The guards below
|
|
15
|
+
// re-validate at the staging chokepoint so a hostile/buggy reader cannot smuggle a
|
|
16
|
+
// token-shaped value into the placeholder-JWT `chatgpt_account_id` claim (the guest
|
|
17
|
+
// BEARER) or the staged metadata: a non-UUID `account_id`, out-of-allowlist
|
|
18
|
+
// `auth_mode`, or non-ISO `last_refresh` is OMITTED (the SAFE failure), not embedded.
|
|
19
|
+
// SHARED account_id guard (codex review, HIGH) — the ONE definition. Both
|
|
20
|
+
// account_id flows MUST validate through it so a hostile/malformed host
|
|
21
|
+
// `~/.codex/auth.json` cannot smuggle a token-shaped value into either sink:
|
|
22
|
+
// (1) the placeholder JWT's `chatgpt_account_id` claim (the guest BEARER), and
|
|
23
|
+
// (2) the staged `~/.codex/auth.json` `tokens.account_id`. Re-exported so this
|
|
24
|
+
// module's importers keep their specifier.
|
|
25
|
+
import { validAccountId } from './account-id.js';
|
|
26
|
+
export { validAccountId };
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Allowlist format guards (the staging-chokepoint re-validation).
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
/** codex auth modes are a tiny closed set. */
|
|
31
|
+
const KNOWN_AUTH_MODES = new Set(['chatgpt', 'apikey']);
|
|
32
|
+
/** `last_refresh` is an ISO-8601 timestamp: digits + `-:.TZ+`, bounded length. */
|
|
33
|
+
const ISO_TIMESTAMP_RE = /^[0-9T:.Z+-]{1,40}$/;
|
|
34
|
+
/** Guard the non-secret top-level `auth_mode` against the tiny closed set. */
|
|
35
|
+
export function validAuthMode(v) {
|
|
36
|
+
return v !== null && KNOWN_AUTH_MODES.has(v) ? v : null;
|
|
37
|
+
}
|
|
38
|
+
/** Guard the non-secret top-level `last_refresh` against the ISO-timestamp shape. */
|
|
39
|
+
export function validLastRefresh(v) {
|
|
40
|
+
return v !== null && ISO_TIMESTAMP_RE.test(v) ? v : null;
|
|
41
|
+
}
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Extractors over already-parsed JSON (the `credential.read_identity` Effect
|
|
44
|
+
// result the shell hands in).
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/**
|
|
47
|
+
* Pure: pull ONLY the non-secret oauthAccount UUIDs out of a parsed `~/.claude.json`.
|
|
48
|
+
* Mirrors the original `extractOauthAccountIdentity` — no token, no device/session
|
|
49
|
+
* id, no local config. Returns null when the file was missing/malformed (parsed is
|
|
50
|
+
* null/non-object) or the oauthAccount UUIDs are absent.
|
|
51
|
+
*/
|
|
52
|
+
export function extractClaudeIdentity(parsed) {
|
|
53
|
+
const acct = pickObject(parsed, 'oauthAccount');
|
|
54
|
+
if (acct === null)
|
|
55
|
+
return null;
|
|
56
|
+
const accountUuid = pickString(acct, 'accountUuid');
|
|
57
|
+
const organizationUuid = pickString(acct, 'organizationUuid');
|
|
58
|
+
if (accountUuid === null || organizationUuid === null)
|
|
59
|
+
return null;
|
|
60
|
+
return { accountUuid, organizationUuid };
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Pure: pull ONLY the non-secret `account_id` out of a parsed `~/.codex/auth.json`
|
|
64
|
+
* `tokens` block. The parsed object also holds the real access/refresh tokens (the
|
|
65
|
+
* shell parsed the whole file), but this reads + returns ONLY `account_id` — the
|
|
66
|
+
* tokens are never returned or emitted.
|
|
67
|
+
*
|
|
68
|
+
* SAFETY-CRITICAL (codex review, HIGH): this value flows into the placeholder JWT's
|
|
69
|
+
* `chatgpt_account_id` claim, and that JWT IS the guest's staged
|
|
70
|
+
* `tokens.access_token` BEARER. So we validate through the SHARED {@link
|
|
71
|
+
* validAccountId} UUID guard here: a hostile/malformed `account_id` (a token /
|
|
72
|
+
* `sk-…` / JWT string) is NOT a UUID → returns null → the claim is OMITTED from the
|
|
73
|
+
* bearer (the SAFE failure), never embedded.
|
|
74
|
+
*/
|
|
75
|
+
export function extractCodexAccountId(parsed) {
|
|
76
|
+
const tokens = pickObject(parsed, 'tokens');
|
|
77
|
+
if (tokens === null)
|
|
78
|
+
return null;
|
|
79
|
+
return validAccountId(pickString(tokens, 'account_id'));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Pure: pull ONLY the allowlisted NON-SECRET codex completeness metadata out of a
|
|
83
|
+
* parsed `~/.codex/auth.json`. SAFETY-CRITICAL: reads three explicit non-secret
|
|
84
|
+
* keys by name (`tokens.account_id`, top-level `auth_mode`, `last_refresh`) and
|
|
85
|
+
* NEVER touches `tokens.access_token` / `tokens.id_token` / `tokens.refresh_token`
|
|
86
|
+
* / a real `OPENAI_API_KEY` — even though the parsed object holds them. Returns
|
|
87
|
+
* null only when the file is entirely missing/unparseable (parsed === null / not an
|
|
88
|
+
* object); a present-but-sparse auth.json yields a struct with null fields (each
|
|
89
|
+
* omitted downstream). Every non-null field is validated through the shared guards
|
|
90
|
+
* so a real token (JWT / `sk-…` / refresh) cannot pass as identity/metadata.
|
|
91
|
+
*/
|
|
92
|
+
export function extractCodexMetadata(parsed) {
|
|
93
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
94
|
+
return null;
|
|
95
|
+
const top = parsed;
|
|
96
|
+
const tokens = pickObject(parsed, 'tokens');
|
|
97
|
+
return {
|
|
98
|
+
accountId: validAccountId(tokens !== null ? pickString(tokens, 'account_id') : null),
|
|
99
|
+
authMode: validAuthMode(pickString(top, 'auth_mode')),
|
|
100
|
+
lastRefresh: validLastRefresh(pickString(top, 'last_refresh')),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// Tiny shape pickers (pure).
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
/** Return `value[key]` when both `value` and the child are plain objects, else null. */
|
|
107
|
+
function pickObject(value, key) {
|
|
108
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
109
|
+
return null;
|
|
110
|
+
const v = value[key];
|
|
111
|
+
if (!v || typeof v !== 'object' || Array.isArray(v))
|
|
112
|
+
return null;
|
|
113
|
+
return v;
|
|
114
|
+
}
|
|
115
|
+
/** Return `obj[key]` when it is a non-empty string, else null. */
|
|
116
|
+
function pickString(obj, key) {
|
|
117
|
+
const v = obj[key];
|
|
118
|
+
return typeof v === 'string' && v.length > 0 ? v : null;
|
|
119
|
+
}
|
|
120
|
+
// NOTE (boundary, settled): the original `safeReadClaudeIdentity` /
|
|
121
|
+
// `safeReadCodexMetadata` are async try/catch wrappers (fs read + warn-on-failure)
|
|
122
|
+
// around the IO readers. They are IO+async by nature, so they live in the shell
|
|
123
|
+
// interpreter for the `credential.read_identity` Effect — porting them here would
|
|
124
|
+
// break the core async-ban. This module is the PURE extraction half only.
|
|
125
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../../src/core/credential/identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
// FCIS rewrite — PURE credential ASSEMBLY (the "shape" half of the original
|
|
2
|
+
// src/agent/credential-secrets.ts).
|
|
3
|
+
//
|
|
4
|
+
// Functional core: every export here is a pure, synchronous (data) -> data
|
|
5
|
+
// function. No IO, no clock, no randomness read off the wall (the placeholder
|
|
6
|
+
// signature/random segments come from an INJECTED RandomSource port), no node:
|
|
7
|
+
// imports, no process/env read, no Promise. Imports ONLY from src/types.
|
|
8
|
+
//
|
|
9
|
+
// This module owns the *shape* of the credential output, NOT its lifecycle:
|
|
10
|
+
// - assemblePlaceholderJwt(...) + PLACEHOLDER_JWT_EXP_SECONDS
|
|
11
|
+
// the JWT-shaped placeholder codex's native mode reads as its (non-expiring)
|
|
12
|
+
// bearer; the host `chatgpt_account_id` is embedded (UUID-guarded) so codex
|
|
13
|
+
// does not attempt an egress-blocked mid-turn refresh.
|
|
14
|
+
// - buildAdapterPlaceholder(adapter, rng, accountId?)
|
|
15
|
+
// the token-shaped placeholder string for an adapter (sk-ant- / JWT / gho_).
|
|
16
|
+
// - buildAdapterCredentialSpec(adapter, placeholder)
|
|
17
|
+
// the per-adapter AdapterCredentialSpec (secretName + substitutionHosts +
|
|
18
|
+
// placeholder), faithful to the original's static per-adapter config.
|
|
19
|
+
// - codexUpstreamRoute(token)
|
|
20
|
+
// the ChatGPT-backend upstream-route decision + chatgpt-account-id header
|
|
21
|
+
// policy (routes ChatGPT-OAuth subscription tokens off the metered platform
|
|
22
|
+
// API onto chatgpt.com/backend-api/codex). Pure decision object; the shell
|
|
23
|
+
// applies it at egress.
|
|
24
|
+
// - buildAdapterHooksConfig(specs, egressAllowlist)
|
|
25
|
+
// the egress-allowlist UNION (every adapter's substitutionHosts ∪
|
|
26
|
+
// egress.allowed_hosts) → AdapterHooksConfig. createHttpHooks ITSELF stays
|
|
27
|
+
// in the shell; this returns the decided config it is constructed from.
|
|
28
|
+
//
|
|
29
|
+
// The original mixed these pure decisions with host IO (file reads, flock,
|
|
30
|
+
// refresher spawns, the live SecretManager registry, createHttpHooks). All of
|
|
31
|
+
// that is now the shell's job; the SHELL constructs createHttpHooks from the
|
|
32
|
+
// AdapterHooksConfig this core returns, registers the SecretManager, and performs
|
|
33
|
+
// the credential.{probe,refresh,push_to_all} Effects.
|
|
34
|
+
// SHARED account_id UUID guard (codex review HIGH) — the ONE definition.
|
|
35
|
+
// Re-exported so this module's importers keep their specifier.
|
|
36
|
+
import { validAccountId } from './account-id.js';
|
|
37
|
+
export { validAccountId };
|
|
38
|
+
import { nonEmptyString } from './strings.js';
|
|
39
|
+
// ─── per-adapter static config (secret name + substitution hosts) ────────────
|
|
40
|
+
//
|
|
41
|
+
// The env var / secret name each adapter's placeholder is keyed under — the SAME
|
|
42
|
+
// name the in-VM client reads its bearer from (claude `ANTHROPIC_AUTH_TOKEN`,
|
|
43
|
+
// codex `OPENAI_API_KEY`).
|
|
44
|
+
export const CLAUDE_SECRET_NAME = 'ANTHROPIC_AUTH_TOKEN';
|
|
45
|
+
export const CODEX_SECRET_NAME = 'OPENAI_API_KEY';
|
|
46
|
+
// The hosts each adapter's real token may be substituted onto at egress (its
|
|
47
|
+
// credential validity scope — NOT the general firewall; see buildAdapterHooksConfig).
|
|
48
|
+
export const CLAUDE_UPSTREAM_HOST = 'api.anthropic.com';
|
|
49
|
+
// codex ChatGPT-OAuth subscription tokens are honored on the ChatGPT backend
|
|
50
|
+
// (chatgpt.com/backend-api/codex), never the metered platform API.
|
|
51
|
+
export const CODEX_UPSTREAM_HOST = 'chatgpt.com';
|
|
52
|
+
/**
|
|
53
|
+
* Far-future JWT `exp` (seconds since epoch — 2100-01-01T00:00:00Z) baked into
|
|
54
|
+
* the codex placeholder so codex's native mode treats it as a long-lived,
|
|
55
|
+
* unexpired token and never attempts a refresh (egress-blocked → wasteful 403).
|
|
56
|
+
* Exported so the fake-creds staging + tests can assert the same instant.
|
|
57
|
+
*/
|
|
58
|
+
export const PLACEHOLDER_JWT_EXP_SECONDS = 4_102_444_800;
|
|
59
|
+
// The CHATGPT-backend route the codexUpstreamRoute decision targets.
|
|
60
|
+
const CHATGPT_BACKEND_HOST = 'chatgpt.com';
|
|
61
|
+
// ─── placeholder JWT assembly (codex) ────────────────────────────────────────
|
|
62
|
+
/**
|
|
63
|
+
* Assemble a structurally-valid (but cryptographically meaningless) JWT-shaped
|
|
64
|
+
* placeholder: `base64url(header).base64url(payload).<signature>`. codex never
|
|
65
|
+
* verifies the signature — it reads `exp` (far-future, so it never tries to
|
|
66
|
+
* refresh) and the `https://api.openai.com/auth.chatgpt_account_id` claim (which
|
|
67
|
+
* it uses to route + to consider the token complete; a missing claim triggers an
|
|
68
|
+
* egress-blocked refresh). The real token replaces this whole string at egress.
|
|
69
|
+
* The `signature` segment is the caller's high-entropy random string (from the
|
|
70
|
+
* injected RandomSource), making each VM's placeholder unique + exact-matchable
|
|
71
|
+
* by Gondolin's header substitution.
|
|
72
|
+
*
|
|
73
|
+
* SAFETY-CRITICAL: this JWT becomes the guest's staged BEARER, so this is the
|
|
74
|
+
* LAST chokepoint before a host `account_id` lands in a bearer slot. The id is
|
|
75
|
+
* re-validated through the shared {@link validAccountId} UUID guard (defense in
|
|
76
|
+
* depth): a non-UUID / token-shaped value is NOT embedded; the claim is simply
|
|
77
|
+
* OMITTED (the well-formed, SAFE failure). A real token (JWT / `sk-…` / refresh)
|
|
78
|
+
* never matches a UUID, so it can never reach the `chatgpt_account_id` claim.
|
|
79
|
+
*/
|
|
80
|
+
export function assemblePlaceholderJwt(signature, accountId = null) {
|
|
81
|
+
const safeAccountId = validAccountId(accountId);
|
|
82
|
+
const header = base64urlJson({ alg: 'RS256', typ: 'JWT' });
|
|
83
|
+
const payload = base64urlJson({
|
|
84
|
+
exp: PLACEHOLDER_JWT_EXP_SECONDS,
|
|
85
|
+
...(safeAccountId !== null
|
|
86
|
+
? { 'https://api.openai.com/auth': { chatgpt_account_id: safeAccountId } }
|
|
87
|
+
: {}),
|
|
88
|
+
});
|
|
89
|
+
return `${header}.${payload}.${signature}`;
|
|
90
|
+
}
|
|
91
|
+
// ─── per-adapter placeholder strings ─────────────────────────────────────────
|
|
92
|
+
/**
|
|
93
|
+
* Build the token-shaped placeholder STRING for an adapter. The original used
|
|
94
|
+
* Gondolin's `makePlaceholderFunc` (shell) called once at createHttpHooks() time;
|
|
95
|
+
* here the random material comes from the injected RandomSource (a pure value to
|
|
96
|
+
* the core) so this stays synchronous + deterministic under test.
|
|
97
|
+
*
|
|
98
|
+
* - claude → `sk-ant-<random>` (claude validates the `sk-ant-` shape)
|
|
99
|
+
* - codex → a JWT-shaped placeholder (header.payload.<random-sig>) with a
|
|
100
|
+
* far-future `exp` + (when known + UUID-valid) the account-id claim
|
|
101
|
+
*
|
|
102
|
+
* `accountId` is consulted ONLY for codex; null/undefined elsewhere.
|
|
103
|
+
*/
|
|
104
|
+
export function buildAdapterPlaceholder(adapter, rng, accountId = null) {
|
|
105
|
+
switch (adapter) {
|
|
106
|
+
case 'claude':
|
|
107
|
+
return `sk-ant-${rng.newToken()}`;
|
|
108
|
+
case 'codex':
|
|
109
|
+
// The signature segment is high-entropy random material (base64url-safe).
|
|
110
|
+
return assemblePlaceholderJwt(rng.newToken(), accountId);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// ─── per-adapter credential spec ─────────────────────────────────────────────
|
|
114
|
+
/**
|
|
115
|
+
* Build the per-adapter {@link AdapterCredentialSpec}: the secret/env name the
|
|
116
|
+
* placeholder is keyed under, the substitution hosts (the credential's validity
|
|
117
|
+
* scope — where the real token may be substituted onto an outbound request), and
|
|
118
|
+
* the placeholder string. Faithful to the original's static per-adapter config.
|
|
119
|
+
*
|
|
120
|
+
* SECURITY: `substitutionHosts` is the credential VALIDITY scope, NOT the general
|
|
121
|
+
* egress firewall — only these are wired into `secrets[].hosts` by the shell, so a
|
|
122
|
+
* general egress host (from egress.allowed_hosts) never receives a real token.
|
|
123
|
+
*/
|
|
124
|
+
export function buildAdapterCredentialSpec(adapter, placeholder) {
|
|
125
|
+
switch (adapter) {
|
|
126
|
+
case 'claude':
|
|
127
|
+
return {
|
|
128
|
+
adapter,
|
|
129
|
+
placeholder,
|
|
130
|
+
secretName: CLAUDE_SECRET_NAME,
|
|
131
|
+
substitutionHosts: [CLAUDE_UPSTREAM_HOST],
|
|
132
|
+
};
|
|
133
|
+
case 'codex':
|
|
134
|
+
return {
|
|
135
|
+
adapter,
|
|
136
|
+
placeholder,
|
|
137
|
+
secretName: CODEX_SECRET_NAME,
|
|
138
|
+
substitutionHosts: [CODEX_UPSTREAM_HOST],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Convenience: assemble both halves (placeholder + spec) for an adapter in one
|
|
144
|
+
* call, drawing placeholder randomness from the injected RandomSource. The
|
|
145
|
+
* `accountId` is only consulted for codex (embedded in the placeholder JWT's auth
|
|
146
|
+
* claim, UUID-guarded).
|
|
147
|
+
*/
|
|
148
|
+
export function buildAdapterCredentialSpecWithPlaceholder(adapter, rng, accountId = null) {
|
|
149
|
+
return buildAdapterCredentialSpec(adapter, buildAdapterPlaceholder(adapter, rng, accountId));
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Decide the codex upstream route for a credential. ChatGPT-OAuth subscription
|
|
153
|
+
* tokens are accepted ONLY by OpenAI's ChatGPT backend
|
|
154
|
+
* (chatgpt.com/backend-api/codex), NOT the metered platform API (api.openai.com/v1,
|
|
155
|
+
* which 401s "Missing scopes: api.responses.write" — the subscription token carries
|
|
156
|
+
* only openid/profile/email/offline_access). So for a ChatGPT-OAuth credential we
|
|
157
|
+
* swap host → chatgpt.com, rewrite `/v1/*` → `/backend-api/codex/*`, and add the
|
|
158
|
+
* `chatgpt-account-id` header WHEN we have it.
|
|
159
|
+
*
|
|
160
|
+
* Routing keys on `chatgptOAuth`, NOT the account id — an OAuth token WITHOUT an
|
|
161
|
+
* account id still must avoid the platform API (codex review finding). API-key
|
|
162
|
+
* credentials (`chatgptOAuth` falsy) get null: they keep the default
|
|
163
|
+
* api.openai.com/v1 route unchanged.
|
|
164
|
+
*/
|
|
165
|
+
export function codexUpstreamRoute(token) {
|
|
166
|
+
if (!token.chatgptOAuth)
|
|
167
|
+
return null;
|
|
168
|
+
// The account id is the routing CONTEXT the backend expects, but it is not the
|
|
169
|
+
// routing TRIGGER: send the header only when present.
|
|
170
|
+
const accountId = nonEmptyString(token.chatgptAccountId ?? null);
|
|
171
|
+
const extraHeaders = accountId !== null ? { 'chatgpt-account-id': accountId } : {};
|
|
172
|
+
return { host: CHATGPT_BACKEND_HOST, rewritePath: rewriteCodexBackendPath, extraHeaders };
|
|
173
|
+
}
|
|
174
|
+
/** `/v1/<rest>` → `/backend-api/codex/<rest>`; non-`/v1` paths pass through unchanged. */
|
|
175
|
+
export function rewriteCodexBackendPath(pathname) {
|
|
176
|
+
return pathname.replace(/^\/v1(?=\/|$|\?)/, '/backend-api/codex');
|
|
177
|
+
}
|
|
178
|
+
// ─── egress-allowlist union → hooks config ───────────────────────────────────
|
|
179
|
+
/**
|
|
180
|
+
* Build the per-VM {@link AdapterHooksConfig} from the per-adapter specs plus the
|
|
181
|
+
* general workspace egress allowlist.
|
|
182
|
+
*
|
|
183
|
+
* The egress firewall (`allowedHosts`) = the general workspace dev-tooling
|
|
184
|
+
* allowlist (`egress.allowed_hosts` from WORKFLOW.yaml — npm/git/CDNs) UNION every
|
|
185
|
+
* adapter's `substitutionHosts` (you must be able to reach the host whose token you
|
|
186
|
+
* substitute on). Deduplicated, order-stable (egress hosts first, then each spec's
|
|
187
|
+
* substitution hosts in order).
|
|
188
|
+
*
|
|
189
|
+
* SECURITY: only `substitutionHosts` are wired (by the shell) into `secrets[].hosts`,
|
|
190
|
+
* so the real token is NEVER substituted for a general egress host — those receive
|
|
191
|
+
* plain network egress only. The FIREWALL is the union; the SUBSTITUTION scope is not.
|
|
192
|
+
*/
|
|
193
|
+
export function buildAdapterHooksConfig(specs, egressAllowlist = []) {
|
|
194
|
+
const substitution = specs.flatMap((s) => s.substitutionHosts);
|
|
195
|
+
const allowedHosts = dedupe([...egressAllowlist, ...substitution]);
|
|
196
|
+
return {
|
|
197
|
+
specs: specs.map((s) => ({ ...s, substitutionHosts: [...s.substitutionHosts] })),
|
|
198
|
+
allowedHosts,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
// ─── internal helpers ────────────────────────────────────────────────────────
|
|
202
|
+
// nonEmptyString is the shared credential helper from ./strings.js (imported above).
|
|
203
|
+
/** Order-stable de-duplication (first occurrence wins). */
|
|
204
|
+
function dedupe(values) {
|
|
205
|
+
const seen = new Set();
|
|
206
|
+
const out = [];
|
|
207
|
+
for (const v of values) {
|
|
208
|
+
if (seen.has(v))
|
|
209
|
+
continue;
|
|
210
|
+
seen.add(v);
|
|
211
|
+
out.push(v);
|
|
212
|
+
}
|
|
213
|
+
return out;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* base64url-encode a JSON-serialized object WITHOUT node:buffer (core may not
|
|
217
|
+
* import node builtins). Mirrors the extract.ts convention (which uses the WHATWG
|
|
218
|
+
* `atob` for decoding): here we JSON-stringify, UTF-8 encode via
|
|
219
|
+
* `unescape(encodeURIComponent(...))` (the inverse of extract.ts's decode), base64
|
|
220
|
+
* via the WHATWG `btoa`, then translate base64 → base64url (strip padding,
|
|
221
|
+
* `+`→`-`, `/`→`_`).
|
|
222
|
+
*/
|
|
223
|
+
function base64urlJson(obj) {
|
|
224
|
+
const json = JSON.stringify(obj);
|
|
225
|
+
// UTF-8 encode the string into a Latin-1 "binary string" btoa accepts.
|
|
226
|
+
const binary = unescape(encodeURIComponent(json));
|
|
227
|
+
const b64 = btoa(binary);
|
|
228
|
+
return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=shape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shape.js","sourceRoot":"","sources":["../../../../src/core/credential/shape.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// FCIS rewrite — shared credential string helpers (the ONE home).
|
|
2
|
+
//
|
|
3
|
+
// `nonEmptyString` was inlined across the credential modules (extract.ts /
|
|
4
|
+
// shape.ts / availability.ts), and availability.ts's copy had DRIFTED to a
|
|
5
|
+
// boolean return while the others returned the string value. The canonical
|
|
6
|
+
// (and strictly more useful — the boolean is just `!== null`) form is the
|
|
7
|
+
// string-valued one; availability.ts's boolean call sites adapt with a
|
|
8
|
+
// `!== null` check. This collapses all three onto one definition.
|
|
9
|
+
//
|
|
10
|
+
// 100% PURE + SYNCHRONOUS. No IO, no node: imports, no clock/randomness.
|
|
11
|
+
/** The value iff it is a non-empty string, else null. (`!== null` ⇒ "is set".) */
|
|
12
|
+
export function nonEmptyString(v) {
|
|
13
|
+
return typeof v === 'string' && v.length > 0 ? v : null;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=strings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strings.js","sourceRoot":"","sources":["../../../../src/core/credential/strings.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,2EAA2E;AAC3E,0EAA0E;AAC1E,uEAAuE;AACvE,kEAAkE;AAClE,EAAE;AACF,yEAAyE;AAEzE,kFAAkF;AAClF,MAAM,UAAU,cAAc,CAAC,CAAU;IACvC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC1D,CAAC"}
|