@oscharko-dev/keiko 0.1.0-beta.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/LICENSE +202 -0
- package/NOTICE +7 -0
- package/README.md +621 -0
- package/TRADEMARKS.md +41 -0
- package/dist/audit/aggregate.d.ts +5 -0
- package/dist/audit/aggregate.js +25 -0
- package/dist/audit/build.d.ts +2 -0
- package/dist/audit/build.js +224 -0
- package/dist/audit/errors.d.ts +25 -0
- package/dist/audit/errors.js +39 -0
- package/dist/audit/index-api.d.ts +14 -0
- package/dist/audit/index-api.js +131 -0
- package/dist/audit/index.d.ts +12 -0
- package/dist/audit/index.js +17 -0
- package/dist/audit/persist.d.ts +8 -0
- package/dist/audit/persist.js +40 -0
- package/dist/audit/redaction.d.ts +3 -0
- package/dist/audit/redaction.js +61 -0
- package/dist/audit/report.d.ts +18 -0
- package/dist/audit/report.js +50 -0
- package/dist/audit/retention.d.ts +3 -0
- package/dist/audit/retention.js +95 -0
- package/dist/audit/runid.d.ts +1 -0
- package/dist/audit/runid.js +29 -0
- package/dist/audit/side-file.d.ts +12 -0
- package/dist/audit/side-file.js +82 -0
- package/dist/audit/store.d.ts +12 -0
- package/dist/audit/store.js +198 -0
- package/dist/audit/types.d.ts +188 -0
- package/dist/audit/types.js +8 -0
- package/dist/audit/workflow-evidence.d.ts +27 -0
- package/dist/audit/workflow-evidence.js +145 -0
- package/dist/cli/context.d.ts +2 -0
- package/dist/cli/context.js +102 -0
- package/dist/cli/evaluate.d.ts +7 -0
- package/dist/cli/evaluate.js +207 -0
- package/dist/cli/evidence.d.ts +8 -0
- package/dist/cli/evidence.js +88 -0
- package/dist/cli/gateway-config.d.ts +10 -0
- package/dist/cli/gateway-config.js +12 -0
- package/dist/cli/gen-tests.d.ts +7 -0
- package/dist/cli/gen-tests.js +208 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +14 -0
- package/dist/cli/investigate.d.ts +8 -0
- package/dist/cli/investigate.js +242 -0
- package/dist/cli/models.d.ts +3 -0
- package/dist/cli/models.js +64 -0
- package/dist/cli/run.d.ts +7 -0
- package/dist/cli/run.js +187 -0
- package/dist/cli/runner.d.ts +6 -0
- package/dist/cli/runner.js +83 -0
- package/dist/cli/ui.d.ts +31 -0
- package/dist/cli/ui.js +240 -0
- package/dist/cli/verify.d.ts +2 -0
- package/dist/cli/verify.js +103 -0
- package/dist/evaluations/fixtures/bug-investigation/happy-path.d.ts +2 -0
- package/dist/evaluations/fixtures/bug-investigation/happy-path.js +66 -0
- package/dist/evaluations/fixtures/bug-investigation/investigation-only.d.ts +2 -0
- package/dist/evaluations/fixtures/bug-investigation/investigation-only.js +39 -0
- package/dist/evaluations/fixtures/bug-investigation/unsafe-action.d.ts +2 -0
- package/dist/evaluations/fixtures/bug-investigation/unsafe-action.js +37 -0
- package/dist/evaluations/fixtures/index.d.ts +7 -0
- package/dist/evaluations/fixtures/index.js +35 -0
- package/dist/evaluations/fixtures/support.d.ts +5 -0
- package/dist/evaluations/fixtures/support.js +42 -0
- package/dist/evaluations/fixtures/unit-tests/happy-path.d.ts +2 -0
- package/dist/evaluations/fixtures/unit-tests/happy-path.js +40 -0
- package/dist/evaluations/fixtures/unit-tests/retry-then-accept.d.ts +2 -0
- package/dist/evaluations/fixtures/unit-tests/retry-then-accept.js +39 -0
- package/dist/evaluations/fixtures/unit-tests/unsafe-action.d.ts +2 -0
- package/dist/evaluations/fixtures/unit-tests/unsafe-action.js +32 -0
- package/dist/evaluations/index.d.ts +12 -0
- package/dist/evaluations/index.js +12 -0
- package/dist/evaluations/manifest-check.d.ts +1 -0
- package/dist/evaluations/manifest-check.js +48 -0
- package/dist/evaluations/model-provider.d.ts +12 -0
- package/dist/evaluations/model-provider.js +26 -0
- package/dist/evaluations/render.d.ts +2 -0
- package/dist/evaluations/render.js +59 -0
- package/dist/evaluations/runner-support.d.ts +27 -0
- package/dist/evaluations/runner-support.js +163 -0
- package/dist/evaluations/runner.d.ts +20 -0
- package/dist/evaluations/runner.js +174 -0
- package/dist/evaluations/scorer.d.ts +14 -0
- package/dist/evaluations/scorer.js +131 -0
- package/dist/evaluations/scripted-model.d.ts +6 -0
- package/dist/evaluations/scripted-model.js +26 -0
- package/dist/evaluations/surface-parity.d.ts +2 -0
- package/dist/evaluations/surface-parity.js +184 -0
- package/dist/evaluations/types.d.ts +74 -0
- package/dist/evaluations/types.js +16 -0
- package/dist/gateway/capabilities.d.ts +11 -0
- package/dist/gateway/capabilities.data.d.ts +2 -0
- package/dist/gateway/capabilities.data.js +203 -0
- package/dist/gateway/capabilities.js +41 -0
- package/dist/gateway/config.d.ts +15 -0
- package/dist/gateway/config.js +154 -0
- package/dist/gateway/errors.d.ts +72 -0
- package/dist/gateway/errors.js +82 -0
- package/dist/gateway/gateway.d.ts +19 -0
- package/dist/gateway/gateway.js +94 -0
- package/dist/gateway/index.d.ts +10 -0
- package/dist/gateway/index.js +11 -0
- package/dist/gateway/model-selection.d.ts +9 -0
- package/dist/gateway/model-selection.js +36 -0
- package/dist/gateway/normalize.d.ts +7 -0
- package/dist/gateway/normalize.js +93 -0
- package/dist/gateway/openai-adapter.d.ts +20 -0
- package/dist/gateway/openai-adapter.js +263 -0
- package/dist/gateway/redaction.d.ts +1 -0
- package/dist/gateway/redaction.js +51 -0
- package/dist/gateway/resilience.d.ts +24 -0
- package/dist/gateway/resilience.js +166 -0
- package/dist/gateway/types.d.ts +108 -0
- package/dist/gateway/types.js +2 -0
- package/dist/harness/adapters.d.ts +23 -0
- package/dist/harness/adapters.js +38 -0
- package/dist/harness/context.d.ts +33 -0
- package/dist/harness/context.js +21 -0
- package/dist/harness/emitter.d.ts +15 -0
- package/dist/harness/emitter.js +72 -0
- package/dist/harness/errors.d.ts +21 -0
- package/dist/harness/errors.js +39 -0
- package/dist/harness/executor.d.ts +3 -0
- package/dist/harness/executor.js +211 -0
- package/dist/harness/fingerprint.d.ts +6 -0
- package/dist/harness/fingerprint.js +43 -0
- package/dist/harness/index.d.ts +9 -0
- package/dist/harness/index.js +13 -0
- package/dist/harness/loop.d.ts +3 -0
- package/dist/harness/loop.js +159 -0
- package/dist/harness/patcher.d.ts +4 -0
- package/dist/harness/patcher.js +49 -0
- package/dist/harness/planner.d.ts +3 -0
- package/dist/harness/planner.js +21 -0
- package/dist/harness/ports.d.ts +61 -0
- package/dist/harness/ports.js +4 -0
- package/dist/harness/session.d.ts +25 -0
- package/dist/harness/session.js +116 -0
- package/dist/harness/sinks.d.ts +30 -0
- package/dist/harness/sinks.js +72 -0
- package/dist/harness/tasks/explain-plan.d.ts +3 -0
- package/dist/harness/tasks/explain-plan.js +29 -0
- package/dist/harness/tasks/generate-unit-tests.d.ts +3 -0
- package/dist/harness/tasks/generate-unit-tests.js +28 -0
- package/dist/harness/tasks/investigate-bug.d.ts +3 -0
- package/dist/harness/tasks/investigate-bug.js +31 -0
- package/dist/harness/tasks/policy.d.ts +11 -0
- package/dist/harness/tasks/policy.js +22 -0
- package/dist/harness/tasks/verify.d.ts +3 -0
- package/dist/harness/tasks/verify.js +16 -0
- package/dist/harness/types.d.ts +270 -0
- package/dist/harness/types.js +33 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +36 -0
- package/dist/sdk/index.d.ts +9 -0
- package/dist/sdk/index.js +37 -0
- package/dist/sdk/run-agent.d.ts +16 -0
- package/dist/sdk/run-agent.js +56 -0
- package/dist/tools/browser/cdp-client.d.ts +35 -0
- package/dist/tools/browser/cdp-client.js +218 -0
- package/dist/tools/browser/errors.d.ts +25 -0
- package/dist/tools/browser/errors.js +55 -0
- package/dist/tools/browser/index.d.ts +5 -0
- package/dist/tools/browser/index.js +6 -0
- package/dist/tools/browser/session.d.ts +44 -0
- package/dist/tools/browser/session.js +748 -0
- package/dist/tools/browser/types.d.ts +48 -0
- package/dist/tools/browser/types.js +2 -0
- package/dist/tools/browser/validators.d.ts +5 -0
- package/dist/tools/browser/validators.js +97 -0
- package/dist/tools/errors.d.ts +59 -0
- package/dist/tools/errors.js +94 -0
- package/dist/tools/exec.d.ts +42 -0
- package/dist/tools/exec.js +327 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.js +14 -0
- package/dist/tools/patch-content.d.ts +10 -0
- package/dist/tools/patch-content.js +126 -0
- package/dist/tools/patch-normalize.d.ts +1 -0
- package/dist/tools/patch-normalize.js +80 -0
- package/dist/tools/patch-parse.d.ts +8 -0
- package/dist/tools/patch-parse.js +201 -0
- package/dist/tools/patch.d.ts +18 -0
- package/dist/tools/patch.js +403 -0
- package/dist/tools/registry.d.ts +36 -0
- package/dist/tools/registry.js +231 -0
- package/dist/tools/sandbox.d.ts +8 -0
- package/dist/tools/sandbox.js +121 -0
- package/dist/tools/schemas.d.ts +2 -0
- package/dist/tools/schemas.js +51 -0
- package/dist/tools/terminal-policy.d.ts +9 -0
- package/dist/tools/terminal-policy.js +313 -0
- package/dist/tools/types.d.ts +99 -0
- package/dist/tools/types.js +103 -0
- package/dist/tools/writer.d.ts +7 -0
- package/dist/tools/writer.js +20 -0
- package/dist/ui/browser.d.ts +10 -0
- package/dist/ui/browser.js +231 -0
- package/dist/ui/chat-handlers.d.ts +4 -0
- package/dist/ui/chat-handlers.js +281 -0
- package/dist/ui/csp-hashes.json +17 -0
- package/dist/ui/csp.d.ts +2 -0
- package/dist/ui/csp.js +66 -0
- package/dist/ui/deps.d.ts +34 -0
- package/dist/ui/deps.js +137 -0
- package/dist/ui/evidence.d.ts +27 -0
- package/dist/ui/evidence.js +142 -0
- package/dist/ui/files-deny.d.ts +2 -0
- package/dist/ui/files-deny.js +12 -0
- package/dist/ui/files.d.ts +65 -0
- package/dist/ui/files.js +492 -0
- package/dist/ui/headers.d.ts +2 -0
- package/dist/ui/headers.js +21 -0
- package/dist/ui/host-check.d.ts +2 -0
- package/dist/ui/host-check.js +58 -0
- package/dist/ui/index.d.ts +20 -0
- package/dist/ui/index.js +23 -0
- package/dist/ui/load-csp.d.ts +1 -0
- package/dist/ui/load-csp.js +28 -0
- package/dist/ui/read-handlers.d.ts +8 -0
- package/dist/ui/read-handlers.js +247 -0
- package/dist/ui/routes.d.ts +36 -0
- package/dist/ui/routes.js +129 -0
- package/dist/ui/run-engine.d.ts +20 -0
- package/dist/ui/run-engine.js +345 -0
- package/dist/ui/run-handlers.d.ts +8 -0
- package/dist/ui/run-handlers.js +431 -0
- package/dist/ui/run-request.d.ts +13 -0
- package/dist/ui/run-request.js +219 -0
- package/dist/ui/runs.d.ts +43 -0
- package/dist/ui/runs.js +92 -0
- package/dist/ui/server.d.ts +11 -0
- package/dist/ui/server.js +143 -0
- package/dist/ui/sink.d.ts +27 -0
- package/dist/ui/sink.js +80 -0
- package/dist/ui/sse.d.ts +7 -0
- package/dist/ui/sse.js +27 -0
- package/dist/ui/static/404.html +1 -0
- package/dist/ui/static/_next/static/ca-A01hy9W98aRvMZKdAw/_buildManifest.js +1 -0
- package/dist/ui/static/_next/static/ca-A01hy9W98aRvMZKdAw/_ssgManifest.js +1 -0
- package/dist/ui/static/_next/static/chunks/255-d47fd57964443afe.js +1 -0
- package/dist/ui/static/_next/static/chunks/4-be1fef693af8e088.js +1 -0
- package/dist/ui/static/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +1 -0
- package/dist/ui/static/_next/static/chunks/app/_not-found/page-75825b09bcecad97.js +1 -0
- package/dist/ui/static/_next/static/chunks/app/launch/page-9c86a13c29884245.js +1 -0
- package/dist/ui/static/_next/static/chunks/app/layout-bdea63fe87947d50.js +1 -0
- package/dist/ui/static/_next/static/chunks/app/page-4168c12c68b7a853.js +1 -0
- package/dist/ui/static/_next/static/chunks/framework-a6e0b7e30f98059a.js +1 -0
- package/dist/ui/static/_next/static/chunks/main-778a50aebff02192.js +1 -0
- package/dist/ui/static/_next/static/chunks/main-app-30679af7240d63e9.js +1 -0
- package/dist/ui/static/_next/static/chunks/pages/_app-7d307437aca18ad4.js +1 -0
- package/dist/ui/static/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +1 -0
- package/dist/ui/static/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- package/dist/ui/static/_next/static/chunks/webpack-4a462cecab786e93.js +1 -0
- package/dist/ui/static/_next/static/css/be7cb54d5c5673b6.css +1 -0
- package/dist/ui/static/assets/editors/goland.svg +35 -0
- package/dist/ui/static/assets/editors/intellij.svg +39 -0
- package/dist/ui/static/assets/editors/pycharm.svg +58 -0
- package/dist/ui/static/assets/editors/rustrover.svg +19 -0
- package/dist/ui/static/assets/editors/vscode.svg +1 -0
- package/dist/ui/static/assets/editors/webstorm.svg +21 -0
- package/dist/ui/static/assets/icons/anthropic.svg +1 -0
- package/dist/ui/static/assets/icons/brave.svg +1 -0
- package/dist/ui/static/assets/icons/css3.svg +1 -0
- package/dist/ui/static/assets/icons/docker.svg +1 -0
- package/dist/ui/static/assets/icons/git.svg +1 -0
- package/dist/ui/static/assets/icons/github.svg +1 -0
- package/dist/ui/static/assets/icons/go.svg +1 -0
- package/dist/ui/static/assets/icons/gradle.svg +1 -0
- package/dist/ui/static/assets/icons/grafana.svg +1 -0
- package/dist/ui/static/assets/icons/graphql.svg +1 -0
- package/dist/ui/static/assets/icons/html5.svg +1 -0
- package/dist/ui/static/assets/icons/image.svg +1 -0
- package/dist/ui/static/assets/icons/java.svg +1 -0
- package/dist/ui/static/assets/icons/javascript.svg +1 -0
- package/dist/ui/static/assets/icons/json.svg +1 -0
- package/dist/ui/static/assets/icons/kafka.svg +1 -0
- package/dist/ui/static/assets/icons/kubernetes.svg +1 -0
- package/dist/ui/static/assets/icons/linear.svg +1 -0
- package/dist/ui/static/assets/icons/markdown.svg +1 -0
- package/dist/ui/static/assets/icons/nginx.svg +1 -0
- package/dist/ui/static/assets/icons/nodejs.svg +1 -0
- package/dist/ui/static/assets/icons/notion.svg +1 -0
- package/dist/ui/static/assets/icons/openai.svg +1 -0
- package/dist/ui/static/assets/icons/playwright.svg +1 -0
- package/dist/ui/static/assets/icons/postgresql.svg +1 -0
- package/dist/ui/static/assets/icons/prometheus.svg +1 -0
- package/dist/ui/static/assets/icons/properties.svg +1 -0
- package/dist/ui/static/assets/icons/puppeteer.svg +1 -0
- package/dist/ui/static/assets/icons/python.svg +1 -0
- package/dist/ui/static/assets/icons/react.svg +1 -0
- package/dist/ui/static/assets/icons/redis.svg +1 -0
- package/dist/ui/static/assets/icons/rust.svg +1 -0
- package/dist/ui/static/assets/icons/sentry.svg +1 -0
- package/dist/ui/static/assets/icons/slack.svg +1 -0
- package/dist/ui/static/assets/icons/spring.svg +1 -0
- package/dist/ui/static/assets/icons/typescript.svg +1 -0
- package/dist/ui/static/assets/icons/upstash.svg +1 -0
- package/dist/ui/static/assets/icons/yaml.svg +1 -0
- package/dist/ui/static/assets/keiko-logo.svg +10 -0
- package/dist/ui/static/index.html +1 -0
- package/dist/ui/static/index.txt +19 -0
- package/dist/ui/static/keiko-logo.svg +10 -0
- package/dist/ui/static/launch.html +1 -0
- package/dist/ui/static/launch.txt +19 -0
- package/dist/ui/static.d.ts +3 -0
- package/dist/ui/static.js +72 -0
- package/dist/ui/store/chats.d.ts +14 -0
- package/dist/ui/store/chats.js +110 -0
- package/dist/ui/store/db.d.ts +6 -0
- package/dist/ui/store/db.js +182 -0
- package/dist/ui/store/errors.d.ts +12 -0
- package/dist/ui/store/errors.js +30 -0
- package/dist/ui/store/index.d.ts +6 -0
- package/dist/ui/store/index.js +6 -0
- package/dist/ui/store/messages.d.ts +5 -0
- package/dist/ui/store/messages.js +137 -0
- package/dist/ui/store/paths.d.ts +4 -0
- package/dist/ui/store/paths.js +69 -0
- package/dist/ui/store/projects.d.ts +7 -0
- package/dist/ui/store/projects.js +61 -0
- package/dist/ui/store/schema.d.ts +3 -0
- package/dist/ui/store/schema.js +77 -0
- package/dist/ui/store/types.d.ts +80 -0
- package/dist/ui/store/types.js +3 -0
- package/dist/ui/store/validation.d.ts +4 -0
- package/dist/ui/store/validation.js +72 -0
- package/dist/ui/store-handlers.d.ts +16 -0
- package/dist/ui/store-handlers.js +465 -0
- package/dist/ui/terminal-errors.d.ts +21 -0
- package/dist/ui/terminal-errors.js +45 -0
- package/dist/ui/terminal-evidence.d.ts +20 -0
- package/dist/ui/terminal-evidence.js +65 -0
- package/dist/ui/terminal-routes.d.ts +9 -0
- package/dist/ui/terminal-routes.js +219 -0
- package/dist/ui/terminal.d.ts +67 -0
- package/dist/ui/terminal.js +835 -0
- package/dist/verification/classify.d.ts +10 -0
- package/dist/verification/classify.js +53 -0
- package/dist/verification/detect.d.ts +4 -0
- package/dist/verification/detect.js +81 -0
- package/dist/verification/errors.d.ts +11 -0
- package/dist/verification/errors.js +21 -0
- package/dist/verification/index.d.ts +17 -0
- package/dist/verification/index.js +13 -0
- package/dist/verification/limits.d.ts +3 -0
- package/dist/verification/limits.js +40 -0
- package/dist/verification/monitor.d.ts +4 -0
- package/dist/verification/monitor.js +58 -0
- package/dist/verification/orchestrator.d.ts +16 -0
- package/dist/verification/orchestrator.js +363 -0
- package/dist/verification/plan.d.ts +9 -0
- package/dist/verification/plan.js +125 -0
- package/dist/verification/summary.d.ts +40 -0
- package/dist/verification/summary.js +67 -0
- package/dist/verification/types.d.ts +63 -0
- package/dist/verification/types.js +13 -0
- package/dist/workflows/bug-investigation/context.d.ts +7 -0
- package/dist/workflows/bug-investigation/context.js +119 -0
- package/dist/workflows/bug-investigation/descriptor.d.ts +3 -0
- package/dist/workflows/bug-investigation/descriptor.js +46 -0
- package/dist/workflows/bug-investigation/emit.d.ts +12 -0
- package/dist/workflows/bug-investigation/emit.js +35 -0
- package/dist/workflows/bug-investigation/events.d.ts +81 -0
- package/dist/workflows/bug-investigation/events.js +9 -0
- package/dist/workflows/bug-investigation/failure-parse.d.ts +3 -0
- package/dist/workflows/bug-investigation/failure-parse.js +154 -0
- package/dist/workflows/bug-investigation/guard.d.ts +2 -0
- package/dist/workflows/bug-investigation/guard.js +69 -0
- package/dist/workflows/bug-investigation/index.d.ts +7 -0
- package/dist/workflows/bug-investigation/index.js +13 -0
- package/dist/workflows/bug-investigation/internal.d.ts +37 -0
- package/dist/workflows/bug-investigation/internal.js +64 -0
- package/dist/workflows/bug-investigation/model-loop.d.ts +4 -0
- package/dist/workflows/bug-investigation/model-loop.js +223 -0
- package/dist/workflows/bug-investigation/parse.d.ts +3 -0
- package/dist/workflows/bug-investigation/parse.js +123 -0
- package/dist/workflows/bug-investigation/prompt.d.ts +4 -0
- package/dist/workflows/bug-investigation/prompt.js +107 -0
- package/dist/workflows/bug-investigation/report.d.ts +23 -0
- package/dist/workflows/bug-investigation/report.js +151 -0
- package/dist/workflows/bug-investigation/stages.d.ts +13 -0
- package/dist/workflows/bug-investigation/stages.js +242 -0
- package/dist/workflows/bug-investigation/types.d.ts +91 -0
- package/dist/workflows/bug-investigation/types.js +14 -0
- package/dist/workflows/bug-investigation/verify-stage.d.ts +10 -0
- package/dist/workflows/bug-investigation/verify-stage.js +91 -0
- package/dist/workflows/bug-investigation/workflow.d.ts +2 -0
- package/dist/workflows/bug-investigation/workflow.js +74 -0
- package/dist/workflows/descriptor.d.ts +20 -0
- package/dist/workflows/descriptor.js +8 -0
- package/dist/workflows/index.d.ts +3 -0
- package/dist/workflows/index.js +2 -0
- package/dist/workflows/unit-tests/context.d.ts +7 -0
- package/dist/workflows/unit-tests/context.js +129 -0
- package/dist/workflows/unit-tests/conventions.d.ts +4 -0
- package/dist/workflows/unit-tests/conventions.js +87 -0
- package/dist/workflows/unit-tests/descriptor.d.ts +4 -0
- package/dist/workflows/unit-tests/descriptor.js +43 -0
- package/dist/workflows/unit-tests/emit.d.ts +12 -0
- package/dist/workflows/unit-tests/emit.js +35 -0
- package/dist/workflows/unit-tests/events.d.ts +78 -0
- package/dist/workflows/unit-tests/events.js +7 -0
- package/dist/workflows/unit-tests/index.d.ts +6 -0
- package/dist/workflows/unit-tests/index.js +10 -0
- package/dist/workflows/unit-tests/internal.d.ts +35 -0
- package/dist/workflows/unit-tests/internal.js +43 -0
- package/dist/workflows/unit-tests/model-loop.d.ts +4 -0
- package/dist/workflows/unit-tests/model-loop.js +95 -0
- package/dist/workflows/unit-tests/parse.d.ts +6 -0
- package/dist/workflows/unit-tests/parse.js +68 -0
- package/dist/workflows/unit-tests/prompt.d.ts +4 -0
- package/dist/workflows/unit-tests/prompt.js +71 -0
- package/dist/workflows/unit-tests/report.d.ts +21 -0
- package/dist/workflows/unit-tests/report.js +90 -0
- package/dist/workflows/unit-tests/stages.d.ts +9 -0
- package/dist/workflows/unit-tests/stages.js +155 -0
- package/dist/workflows/unit-tests/types.d.ts +70 -0
- package/dist/workflows/unit-tests/types.js +11 -0
- package/dist/workflows/unit-tests/verify-stage.d.ts +9 -0
- package/dist/workflows/unit-tests/verify-stage.js +56 -0
- package/dist/workflows/unit-tests/workflow.d.ts +2 -0
- package/dist/workflows/unit-tests/workflow.js +58 -0
- package/dist/workspace/contextPack.d.ts +9 -0
- package/dist/workspace/contextPack.js +94 -0
- package/dist/workspace/detect.d.ts +3 -0
- package/dist/workspace/detect.js +135 -0
- package/dist/workspace/discovery.d.ts +9 -0
- package/dist/workspace/discovery.js +167 -0
- package/dist/workspace/errors.d.ts +39 -0
- package/dist/workspace/errors.js +66 -0
- package/dist/workspace/fs.d.ts +21 -0
- package/dist/workspace/fs.js +36 -0
- package/dist/workspace/ignore.d.ts +14 -0
- package/dist/workspace/ignore.js +176 -0
- package/dist/workspace/index.d.ts +11 -0
- package/dist/workspace/index.js +13 -0
- package/dist/workspace/paths.d.ts +2 -0
- package/dist/workspace/paths.js +38 -0
- package/dist/workspace/realpath.d.ts +7 -0
- package/dist/workspace/realpath.js +72 -0
- package/dist/workspace/retrieval.d.ts +9 -0
- package/dist/workspace/retrieval.js +74 -0
- package/dist/workspace/summary.d.ts +3 -0
- package/dist/workspace/summary.js +54 -0
- package/dist/workspace/types.d.ts +103 -0
- package/dist/workspace/types.js +27 -0
- package/package.json +58 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Usage/cost aggregation (ADR-0010 D7). aggregateUsage is a PURE fold over model:call:completed
|
|
2
|
+
// events; resolveCostClass recovers the cost class from the gateway capability registry rather than
|
|
3
|
+
// the event (the harness model:call:completed event omits costClass by design and we do NOT add it —
|
|
4
|
+
// no harness edit). One model per run is assumed (RunManifest.modelId is single-valued); the
|
|
5
|
+
// multi-model caveat is documented in the ADR Consequences, not silently mis-aggregated.
|
|
6
|
+
import { findCapability } from "../gateway/capabilities.js";
|
|
7
|
+
export function aggregateUsage(events) {
|
|
8
|
+
let promptTokens = 0;
|
|
9
|
+
let completionTokens = 0;
|
|
10
|
+
let requestCount = 0;
|
|
11
|
+
let totalLatencyMs = 0;
|
|
12
|
+
for (const event of events) {
|
|
13
|
+
if (event.type !== "model:call:completed") {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
promptTokens += event.usage.promptTokens;
|
|
17
|
+
completionTokens += event.usage.completionTokens;
|
|
18
|
+
totalLatencyMs += event.usage.latencyMs;
|
|
19
|
+
requestCount += 1;
|
|
20
|
+
}
|
|
21
|
+
return { promptTokens, completionTokens, requestCount, totalLatencyMs };
|
|
22
|
+
}
|
|
23
|
+
export function resolveCostClass(modelId) {
|
|
24
|
+
return findCapability(modelId)?.costClass ?? "unknown";
|
|
25
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
// The redacted-by-construction manifest builder (ADR-0010 D2/D3/D7/D8). It maps a harness
|
|
2
|
+
// RunResult/RunManifest (+ optional #5/#7 audit summaries) into an EvidenceManifest, applying the
|
|
3
|
+
// audit redactor at the moment each sensitive value is copied in — there is no intermediate "raw
|
|
4
|
+
// manifest" object. The persist layer (D3 defense-in-depth) additionally deep-redacts every string
|
|
5
|
+
// leaf before serialization, so a builder bug that missed a field cannot silently persist a secret.
|
|
6
|
+
import { aggregateUsage, resolveCostClass } from "./aggregate.js";
|
|
7
|
+
import { createAuditRedactor, deepRedactStrings } from "./redaction.js";
|
|
8
|
+
import { EVIDENCE_SCHEMA_VERSION } from "./types.js";
|
|
9
|
+
function buildIdentity(input) {
|
|
10
|
+
const { result, manifest } = input;
|
|
11
|
+
return {
|
|
12
|
+
runId: result.runId,
|
|
13
|
+
fingerprint: result.fingerprint,
|
|
14
|
+
harnessVersion: manifest.harnessVersion,
|
|
15
|
+
taskType: result.taskType,
|
|
16
|
+
outcome: result.outcome,
|
|
17
|
+
startedAt: result.startedAt,
|
|
18
|
+
finishedAt: result.finishedAt,
|
|
19
|
+
durationMs: result.finishedAt - result.startedAt,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function mapStateTransition(e, redact) {
|
|
23
|
+
return { seq: e.seq, ts: e.ts, from: e.from, to: e.to, reason: redact(e.reason) };
|
|
24
|
+
}
|
|
25
|
+
function mapToolCompleted(e) {
|
|
26
|
+
return {
|
|
27
|
+
seq: e.seq,
|
|
28
|
+
ts: e.ts,
|
|
29
|
+
toolName: e.toolName,
|
|
30
|
+
toolCallId: e.toolCallId,
|
|
31
|
+
outcome: "completed",
|
|
32
|
+
durationMs: e.durationMs,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
function mapToolFailed(e) {
|
|
36
|
+
// The redacted message is dropped (D3); only the stable errorCode is retained.
|
|
37
|
+
return {
|
|
38
|
+
seq: e.seq,
|
|
39
|
+
ts: e.ts,
|
|
40
|
+
toolName: e.toolName,
|
|
41
|
+
toolCallId: e.toolCallId,
|
|
42
|
+
outcome: "failed",
|
|
43
|
+
errorCode: e.errorCode,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function mapCommand(e) {
|
|
47
|
+
return {
|
|
48
|
+
seq: e.seq,
|
|
49
|
+
ts: e.ts,
|
|
50
|
+
executable: e.executable,
|
|
51
|
+
argCount: e.argCount,
|
|
52
|
+
exitCode: e.exitCode,
|
|
53
|
+
timedOut: e.timedOut,
|
|
54
|
+
durationMs: e.durationMs,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function mapSandbox(e) {
|
|
58
|
+
return {
|
|
59
|
+
seq: e.seq,
|
|
60
|
+
ts: e.ts,
|
|
61
|
+
envAllowlist: e.envAllowlist,
|
|
62
|
+
network: e.network,
|
|
63
|
+
maxOutputBytes: e.maxOutputBytes,
|
|
64
|
+
timeoutMs: e.timeoutMs,
|
|
65
|
+
terminationGraceMs: e.terminationGraceMs,
|
|
66
|
+
cwdRequested: e.cwdRequested,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function mapVerificationResult(e, redact) {
|
|
70
|
+
return { seq: e.seq, ts: e.ts, passed: e.passed, detail: redact(e.detail) };
|
|
71
|
+
}
|
|
72
|
+
function mapReasoning(e, redact) {
|
|
73
|
+
return {
|
|
74
|
+
seq: e.seq,
|
|
75
|
+
ts: e.ts,
|
|
76
|
+
phase: e.phase,
|
|
77
|
+
rationale: redact(e.rationale),
|
|
78
|
+
...(e.modelResponse === undefined ? {} : { modelResponse: redact(e.modelResponse) }),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function newPatchAccumulator() {
|
|
82
|
+
return {
|
|
83
|
+
seen: false,
|
|
84
|
+
proposed: false,
|
|
85
|
+
applied: false,
|
|
86
|
+
targetFileCount: 0,
|
|
87
|
+
patchBytes: 0,
|
|
88
|
+
changedFiles: 0,
|
|
89
|
+
created: 0,
|
|
90
|
+
deleted: 0,
|
|
91
|
+
redactedDiff: undefined,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function foldPatchProposed(acc, e, redact, includeDiff) {
|
|
95
|
+
acc.seen = true;
|
|
96
|
+
acc.proposed = true;
|
|
97
|
+
acc.targetFileCount += 1;
|
|
98
|
+
acc.patchBytes += e.patchBytes;
|
|
99
|
+
if (includeDiff) {
|
|
100
|
+
acc.redactedDiff = redact(e.diff);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function foldPatchApplied(acc, e) {
|
|
104
|
+
acc.seen = true;
|
|
105
|
+
acc.applied = true;
|
|
106
|
+
acc.changedFiles += e.changedFiles;
|
|
107
|
+
acc.created += e.created;
|
|
108
|
+
acc.deleted += e.deleted;
|
|
109
|
+
}
|
|
110
|
+
function toPatch(acc) {
|
|
111
|
+
if (!acc.seen) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
proposed: acc.proposed,
|
|
116
|
+
applied: acc.applied,
|
|
117
|
+
targetFileCount: acc.targetFileCount,
|
|
118
|
+
patchBytes: acc.patchBytes,
|
|
119
|
+
changedFiles: acc.changedFiles,
|
|
120
|
+
created: acc.created,
|
|
121
|
+
deleted: acc.deleted,
|
|
122
|
+
...(acc.redactedDiff === undefined ? {} : { redactedDiff: acc.redactedDiff }),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
function toFailure(result, redact) {
|
|
126
|
+
if (result.failure === undefined) {
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
return { category: result.failure.category, message: redact(result.failure.message) };
|
|
130
|
+
}
|
|
131
|
+
function foldRecordEvent(state, event, redact) {
|
|
132
|
+
if (event.type === "state:transition") {
|
|
133
|
+
state.stateTransitions.push(mapStateTransition(event, redact));
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
else if (event.type === "tool:call:completed") {
|
|
137
|
+
state.toolCalls.push(mapToolCompleted(event));
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
else if (event.type === "tool:call:failed") {
|
|
141
|
+
state.toolCalls.push(mapToolFailed(event));
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
else if (event.type === "command:executed") {
|
|
145
|
+
state.commandExecutions.push(mapCommand(event));
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
else if (event.type === "sandbox:configured") {
|
|
149
|
+
state.sandboxConfigurations.push(mapSandbox(event));
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
else if (event.type === "verification:result") {
|
|
153
|
+
state.verificationResults.push(mapVerificationResult(event, redact));
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
function foldEvent(state, event, redact, options) {
|
|
159
|
+
if (foldRecordEvent(state, event, redact)) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (event.type === "patch:proposed") {
|
|
163
|
+
foldPatchProposed(state.patch, event, redact, options.includeDiff);
|
|
164
|
+
}
|
|
165
|
+
else if (event.type === "patch:applied") {
|
|
166
|
+
foldPatchApplied(state.patch, event);
|
|
167
|
+
}
|
|
168
|
+
else if (event.type === "reasoning:trace" && options.includeReasoning) {
|
|
169
|
+
state.reasoning.push(mapReasoning(event, redact));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Assembles the optional sections (undefined-when-absent, never an empty object/array masquerading
|
|
173
|
+
// as "ran but produced nothing" — D2). exactOptionalPropertyTypes means each key is only present
|
|
174
|
+
// when its value exists; reasoning is keyed only under its opt-in.
|
|
175
|
+
function optionalSections(input, state, redact, includeReasoning) {
|
|
176
|
+
const patch = toPatch(state.patch);
|
|
177
|
+
const failure = toFailure(input.result, redact);
|
|
178
|
+
return {
|
|
179
|
+
...(input.context === undefined ? {} : { context: input.context }),
|
|
180
|
+
...(patch === undefined ? {} : { patch }),
|
|
181
|
+
...(input.verification === undefined ? {} : { verification: input.verification }),
|
|
182
|
+
...(failure === undefined ? {} : { failure }),
|
|
183
|
+
...(includeReasoning ? { reasoning: state.reasoning } : {}),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
export function buildEvidenceManifest(input, deps) {
|
|
187
|
+
const redact = createAuditRedactor(input.redaction ?? {}, deps.env ?? {});
|
|
188
|
+
const includeDiff = input.options?.includeDiff ?? false;
|
|
189
|
+
const includeReasoning = input.options?.includeReasoning ?? false;
|
|
190
|
+
const state = {
|
|
191
|
+
stateTransitions: [],
|
|
192
|
+
toolCalls: [],
|
|
193
|
+
commandExecutions: [],
|
|
194
|
+
sandboxConfigurations: [],
|
|
195
|
+
verificationResults: [],
|
|
196
|
+
reasoning: [],
|
|
197
|
+
patch: newPatchAccumulator(),
|
|
198
|
+
};
|
|
199
|
+
for (const event of input.result.events) {
|
|
200
|
+
foldEvent(state, event, redact, { includeDiff, includeReasoning });
|
|
201
|
+
}
|
|
202
|
+
const manifest = {
|
|
203
|
+
evidenceSchemaVersion: EVIDENCE_SCHEMA_VERSION,
|
|
204
|
+
run: buildIdentity(input),
|
|
205
|
+
model: { modelId: input.manifest.modelId, costClass: resolveCostClass(input.manifest.modelId) },
|
|
206
|
+
usageTotals: aggregateUsage(input.result.events),
|
|
207
|
+
stateTransitions: state.stateTransitions,
|
|
208
|
+
toolCalls: state.toolCalls,
|
|
209
|
+
commandExecutions: state.commandExecutions,
|
|
210
|
+
...(state.sandboxConfigurations.length === 0
|
|
211
|
+
? {}
|
|
212
|
+
: { sandboxConfigurations: state.sandboxConfigurations }),
|
|
213
|
+
...(state.verificationResults.length === 0
|
|
214
|
+
? {}
|
|
215
|
+
: { verificationResults: state.verificationResults }),
|
|
216
|
+
...optionalSections(input, state, redact, includeReasoning),
|
|
217
|
+
};
|
|
218
|
+
// C2: the #5 context and #7 verification summaries are embedded VERBATIM above, so per-field
|
|
219
|
+
// redaction during the fold does not reach them. Apply the audit redactor over every string leaf so
|
|
220
|
+
// a DIRECT builder caller (not only via persistEvidence) gets a truly redacted-by-construction
|
|
221
|
+
// manifest. Idempotent, so the fold's per-field redaction still stands and persist's DiD pass is a
|
|
222
|
+
// no-op on already-redacted tokens.
|
|
223
|
+
return deepRedactStrings(manifest, redact);
|
|
224
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare const AUDIT_CODES: {
|
|
2
|
+
readonly INVALID_RUN_ID: "AUDIT_INVALID_RUN_ID";
|
|
3
|
+
readonly WRITE: "AUDIT_WRITE";
|
|
4
|
+
readonly SCHEMA: "AUDIT_SCHEMA";
|
|
5
|
+
readonly READ: "AUDIT_READ";
|
|
6
|
+
};
|
|
7
|
+
export type AuditCode = (typeof AUDIT_CODES)[keyof typeof AUDIT_CODES];
|
|
8
|
+
export declare abstract class AuditError extends Error {
|
|
9
|
+
abstract readonly code: AuditCode;
|
|
10
|
+
constructor(message: string, secrets?: readonly string[]);
|
|
11
|
+
}
|
|
12
|
+
export declare class InvalidRunIdError extends AuditError {
|
|
13
|
+
readonly code: "AUDIT_INVALID_RUN_ID";
|
|
14
|
+
}
|
|
15
|
+
export declare class EvidenceWriteError extends AuditError {
|
|
16
|
+
readonly code: "AUDIT_WRITE";
|
|
17
|
+
}
|
|
18
|
+
export declare class EvidenceReadError extends AuditError {
|
|
19
|
+
readonly code: "AUDIT_READ";
|
|
20
|
+
}
|
|
21
|
+
export declare class EvidenceSchemaError extends AuditError {
|
|
22
|
+
readonly code: "AUDIT_SCHEMA";
|
|
23
|
+
readonly foundVersion: string;
|
|
24
|
+
constructor(message: string, foundVersion: string, secrets?: readonly string[]);
|
|
25
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Audit error taxonomy, mirroring gateway/harness/workspace/tools (ADR-0003..0006). Errors carry a
|
|
2
|
+
// stable `code` discriminant; callers switch on `code`, never parse `message`. Every message is
|
|
3
|
+
// redacted at construction (D11: typed errors with redacted messages) so errors are always safe to
|
|
4
|
+
// log or surface.
|
|
5
|
+
import { redact } from "../gateway/redaction.js";
|
|
6
|
+
export const AUDIT_CODES = {
|
|
7
|
+
INVALID_RUN_ID: "AUDIT_INVALID_RUN_ID",
|
|
8
|
+
WRITE: "AUDIT_WRITE",
|
|
9
|
+
SCHEMA: "AUDIT_SCHEMA",
|
|
10
|
+
READ: "AUDIT_READ",
|
|
11
|
+
};
|
|
12
|
+
export class AuditError extends Error {
|
|
13
|
+
constructor(message, secrets = []) {
|
|
14
|
+
super(redact(message, secrets));
|
|
15
|
+
this.name = new.target.name;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// A runId failed the bounded character-class / length validation (D4 iii). Nothing was written.
|
|
19
|
+
export class InvalidRunIdError extends AuditError {
|
|
20
|
+
code = AUDIT_CODES.INVALID_RUN_ID;
|
|
21
|
+
}
|
|
22
|
+
// A write or delete at the filesystem boundary failed, or a path escaped the contained base dir.
|
|
23
|
+
export class EvidenceWriteError extends AuditError {
|
|
24
|
+
code = AUDIT_CODES.WRITE;
|
|
25
|
+
}
|
|
26
|
+
// A persisted manifest could not be parsed as JSON (truncated, hand-edited, or corrupt). Surfaced as
|
|
27
|
+
// a typed error so the CLI maps it to a clean exit code instead of leaking a raw SyntaxError (C1).
|
|
28
|
+
export class EvidenceReadError extends AuditError {
|
|
29
|
+
code = AUDIT_CODES.READ;
|
|
30
|
+
}
|
|
31
|
+
// A persisted manifest carried an unrecognised evidenceSchemaVersion (D5) — not silently coerced.
|
|
32
|
+
export class EvidenceSchemaError extends AuditError {
|
|
33
|
+
code = AUDIT_CODES.SCHEMA;
|
|
34
|
+
foundVersion;
|
|
35
|
+
constructor(message, foundVersion, secrets = []) {
|
|
36
|
+
super(message, secrets);
|
|
37
|
+
this.foundVersion = foundVersion;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { RunOutcome } from "../harness/types.js";
|
|
2
|
+
import type { EvidenceStore } from "./store.js";
|
|
3
|
+
import type { EvidenceManifest, EvidenceTaskType } from "./types.js";
|
|
4
|
+
export interface EvidenceListEntry {
|
|
5
|
+
readonly runId: string;
|
|
6
|
+
readonly taskType: EvidenceTaskType;
|
|
7
|
+
readonly outcome: RunOutcome;
|
|
8
|
+
readonly startedAt: number;
|
|
9
|
+
readonly finishedAt: number;
|
|
10
|
+
readonly modelId: string;
|
|
11
|
+
readonly workspaceRoot?: string | undefined;
|
|
12
|
+
}
|
|
13
|
+
export declare function listEvidence(store: EvidenceStore): readonly EvidenceListEntry[];
|
|
14
|
+
export declare function loadEvidence(store: EvidenceStore, runId: string): EvidenceManifest | undefined;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// Evidence index/list API (ADR-0010 D5). listEvidence enumerates and loadEvidence loads past runs
|
|
2
|
+
// reading ONLY the contained base dir via the EvidenceStore — never scanning arbitrary workspace
|
|
3
|
+
// files. Because the persisted JSON is redacted by construction (D3), the loaded data is
|
|
4
|
+
// redacted-by-construction: there is no un-redaction path. A manifest whose evidenceSchemaVersion is
|
|
5
|
+
// not a recognised version is reported with a typed error (D5), not silently coerced. This is the
|
|
6
|
+
// #13 UI seam.
|
|
7
|
+
import { EvidenceReadError, EvidenceSchemaError } from "./errors.js";
|
|
8
|
+
import { EVIDENCE_SCHEMA_VERSION } from "./types.js";
|
|
9
|
+
// Parses raw JSON and verifies the schema version before trusting the shape. We narrow on the
|
|
10
|
+
// version discriminant exactly as harness consumers narrow on the event schemaVersion (D2).
|
|
11
|
+
// JSON.parse can throw a raw SyntaxError on a truncated/hand-edited manifest; the parse is a system
|
|
12
|
+
// boundary (reading developer-writable files), so catching it and re-throwing a typed AuditError is
|
|
13
|
+
// correct — the CLI maps AuditError to an exit code instead of leaking an unhandled stack (C1).
|
|
14
|
+
function parseJson(json, runId) {
|
|
15
|
+
try {
|
|
16
|
+
return JSON.parse(json);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
throw new EvidenceReadError(`evidence manifest is not valid JSON: ${runId}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function isRecord(value) {
|
|
23
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24
|
+
}
|
|
25
|
+
function requireRecord(parent, key, runId) {
|
|
26
|
+
const value = parent[key];
|
|
27
|
+
if (!isRecord(value)) {
|
|
28
|
+
throw new EvidenceSchemaError(`evidence manifest is missing object field ${key}: ${runId}`, "1");
|
|
29
|
+
}
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
function requireArray(parent, key, runId) {
|
|
33
|
+
if (!Array.isArray(parent[key])) {
|
|
34
|
+
throw new EvidenceSchemaError(`evidence manifest is missing array field ${key}: ${runId}`, "1");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function requireString(parent, key, runId) {
|
|
38
|
+
if (typeof parent[key] !== "string") {
|
|
39
|
+
throw new EvidenceSchemaError(`evidence manifest is missing string field ${key}: ${runId}`, "1");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function requireNumber(parent, key, runId) {
|
|
43
|
+
if (typeof parent[key] !== "number" || !Number.isFinite(parent[key])) {
|
|
44
|
+
throw new EvidenceSchemaError(`evidence manifest is missing numeric field ${key}: ${runId}`, "1");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function requireOptionalRecord(parent, key, runId) {
|
|
48
|
+
const value = parent[key];
|
|
49
|
+
if (value !== undefined && !isRecord(value)) {
|
|
50
|
+
throw new EvidenceSchemaError(`evidence manifest has invalid object field ${key}: ${runId}`, "1");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function requireOptionalArray(parent, key, runId) {
|
|
54
|
+
const value = parent[key];
|
|
55
|
+
if (value !== undefined && !Array.isArray(value)) {
|
|
56
|
+
throw new EvidenceSchemaError(`evidence manifest has invalid array field ${key}: ${runId}`, "1");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function validateManifestShape(parsed, runId) {
|
|
60
|
+
const run = requireRecord(parsed, "run", runId);
|
|
61
|
+
requireString(run, "runId", runId);
|
|
62
|
+
requireString(run, "fingerprint", runId);
|
|
63
|
+
requireString(run, "harnessVersion", runId);
|
|
64
|
+
requireString(run, "taskType", runId);
|
|
65
|
+
requireString(run, "outcome", runId);
|
|
66
|
+
requireNumber(run, "startedAt", runId);
|
|
67
|
+
requireNumber(run, "finishedAt", runId);
|
|
68
|
+
requireNumber(run, "durationMs", runId);
|
|
69
|
+
const model = requireRecord(parsed, "model", runId);
|
|
70
|
+
requireString(model, "modelId", runId);
|
|
71
|
+
requireString(model, "costClass", runId);
|
|
72
|
+
const usage = requireRecord(parsed, "usageTotals", runId);
|
|
73
|
+
requireNumber(usage, "promptTokens", runId);
|
|
74
|
+
requireNumber(usage, "completionTokens", runId);
|
|
75
|
+
requireNumber(usage, "requestCount", runId);
|
|
76
|
+
requireNumber(usage, "totalLatencyMs", runId);
|
|
77
|
+
requireArray(parsed, "stateTransitions", runId);
|
|
78
|
+
requireArray(parsed, "toolCalls", runId);
|
|
79
|
+
requireArray(parsed, "commandExecutions", runId);
|
|
80
|
+
requireOptionalArray(parsed, "sandboxConfigurations", runId);
|
|
81
|
+
requireOptionalArray(parsed, "verificationResults", runId);
|
|
82
|
+
requireOptionalArray(parsed, "reasoning", runId);
|
|
83
|
+
requireOptionalRecord(parsed, "context", runId);
|
|
84
|
+
requireOptionalRecord(parsed, "patch", runId);
|
|
85
|
+
requireOptionalRecord(parsed, "verification", runId);
|
|
86
|
+
requireOptionalRecord(parsed, "failure", runId);
|
|
87
|
+
requireOptionalRecord(parsed, "browser", runId);
|
|
88
|
+
}
|
|
89
|
+
function parseManifest(json, runId) {
|
|
90
|
+
const parsed = parseJson(json, runId);
|
|
91
|
+
if (!isRecord(parsed)) {
|
|
92
|
+
throw new EvidenceSchemaError(`evidence manifest is not an object: ${runId}`, "none");
|
|
93
|
+
}
|
|
94
|
+
const version = parsed.evidenceSchemaVersion;
|
|
95
|
+
if (version !== EVIDENCE_SCHEMA_VERSION) {
|
|
96
|
+
throw new EvidenceSchemaError(`unrecognised evidence schema version for ${runId}`, typeof version === "string" ? version : "none");
|
|
97
|
+
}
|
|
98
|
+
validateManifestShape(parsed, runId);
|
|
99
|
+
return parsed;
|
|
100
|
+
}
|
|
101
|
+
function toListEntry(manifest) {
|
|
102
|
+
return {
|
|
103
|
+
runId: manifest.run.runId,
|
|
104
|
+
taskType: manifest.run.taskType,
|
|
105
|
+
outcome: manifest.run.outcome,
|
|
106
|
+
startedAt: manifest.run.startedAt,
|
|
107
|
+
finishedAt: manifest.run.finishedAt,
|
|
108
|
+
modelId: manifest.model.modelId,
|
|
109
|
+
...(manifest.context?.workspaceRoot === undefined
|
|
110
|
+
? {}
|
|
111
|
+
: { workspaceRoot: manifest.context.workspaceRoot }),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export function listEvidence(store) {
|
|
115
|
+
const entries = [];
|
|
116
|
+
for (const runId of store.list()) {
|
|
117
|
+
const json = store.get(runId);
|
|
118
|
+
if (json === undefined) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
entries.push(toListEntry(parseManifest(json, runId)));
|
|
122
|
+
}
|
|
123
|
+
return entries;
|
|
124
|
+
}
|
|
125
|
+
export function loadEvidence(store, runId) {
|
|
126
|
+
const json = store.get(runId);
|
|
127
|
+
if (json === undefined) {
|
|
128
|
+
return undefined;
|
|
129
|
+
}
|
|
130
|
+
return parseManifest(json, runId);
|
|
131
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { buildEvidenceManifest } from "./build.js";
|
|
2
|
+
export { persistEvidence, type PersistResult } from "./persist.js";
|
|
3
|
+
export { createAuditRedactor, deepRedactStrings } from "./redaction.js";
|
|
4
|
+
export { aggregateUsage, resolveCostClass } from "./aggregate.js";
|
|
5
|
+
export { listEvidence, loadEvidence, type EvidenceListEntry } from "./index-api.js";
|
|
6
|
+
export { applyRetention } from "./retention.js";
|
|
7
|
+
export { buildEvidenceReport, renderEvidenceReport, type EvidenceReport } from "./report.js";
|
|
8
|
+
export { assertValidRunId } from "./runid.js";
|
|
9
|
+
export { buildWorkflowManifest, foldWorkflowUsage, persistWorkflowEvidence, type EvidencePersistContext, type WorkflowEventLike, type WorkflowRunIdentity, type WorkflowRunKind, type WorkflowTerminalStatus, } from "./workflow-evidence.js";
|
|
10
|
+
export { createInMemoryEvidenceStore, createNodeEvidenceStore, resolveEvidenceDir, type EvidenceStore, } from "./store.js";
|
|
11
|
+
export { AUDIT_CODES, AuditError, EvidenceReadError, EvidenceSchemaError, EvidenceWriteError, InvalidRunIdError, type AuditCode, } from "./errors.js";
|
|
12
|
+
export { EVIDENCE_SCHEMA_VERSION, DEFAULT_RETENTION, type AuditRedactionConfig, type BuildOptions, type EvidenceBuildInput, type EvidenceCommandExecution, type EvidenceDeps, type EvidenceFailure, type EvidenceManifest, type EvidenceModel, type EvidenceBrowserCapture, type EvidenceBrowserContentCapture, type EvidenceBrowserEvent, type EvidenceBrowserEventType, type EvidenceBrowserScreenshot, type EvidenceBrowserViewportPx, type EvidencePatch, type EvidenceReasoningEntry, type EvidenceRunIdentity, type EvidenceStateTransition, type EvidenceTaskType, type EvidenceToolCall, type EvidenceUsageTotals, type EvidenceVerificationResult, type RetentionPolicy, } from "./types.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// Audit ledger barrel (ADR-0010 D12). Re-exports the public surface of the audit layer: the builder,
|
|
2
|
+
// the persist orchestration, the redactor, the store port + adapters, aggregation, the index/list
|
|
3
|
+
// API, retention, the report, and runId validation, plus the schema/types. None of these names
|
|
4
|
+
// collides with an existing layer export (D9) — in particular the layer does NOT export a bare
|
|
5
|
+
// `summarizeForAudit` or `redact` (it composes them internally).
|
|
6
|
+
export { buildEvidenceManifest } from "./build.js";
|
|
7
|
+
export { persistEvidence } from "./persist.js";
|
|
8
|
+
export { createAuditRedactor, deepRedactStrings } from "./redaction.js";
|
|
9
|
+
export { aggregateUsage, resolveCostClass } from "./aggregate.js";
|
|
10
|
+
export { listEvidence, loadEvidence } from "./index-api.js";
|
|
11
|
+
export { applyRetention } from "./retention.js";
|
|
12
|
+
export { buildEvidenceReport, renderEvidenceReport } from "./report.js";
|
|
13
|
+
export { assertValidRunId } from "./runid.js";
|
|
14
|
+
export { buildWorkflowManifest, foldWorkflowUsage, persistWorkflowEvidence, } from "./workflow-evidence.js";
|
|
15
|
+
export { createInMemoryEvidenceStore, createNodeEvidenceStore, resolveEvidenceDir, } from "./store.js";
|
|
16
|
+
export { AUDIT_CODES, AuditError, EvidenceReadError, EvidenceSchemaError, EvidenceWriteError, InvalidRunIdError, } from "./errors.js";
|
|
17
|
+
export { EVIDENCE_SCHEMA_VERSION, DEFAULT_RETENTION, } from "./types.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type EvidenceReport } from "./report.js";
|
|
2
|
+
import type { EvidenceBuildInput, EvidenceDeps, EvidenceManifest, RetentionPolicy } from "./types.js";
|
|
3
|
+
export interface PersistResult {
|
|
4
|
+
readonly manifest: EvidenceManifest;
|
|
5
|
+
readonly location: string;
|
|
6
|
+
readonly report: EvidenceReport;
|
|
7
|
+
}
|
|
8
|
+
export declare function persistEvidence(input: EvidenceBuildInput, deps: EvidenceDeps, retention?: RetentionPolicy): PersistResult;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Top-level orchestration (ADR-0010 D11, D9): build -> deep re-redact (defense in depth) ->
|
|
2
|
+
// store.put -> applyRetention -> buildEvidenceReport. This is the single entry the CLI and the SDK
|
|
3
|
+
// call to write evidence. It is the supported SDK persist entry (the harness is NOT modified — the
|
|
4
|
+
// reuse-unchanged rule is absolute; AC #6 "SDK runs write evidence" is satisfied here and at the CLI
|
|
5
|
+
// layer, not by editing runAgent).
|
|
6
|
+
//
|
|
7
|
+
// Defense-in-depth redaction (coordinator refinement, replacing the ADR's serialized-string pass):
|
|
8
|
+
// the builder is redacted-by-construction (primary), and this layer re-applies the redactor to EVERY
|
|
9
|
+
// STRING LEAF of the assembled manifest object via a generic deep walk BEFORE JSON.stringify. This is
|
|
10
|
+
// idempotent and cannot break JSON structure (a serialized-string re-redaction could miss
|
|
11
|
+
// JSON-escaped secrets and risk corrupting the document). It catches a secret smuggled in through a
|
|
12
|
+
// verbatim-embedded summary (context/verification) that the builder does not itself redact.
|
|
13
|
+
import { isAbsolute, resolve } from "node:path";
|
|
14
|
+
import { buildEvidenceManifest } from "./build.js";
|
|
15
|
+
import { createAuditRedactor, deepRedactStrings } from "./redaction.js";
|
|
16
|
+
import { buildEvidenceReport } from "./report.js";
|
|
17
|
+
import { applyRetention } from "./retention.js";
|
|
18
|
+
import { createNodeEvidenceStore, resolveEvidenceDir } from "./store.js";
|
|
19
|
+
import { DEFAULT_RETENTION } from "./types.js";
|
|
20
|
+
function defaultEvidenceDir(input, env) {
|
|
21
|
+
const configured = resolveEvidenceDir(undefined, env);
|
|
22
|
+
return isAbsolute(configured) ? configured : resolve(input.manifest.workingDirectory, configured);
|
|
23
|
+
}
|
|
24
|
+
export function persistEvidence(input, deps, retention = DEFAULT_RETENTION) {
|
|
25
|
+
const env = deps.env ?? {};
|
|
26
|
+
// The builder is already redacted-by-construction (incl. the deep-redact of embedded summaries);
|
|
27
|
+
// re-apply the redactor over every string leaf here as IDEMPOTENT defense in depth, so a builder
|
|
28
|
+
// bug that missed a field still cannot persist a secret.
|
|
29
|
+
const manifest = buildEvidenceManifest(input, deps);
|
|
30
|
+
const redact = createAuditRedactor(input.redaction ?? {}, env);
|
|
31
|
+
const safeManifest = deepRedactStrings(manifest, redact);
|
|
32
|
+
const json = JSON.stringify(safeManifest, null, 2);
|
|
33
|
+
// C5/AC#6: with no explicit store, persist to the predictable local node store (resolved dir incl.
|
|
34
|
+
// KEIKO_EVIDENCE_DIR), NOT an in-memory store that would silently discard the evidence. Tests
|
|
35
|
+
// inject createInMemoryEvidenceStore explicitly so they never write to the repository tree.
|
|
36
|
+
const store = deps.store ?? createNodeEvidenceStore(defaultEvidenceDir(input, deps.env));
|
|
37
|
+
const location = store.put(safeManifest.run.runId, json);
|
|
38
|
+
applyRetention(store, retention);
|
|
39
|
+
return { manifest: safeManifest, location, report: buildEvidenceReport(safeManifest, location) };
|
|
40
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { AuditRedactionConfig } from "./types.js";
|
|
2
|
+
export declare function createAuditRedactor(config: AuditRedactionConfig, env: Readonly<Record<string, string | undefined>>): (input: string) => string;
|
|
3
|
+
export declare function deepRedactStrings(value: unknown, redact: (input: string) => string): unknown;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// The audit redaction surface (ADR-0010 D3). It COMPOSES the gateway redact() (imported, never
|
|
2
|
+
// modified) with three additional literal-secret sources, producing one redactor the builder applies
|
|
3
|
+
// to every sensitive field before the manifest is constructed (redacted-by-construction).
|
|
4
|
+
//
|
|
5
|
+
// ReDoS-safe by construction: env values and configured literals are passed to redact() as
|
|
6
|
+
// `additionalSecrets`, which escapes each literal via escapeRegExp before building a RegExp. No
|
|
7
|
+
// caller-controlled metacharacter reaches the regex engine and NO NEW REGEX is introduced here —
|
|
8
|
+
// the layer reuses the gateway's audited linear patterns and the escaped-literal path only. This
|
|
9
|
+
// keeps the CodeQL js/polynomial-redos required gate green (ADR-0002).
|
|
10
|
+
import { redact } from "../gateway/redaction.js";
|
|
11
|
+
// A literal shorter than this is too generic to scrub safely: redacting a 2-char value would
|
|
12
|
+
// over-redact ordinary prose. redact() itself only skips empty strings, so the floor lives here.
|
|
13
|
+
const MIN_LITERAL_LENGTH = 4;
|
|
14
|
+
// Resolves the VALUES of the named env vars (never the names), keeping only non-empty values long
|
|
15
|
+
// enough to be a plausible secret. The builder passes these as escaped literals to redact().
|
|
16
|
+
function resolveEnvValues(names, env) {
|
|
17
|
+
const values = [];
|
|
18
|
+
for (const name of names) {
|
|
19
|
+
const value = env[name];
|
|
20
|
+
if (value !== undefined && value.length >= MIN_LITERAL_LENGTH) {
|
|
21
|
+
values.push(value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return values;
|
|
25
|
+
}
|
|
26
|
+
function keepLongEnough(literals) {
|
|
27
|
+
return literals.filter((literal) => literal.length >= MIN_LITERAL_LENGTH);
|
|
28
|
+
}
|
|
29
|
+
// Returns a function string -> string applying gateway redact() with the union of all literal
|
|
30
|
+
// secrets (additionalSecrets ∪ resolved env values ∪ sensitiveLiterals). Idempotent: redact() over
|
|
31
|
+
// already-redacted text is a no-op on the redacted tokens.
|
|
32
|
+
export function createAuditRedactor(config, env) {
|
|
33
|
+
const literals = [
|
|
34
|
+
...keepLongEnough(config.additionalSecrets ?? []),
|
|
35
|
+
...resolveEnvValues(config.redactEnvValues ?? [], env),
|
|
36
|
+
...keepLongEnough(config.sensitiveLiterals ?? []),
|
|
37
|
+
];
|
|
38
|
+
return (input) => redact(input, literals);
|
|
39
|
+
}
|
|
40
|
+
// Recursively re-applies a redactor to EVERY STRING LEAF of a plain-JSON value, rebuilding
|
|
41
|
+
// arrays/objects so the input is never mutated and the JSON structure is preserved exactly. Bounded
|
|
42
|
+
// by the (finite) nesting depth of an EvidenceManifest. Idempotent (redact over already-redacted
|
|
43
|
+
// text is a no-op), so it is safe to apply at build time AND again as defense in depth at persist
|
|
44
|
+
// time. This is what makes the builder truly redacted-by-construction even for the #5/#7 summaries it
|
|
45
|
+
// embeds verbatim and the audit redactor (env-values/configured literals) would otherwise miss.
|
|
46
|
+
export function deepRedactStrings(value, redact) {
|
|
47
|
+
if (typeof value === "string") {
|
|
48
|
+
return redact(value);
|
|
49
|
+
}
|
|
50
|
+
if (Array.isArray(value)) {
|
|
51
|
+
return value.map((item) => deepRedactStrings(item, redact));
|
|
52
|
+
}
|
|
53
|
+
if (typeof value === "object" && value !== null) {
|
|
54
|
+
const out = {};
|
|
55
|
+
for (const [key, child] of Object.entries(value)) {
|
|
56
|
+
out[key] = deepRedactStrings(child, redact);
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CostClass } from "../gateway/types.js";
|
|
2
|
+
import type { RunOutcome } from "../harness/types.js";
|
|
3
|
+
import type { VerificationStatus } from "../verification/types.js";
|
|
4
|
+
import type { EvidenceManifest, EvidenceTaskType, EvidenceUsageTotals } from "./types.js";
|
|
5
|
+
export interface EvidenceReport {
|
|
6
|
+
readonly evidenceLocation: string;
|
|
7
|
+
readonly runId: string;
|
|
8
|
+
readonly fingerprint: string;
|
|
9
|
+
readonly taskType: EvidenceTaskType;
|
|
10
|
+
readonly outcome: RunOutcome;
|
|
11
|
+
readonly changedFiles: number;
|
|
12
|
+
readonly usageTotals: EvidenceUsageTotals;
|
|
13
|
+
readonly costClass: CostClass | "unknown";
|
|
14
|
+
readonly verificationStatus: VerificationStatus | "not-run";
|
|
15
|
+
readonly knownLimitations: readonly string[];
|
|
16
|
+
}
|
|
17
|
+
export declare function buildEvidenceReport(manifest: EvidenceManifest, location: string): EvidenceReport;
|
|
18
|
+
export declare function renderEvidenceReport(report: EvidenceReport): string;
|