zob-harness 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.pi/adapters/registry.json +103 -0
- package/.pi/agents/architecture-cartographer.md +53 -0
- package/.pi/agents/chief-vision.md +39 -0
- package/.pi/agents/clarifier.md +58 -0
- package/.pi/agents/context-steward.md +52 -0
- package/.pi/agents/doc-steward.md +34 -0
- package/.pi/agents/explore.md +49 -0
- package/.pi/agents/factory.md +41 -0
- package/.pi/agents/implementer.md +44 -0
- package/.pi/agents/librarian.md +32 -0
- package/.pi/agents/oracle-merge.md +50 -0
- package/.pi/agents/oracle.md +55 -0
- package/.pi/agents/pattern-miner.md +53 -0
- package/.pi/agents/planner.md +39 -0
- package/.pi/agents/project-dna-golden-evaluator.md +32 -0
- package/.pi/agents/project-dna-ontology-steward.md +30 -0
- package/.pi/agents/project-dna-oracle.md +56 -0
- package/.pi/agents/project-dna-orchestrator.md +60 -0
- package/.pi/agents/project-dna-query-steward.md +38 -0
- package/.pi/agents/project-dna-safety-preflight.md +54 -0
- package/.pi/agents/project-dna-test-linker.md +27 -0
- package/.pi/agents/qa.md +38 -0
- package/.pi/agents/refactor-cartographer.md +28 -0
- package/.pi/agents/refactor-mover.md +31 -0
- package/.pi/agents/refactor-oracle.md +49 -0
- package/.pi/agents/repo-scout.md +60 -0
- package/.pi/agents/sample-architect.md +48 -0
- package/.pi/agents/specifier.md +57 -0
- package/.pi/agents/symbol-range-curator.md +41 -0
- package/.pi/agents/synthesis.md +52 -0
- package/.pi/agents/temp-agent-creator.md +35 -0
- package/.pi/autonomy-policy.json +67 -0
- package/.pi/budget-policy.json +54 -0
- package/.pi/capabilities/zob-public-runtime-capabilities.json +1700 -0
- package/.pi/chains/explore-plan-oracle.json +78 -0
- package/.pi/chains/explore-spec-clarify-plan-oracle.json +64 -0
- package/.pi/chains/explore-spec-plan-oracle.json +53 -0
- package/.pi/chains/spec-clarify-plan-oracle.json +53 -0
- package/.pi/chains/spec-factory-oracle.json +42 -0
- package/.pi/chains/spec-plan-oracle.json +42 -0
- package/.pi/compute-profiles/defaults.json +19 -0
- package/.pi/compute-profiles/overrides.json +13 -0
- package/.pi/compute-profiles/risk-rules.json +16 -0
- package/.pi/daemon-policy.json +80 -0
- package/.pi/damage-control-rules.json +45 -0
- package/.pi/extensions/zob-child-safety/index.ts +212 -0
- package/.pi/extensions/zob-harness/AGENTS.md +28 -0
- package/.pi/extensions/zob-harness/index.ts +391 -0
- package/.pi/extensions/zob-harness/src/AGENTS.md +25 -0
- package/.pi/extensions/zob-harness/src/agents.ts +82 -0
- package/.pi/extensions/zob-harness/src/autonomous-runtime.ts +2912 -0
- package/.pi/extensions/zob-harness/src/autonomy-readiness.ts +778 -0
- package/.pi/extensions/zob-harness/src/budget-policy.ts +308 -0
- package/.pi/extensions/zob-harness/src/capabilities.ts +249 -0
- package/.pi/extensions/zob-harness/src/child-runner.ts +249 -0
- package/.pi/extensions/zob-harness/src/chronicle.ts +262 -0
- package/.pi/extensions/zob-harness/src/compute-profile.ts +602 -0
- package/.pi/extensions/zob-harness/src/compute-workflow-shape.ts +168 -0
- package/.pi/extensions/zob-harness/src/coms-v2/AGENTS.md +16 -0
- package/.pi/extensions/zob-harness/src/coms-v2/envelope.ts +121 -0
- package/.pi/extensions/zob-harness/src/coms-v2/identity.ts +53 -0
- package/.pi/extensions/zob-harness/src/coms-v2/ledger-bridge.ts +67 -0
- package/.pi/extensions/zob-harness/src/coms-v2/local-transport.ts +147 -0
- package/.pi/extensions/zob-harness/src/coms-v2/pending-replies.ts +80 -0
- package/.pi/extensions/zob-harness/src/coms-v2/policy.ts +125 -0
- package/.pi/extensions/zob-harness/src/coms-v2/presence.ts +55 -0
- package/.pi/extensions/zob-harness/src/coms-v2/registry.ts +113 -0
- package/.pi/extensions/zob-harness/src/coms-v2/response-capture.ts +50 -0
- package/.pi/extensions/zob-harness/src/coms-v2/transcript-capture.ts +164 -0
- package/.pi/extensions/zob-harness/src/coms-v2/types.ts +149 -0
- package/.pi/extensions/zob-harness/src/coms-v2/zpeer-profile.ts +140 -0
- package/.pi/extensions/zob-harness/src/coms-v2/zpeer.ts +452 -0
- package/.pi/extensions/zob-harness/src/constants.ts +108 -0
- package/.pi/extensions/zob-harness/src/context-gbrain.ts +465 -0
- package/.pi/extensions/zob-harness/src/daemon-policy.ts +223 -0
- package/.pi/extensions/zob-harness/src/daemon-readiness.ts +134 -0
- package/.pi/extensions/zob-harness/src/daemon-runtime.ts +393 -0
- package/.pi/extensions/zob-harness/src/factory/AGENTS.md +24 -0
- package/.pi/extensions/zob-harness/src/factory/agentic-plan.ts +65 -0
- package/.pi/extensions/zob-harness/src/factory/quarantine.ts +319 -0
- package/.pi/extensions/zob-harness/src/factory/run.ts +520 -0
- package/.pi/extensions/zob-harness/src/factory/validation.ts +454 -0
- package/.pi/extensions/zob-harness/src/factory-selector.ts +318 -0
- package/.pi/extensions/zob-harness/src/full-autonomy-test.ts +226 -0
- package/.pi/extensions/zob-harness/src/git-ops.ts +868 -0
- package/.pi/extensions/zob-harness/src/goal-room.ts +178 -0
- package/.pi/extensions/zob-harness/src/goal-runtime.ts +1569 -0
- package/.pi/extensions/zob-harness/src/goal-todo-imports.ts +111 -0
- package/.pi/extensions/zob-harness/src/goal-todo-types.ts +231 -0
- package/.pi/extensions/zob-harness/src/goal-todos.ts +1410 -0
- package/.pi/extensions/zob-harness/src/goal.ts +152 -0
- package/.pi/extensions/zob-harness/src/governed-requests.ts +436 -0
- package/.pi/extensions/zob-harness/src/interactive-autonomy.ts +595 -0
- package/.pi/extensions/zob-harness/src/launch-apply.ts +313 -0
- package/.pi/extensions/zob-harness/src/merge-queue.ts +290 -0
- package/.pi/extensions/zob-harness/src/mission-control.ts +573 -0
- package/.pi/extensions/zob-harness/src/model-availability.ts +52 -0
- package/.pi/extensions/zob-harness/src/model-routing.ts +429 -0
- package/.pi/extensions/zob-harness/src/orchestration/AGENTS.md +23 -0
- package/.pi/extensions/zob-harness/src/orchestration/adaptive-delegation.ts +547 -0
- package/.pi/extensions/zob-harness/src/orchestration/adaptive-workflow.ts +585 -0
- package/.pi/extensions/zob-harness/src/orchestration/lead-plan.ts +192 -0
- package/.pi/extensions/zob-harness/src/orchestration/plan.ts +168 -0
- package/.pi/extensions/zob-harness/src/orchestration/room.ts +346 -0
- package/.pi/extensions/zob-harness/src/orchestration/run.ts +134 -0
- package/.pi/extensions/zob-harness/src/orchestration/supervised-readonly.ts +1147 -0
- package/.pi/extensions/zob-harness/src/orchestration/widget-readers.ts +132 -0
- package/.pi/extensions/zob-harness/src/output-contracts.ts +656 -0
- package/.pi/extensions/zob-harness/src/project-dna.ts +533 -0
- package/.pi/extensions/zob-harness/src/promotion/AGENTS.md +24 -0
- package/.pi/extensions/zob-harness/src/promotion/candidate.ts +336 -0
- package/.pi/extensions/zob-harness/src/promotion/coms.ts +127 -0
- package/.pi/extensions/zob-harness/src/promotion/documentation.ts +142 -0
- package/.pi/extensions/zob-harness/src/promotion/factory.ts +107 -0
- package/.pi/extensions/zob-harness/src/promotion/ledger.ts +2 -0
- package/.pi/extensions/zob-harness/src/promotion/temp-agent.ts +151 -0
- package/.pi/extensions/zob-harness/src/promotion/types.ts +149 -0
- package/.pi/extensions/zob-harness/src/promotion/validate.ts +6 -0
- package/.pi/extensions/zob-harness/src/promotion/write-lane.ts +162 -0
- package/.pi/extensions/zob-harness/src/prompt-packs.ts +239 -0
- package/.pi/extensions/zob-harness/src/queue.ts +386 -0
- package/.pi/extensions/zob-harness/src/rules.ts +225 -0
- package/.pi/extensions/zob-harness/src/runtime/AGENTS.md +26 -0
- package/.pi/extensions/zob-harness/src/runtime/adaptive-zmode.ts +116 -0
- package/.pi/extensions/zob-harness/src/runtime/auto-compaction.ts +715 -0
- package/.pi/extensions/zob-harness/src/runtime/commands.ts +1315 -0
- package/.pi/extensions/zob-harness/src/runtime/compaction-policy.ts +516 -0
- package/.pi/extensions/zob-harness/src/runtime/delegation-click-markers.ts +141 -0
- package/.pi/extensions/zob-harness/src/runtime/delegation-feed.ts +415 -0
- package/.pi/extensions/zob-harness/src/runtime/delegation-markdown.ts +97 -0
- package/.pi/extensions/zob-harness/src/runtime/delegation-monitor.ts +553 -0
- package/.pi/extensions/zob-harness/src/runtime/delegation-mouse.ts +205 -0
- package/.pi/extensions/zob-harness/src/runtime/delegation-overlay.ts +434 -0
- package/.pi/extensions/zob-harness/src/runtime/events.ts +736 -0
- package/.pi/extensions/zob-harness/src/runtime/goal-todo-overlay.ts +214 -0
- package/.pi/extensions/zob-harness/src/runtime/mode-intent.ts +144 -0
- package/.pi/extensions/zob-harness/src/runtime/plan-capture.ts +270 -0
- package/.pi/extensions/zob-harness/src/runtime/state.ts +403 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-autonomous.ts +117 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-compute.ts +136 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-coms.ts +365 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-context.ts +70 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-delegation.ts +1854 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-factory.ts +810 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-goal-room.ts +46 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-governed-requests.ts +38 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-merge-queue.ts +61 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-mission-control.ts +77 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-orchestration.ts +106 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-project-dna.ts +123 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-worker-pool.ts +93 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-workspace-claims.ts +62 -0
- package/.pi/extensions/zob-harness/src/runtime/tools-zcommit.ts +147 -0
- package/.pi/extensions/zob-harness/src/runtime/widget.ts +353 -0
- package/.pi/extensions/zob-harness/src/runtime/zobHarness.ts +60 -0
- package/.pi/extensions/zob-harness/src/safety.ts +338 -0
- package/.pi/extensions/zob-harness/src/sandbox.ts +1508 -0
- package/.pi/extensions/zob-harness/src/schemas-project-dna.ts +47 -0
- package/.pi/extensions/zob-harness/src/schemas.ts +695 -0
- package/.pi/extensions/zob-harness/src/telemetry.ts +373 -0
- package/.pi/extensions/zob-harness/src/topology/AGENTS.md +22 -0
- package/.pi/extensions/zob-harness/src/topology/chains.ts +236 -0
- package/.pi/extensions/zob-harness/src/topology/coms.ts +211 -0
- package/.pi/extensions/zob-harness/src/topology/orchestration-profiles.ts +204 -0
- package/.pi/extensions/zob-harness/src/topology/teams.ts +113 -0
- package/.pi/extensions/zob-harness/src/types/core.ts +47 -0
- package/.pi/extensions/zob-harness/src/types.ts +939 -0
- package/.pi/extensions/zob-harness/src/utils/AGENTS.md +22 -0
- package/.pi/extensions/zob-harness/src/utils/formatting.ts +34 -0
- package/.pi/extensions/zob-harness/src/utils/hashing.ts +11 -0
- package/.pi/extensions/zob-harness/src/utils/json.ts +28 -0
- package/.pi/extensions/zob-harness/src/utils/paths.ts +54 -0
- package/.pi/extensions/zob-harness/src/utils/records.ts +25 -0
- package/.pi/extensions/zob-harness/src/utils/resources.ts +38 -0
- package/.pi/extensions/zob-harness/src/worker-pool.ts +672 -0
- package/.pi/extensions/zob-harness/src/workspace-claims.ts +297 -0
- package/.pi/extensions/zob-switch/index.ts +180 -0
- package/.pi/factories/budget-preflight-dry-run/batch-manifest.json +59 -0
- package/.pi/factories/budget-preflight-dry-run/factory.json +94 -0
- package/.pi/factories/budget-preflight-dry-run/pilot-manifest.json +50 -0
- package/.pi/factories/budget-preflight-dry-run/smoke-manifest.json +43 -0
- package/.pi/factories/code-review-matrix/batch-manifest.json +61 -0
- package/.pi/factories/code-review-matrix/factory.json +163 -0
- package/.pi/factories/code-review-matrix/pilot-manifest.json +41 -0
- package/.pi/factories/code-review-matrix/smoke-manifest.json +35 -0
- package/.pi/factories/factory-forge/batch-manifest.json +56 -0
- package/.pi/factories/factory-forge/factory.json +84 -0
- package/.pi/factories/factory-forge/pilot-manifest.json +32 -0
- package/.pi/factories/factory-forge/smoke-manifest.json +19 -0
- package/.pi/factories/opencode-pattern-canonizer/batch-manifest.json +54 -0
- package/.pi/factories/opencode-pattern-canonizer/factory.json +86 -0
- package/.pi/factories/opencode-pattern-canonizer/pilot-manifest.json +39 -0
- package/.pi/factories/opencode-pattern-canonizer/smoke-manifest.json +26 -0
- package/.pi/factories/project-dna/README.md +182 -0
- package/.pi/factories/project-dna/batch-manifest.json +37 -0
- package/.pi/factories/project-dna/example-project-dna-manifest-v2.json +80 -0
- package/.pi/factories/project-dna/example-project-dna-manifest.json +58 -0
- package/.pi/factories/project-dna/factory.json +131 -0
- package/.pi/factories/project-dna/golden-cases-smoke.json +62 -0
- package/.pi/factories/project-dna/pi-agentic-ontology.json +88 -0
- package/.pi/factories/project-dna/pilot-manifest.json +32 -0
- package/.pi/factories/project-dna/schemas/benchmark-suite.schema.json +27 -0
- package/.pi/factories/project-dna/schemas/code-knowledge-graph.schema.json +97 -0
- package/.pi/factories/project-dna/schemas/context-pack.schema.json +43 -0
- package/.pi/factories/project-dna/schemas/golden-case.schema.json +36 -0
- package/.pi/factories/project-dna/schemas/manifest-v2.schema.json +128 -0
- package/.pi/factories/project-dna/schemas/manifest.schema.json +77 -0
- package/.pi/factories/project-dna/schemas/ontology.schema.json +45 -0
- package/.pi/factories/project-dna/schemas/project-fingerprint.schema.json +28 -0
- package/.pi/factories/project-dna/schemas/query-steward-report.schema.json +52 -0
- package/.pi/factories/project-dna/smoke-manifest.json +27 -0
- package/.pi/factories/roadmap-smoke-lots/batch-manifest.json +49 -0
- package/.pi/factories/roadmap-smoke-lots/factory.json +89 -0
- package/.pi/factories/roadmap-smoke-lots/pilot-manifest.json +50 -0
- package/.pi/factories/roadmap-smoke-lots/smoke-manifest.json +35 -0
- package/.pi/git-policy.json +120 -0
- package/.pi/mission-control/zob_coms_transport.json +64 -0
- package/.pi/model-catalog.example.json +345 -0
- package/.pi/model-economy.example.json +196 -0
- package/.pi/model-routing.json +86 -0
- package/.pi/orchestrations/adaptive-chief-vision.json +193 -0
- package/.pi/orchestrations/ceo-feature-build.json +182 -0
- package/.pi/orchestrations/readonly-dynamic-smoke.json +75 -0
- package/.pi/output-contracts/agent-event.v1.json +19 -0
- package/.pi/output-contracts/base.v1.json +24 -0
- package/.pi/output-contracts/brain-lookup.v1.json +21 -0
- package/.pi/output-contracts/clarification.v1.json +21 -0
- package/.pi/output-contracts/context-pack.v1.json +20 -0
- package/.pi/output-contracts/context-request.v1.json +21 -0
- package/.pi/output-contracts/context-steward.v1.json +19 -0
- package/.pi/output-contracts/context-writeback-proposal.v1.json +18 -0
- package/.pi/output-contracts/delegation-request.v1.json +21 -0
- package/.pi/output-contracts/explore.v1.json +52 -0
- package/.pi/output-contracts/factory.v1.json +48 -0
- package/.pi/output-contracts/guidance-steward.v1.json +18 -0
- package/.pi/output-contracts/implement.v1.json +40 -0
- package/.pi/output-contracts/launch-authorization.v1.json +21 -0
- package/.pi/output-contracts/lead-plan.v1.json +22 -0
- package/.pi/output-contracts/mission-readiness.v1.json +20 -0
- package/.pi/output-contracts/oracle-merge.v1.json +44 -0
- package/.pi/output-contracts/oracle-request.v1.json +20 -0
- package/.pi/output-contracts/oracle.v1.json +44 -0
- package/.pi/output-contracts/orchestration-profile.v1.json +22 -0
- package/.pi/output-contracts/plan.v1.json +48 -0
- package/.pi/output-contracts/prompt-pack.v1.json +20 -0
- package/.pi/output-contracts/qa.v1.json +40 -0
- package/.pi/output-contracts/research.v1.json +36 -0
- package/.pi/output-contracts/spec.v1.json +22 -0
- package/.pi/output-contracts/synthesis.v1.json +44 -0
- package/.pi/output-contracts/temp-agent-card.v1.json +23 -0
- package/.pi/output-contracts/todo-child-result.v1.json +20 -0
- package/.pi/output-contracts/todo-child-result.v2.json +22 -0
- package/.pi/output-contracts/todo-claim-validation.v1.json +22 -0
- package/.pi/output-contracts/todo-split-request.v1.json +20 -0
- package/.pi/prompts/adaptive-workflow.md +63 -0
- package/.pi/prompts/autonomous-runtime.md +15 -0
- package/.pi/prompts/benchmark-contender.md +15 -0
- package/.pi/prompts/benchmark-judge.md +19 -0
- package/.pi/prompts/clarify-spec.md +20 -0
- package/.pi/prompts/compute-plan.md +36 -0
- package/.pi/prompts/compute-preview.md +42 -0
- package/.pi/prompts/contract.md +29 -0
- package/.pi/prompts/explore.md +13 -0
- package/.pi/prompts/factory-run.md +36 -0
- package/.pi/prompts/factory.md +20 -0
- package/.pi/prompts/implement.md +27 -0
- package/.pi/prompts/model-catalog.md +68 -0
- package/.pi/prompts/model-economy.md +64 -0
- package/.pi/prompts/oracle-merge.md +18 -0
- package/.pi/prompts/oracle.md +13 -0
- package/.pi/prompts/orchestrator.md +48 -0
- package/.pi/prompts/parallel-review.md +21 -0
- package/.pi/prompts/plan.md +21 -0
- package/.pi/prompts/project-dna.md +90 -0
- package/.pi/prompts/refactor-oracle.md +23 -0
- package/.pi/prompts/refactor-slice.md +24 -0
- package/.pi/prompts/research.md +20 -0
- package/.pi/prompts/spec.md +19 -0
- package/.pi/prompts/synthesis.md +18 -0
- package/.pi/rules/always.md +38 -0
- package/.pi/rules/docs.md +32 -0
- package/.pi/rules/factory.md +44 -0
- package/.pi/rules/oracle.md +34 -0
- package/.pi/rules/orchestration.md +44 -0
- package/.pi/rules/project.md +34 -0
- package/.pi/rules/prompts.md +43 -0
- package/.pi/rules/runtime.md +43 -0
- package/.pi/rules/sandbox.md +43 -0
- package/.pi/settings.json +28 -0
- package/.pi/skills/zob-agentic-access/SKILL.md +20 -0
- package/.pi/skills/zob-autonomous-runtime/SKILL.md +41 -0
- package/.pi/skills/zob-commit/SKILL.md +79 -0
- package/.pi/skills/zob-compaction-policy/SKILL.md +92 -0
- package/.pi/skills/zob-compute-profile/SKILL.md +108 -0
- package/.pi/skills/zob-coms-safety/SKILL.md +54 -0
- package/.pi/skills/zob-coms-v2-live/SKILL.md +47 -0
- package/.pi/skills/zob-delegation-routing/SKILL.md +82 -0
- package/.pi/skills/zob-factory/SKILL.md +28 -0
- package/.pi/skills/zob-goal-todo-tree/SKILL.md +279 -0
- package/.pi/skills/zob-harness/SKILL.md +68 -0
- package/.pi/skills/zob-mission-control-coms/SKILL.md +39 -0
- package/.pi/skills/zob-oracle/SKILL.md +21 -0
- package/.pi/skills/zob-owner-pool-drill-writer/SKILL.md +244 -0
- package/.pi/skills/zob-owner-pool-launcher/SKILL.md +261 -0
- package/.pi/skills/zob-project-dna/SKILL.md +275 -0
- package/.pi/skills/zob-sandbox/SKILL.md +29 -0
- package/.pi/skills/zob-spec/SKILL.md +25 -0
- package/.pi/skills/zob-split-refactor/SKILL.md +39 -0
- package/.pi/skills/zob-tool-router/SKILL.md +104 -0
- package/.pi/teams/zob-core.json +122 -0
- package/AGENTS.md +89 -0
- package/CONTRIBUTING.md +56 -0
- package/LICENSE +21 -0
- package/README.md +360 -0
- package/SECURITY.md +35 -0
- package/SOURCE_INDEX.md +46 -0
- package/package.json +135 -0
- package/scripts/README.md +57 -0
- package/scripts/autonomy/mission-readiness-secret-smoke.mjs +90 -0
- package/scripts/compute-profile/plan-workflow.mjs +85 -0
- package/scripts/compute-profile/preview.mjs +242 -0
- package/scripts/compute-profile/regression-smoke.mjs +38 -0
- package/scripts/compute-profile/summarize.mjs +72 -0
- package/scripts/compute-profile/validate-policy.mjs +50 -0
- package/scripts/compute-profile/validate-preview.mjs +95 -0
- package/scripts/compute-profile/validate-workflow.mjs +58 -0
- package/scripts/git-ops/commit-policy-smoke.mjs +221 -0
- package/scripts/goal-todo/child-goal-ref-smoke.mjs +252 -0
- package/scripts/harness-switch/static-smoke.mjs +43 -0
- package/scripts/model-catalog/validate-economy.mjs +223 -0
- package/scripts/model-catalog/validate.mjs +199 -0
- package/scripts/package-surface/validate-script-refs.mjs +190 -0
- package/scripts/path-policy/validate-smoke.mjs +103 -0
- package/scripts/project-dna/bench-smoke.mjs +217 -0
- package/scripts/project-dna/build-capsules.mjs +207 -0
- package/scripts/project-dna/build-sample-spec.mjs +140 -0
- package/scripts/project-dna/emit-golden-cases.mjs +75 -0
- package/scripts/project-dna/emit-ontology.mjs +75 -0
- package/scripts/project-dna/generate-sample.mjs +302 -0
- package/scripts/project-dna/oracle-review-smoke.mjs +157 -0
- package/scripts/project-dna/plan-workflow.mjs +289 -0
- package/scripts/project-dna/query-context.mjs +276 -0
- package/scripts/project-dna/query-steward.mjs +149 -0
- package/scripts/project-dna/scan.mjs +553 -0
- package/scripts/project-dna/validate-5of5.mjs +159 -0
- package/scripts/project-dna/validate-golden-cases.mjs +78 -0
- package/scripts/project-dna/validate-ontology.mjs +97 -0
- package/scripts/project-dna/validate-sample-project.mjs +105 -0
- package/scripts/project-dna/validate-scaffold.mjs +383 -0
- package/scripts/project-dna/validate-scan-artifacts.mjs +187 -0
- package/scripts/project-dna/validate-workflow.mjs +166 -0
- package/scripts/start-pi.sh +4 -0
- package/scripts/worker-pool/static-smoke.mjs +54 -0
- package/scripts/zpeer-local-e2e-smoke.mjs +395 -0
- package/scripts/zpeer-static-smoke.mjs +129 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { discoverAgents } from "../agents.js";
|
|
5
|
+
import { DEFAULT_RULES, SUPERVISED_READONLY_CHILD_TOOLS } from "../constants.js";
|
|
6
|
+
import { validateOutputContractId } from "../output-contracts.js";
|
|
7
|
+
import { validateAllowedPathPolicy } from "../safety.js";
|
|
8
|
+
import type {
|
|
9
|
+
AdaptiveDelegationGovernorState,
|
|
10
|
+
AdaptiveDelegationPolicy,
|
|
11
|
+
AdaptiveDelegationPolicyInput,
|
|
12
|
+
AdaptiveDelegationSandboxGate,
|
|
13
|
+
AdaptiveDelegationSandboxGateInput,
|
|
14
|
+
AdaptiveDelegationScaleApproval,
|
|
15
|
+
AdaptiveDelegationScaleApprovalInput,
|
|
16
|
+
DelegationRequestProposal,
|
|
17
|
+
DelegationScore,
|
|
18
|
+
GovernorDecision,
|
|
19
|
+
ParentDispatchContract,
|
|
20
|
+
} from "../types.js";
|
|
21
|
+
import { sha256 } from "../utils/hashing.js";
|
|
22
|
+
import { pathMatches } from "../utils/paths.js";
|
|
23
|
+
import { isRecord } from "../utils/records.js";
|
|
24
|
+
|
|
25
|
+
const ADAPTIVE_DELEGATION_SCHEMA = "zob.adaptive-delegation-policy.v1" as const;
|
|
26
|
+
const GOVERNOR_STATE_SCHEMA = "zob.adaptive-delegation-governor-state.v1" as const;
|
|
27
|
+
const GOVERNOR_DECISION_SCHEMA = "zob.governor-decision.v1" as const;
|
|
28
|
+
const DELEGATION_SCORE_SCHEMA = "zob.delegation-score.v1" as const;
|
|
29
|
+
|
|
30
|
+
const FORBIDDEN_BODY_KEYS = new Set(["body", "prompt", "output", "task", "content", "patch", "diff", "rawRationale", "rawContext", "messages", "transcript"]);
|
|
31
|
+
const WRITE_OR_DELEGATION_TOOLS = new Set(["bash", "edit", "write", "delegate_agent", "delegate_task", "orchestrate_run", "factory_run"]);
|
|
32
|
+
const READONLY_TOOL_ALLOWLIST = new Set<string>(SUPERVISED_READONLY_CHILD_TOOLS);
|
|
33
|
+
const SHA256_HEX_PATTERN = /^[a-f0-9]{64}$/;
|
|
34
|
+
|
|
35
|
+
export const ADAPTIVE_DELEGATION_HARD_MAX_DEPTH = 4;
|
|
36
|
+
export const ADAPTIVE_DELEGATION_DEFAULT_MAX_TOTAL_AGENTS = 20;
|
|
37
|
+
export const ADAPTIVE_DELEGATION_HARD_MAX_TOTAL_AGENTS_WITH_ORACLE = 30;
|
|
38
|
+
|
|
39
|
+
function asPositiveInteger(value: unknown, fallback: number): number {
|
|
40
|
+
return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : fallback;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function asFiniteNumber(value: unknown, fallback: number): number {
|
|
44
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function normalizeAdaptiveDelegationSandboxGate(input?: AdaptiveDelegationSandboxGateInput): AdaptiveDelegationSandboxGate | undefined {
|
|
48
|
+
if (!input) return undefined;
|
|
49
|
+
const sandboxRunId = typeof input.sandboxRunId === "string" ? input.sandboxRunId.trim() : "";
|
|
50
|
+
return {
|
|
51
|
+
schema: "zob.adaptive-delegation-sandbox-gate.v1",
|
|
52
|
+
enabled: input.enabled === true,
|
|
53
|
+
mode: input.enabled === true ? (input.mode ?? "proposal_only") : "off",
|
|
54
|
+
sandboxRunIdHash: sandboxRunId ? sha256(sandboxRunId) : undefined,
|
|
55
|
+
diffReviewGateHash: typeof input.diffReviewGateHash === "string" ? input.diffReviewGateHash : undefined,
|
|
56
|
+
applyReadinessHash: typeof input.applyReadinessHash === "string" ? input.applyReadinessHash : undefined,
|
|
57
|
+
approvalHash: typeof input.approvalHash === "string" ? input.approvalHash : undefined,
|
|
58
|
+
liveWriteDispatchEnabled: false,
|
|
59
|
+
productionWritesPerformed: false,
|
|
60
|
+
autoApply: false,
|
|
61
|
+
bodyStored: false,
|
|
62
|
+
promptBodiesStored: false,
|
|
63
|
+
outputBodiesStored: false,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function normalizeAdaptiveDelegationScaleApproval(input?: AdaptiveDelegationScaleApprovalInput): AdaptiveDelegationScaleApproval | undefined {
|
|
68
|
+
if (!input) return undefined;
|
|
69
|
+
const approvedBy = typeof input.approvedBy === "string" ? input.approvedBy.trim() : "";
|
|
70
|
+
const approvalId = typeof input.approvalId === "string" ? input.approvalId.trim() : "";
|
|
71
|
+
const scope = typeof input.scope === "string" ? input.scope.trim() : "";
|
|
72
|
+
return {
|
|
73
|
+
schema: "zob.adaptive-delegation-scale-approval.v1",
|
|
74
|
+
approvedByHash: approvedBy ? sha256(approvedBy) : undefined,
|
|
75
|
+
approvedAt: typeof input.approvedAt === "string" && input.approvedAt.trim().length > 0 ? input.approvedAt.trim() : undefined,
|
|
76
|
+
approvalIdHash: approvalId ? sha256(approvalId) : undefined,
|
|
77
|
+
scopeHash: scope ? sha256(scope) : undefined,
|
|
78
|
+
bodyStored: false,
|
|
79
|
+
promptBodiesStored: false,
|
|
80
|
+
outputBodiesStored: false,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function canonicalizeAdaptiveRequestedAgent(value: string): string {
|
|
85
|
+
const trimmed = value.trim();
|
|
86
|
+
const normalized = trimmed.toLowerCase().replace(/_/g, "-");
|
|
87
|
+
const aliases: Record<string, string> = {
|
|
88
|
+
"explore-agent": "explore",
|
|
89
|
+
"explore-worker": "explore",
|
|
90
|
+
"explorer-agent": "explore",
|
|
91
|
+
"read-only-explore-agent": "explore",
|
|
92
|
+
"readonly-explore-agent": "explore",
|
|
93
|
+
"read-only-explorer-agent": "explore",
|
|
94
|
+
"qa-agent": "qa",
|
|
95
|
+
"oracle-agent": "oracle",
|
|
96
|
+
"planner-agent": "planner",
|
|
97
|
+
};
|
|
98
|
+
return aliases[normalized] ?? trimmed;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function normalizeAdaptiveDelegationPolicy(input?: AdaptiveDelegationPolicyInput): AdaptiveDelegationPolicy {
|
|
102
|
+
const enabled = input?.enabled === true;
|
|
103
|
+
const mode = enabled ? (input?.mode ?? "advisory_only") : "off";
|
|
104
|
+
const dispatch = enabled && input?.dispatch === true;
|
|
105
|
+
return {
|
|
106
|
+
schema: ADAPTIVE_DELEGATION_SCHEMA,
|
|
107
|
+
enabled,
|
|
108
|
+
mode,
|
|
109
|
+
dispatch,
|
|
110
|
+
recordDecisionsOnly: input?.recordDecisionsOnly ?? !dispatch,
|
|
111
|
+
configuredMaxDepth: asPositiveInteger(input?.configuredMaxDepth, ADAPTIVE_DELEGATION_HARD_MAX_DEPTH),
|
|
112
|
+
runtimeMaxDepth: asPositiveInteger(input?.runtimeMaxDepth, 1),
|
|
113
|
+
rootFanoutMax: asPositiveInteger(input?.rootFanoutMax, 6),
|
|
114
|
+
nodeFanoutMax: asPositiveInteger(input?.nodeFanoutMax, 4),
|
|
115
|
+
globalParallelMax: asPositiveInteger(input?.globalParallelMax, 4),
|
|
116
|
+
maxTotalAgents: asPositiveInteger(input?.maxTotalAgents, ADAPTIVE_DELEGATION_DEFAULT_MAX_TOTAL_AGENTS),
|
|
117
|
+
maxTotalAgentsWithOracle: asPositiveInteger(input?.maxTotalAgentsWithOracle, ADAPTIVE_DELEGATION_DEFAULT_MAX_TOTAL_AGENTS),
|
|
118
|
+
ttlPerRequest: asPositiveInteger(input?.ttlPerRequest, 3),
|
|
119
|
+
minApprovalScore: asFiniteNumber(input?.minApprovalScore, 0.7),
|
|
120
|
+
oracle: input?.oracle ?? "conditional",
|
|
121
|
+
strictBudgetRequired: input?.strictBudgetRequired ?? true,
|
|
122
|
+
sandboxGate: normalizeAdaptiveDelegationSandboxGate(input?.sandboxGate),
|
|
123
|
+
scaleApproval: normalizeAdaptiveDelegationScaleApproval(input?.scaleApproval),
|
|
124
|
+
parentOwnedDispatch: true,
|
|
125
|
+
childDirectDispatch: false,
|
|
126
|
+
bodyStored: false,
|
|
127
|
+
promptBodiesStored: false,
|
|
128
|
+
outputBodiesStored: false,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function validateAdaptiveDelegationPolicy(policy: AdaptiveDelegationPolicy): string[] {
|
|
133
|
+
const errors: string[] = [];
|
|
134
|
+
if (!policy.enabled && policy.mode !== "off") errors.push("adaptive_delegation mode must be off when enabled=false");
|
|
135
|
+
if (!policy.enabled && policy.dispatch) errors.push("adaptive_delegation dispatch cannot be true when enabled=false");
|
|
136
|
+
if (policy.enabled && policy.mode === "off") errors.push("adaptive_delegation enabled=true requires mode advisory_only or when_pertinent");
|
|
137
|
+
if (policy.mode === "advisory_only" && policy.dispatch) errors.push("adaptive_delegation advisory_only mode cannot dispatch live children");
|
|
138
|
+
if (policy.dispatch && policy.mode !== "when_pertinent") errors.push("adaptive_delegation dispatch=true requires mode=when_pertinent");
|
|
139
|
+
|
|
140
|
+
const integerFields: Array<[keyof AdaptiveDelegationPolicy, number]> = [
|
|
141
|
+
["configuredMaxDepth", policy.configuredMaxDepth],
|
|
142
|
+
["runtimeMaxDepth", policy.runtimeMaxDepth],
|
|
143
|
+
["rootFanoutMax", policy.rootFanoutMax],
|
|
144
|
+
["nodeFanoutMax", policy.nodeFanoutMax],
|
|
145
|
+
["globalParallelMax", policy.globalParallelMax],
|
|
146
|
+
["maxTotalAgents", policy.maxTotalAgents],
|
|
147
|
+
["maxTotalAgentsWithOracle", policy.maxTotalAgentsWithOracle],
|
|
148
|
+
["ttlPerRequest", policy.ttlPerRequest],
|
|
149
|
+
];
|
|
150
|
+
for (const [field, value] of integerFields) {
|
|
151
|
+
if (!Number.isInteger(value) || value < 1) errors.push(`adaptive_delegation ${String(field)} must be a positive integer`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (policy.configuredMaxDepth > ADAPTIVE_DELEGATION_HARD_MAX_DEPTH) errors.push(`adaptive_delegation configuredMaxDepth must be <= ${ADAPTIVE_DELEGATION_HARD_MAX_DEPTH}`);
|
|
155
|
+
if (policy.runtimeMaxDepth > policy.configuredMaxDepth) errors.push("adaptive_delegation runtimeMaxDepth must be <= configuredMaxDepth");
|
|
156
|
+
if (policy.maxTotalAgents > policy.maxTotalAgentsWithOracle) errors.push("adaptive_delegation maxTotalAgents must be <= maxTotalAgentsWithOracle");
|
|
157
|
+
if (policy.maxTotalAgentsWithOracle > ADAPTIVE_DELEGATION_HARD_MAX_TOTAL_AGENTS_WITH_ORACLE) errors.push(`adaptive_delegation maxTotalAgentsWithOracle must be <= ${ADAPTIVE_DELEGATION_HARD_MAX_TOTAL_AGENTS_WITH_ORACLE}`);
|
|
158
|
+
if (policy.minApprovalScore < 0 || policy.minApprovalScore > 1) errors.push("adaptive_delegation minApprovalScore must be between 0 and 1");
|
|
159
|
+
if (policy.parentOwnedDispatch !== true) errors.push("adaptive_delegation parentOwnedDispatch must be true");
|
|
160
|
+
if (policy.childDirectDispatch !== false) errors.push("adaptive_delegation childDirectDispatch must be false");
|
|
161
|
+
const highScaleRequested = policy.maxTotalAgents > ADAPTIVE_DELEGATION_DEFAULT_MAX_TOTAL_AGENTS || policy.maxTotalAgentsWithOracle > ADAPTIVE_DELEGATION_DEFAULT_MAX_TOTAL_AGENTS;
|
|
162
|
+
if (highScaleRequested && policy.oracle === "off") errors.push("adaptive_delegation 20/30-agent scale requires oracle=conditional or oracle=always");
|
|
163
|
+
if (policy.sandboxGate) {
|
|
164
|
+
if (policy.sandboxGate.enabled === true && policy.sandboxGate.mode !== "proposal_only") errors.push("adaptive_delegation sandboxGate P9 supports only mode=proposal_only");
|
|
165
|
+
if (policy.sandboxGate.enabled === false && policy.sandboxGate.mode !== "off") errors.push("adaptive_delegation sandboxGate mode must be off when enabled=false");
|
|
166
|
+
if (policy.sandboxGate.diffReviewGateHash !== undefined && !isSha256Hex(policy.sandboxGate.diffReviewGateHash)) errors.push("adaptive_delegation sandboxGate.diffReviewGateHash must be lowercase sha256 hex");
|
|
167
|
+
if (policy.sandboxGate.applyReadinessHash !== undefined && !isSha256Hex(policy.sandboxGate.applyReadinessHash)) errors.push("adaptive_delegation sandboxGate.applyReadinessHash must be lowercase sha256 hex");
|
|
168
|
+
if (policy.sandboxGate.approvalHash !== undefined && !isSha256Hex(policy.sandboxGate.approvalHash)) errors.push("adaptive_delegation sandboxGate.approvalHash must be lowercase sha256 hex");
|
|
169
|
+
if (policy.sandboxGate.liveWriteDispatchEnabled !== false || policy.sandboxGate.productionWritesPerformed !== false || policy.sandboxGate.autoApply !== false) errors.push("adaptive_delegation sandboxGate must keep live writes and auto-apply disabled");
|
|
170
|
+
if (policy.sandboxGate.bodyStored !== false || policy.sandboxGate.promptBodiesStored !== false || policy.sandboxGate.outputBodiesStored !== false) errors.push("adaptive_delegation sandboxGate must be hash-only with body flags false");
|
|
171
|
+
}
|
|
172
|
+
if (policy.scaleApproval) {
|
|
173
|
+
if (!isSha256Hex(policy.scaleApproval.approvedByHash)) errors.push("adaptive_delegation scaleApproval.approvedBy is required and stored as approvedByHash");
|
|
174
|
+
if (!isSha256Hex(policy.scaleApproval.approvalIdHash)) errors.push("adaptive_delegation scaleApproval.approvalId is required and stored as approvalIdHash");
|
|
175
|
+
if (typeof policy.scaleApproval.approvedAt !== "string" || policy.scaleApproval.approvedAt.trim().length === 0) errors.push("adaptive_delegation scaleApproval.approvedAt is required");
|
|
176
|
+
if (policy.scaleApproval.scopeHash !== undefined && !isSha256Hex(policy.scaleApproval.scopeHash)) errors.push("adaptive_delegation scaleApproval.scopeHash must be lowercase sha256 hex");
|
|
177
|
+
if (policy.scaleApproval.bodyStored !== false || policy.scaleApproval.promptBodiesStored !== false || policy.scaleApproval.outputBodiesStored !== false) errors.push("adaptive_delegation scaleApproval must be hash-only with body flags false");
|
|
178
|
+
}
|
|
179
|
+
if (policy.dispatch && policy.strictBudgetRequired !== true) errors.push("adaptive_delegation dispatch=true requires strictBudgetRequired=true");
|
|
180
|
+
if (highScaleRequested && !policy.scaleApproval) errors.push("adaptive_delegation 20/30-agent scale requires scaleApproval metadata");
|
|
181
|
+
if (policy.dispatch && policy.runtimeMaxDepth === ADAPTIVE_DELEGATION_HARD_MAX_DEPTH) {
|
|
182
|
+
if (policy.oracle === "off") errors.push("adaptive_delegation runtimeMaxDepth=4 requires oracle=conditional or oracle=always");
|
|
183
|
+
if (policy.minApprovalScore < 0.85) errors.push("adaptive_delegation runtimeMaxDepth=4 requires minApprovalScore >= 0.85");
|
|
184
|
+
if (policy.maxTotalAgentsWithOracle > ADAPTIVE_DELEGATION_DEFAULT_MAX_TOTAL_AGENTS && !policy.scaleApproval) errors.push("adaptive_delegation runtimeMaxDepth=4 with 20/30-agent scale requires scaleApproval metadata");
|
|
185
|
+
}
|
|
186
|
+
return errors;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function isSha256Hex(value: unknown): value is string {
|
|
190
|
+
return typeof value === "string" && SHA256_HEX_PATTERN.test(value);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function optionalHashError(field: string, value: unknown): string | undefined {
|
|
194
|
+
return value === undefined || isSha256Hex(value) ? undefined : `adaptive_delegation ${field} must be a lowercase sha256 hex string`;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function hasForbiddenBodyKeys(value: unknown): boolean {
|
|
198
|
+
if (!value || typeof value !== "object") return false;
|
|
199
|
+
if (Array.isArray(value)) return value.some((child) => hasForbiddenBodyKeys(child));
|
|
200
|
+
return Object.entries(value as Record<string, unknown>).some(([key, child]) => FORBIDDEN_BODY_KEYS.has(key) || hasForbiddenBodyKeys(child));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
function stableJson(value: unknown): string {
|
|
204
|
+
if (Array.isArray(value)) return `[${value.map((item) => stableJson(item)).join(",")}]`;
|
|
205
|
+
if (value && typeof value === "object") {
|
|
206
|
+
return `{${Object.entries(value as Record<string, unknown>).sort(([left], [right]) => left.localeCompare(right)).map(([key, child]) => `${JSON.stringify(key)}:${stableJson(child)}`).join(",")}}`;
|
|
207
|
+
}
|
|
208
|
+
return JSON.stringify(value);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function normalizedTaskShape(request: DelegationRequestProposal): Record<string, unknown> {
|
|
212
|
+
return {
|
|
213
|
+
requesterRole: request.requesterRole,
|
|
214
|
+
referentRole: request.referentRole,
|
|
215
|
+
requestedAgent: request.requestedAgent,
|
|
216
|
+
requestedOutputContract: request.requestedOutputContract,
|
|
217
|
+
requiredTools: [...request.requiredTools].sort(),
|
|
218
|
+
evidenceRefs: [...request.evidenceRefs].sort(),
|
|
219
|
+
targetFileSet: [...(request.targetFileSet ?? [])].sort(),
|
|
220
|
+
targetDepth: request.targetDepth,
|
|
221
|
+
proposedTaskHash: request.proposedTaskHash,
|
|
222
|
+
proposedContextHash: request.proposedContextHash,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export function computeAdaptiveDelegationNormalizedTaskHash(request: DelegationRequestProposal): string {
|
|
227
|
+
return sha256(stableJson(normalizedTaskShape(request)));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export function computeAdaptiveDelegationRequestId(input: { runId: string; parentTaskId: string; request: DelegationRequestProposal }): string {
|
|
231
|
+
return `adreq_${sha256(stableJson({ runId: input.runId, parentTaskId: input.parentTaskId, normalizedTaskHash: computeAdaptiveDelegationNormalizedTaskHash(input.request) })).slice(0, 24)}`;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export function computeAdaptiveDelegationLineageHash(input: { rootGoalHash: string; parentTaskId: string; request: DelegationRequestProposal }): string {
|
|
235
|
+
return sha256(stableJson({ rootGoalHash: input.rootGoalHash, parentTaskId: input.parentTaskId, normalizedTaskHash: computeAdaptiveDelegationNormalizedTaskHash(input.request), requesterRole: input.request.requesterRole, targetDepth: input.request.targetDepth }));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function computeAdaptiveDelegationDuplicateSignature(request: DelegationRequestProposal, rootGoalHash = ""): string {
|
|
239
|
+
return sha256(stableJson({
|
|
240
|
+
rootGoalHash,
|
|
241
|
+
requesterRole: request.requesterRole,
|
|
242
|
+
referentRole: request.referentRole,
|
|
243
|
+
targetDepth: request.targetDepth,
|
|
244
|
+
requestedAgent: request.requestedAgent,
|
|
245
|
+
requestedOutputContract: request.requestedOutputContract,
|
|
246
|
+
requiredTools: [...request.requiredTools].sort(),
|
|
247
|
+
evidenceRefs: [...request.evidenceRefs].sort(),
|
|
248
|
+
targetFileSet: [...(request.targetFileSet ?? [])].sort(),
|
|
249
|
+
normalizedTaskHash: computeAdaptiveDelegationNormalizedTaskHash(request),
|
|
250
|
+
}));
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
export function validateAdaptiveDelegationEvidenceRefs(repoRoot: string, evidenceRefs: string[]): string[] {
|
|
254
|
+
const errors: string[] = [];
|
|
255
|
+
if (evidenceRefs.length === 0) errors.push("adaptive_delegation request requires at least one evidenceRef");
|
|
256
|
+
for (const ref of evidenceRefs) {
|
|
257
|
+
if (typeof ref !== "string" || ref.trim().length === 0) {
|
|
258
|
+
errors.push("adaptive_delegation evidenceRef must be a non-empty string");
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
if (ref.includes("\0")) errors.push(`adaptive_delegation evidenceRef contains NUL byte: ${ref}`);
|
|
262
|
+
if (ref.startsWith("/") || ref === "~" || ref.startsWith("~/")) errors.push(`adaptive_delegation evidenceRef must be repo-relative: ${ref}`);
|
|
263
|
+
if (ref === "." || ref === "./" || ref === ".." || ref.startsWith("../")) errors.push(`adaptive_delegation evidenceRef is too broad or escapes repo: ${ref}`);
|
|
264
|
+
if (!ref.startsWith("/") && ref !== "~" && !ref.startsWith("~/") && !ref.includes("\0") && !existsSync(join(repoRoot, ref))) errors.push(`adaptive_delegation evidenceRef does not exist: ${ref}`);
|
|
265
|
+
for (const protectedPattern of DEFAULT_RULES.zeroAccessPaths) {
|
|
266
|
+
if (pathMatches(ref, protectedPattern, repoRoot, repoRoot)) errors.push(`adaptive_delegation evidenceRef references zero-access path: ${protectedPattern}`);
|
|
267
|
+
}
|
|
268
|
+
for (const readonlyGenerated of ["node_modules/", "dist/", "build/"]) {
|
|
269
|
+
if (pathMatches(ref, readonlyGenerated, repoRoot, repoRoot)) errors.push(`adaptive_delegation evidenceRef references generated/vendor path: ${readonlyGenerated}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return errors;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export function validateDelegationRequestHardGates(input: {
|
|
276
|
+
repoRoot: string;
|
|
277
|
+
request: DelegationRequestProposal;
|
|
278
|
+
policy: AdaptiveDelegationPolicy;
|
|
279
|
+
rootGoalHash: string;
|
|
280
|
+
parentTaskId: string;
|
|
281
|
+
seenLineageHashes?: Set<string>;
|
|
282
|
+
totalDispatched?: number;
|
|
283
|
+
fanoutForRequester?: number;
|
|
284
|
+
}): string[] {
|
|
285
|
+
const { request, policy } = input;
|
|
286
|
+
const errors: string[] = [];
|
|
287
|
+
if (hasForbiddenBodyKeys(request)) errors.push("adaptive_delegation request must not contain plaintext body/prompt/output/task/content fields");
|
|
288
|
+
if (request.bodyStored !== false || request.promptBodiesStored !== false || request.outputBodiesStored !== false) errors.push("adaptive_delegation request must declare bodyStored=false, promptBodiesStored=false, outputBodiesStored=false");
|
|
289
|
+
if (request.targetDepth !== request.requesterDepth + 1) errors.push("adaptive_delegation targetDepth must equal requesterDepth + 1");
|
|
290
|
+
if (request.targetDepth > policy.configuredMaxDepth) errors.push("adaptive_delegation targetDepth exceeds configuredMaxDepth");
|
|
291
|
+
if (request.targetDepth > policy.runtimeMaxDepth) errors.push("adaptive_delegation targetDepth exceeds runtimeMaxDepth");
|
|
292
|
+
if ((request.ttlRequested ?? policy.ttlPerRequest) <= 0) errors.push("adaptive_delegation ttlRemaining must be positive");
|
|
293
|
+
if (input.seenLineageHashes?.has(computeAdaptiveDelegationLineageHash({ rootGoalHash: input.rootGoalHash, parentTaskId: input.parentTaskId, request }))) errors.push("adaptive_delegation duplicate lineage detected");
|
|
294
|
+
if ((input.totalDispatched ?? 0) >= policy.maxTotalAgentsWithOracle) errors.push("adaptive_delegation maxTotalAgentsWithOracle cap exceeded");
|
|
295
|
+
if ((input.totalDispatched ?? 0) >= policy.maxTotalAgents && policy.oracle === "off") errors.push("adaptive_delegation maxTotalAgents cap exceeded and oracle is off");
|
|
296
|
+
const fanoutCap = request.requesterDepth === 0 ? policy.rootFanoutMax : policy.nodeFanoutMax;
|
|
297
|
+
if ((input.fanoutForRequester ?? 0) >= fanoutCap) errors.push("adaptive_delegation fanout cap exceeded for requester");
|
|
298
|
+
if (request.requiredTools.length === 0) errors.push("adaptive_delegation request requires requiredTools");
|
|
299
|
+
for (const tool of request.requiredTools) {
|
|
300
|
+
if (WRITE_OR_DELEGATION_TOOLS.has(tool)) {
|
|
301
|
+
if (tool === "bash" || tool === "edit" || tool === "write") errors.push(`adaptive_delegation sandbox/write dispatch is not enabled in P9; blocked requested tool: ${tool}`);
|
|
302
|
+
else errors.push(`adaptive_delegation request forbids write/delegation tool: ${tool}`);
|
|
303
|
+
}
|
|
304
|
+
if (!READONLY_TOOL_ALLOWLIST.has(tool)) errors.push(`adaptive_delegation tool is not in supervised_readonly allowlist: ${tool}`);
|
|
305
|
+
}
|
|
306
|
+
errors.push(...validateOutputContractId(request.requestedOutputContract).map((error) => `adaptive_delegation output contract: ${error}`));
|
|
307
|
+
const knownAgents = new Set(discoverAgents(input.repoRoot, "project").map((agent) => agent.name.toLowerCase()));
|
|
308
|
+
if (request.requestedAgent && !knownAgents.has(request.requestedAgent.toLowerCase())) errors.push(`adaptive_delegation requestedAgent is not a known project agent: ${request.requestedAgent}`);
|
|
309
|
+
errors.push(...validateAdaptiveDelegationEvidenceRefs(input.repoRoot, request.evidenceRefs));
|
|
310
|
+
errors.push(...validateAllowedPathPolicy(request.targetFileSet, "adaptive_delegation targetFileSet", input.repoRoot));
|
|
311
|
+
for (const [field, value] of [["proposedTaskHash", request.proposedTaskHash], ["proposedContextHash", request.proposedContextHash], ["rationaleHash", request.rationaleHash]] as const) {
|
|
312
|
+
const error = optionalHashError(field, value);
|
|
313
|
+
if (error) errors.push(error);
|
|
314
|
+
}
|
|
315
|
+
if (!request.requesterRole || !request.referentRole || !request.requestedAgent) errors.push("adaptive_delegation requesterRole, referentRole, and requestedAgent are required");
|
|
316
|
+
return errors;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function clampScore(value: number): number {
|
|
320
|
+
if (!Number.isFinite(value)) return 0;
|
|
321
|
+
return Math.max(0, Math.min(1, value));
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export function scoreDelegationRequest(input: { request: DelegationRequestProposal; hardGateErrors: string[]; policy: AdaptiveDelegationPolicy }): DelegationScore {
|
|
325
|
+
const { request, hardGateErrors, policy } = input;
|
|
326
|
+
const evidenceQuality = clampScore(request.evidenceRefs.length / 3);
|
|
327
|
+
const successDelta = typeof request.estimatedSuccessIfAlone === "number" && typeof request.estimatedSuccessWithDelegation === "number"
|
|
328
|
+
? request.estimatedSuccessWithDelegation - request.estimatedSuccessIfAlone
|
|
329
|
+
: 0;
|
|
330
|
+
const tokenBenefit = typeof request.estimatedTokensIfAlone === "number" && typeof request.estimatedTokensWithDelegation === "number" && request.estimatedTokensIfAlone > 0
|
|
331
|
+
? (request.estimatedTokensIfAlone - request.estimatedTokensWithDelegation) / request.estimatedTokensIfAlone
|
|
332
|
+
: 0;
|
|
333
|
+
const costBenefit = clampScore(Math.max(successDelta, tokenBenefit, 0));
|
|
334
|
+
const safety = hardGateErrors.length === 0 ? (request.risk === "low" ? 1 : request.risk === "medium" ? 0.75 : 0.35) : 0;
|
|
335
|
+
const relevance = request.proposedTaskHash || request.targetFileSet?.length ? 0.8 : 0.55;
|
|
336
|
+
const novelty = request.targetFileSet && request.targetFileSet.length > 0 ? 0.75 : 0.5;
|
|
337
|
+
const urgency = request.targetDepth >= policy.runtimeMaxDepth ? 0.4 : 0.55;
|
|
338
|
+
const total = clampScore((0.25 * relevance) + (0.25 * evidenceQuality) + (0.20 * costBenefit) + (0.15 * safety) + (0.10 * novelty) + (0.05 * urgency));
|
|
339
|
+
const greyZone = total >= 0.45 && total < policy.minApprovalScore;
|
|
340
|
+
const decisionHint = hardGateErrors.length > 0 ? "deny" : request.risk === "high" || greyZone || request.targetDepth === ADAPTIVE_DELEGATION_HARD_MAX_DEPTH ? "oracle_required" : total >= policy.minApprovalScore ? "approve" : "deny";
|
|
341
|
+
return {
|
|
342
|
+
schema: DELEGATION_SCORE_SCHEMA,
|
|
343
|
+
relevance,
|
|
344
|
+
evidenceQuality,
|
|
345
|
+
costBenefit,
|
|
346
|
+
safety,
|
|
347
|
+
novelty,
|
|
348
|
+
urgency,
|
|
349
|
+
total,
|
|
350
|
+
decisionHint,
|
|
351
|
+
reasons: [
|
|
352
|
+
...(hardGateErrors.length > 0 ? ["hard_gates_failed"] : []),
|
|
353
|
+
...(greyZone ? ["score_grey_zone"] : []),
|
|
354
|
+
...(request.risk === "high" ? ["high_risk_requires_oracle"] : []),
|
|
355
|
+
...(request.targetDepth === ADAPTIVE_DELEGATION_HARD_MAX_DEPTH ? ["target_depth_4_requires_oracle"] : []),
|
|
356
|
+
],
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
export function decideDelegationRequest(input: {
|
|
361
|
+
repoRoot: string;
|
|
362
|
+
runId: string;
|
|
363
|
+
rootGoalHash: string;
|
|
364
|
+
parentTaskId: string;
|
|
365
|
+
request: DelegationRequestProposal;
|
|
366
|
+
policy: AdaptiveDelegationPolicy;
|
|
367
|
+
seenLineageHashes?: Set<string>;
|
|
368
|
+
totalDispatched?: number;
|
|
369
|
+
fanoutForRequester?: number;
|
|
370
|
+
}): GovernorDecision {
|
|
371
|
+
const hardGateErrors = validateDelegationRequestHardGates(input);
|
|
372
|
+
const score = scoreDelegationRequest({ request: input.request, hardGateErrors, policy: input.policy });
|
|
373
|
+
const requestId = computeAdaptiveDelegationRequestId(input);
|
|
374
|
+
const lineageHash = computeAdaptiveDelegationLineageHash(input);
|
|
375
|
+
const normalizedTaskHash = computeAdaptiveDelegationNormalizedTaskHash(input.request);
|
|
376
|
+
const oracleRequired = score.decisionHint === "oracle_required" || input.request.targetDepth === ADAPTIVE_DELEGATION_HARD_MAX_DEPTH || input.request.risk === "high";
|
|
377
|
+
const approvedByScore = score.total >= input.policy.minApprovalScore;
|
|
378
|
+
const dispatchAllowed = hardGateErrors.length === 0 && approvedByScore && !oracleRequired && input.policy.dispatch === true && input.policy.mode === "when_pertinent";
|
|
379
|
+
const status: GovernorDecision["status"] = hardGateErrors.length > 0
|
|
380
|
+
? "blocked"
|
|
381
|
+
: oracleRequired
|
|
382
|
+
? "oracle_required"
|
|
383
|
+
: approvedByScore
|
|
384
|
+
? (input.policy.dispatch ? "approved" : "deferred")
|
|
385
|
+
: "denied";
|
|
386
|
+
return {
|
|
387
|
+
schema: GOVERNOR_DECISION_SCHEMA,
|
|
388
|
+
parentAssignedRequestId: requestId,
|
|
389
|
+
parentComputedLineageHash: lineageHash,
|
|
390
|
+
parentComputedNormalizedTaskHash: normalizedTaskHash,
|
|
391
|
+
requesterRole: input.request.requesterRole,
|
|
392
|
+
referentRole: input.request.referentRole,
|
|
393
|
+
requesterDepth: input.request.requesterDepth,
|
|
394
|
+
targetDepth: input.request.targetDepth,
|
|
395
|
+
ttlRemaining: input.request.ttlRequested ?? input.policy.ttlPerRequest,
|
|
396
|
+
hardGateStatus: hardGateErrors.length === 0 ? "passed" : "blocked",
|
|
397
|
+
hardGateErrors,
|
|
398
|
+
score,
|
|
399
|
+
status,
|
|
400
|
+
dispatchAllowed,
|
|
401
|
+
noShip: status === "blocked" || status === "oracle_required" || (input.request.targetDepth > 1 && input.policy.dispatch !== true),
|
|
402
|
+
reasons: [...hardGateErrors, ...score.reasons, ...(input.policy.dispatch ? [] : ["dispatch_disabled_or_advisory_only"])],
|
|
403
|
+
bodyStored: false,
|
|
404
|
+
promptBodiesStored: false,
|
|
405
|
+
outputBodiesStored: false,
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
export function buildParentDispatchContractForDecision(input: { runId: string; parentTaskId: string; request: DelegationRequestProposal; decision: GovernorDecision; dispatchGate?: string }): ParentDispatchContract | undefined {
|
|
410
|
+
const { request, decision } = input;
|
|
411
|
+
if (decision.hardGateStatus !== "passed") return undefined;
|
|
412
|
+
if (decision.status !== "deferred" && decision.status !== "approved") return undefined;
|
|
413
|
+
return {
|
|
414
|
+
schema: "zob.parent-dispatch-contract.v1",
|
|
415
|
+
requestId: decision.parentAssignedRequestId,
|
|
416
|
+
runId: input.runId,
|
|
417
|
+
parentTaskId: input.parentTaskId,
|
|
418
|
+
agent: request.requestedAgent,
|
|
419
|
+
taskHash: isSha256Hex(request.proposedTaskHash) ? request.proposedTaskHash : decision.parentComputedNormalizedTaskHash,
|
|
420
|
+
contextHash: isSha256Hex(request.proposedContextHash) ? request.proposedContextHash : undefined,
|
|
421
|
+
rationaleHash: isSha256Hex(request.rationaleHash) ? request.rationaleHash : undefined,
|
|
422
|
+
outputContract: request.requestedOutputContract,
|
|
423
|
+
requiredTools: [...request.requiredTools],
|
|
424
|
+
allowedPaths: request.targetFileSet ? [...request.targetFileSet] : undefined,
|
|
425
|
+
forbiddenPaths: [...DEFAULT_RULES.zeroAccessPaths],
|
|
426
|
+
requesterDepth: request.requesterDepth,
|
|
427
|
+
targetDepth: request.targetDepth,
|
|
428
|
+
referentRole: request.referentRole,
|
|
429
|
+
dispatcher: "parent",
|
|
430
|
+
status: "queued_not_dispatched",
|
|
431
|
+
dispatchGate: input.dispatchGate ?? (decision.dispatchAllowed ? "p4_parent_dispatch_pending" : "dispatch_disabled_or_advisory_only"),
|
|
432
|
+
liveDispatched: false,
|
|
433
|
+
bodyStored: false,
|
|
434
|
+
promptBodiesStored: false,
|
|
435
|
+
outputBodiesStored: false,
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
export function buildInitialAdaptiveDelegationGovernorState(input: { runId: string; rootGoalHash: string; policy: AdaptiveDelegationPolicy }): AdaptiveDelegationGovernorState {
|
|
440
|
+
return {
|
|
441
|
+
schema: GOVERNOR_STATE_SCHEMA,
|
|
442
|
+
runId: input.runId,
|
|
443
|
+
rootGoalHash: input.rootGoalHash,
|
|
444
|
+
policyHash: sha256(stableJson(input.policy)),
|
|
445
|
+
totalRequested: 0,
|
|
446
|
+
totalApproved: 0,
|
|
447
|
+
totalDispatched: 0,
|
|
448
|
+
totalDenied: 0,
|
|
449
|
+
totalDeferred: 0,
|
|
450
|
+
totalOracleRequired: 0,
|
|
451
|
+
maxDepthObserved: 0,
|
|
452
|
+
fanoutByRequester: {},
|
|
453
|
+
requestIds: [],
|
|
454
|
+
lineageHashes: [],
|
|
455
|
+
paused: false,
|
|
456
|
+
stopped: false,
|
|
457
|
+
bodyStored: false,
|
|
458
|
+
promptBodiesStored: false,
|
|
459
|
+
outputBodiesStored: false,
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
export function updateGovernorState(state: AdaptiveDelegationGovernorState, decision: GovernorDecision): AdaptiveDelegationGovernorState {
|
|
464
|
+
const nextFanout = { ...state.fanoutByRequester };
|
|
465
|
+
nextFanout[decision.requesterRole] = (nextFanout[decision.requesterRole] ?? 0) + 1;
|
|
466
|
+
return {
|
|
467
|
+
...state,
|
|
468
|
+
totalRequested: state.totalRequested + 1,
|
|
469
|
+
totalApproved: state.totalApproved + (decision.status === "approved" ? 1 : 0),
|
|
470
|
+
totalDispatched: state.totalDispatched + (decision.dispatchAllowed ? 1 : 0),
|
|
471
|
+
totalDenied: state.totalDenied + (decision.status === "denied" || decision.status === "blocked" ? 1 : 0),
|
|
472
|
+
totalDeferred: state.totalDeferred + (decision.status === "deferred" ? 1 : 0),
|
|
473
|
+
totalOracleRequired: state.totalOracleRequired + (decision.status === "oracle_required" ? 1 : 0),
|
|
474
|
+
maxDepthObserved: Math.max(state.maxDepthObserved, decision.targetDepth),
|
|
475
|
+
fanoutByRequester: nextFanout,
|
|
476
|
+
requestIds: state.requestIds.includes(decision.parentAssignedRequestId) ? state.requestIds : [...state.requestIds, decision.parentAssignedRequestId],
|
|
477
|
+
lineageHashes: state.lineageHashes.includes(decision.parentComputedLineageHash) ? state.lineageHashes : [...state.lineageHashes, decision.parentComputedLineageHash],
|
|
478
|
+
bodyStored: false,
|
|
479
|
+
promptBodiesStored: false,
|
|
480
|
+
outputBodiesStored: false,
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
export function extractDelegationRequestsFromText(text: string): { requests: DelegationRequestProposal[]; errors: string[] } {
|
|
485
|
+
const errors: string[] = [];
|
|
486
|
+
const requests: DelegationRequestProposal[] = [];
|
|
487
|
+
for (const match of text.matchAll(/<delegation_requests>\s*([\s\S]*?)\s*<\/delegation_requests>/gi)) {
|
|
488
|
+
try {
|
|
489
|
+
const parsed = JSON.parse(match[1].trim());
|
|
490
|
+
const root = isRecord(parsed) && Array.isArray(parsed.requests) ? parsed.requests : Array.isArray(parsed) ? parsed : undefined;
|
|
491
|
+
if (!root) {
|
|
492
|
+
errors.push("delegation_requests block must contain an array or { requests: [...] }");
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
for (const item of root) {
|
|
496
|
+
if (!isRecord(item)) {
|
|
497
|
+
errors.push("delegation request entry must be an object");
|
|
498
|
+
continue;
|
|
499
|
+
}
|
|
500
|
+
if (hasForbiddenBodyKeys(item)) {
|
|
501
|
+
errors.push("delegation request entry must not include plaintext body/prompt/output/task/content fields");
|
|
502
|
+
continue;
|
|
503
|
+
}
|
|
504
|
+
const hashFieldErrors = [
|
|
505
|
+
optionalHashError("proposedTaskHash", item.proposedTaskHash),
|
|
506
|
+
optionalHashError("proposedContextHash", item.proposedContextHash),
|
|
507
|
+
optionalHashError("rationaleHash", item.rationaleHash),
|
|
508
|
+
].filter((error): error is string => typeof error === "string");
|
|
509
|
+
if (hashFieldErrors.length > 0) {
|
|
510
|
+
errors.push(...hashFieldErrors.map((error) => `delegation request entry ${error}`));
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
const requiredTools = Array.isArray(item.requiredTools) ? item.requiredTools.filter((tool): tool is string => typeof tool === "string") : [];
|
|
514
|
+
const evidenceRefs = Array.isArray(item.evidenceRefs) ? item.evidenceRefs.filter((ref): ref is string => typeof ref === "string") : [];
|
|
515
|
+
requests.push({
|
|
516
|
+
schema: "zob.delegation-request.v1",
|
|
517
|
+
requesterRole: typeof item.requesterRole === "string" ? item.requesterRole : "",
|
|
518
|
+
referentRole: typeof item.referentRole === "string" ? item.referentRole : "",
|
|
519
|
+
requestedAgent: typeof item.requestedAgent === "string" ? canonicalizeAdaptiveRequestedAgent(item.requestedAgent) : "",
|
|
520
|
+
requestedOutputContract: typeof item.requestedOutputContract === "string" ? item.requestedOutputContract : "",
|
|
521
|
+
requiredTools,
|
|
522
|
+
requesterDepth: typeof item.requesterDepth === "number" ? item.requesterDepth : 0,
|
|
523
|
+
targetDepth: typeof item.targetDepth === "number" ? item.targetDepth : 1,
|
|
524
|
+
ttlRequested: typeof item.ttlRequested === "number" ? item.ttlRequested : undefined,
|
|
525
|
+
evidenceRefs,
|
|
526
|
+
targetFileSet: Array.isArray(item.targetFileSet) ? item.targetFileSet.filter((ref): ref is string => typeof ref === "string") : undefined,
|
|
527
|
+
estimatedTokensIfAlone: typeof item.estimatedTokensIfAlone === "number" ? item.estimatedTokensIfAlone : undefined,
|
|
528
|
+
estimatedTokensWithDelegation: typeof item.estimatedTokensWithDelegation === "number" ? item.estimatedTokensWithDelegation : undefined,
|
|
529
|
+
estimatedCostUsd: typeof item.estimatedCostUsd === "number" ? item.estimatedCostUsd : undefined,
|
|
530
|
+
estimatedDurationMs: typeof item.estimatedDurationMs === "number" ? item.estimatedDurationMs : undefined,
|
|
531
|
+
estimatedSuccessIfAlone: typeof item.estimatedSuccessIfAlone === "number" ? item.estimatedSuccessIfAlone : undefined,
|
|
532
|
+
estimatedSuccessWithDelegation: typeof item.estimatedSuccessWithDelegation === "number" ? item.estimatedSuccessWithDelegation : undefined,
|
|
533
|
+
risk: item.risk === "high" || item.risk === "medium" || item.risk === "low" ? item.risk : "medium",
|
|
534
|
+
proposedTaskHash: typeof item.proposedTaskHash === "string" ? item.proposedTaskHash : undefined,
|
|
535
|
+
proposedContextHash: typeof item.proposedContextHash === "string" ? item.proposedContextHash : undefined,
|
|
536
|
+
rationaleHash: typeof item.rationaleHash === "string" ? item.rationaleHash : undefined,
|
|
537
|
+
bodyStored: false,
|
|
538
|
+
promptBodiesStored: false,
|
|
539
|
+
outputBodiesStored: false,
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
} catch (error) {
|
|
543
|
+
errors.push(`Could not parse delegation_requests JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
return { requests, errors };
|
|
547
|
+
}
|