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,810 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
|
|
5
|
+
import { buildZobLivePresenceSummary } from "../coms-v2/presence.js";
|
|
6
|
+
import { readZobComsV2Policy } from "../coms-v2/policy.js";
|
|
7
|
+
import { discoverAgents } from "../agents.js";
|
|
8
|
+
import { evaluateStrictBudgetDispatchGate } from "../budget-policy.js";
|
|
9
|
+
import { isFailed, runChildAgent } from "../child-runner.js";
|
|
10
|
+
import { classifyChronicleCompletion, outputHasEvidenceMarker } from "../chronicle.js";
|
|
11
|
+
import { buildAgenticFactoryNoMockFinalGate, factoryLedger, runFactoryRun } from "../factory/run.js";
|
|
12
|
+
import { buildInitialAdaptiveDelegationGovernorState, buildParentDispatchContractForDecision, decideDelegationRequest, extractDelegationRequestsFromText, normalizeAdaptiveDelegationPolicy, updateGovernorState } from "../orchestration/adaptive-delegation.js";
|
|
13
|
+
import { runFactoryQuarantineActivate, runFactoryQuarantineReview, runFactoryQuarantineVerifyActivation } from "../factory/quarantine.js";
|
|
14
|
+
import { evaluateModelRoutingDispatchGate } from "../model-routing.js";
|
|
15
|
+
import { applyChildGates, inferOutputContract, validateOutputContractId } from "../output-contracts.js";
|
|
16
|
+
import { FactoryQuarantineActivateParams, FactoryQuarantineReviewParams, FactoryQuarantineVerifyActivationParams, FactoryRunParams } from "../schemas.js";
|
|
17
|
+
import { factoryPhaseSentinelForMode, loadFactoryDefinition, loadFactoryInputManifest } from "../factory/validation.js";
|
|
18
|
+
import { validateToolList } from "../safety.js";
|
|
19
|
+
import { addUsage, usageEmpty, writeFactoryTelemetrySummary } from "../telemetry.js";
|
|
20
|
+
import { sha256 } from "../utils/hashing.js";
|
|
21
|
+
import { parseJsonFile } from "../utils/json.js";
|
|
22
|
+
import { safeFileStem } from "../utils/paths.js";
|
|
23
|
+
import { isRecord } from "../utils/records.js";
|
|
24
|
+
import type { DelegationRequestProposal, GovernorDecision, ParentDispatchContract } from "../types.js";
|
|
25
|
+
import type { HarnessRuntimeState } from "./state.js";
|
|
26
|
+
import { strictGoalSpecErrors } from "./state.js";
|
|
27
|
+
|
|
28
|
+
function persistableModelRouting(route: Record<string, unknown>): Record<string, unknown> {
|
|
29
|
+
return {
|
|
30
|
+
schema: route.schema,
|
|
31
|
+
liveRoutingEnabled: route.liveRoutingEnabled === true,
|
|
32
|
+
modelRouterUsed: route.modelRouterUsed === true,
|
|
33
|
+
routingApplied: route.routingApplied === true,
|
|
34
|
+
selectedModelClass: route.selectedModelClass,
|
|
35
|
+
recommendedModelClass: route.recommendedModelClass,
|
|
36
|
+
selectedModelHash: route.selectedModelHash,
|
|
37
|
+
selectedModelStored: false,
|
|
38
|
+
modelByClassProvided: route.modelByClassProvided === true,
|
|
39
|
+
reasonCodes: Array.isArray(route.reasonCodes) ? route.reasonCodes : [],
|
|
40
|
+
childDispatchAllowed: route.childDispatchAllowed === true,
|
|
41
|
+
budgetEnforced: false,
|
|
42
|
+
noExecution: true,
|
|
43
|
+
bodyStored: false,
|
|
44
|
+
promptBodiesStored: false,
|
|
45
|
+
outputBodiesStored: false,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function factoryStrictGoalSpecErrors(state: HarnessRuntimeState, repoRoot: string, params: { factory: string; input_manifest: string }): string[] {
|
|
50
|
+
const loadedFactory = loadFactoryDefinition(repoRoot, params.factory);
|
|
51
|
+
const loadedManifest = loadFactoryInputManifest(repoRoot, params.input_manifest);
|
|
52
|
+
return strictGoalSpecErrors(state, {
|
|
53
|
+
kind: "factory_run",
|
|
54
|
+
factoryName: params.factory,
|
|
55
|
+
factoryDescription: loadedFactory.definition?.description,
|
|
56
|
+
inputManifest: params.input_manifest,
|
|
57
|
+
manifestFactory: loadedManifest.manifest?.factory,
|
|
58
|
+
manifestDescription: loadedManifest.manifest?.description,
|
|
59
|
+
manifestItems: loadedManifest.manifest?.items.length,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function factoryAgenticComsLivePreflightErrors(repoRoot: string, execution: string | undefined): string[] {
|
|
64
|
+
if (execution !== "agentic") return [];
|
|
65
|
+
const policy = readZobComsV2Policy(repoRoot);
|
|
66
|
+
if (!policy.agenticWorkflowsRequireLive) return [];
|
|
67
|
+
if (policy.legacy.appendOnlySendEnabled !== false) return ["ZOB coms v2 blocks factory agentic execution: legacy append-only send must be disabled for agentic workflows"];
|
|
68
|
+
if (policy.mode !== "required_local" && policy.mode !== "required_network") return [`ZOB coms v2 blocks factory agentic execution: agentic workflows require required_local live transport, current mode=${policy.mode}`];
|
|
69
|
+
if (policy.mode === "required_network") return ["ZOB coms v2 blocks factory agentic execution: required_network remains gated; use required_local live transport"];
|
|
70
|
+
const presence = buildZobLivePresenceSummary(repoRoot);
|
|
71
|
+
if (presence.dispatchEnabled !== true || presence.online <= 0 || presence.networkEnabled !== false) return [`ZOB coms v2 blocks factory agentic execution: live local registry is not ready (${JSON.stringify({ online: presence.online, stale: presence.stale, offline: presence.offline, dispatchEnabled: presence.dispatchEnabled, networkEnabled: presence.networkEnabled })})`];
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function factoryAdaptiveLiveReadonlyProofEnabled(params: Record<string, unknown>): boolean {
|
|
76
|
+
const adaptive = isRecord(params.adaptive_delegation) ? params.adaptive_delegation : undefined;
|
|
77
|
+
const gate = isRecord(params.adaptive_factory_dispatch_gate) ? params.adaptive_factory_dispatch_gate : undefined;
|
|
78
|
+
return params.execution === "agentic"
|
|
79
|
+
&& (params.mode ?? "smoke") === "smoke"
|
|
80
|
+
&& adaptive?.enabled === true
|
|
81
|
+
&& adaptive?.dispatch === true
|
|
82
|
+
&& adaptive?.mode === "when_pertinent"
|
|
83
|
+
&& adaptive?.strictBudgetRequired === true
|
|
84
|
+
&& gate?.enabled === true
|
|
85
|
+
&& gate?.liveReadOnlyProofEnabled === true;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function buildFactoryAdaptiveProposalGuidance(input: { runId: string; stageName: string; itemId: string; evidenceRefs: string[] }): string {
|
|
89
|
+
return [
|
|
90
|
+
"FACTORY ADAPTIVE PROOF GUIDANCE:",
|
|
91
|
+
"For this registered proof, you MUST emit exactly one metadata-only adaptive proposal. Place it before the final deliverable line inside <delegation_requests>{\"requests\":[...]}</delegation_requests>.",
|
|
92
|
+
`Use requesterRole \"factory:${input.stageName}\", referentRole \"factory-runner\", requesterDepth 1, targetDepth 2, requestedAgent \"explore\", requestedOutputContract \"explore.v1\", requiredTools [\"read\",\"grep\",\"find\",\"ls\"], risk \"low\".`,
|
|
93
|
+
`Use evidenceRefs ${JSON.stringify(input.evidenceRefs)} and targetFileSet ${JSON.stringify(input.evidenceRefs)}.`,
|
|
94
|
+
"Do not include task/context/prompt/output/body/content/diff/patch/messages/transcript fields in the proposal. Do not dispatch children yourself.",
|
|
95
|
+
`Factory run id: ${input.runId}; stage: ${input.stageName}; item: ${input.itemId}.`,
|
|
96
|
+
].join("\n");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function buildFactoryAdaptiveReadonlyTaskText(input: { requestId: string; request: DelegationRequestProposal; runId: string }): string {
|
|
100
|
+
return [
|
|
101
|
+
"Parent-owned factory adaptive read-only dispatch.",
|
|
102
|
+
`Factory run id: ${input.runId}.`,
|
|
103
|
+
`Adaptive request id: ${input.requestId}.`,
|
|
104
|
+
`Evidence refs: ${input.request.evidenceRefs.join(", ")}.`,
|
|
105
|
+
`Target files: ${(input.request.targetFileSet ?? input.request.evidenceRefs).join(", ")}.`,
|
|
106
|
+
"Use only read/grep/find/ls. Do not write files. Do not access secrets. Do not delegate.",
|
|
107
|
+
"Return the requested output contract with evidence, risks/blockers, compliance, and final line deliverable_delivered: yes.",
|
|
108
|
+
].join("\n");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function registerFactoryTools(pi: ExtensionAPI, state: HarnessRuntimeState): void {
|
|
112
|
+
pi.registerTool({
|
|
113
|
+
name: "factory_quarantine_review",
|
|
114
|
+
label: "Factory Quarantine Review",
|
|
115
|
+
description: [
|
|
116
|
+
"Review a quarantined factory-forge scaffold for manual activation readiness.",
|
|
117
|
+
"Writes review artifacts only under reports/factory-runs/<runId>/reviews/<reviewId> and never activates or registers the generated factory.",
|
|
118
|
+
].join(" "),
|
|
119
|
+
promptSnippet: "Review quarantined factory-forge output for manual activation readiness",
|
|
120
|
+
promptGuidelines: [
|
|
121
|
+
"Use only for factory-forge outputs that already live under a run quarantine directory.",
|
|
122
|
+
"Require local checks, oracle PASS, and approval metadata before treating activationReady as true.",
|
|
123
|
+
"This tool never performs activation, copying, or registration under .pi/factories.",
|
|
124
|
+
],
|
|
125
|
+
parameters: FactoryQuarantineReviewParams,
|
|
126
|
+
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
127
|
+
const goalErrors = strictGoalSpecErrors(state, { kind: "quarantine", operation: "factory_quarantine_review", runId: params.run_id });
|
|
128
|
+
if (goalErrors.length > 0) {
|
|
129
|
+
const result = { status: "failed_preflight", runId: params.run_id, reviewId: params.review_id ?? "not-started", reviewDir: "", activationReady: false, activationPerformed: false, generatedFactoryRegistered: false, errors: goalErrors };
|
|
130
|
+
return { content: [{ type: "text", text: `factory_quarantine_review failed_preflight:\n- ${goalErrors.join("\n- ")}\nSet /goal_gate or /job_intake before review.` }], details: result };
|
|
131
|
+
}
|
|
132
|
+
const result = runFactoryQuarantineReview(ctx.cwd, params);
|
|
133
|
+
const text = [
|
|
134
|
+
`factory_quarantine_review ${result.status}: ${result.runId}/${result.reviewId}`,
|
|
135
|
+
`reviewDir: ${result.reviewDir}`,
|
|
136
|
+
`activationReady: ${result.activationReady}`,
|
|
137
|
+
`activationPerformed: false`,
|
|
138
|
+
`generatedFactoryRegistered: ${result.generatedFactoryRegistered}`,
|
|
139
|
+
result.errors.length > 0 ? `errors:\n- ${result.errors.join("\n- ")}` : "errors: none",
|
|
140
|
+
].join("\n");
|
|
141
|
+
return { content: [{ type: "text", text }], details: result };
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
pi.registerTool({
|
|
146
|
+
name: "factory_quarantine_activate",
|
|
147
|
+
label: "Factory Quarantine Activate",
|
|
148
|
+
description: [
|
|
149
|
+
"Explicitly activate a reviewed quarantined factory-forge scaffold by copying only allowlisted files into .pi/factories/<generated>.",
|
|
150
|
+
"Requires activation-readiness.json with activationReady=true/activationPerformed=false and an exact confirmation phrase.",
|
|
151
|
+
].join(" "),
|
|
152
|
+
promptSnippet: "Activate a quarantined generated factory after manual review",
|
|
153
|
+
promptGuidelines: [
|
|
154
|
+
"Use only after factory_quarantine_review reports activationReady=true.",
|
|
155
|
+
"Require the exact confirmation phrase shown in the tool schema; never paraphrase it.",
|
|
156
|
+
"This tool refuses existing .pi/factories targets and never overwrites.",
|
|
157
|
+
],
|
|
158
|
+
parameters: FactoryQuarantineActivateParams,
|
|
159
|
+
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
160
|
+
const goalErrors = strictGoalSpecErrors(state, { kind: "quarantine", operation: "factory_quarantine_activate", runId: params.run_id });
|
|
161
|
+
if (goalErrors.length > 0) {
|
|
162
|
+
const result = { status: "failed_preflight", runId: params.run_id, reviewId: params.review_id, activationId: params.activation_id ?? "not-started", generatedFactory: params.generated_factory, activationPerformed: false, confirmationMatched: false, targetDir: "", journalPath: "", copiedFiles: [], errors: goalErrors };
|
|
163
|
+
return { content: [{ type: "text", text: `factory_quarantine_activate failed_preflight:\n- ${goalErrors.join("\n- ")}\nSet /goal_gate or /job_intake before activation.` }], details: result };
|
|
164
|
+
}
|
|
165
|
+
const result = runFactoryQuarantineActivate(ctx.cwd, params);
|
|
166
|
+
const text = [
|
|
167
|
+
`factory_quarantine_activate ${result.status}: ${result.runId}/${result.reviewId}`,
|
|
168
|
+
`targetDir: ${result.targetDir}`,
|
|
169
|
+
`activationPerformed: ${result.activationPerformed}`,
|
|
170
|
+
`confirmationMatched: ${result.confirmationMatched}`,
|
|
171
|
+
`journalPath: ${result.journalPath}`,
|
|
172
|
+
result.errors.length > 0 ? `errors:\n- ${result.errors.join("\n- ")}` : "errors: none",
|
|
173
|
+
].join("\n");
|
|
174
|
+
return { content: [{ type: "text", text }], details: result };
|
|
175
|
+
},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
pi.registerTool({
|
|
179
|
+
name: "factory_quarantine_verify_activation",
|
|
180
|
+
label: "Factory Quarantine Verify Activation",
|
|
181
|
+
description: [
|
|
182
|
+
"Verify a manually activated factory-forge scaffold by requiring a successful activation journal entry and running deterministic factory_run smoke.",
|
|
183
|
+
"Writes verification artifacts under reports/factory-runs/<runId>/verification/<verificationId> and appends activation-verification-journal.jsonl.",
|
|
184
|
+
].join(" "),
|
|
185
|
+
promptSnippet: "Verify a manually activated generated factory with deterministic smoke",
|
|
186
|
+
promptGuidelines: [
|
|
187
|
+
"Use only after factory_quarantine_activate reports activationPerformed=true.",
|
|
188
|
+
"Do not use agentic/live model verification; this tool always runs deterministic mode=smoke.",
|
|
189
|
+
"If the verification factory_run id already exists, choose a fresh verification_id or clean it manually.",
|
|
190
|
+
],
|
|
191
|
+
parameters: FactoryQuarantineVerifyActivationParams,
|
|
192
|
+
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
193
|
+
const goalErrors = strictGoalSpecErrors(state, { kind: "quarantine", operation: "factory_quarantine_verify_activation", runId: params.run_id });
|
|
194
|
+
if (goalErrors.length > 0) {
|
|
195
|
+
const result = { status: "failed_preflight", runId: params.run_id, activationId: params.activation_id, verificationId: params.verification_id ?? "not-started", generatedFactory: params.generated_factory, verificationDir: "", journalPath: "", factoryRunId: "", factoryRunDir: "", artifacts: [], errors: goalErrors };
|
|
196
|
+
return { content: [{ type: "text", text: `factory_quarantine_verify_activation failed_preflight:\n- ${goalErrors.join("\n- ")}\nSet /goal_gate or /job_intake before verification.` }], details: result };
|
|
197
|
+
}
|
|
198
|
+
const result = runFactoryQuarantineVerifyActivation(ctx.cwd, params);
|
|
199
|
+
const text = [
|
|
200
|
+
`factory_quarantine_verify_activation ${result.status}: ${result.runId}/${result.verificationId}`,
|
|
201
|
+
`verificationDir: ${result.verificationDir}`,
|
|
202
|
+
`factoryRunId: ${result.factoryRunId}`,
|
|
203
|
+
`journalPath: ${result.journalPath}`,
|
|
204
|
+
result.errors.length > 0 ? `errors:\n- ${result.errors.join("\n- ")}` : "errors: none",
|
|
205
|
+
].join("\n");
|
|
206
|
+
return { content: [{ type: "text", text }], details: result };
|
|
207
|
+
},
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
pi.registerTool({
|
|
211
|
+
name: "factory_run",
|
|
212
|
+
label: "Factory Run",
|
|
213
|
+
description: [
|
|
214
|
+
"Run a ZOB software factory with manifest/checkpoint/output/validation/sentinel artifacts.",
|
|
215
|
+
"Supports deterministic local runs, plan_only runs, and optional agentic execution of the generated map/reduce/validate plan.",
|
|
216
|
+
].join(" "),
|
|
217
|
+
promptSnippet: "Run a manifest/checkpoint/sentinel software factory",
|
|
218
|
+
promptGuidelines: [
|
|
219
|
+
"Use factory_run only after the harness goal and factory contract are clear.",
|
|
220
|
+
"Start with mode=smoke before pilot or batch.",
|
|
221
|
+
"Use execution=plan_only to inspect child-agent tasks without spending model tokens.",
|
|
222
|
+
"Do not claim a factory run is complete without validation.json and DONE.sentinel.",
|
|
223
|
+
],
|
|
224
|
+
parameters: FactoryRunParams,
|
|
225
|
+
async execute(_toolCallId, params, signal, onUpdate, ctx) {
|
|
226
|
+
const goalErrors = factoryStrictGoalSpecErrors(state, ctx.cwd, params);
|
|
227
|
+
if (goalErrors.length > 0) {
|
|
228
|
+
const result = { status: "failed_preflight", runId: params.run_id ?? "not-started", runDir: "", processed: 0, failed: 0, artifacts: [], errors: goalErrors };
|
|
229
|
+
return { content: [{ type: "text", text: `factory_run failed_preflight:\n- ${goalErrors.join("\n- ")}\nSet /goal_gate or /job_intake before dispatch.` }], details: result };
|
|
230
|
+
}
|
|
231
|
+
let result = runFactoryRun(ctx.cwd, params);
|
|
232
|
+
|
|
233
|
+
if (params.execution === "agentic" && result.status === "planned") {
|
|
234
|
+
const runDir = result.runDir;
|
|
235
|
+
const checkpointsDir = join(runDir, "checkpoints");
|
|
236
|
+
const agenticResultsDir = join(runDir, "agentic-results");
|
|
237
|
+
mkdirSync(agenticResultsDir, { recursive: true });
|
|
238
|
+
const planPath = join(runDir, "agentic-plan.json");
|
|
239
|
+
const plan = parseJsonFile(planPath);
|
|
240
|
+
const tasks = isRecord(plan) && Array.isArray(plan.tasks) ? plan.tasks : [];
|
|
241
|
+
const agents = discoverAgents(ctx.cwd, "project");
|
|
242
|
+
const agentsByName = new Map(agents.map((agent) => [agent.name.toLowerCase(), agent]));
|
|
243
|
+
const stageResults: Array<Record<string, unknown>> = [];
|
|
244
|
+
let failed = 0;
|
|
245
|
+
const initialTelemetryPath = join(runDir, "telemetry.json");
|
|
246
|
+
const initialTelemetry = existsSync(initialTelemetryPath) && isRecord(parseJsonFile(initialTelemetryPath)) ? (parseJsonFile(initialTelemetryPath) as Record<string, unknown>) : {};
|
|
247
|
+
const initialItems = isRecord(initialTelemetry.items) ? initialTelemetry.items : {};
|
|
248
|
+
const initialStartedAt = typeof initialTelemetry.startedAt === "string" ? initialTelemetry.startedAt : new Date().toISOString();
|
|
249
|
+
const initialStartedAtMs = Number.isFinite(Date.parse(initialStartedAt)) ? Date.parse(initialStartedAt) : Date.now();
|
|
250
|
+
const selectedItemCount = typeof initialItems.selected === "number" ? initialItems.selected : result.processed + result.failed;
|
|
251
|
+
const initialItemFailed = typeof initialItems.failed === "number" ? initialItems.failed : result.failed;
|
|
252
|
+
const aggregateUsage = usageEmpty();
|
|
253
|
+
const failuresByStage: Record<string, number> = {};
|
|
254
|
+
const incrementStageFailure = (stage: string): void => {
|
|
255
|
+
failuresByStage[stage] = (failuresByStage[stage] ?? 0) + 1;
|
|
256
|
+
};
|
|
257
|
+
const factoryAdaptiveLiveProofEnabled = factoryAdaptiveLiveReadonlyProofEnabled(params as Record<string, unknown>);
|
|
258
|
+
const adaptiveDelegationPolicy = normalizeAdaptiveDelegationPolicy(params.adaptive_delegation);
|
|
259
|
+
const adaptiveRootGoalHash = sha256(`${params.factory}:${params.input_manifest}:${result.runId}`);
|
|
260
|
+
let adaptiveGovernorState = adaptiveDelegationPolicy.enabled ? buildInitialAdaptiveDelegationGovernorState({ runId: result.runId, rootGoalHash: adaptiveRootGoalHash, policy: adaptiveDelegationPolicy }) : undefined;
|
|
261
|
+
const adaptiveRequests: DelegationRequestProposal[] = [];
|
|
262
|
+
const adaptiveDecisions: GovernorDecision[] = [];
|
|
263
|
+
const adaptiveContracts: ParentDispatchContract[] = [];
|
|
264
|
+
const adaptiveDispatchRecords: Array<Record<string, unknown>> = [];
|
|
265
|
+
const adaptiveExtractionErrors: Array<Record<string, unknown>> = [];
|
|
266
|
+
let adaptiveProofAttempted = false;
|
|
267
|
+
let adaptiveProofFailed = false;
|
|
268
|
+
|
|
269
|
+
const strictBudgetGate = evaluateStrictBudgetDispatchGate({
|
|
270
|
+
runId: result.runId,
|
|
271
|
+
mode: params.mode ?? "smoke",
|
|
272
|
+
execution: "agentic",
|
|
273
|
+
taskCount: tasks.length,
|
|
274
|
+
selectedItems: selectedItemCount,
|
|
275
|
+
budget: params.budget,
|
|
276
|
+
});
|
|
277
|
+
factoryLedger(runDir, { event: "strict_budget_dispatch_gate", dispatchDecision: strictBudgetGate.dispatchDecision, budgetEnforced: strictBudgetGate.budgetEnforced, wouldBlockDispatch: strictBudgetGate.wouldBlockDispatch, failures: strictBudgetGate.failures });
|
|
278
|
+
if (strictBudgetGate.wouldBlockDispatch === true) {
|
|
279
|
+
incrementStageFailure("strict_budget");
|
|
280
|
+
const mode = params.mode ?? "smoke";
|
|
281
|
+
const phaseSentinel = mode === "pilot" || mode === "batch" ? factoryPhaseSentinelForMode(mode) : factoryPhaseSentinelForMode("smoke");
|
|
282
|
+
const validationPath = join(runDir, "validation.json");
|
|
283
|
+
const validation = existsSync(validationPath) && isRecord(parseJsonFile(validationPath)) ? (parseJsonFile(validationPath) as Record<string, unknown>) : {};
|
|
284
|
+
const { noMockReady, finalGate } = buildAgenticFactoryNoMockFinalGate({
|
|
285
|
+
status: "blocked_by_budget",
|
|
286
|
+
tasks: tasks.length,
|
|
287
|
+
completed: 0,
|
|
288
|
+
failed: tasks.length,
|
|
289
|
+
liveDispatches: 0,
|
|
290
|
+
mockedDispatches: 0,
|
|
291
|
+
outputContractsValidated: 0,
|
|
292
|
+
childSessionPaths: 0,
|
|
293
|
+
phaseSentinelWritten: false,
|
|
294
|
+
doneSentinelWritten: false,
|
|
295
|
+
});
|
|
296
|
+
const budgetBlockedExecution = {
|
|
297
|
+
schema: "zob.agentic-factory-execution.v1",
|
|
298
|
+
status: "blocked_by_budget",
|
|
299
|
+
tasks: tasks.length,
|
|
300
|
+
completed: 0,
|
|
301
|
+
failed: tasks.length,
|
|
302
|
+
dispatcher: "not_dispatched",
|
|
303
|
+
mocked: false,
|
|
304
|
+
liveDispatches: 0,
|
|
305
|
+
mockedDispatches: 0,
|
|
306
|
+
outputContractsValidated: 0,
|
|
307
|
+
childSessionPaths: 0,
|
|
308
|
+
budgetGate: strictBudgetGate,
|
|
309
|
+
noMockReady,
|
|
310
|
+
finalGate,
|
|
311
|
+
results: [],
|
|
312
|
+
bodyStored: false,
|
|
313
|
+
promptBodiesStored: false,
|
|
314
|
+
outputBodiesStored: false,
|
|
315
|
+
};
|
|
316
|
+
writeFileSync(join(runDir, "agentic-results.json"), JSON.stringify(budgetBlockedExecution, null, 2), "utf8");
|
|
317
|
+
validation.status = "failed";
|
|
318
|
+
validation.budgetGate = strictBudgetGate;
|
|
319
|
+
validation.agenticExecution = { schema: budgetBlockedExecution.schema, status: budgetBlockedExecution.status, tasks: budgetBlockedExecution.tasks, completed: budgetBlockedExecution.completed, failed: budgetBlockedExecution.failed, dispatcher: budgetBlockedExecution.dispatcher, mocked: budgetBlockedExecution.mocked, liveDispatches: 0, mockedDispatches: 0, outputContractsValidated: 0, childSessionPaths: 0, budgetGate: strictBudgetGate, noMockReady, finalGate };
|
|
320
|
+
validation.phaseSentinel = { mode, artifact: phaseSentinel, written: false, validationRequired: true };
|
|
321
|
+
validation.sentinelWritten = false;
|
|
322
|
+
validation.completionArtifactsPresent = ["manifest.json", "ledger.jsonl", "agentic-plan.json", "final-report.md", phaseSentinel, "DONE.sentinel"].map((artifact) => ({ artifact, exists: existsSync(join(runDir, artifact)) }));
|
|
323
|
+
writeFileSync(validationPath, JSON.stringify(validation, null, 2), "utf8");
|
|
324
|
+
writeFileSync(join(runDir, "final-report.md"), [`# Factory Run Report`, ``, `- runId: ${result.runId}`, `- factory: ${params.factory}`, `- status: failed`, `- execution: agentic`, `- agentic_tasks: ${tasks.length}`, `- agentic_completed: 0`, `- agentic_failed: ${tasks.length}`, `- live_dispatches: 0`, `- mocked_dispatches: 0`, `- strict_budget_gate: blocked`, `- phase_sentinel: not written`, `- sentinel: not written`, ``].join("\n"), "utf8");
|
|
325
|
+
factoryLedger(runDir, { event: "strict_budget_dispatch_blocked", dispatchDecision: strictBudgetGate.dispatchDecision, failures: strictBudgetGate.failures, liveDispatches: 0 });
|
|
326
|
+
const blockedArtifacts = [...new Set([...result.artifacts, "agentic-results.json", "telemetry.json"])];
|
|
327
|
+
result = { ...result, status: "agentic_failed", failed: tasks.length, artifacts: blockedArtifacts, errors: ["Strict budget dispatch gate blocked live child dispatch"] };
|
|
328
|
+
const blockedEndedAtMs = Date.now();
|
|
329
|
+
const expectedArtifacts = Array.isArray(validation.expectedArtifacts) ? validation.expectedArtifacts.filter((artifact): artifact is string => typeof artifact === "string") : [];
|
|
330
|
+
writeFactoryTelemetrySummary(ctx.cwd, {
|
|
331
|
+
runId: result.runId,
|
|
332
|
+
runDir,
|
|
333
|
+
factory: params.factory,
|
|
334
|
+
mode,
|
|
335
|
+
execution: "agentic",
|
|
336
|
+
status: result.status,
|
|
337
|
+
itemCount: selectedItemCount,
|
|
338
|
+
processed: typeof validation.processed === "number" ? validation.processed : result.processed,
|
|
339
|
+
failed: initialItemFailed,
|
|
340
|
+
expectedArtifacts,
|
|
341
|
+
generatedArtifacts: blockedArtifacts.filter((artifact) => artifact !== "telemetry.json"),
|
|
342
|
+
stageCount: isRecord(plan) && typeof plan.stageCount === "number" ? plan.stageCount : 0,
|
|
343
|
+
agenticTasks: tasks.length,
|
|
344
|
+
failuresByStage,
|
|
345
|
+
retryCount: 0,
|
|
346
|
+
usage: aggregateUsage,
|
|
347
|
+
wallTimeMs: blockedEndedAtMs - initialStartedAtMs,
|
|
348
|
+
startedAt: initialStartedAt,
|
|
349
|
+
endedAt: new Date(blockedEndedAtMs).toISOString(),
|
|
350
|
+
errors: result.errors,
|
|
351
|
+
budgetEnforced: true,
|
|
352
|
+
});
|
|
353
|
+
pi.appendEntry("zob-factory-run", {
|
|
354
|
+
runId: result.runId,
|
|
355
|
+
factory: params.factory,
|
|
356
|
+
inputManifest: params.input_manifest,
|
|
357
|
+
mode,
|
|
358
|
+
execution: "agentic",
|
|
359
|
+
status: result.status,
|
|
360
|
+
processed: result.processed,
|
|
361
|
+
failed: result.failed,
|
|
362
|
+
artifacts: result.artifacts,
|
|
363
|
+
errors: result.errors,
|
|
364
|
+
});
|
|
365
|
+
const text = [
|
|
366
|
+
`factory_run ${result.status}: ${result.runId}`,
|
|
367
|
+
`runDir: ${result.runDir}`,
|
|
368
|
+
`execution: agentic`,
|
|
369
|
+
`processed: ${result.processed}`,
|
|
370
|
+
`failed: ${result.failed}`,
|
|
371
|
+
`budget: strict dispatch gate blocked live child dispatch`,
|
|
372
|
+
result.artifacts.length > 0 ? `artifacts:\n- ${result.artifacts.join("\n- ")}` : "artifacts: none",
|
|
373
|
+
result.errors.length > 0 ? `errors:\n- ${result.errors.join("\n- ")}` : "errors: none",
|
|
374
|
+
].join("\n");
|
|
375
|
+
return { content: [{ type: "text", text }], details: result };
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const liveComsErrors = factoryAgenticComsLivePreflightErrors(ctx.cwd, params.execution);
|
|
379
|
+
factoryLedger(runDir, { event: "agentic_coms_live_gate", passed: liveComsErrors.length === 0, errors: liveComsErrors, bodyStored: false });
|
|
380
|
+
if (liveComsErrors.length > 0) {
|
|
381
|
+
incrementStageFailure("zob_coms_live_required");
|
|
382
|
+
const mode = params.mode ?? "smoke";
|
|
383
|
+
const phaseSentinel = mode === "pilot" || mode === "batch" ? factoryPhaseSentinelForMode(mode) : factoryPhaseSentinelForMode("smoke");
|
|
384
|
+
const validationPath = join(runDir, "validation.json");
|
|
385
|
+
const validation = existsSync(validationPath) && isRecord(parseJsonFile(validationPath)) ? (parseJsonFile(validationPath) as Record<string, unknown>) : {};
|
|
386
|
+
const { noMockReady, finalGate } = buildAgenticFactoryNoMockFinalGate({
|
|
387
|
+
status: "blocked_by_coms_live_required",
|
|
388
|
+
tasks: tasks.length,
|
|
389
|
+
completed: 0,
|
|
390
|
+
failed: tasks.length,
|
|
391
|
+
liveDispatches: 0,
|
|
392
|
+
mockedDispatches: 0,
|
|
393
|
+
outputContractsValidated: 0,
|
|
394
|
+
childSessionPaths: 0,
|
|
395
|
+
phaseSentinelWritten: false,
|
|
396
|
+
doneSentinelWritten: false,
|
|
397
|
+
});
|
|
398
|
+
const liveBlockedExecution = {
|
|
399
|
+
schema: "zob.agentic-factory-execution.v1",
|
|
400
|
+
status: "blocked_by_coms_live_required",
|
|
401
|
+
tasks: tasks.length,
|
|
402
|
+
completed: 0,
|
|
403
|
+
failed: tasks.length,
|
|
404
|
+
dispatcher: "not_dispatched",
|
|
405
|
+
mocked: false,
|
|
406
|
+
liveDispatches: 0,
|
|
407
|
+
mockedDispatches: 0,
|
|
408
|
+
outputContractsValidated: 0,
|
|
409
|
+
childSessionPaths: 0,
|
|
410
|
+
budgetGate: strictBudgetGate,
|
|
411
|
+
comsLiveGate: { passed: false, errors: liveComsErrors, bodyStored: false },
|
|
412
|
+
noMockReady,
|
|
413
|
+
finalGate,
|
|
414
|
+
results: [],
|
|
415
|
+
bodyStored: false,
|
|
416
|
+
promptBodiesStored: false,
|
|
417
|
+
outputBodiesStored: false,
|
|
418
|
+
};
|
|
419
|
+
writeFileSync(join(runDir, "agentic-results.json"), JSON.stringify(liveBlockedExecution, null, 2), "utf8");
|
|
420
|
+
validation.status = "failed";
|
|
421
|
+
validation.budgetGate = strictBudgetGate;
|
|
422
|
+
validation.agenticExecution = { schema: liveBlockedExecution.schema, status: liveBlockedExecution.status, tasks: liveBlockedExecution.tasks, completed: liveBlockedExecution.completed, failed: liveBlockedExecution.failed, dispatcher: liveBlockedExecution.dispatcher, mocked: liveBlockedExecution.mocked, liveDispatches: 0, mockedDispatches: 0, outputContractsValidated: 0, childSessionPaths: 0, budgetGate: strictBudgetGate, comsLiveGate: liveBlockedExecution.comsLiveGate, noMockReady, finalGate };
|
|
423
|
+
validation.phaseSentinel = { mode, artifact: phaseSentinel, written: false, validationRequired: true };
|
|
424
|
+
validation.sentinelWritten = false;
|
|
425
|
+
validation.completionArtifactsPresent = ["manifest.json", "ledger.jsonl", "agentic-plan.json", "final-report.md", phaseSentinel, "DONE.sentinel"].map((artifact) => ({ artifact, exists: existsSync(join(runDir, artifact)) }));
|
|
426
|
+
writeFileSync(validationPath, JSON.stringify(validation, null, 2), "utf8");
|
|
427
|
+
writeFileSync(join(runDir, "final-report.md"), [`# Factory Run Report`, ``, `- runId: ${result.runId}`, `- factory: ${params.factory}`, `- status: failed`, `- execution: agentic`, `- agentic_tasks: ${tasks.length}`, `- agentic_completed: 0`, `- agentic_failed: ${tasks.length}`, `- live_dispatches: 0`, `- mocked_dispatches: 0`, `- zob_coms_live_gate: blocked`, `- phase_sentinel: not written`, `- sentinel: not written`, ``].join("\n"), "utf8");
|
|
428
|
+
factoryLedger(runDir, { event: "agentic_coms_live_blocked", errors: liveComsErrors, liveDispatches: 0, bodyStored: false });
|
|
429
|
+
const blockedArtifacts = [...new Set([...result.artifacts, "agentic-results.json", "telemetry.json"])];
|
|
430
|
+
result = { ...result, status: "agentic_failed", failed: tasks.length, artifacts: blockedArtifacts, errors: liveComsErrors };
|
|
431
|
+
const blockedEndedAtMs = Date.now();
|
|
432
|
+
const expectedArtifacts = Array.isArray(validation.expectedArtifacts) ? validation.expectedArtifacts.filter((artifact): artifact is string => typeof artifact === "string") : [];
|
|
433
|
+
writeFactoryTelemetrySummary(ctx.cwd, { runId: result.runId, runDir, factory: params.factory, mode, execution: "agentic", status: result.status, itemCount: selectedItemCount, processed: typeof validation.processed === "number" ? validation.processed : result.processed, failed: initialItemFailed, expectedArtifacts, generatedArtifacts: blockedArtifacts.filter((artifact) => artifact !== "telemetry.json"), stageCount: isRecord(plan) && typeof plan.stageCount === "number" ? plan.stageCount : 0, agenticTasks: tasks.length, failuresByStage, retryCount: 0, usage: aggregateUsage, wallTimeMs: blockedEndedAtMs - initialStartedAtMs, startedAt: initialStartedAt, endedAt: new Date(blockedEndedAtMs).toISOString(), errors: result.errors, budgetEnforced: strictBudgetGate.budgetEnforced === true });
|
|
434
|
+
pi.appendEntry("zob-factory-run", { runId: result.runId, factory: params.factory, inputManifest: params.input_manifest, mode, execution: "agentic", status: result.status, processed: result.processed, failed: result.failed, artifacts: result.artifacts, errors: result.errors });
|
|
435
|
+
const text = [`factory_run ${result.status}: ${result.runId}`, `runDir: ${result.runDir}`, `execution: agentic`, `processed: ${result.processed}`, `failed: ${result.failed}`, `zob_coms_live_gate: blocked`, result.artifacts.length > 0 ? `artifacts:\n- ${result.artifacts.join("\n- ")}` : "artifacts: none", result.errors.length > 0 ? `errors:\n- ${result.errors.join("\n- ")}` : "errors: none"].join("\n");
|
|
436
|
+
return { content: [{ type: "text", text }], details: result };
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
factoryLedger(runDir, { event: "agentic_execution_start", tasks: tasks.length, budgetGate: strictBudgetGate });
|
|
440
|
+
|
|
441
|
+
for (const [index, task] of tasks.entries()) {
|
|
442
|
+
if (!isRecord(task)) {
|
|
443
|
+
failed += 1;
|
|
444
|
+
incrementStageFailure("agentic_plan");
|
|
445
|
+
stageResults.push({ index, status: "failed", errors: ["Invalid task record"] });
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
const agentName = typeof task.agent === "string" ? task.agent : "";
|
|
449
|
+
const agent = agentsByName.get(agentName.toLowerCase());
|
|
450
|
+
const requiredTools = Array.isArray(task.required_tools) ? task.required_tools.filter((tool): tool is string => typeof tool === "string") : [];
|
|
451
|
+
const outputContract = typeof task.output_contract === "string" ? task.output_contract : inferOutputContract(agentName);
|
|
452
|
+
const stageName = typeof task.stage === "string" ? task.stage : `stage-${index + 1}`;
|
|
453
|
+
const itemId = typeof task.itemId === "string" ? task.itemId : "all-items";
|
|
454
|
+
const modelRoute = evaluateModelRoutingDispatchGate({
|
|
455
|
+
runId: result.runId,
|
|
456
|
+
mode: "factory",
|
|
457
|
+
stage: stageName,
|
|
458
|
+
agent: agentName,
|
|
459
|
+
taskType: `${stageName}:${agentName}`,
|
|
460
|
+
outputContract,
|
|
461
|
+
risk: agentName.toLowerCase().includes("oracle") || stageName.toLowerCase().includes("validate") ? "high" : "medium",
|
|
462
|
+
defaultModel: params.model,
|
|
463
|
+
modelRouting: params.model_routing,
|
|
464
|
+
});
|
|
465
|
+
const persistedModelRoute = persistableModelRouting(modelRoute);
|
|
466
|
+
const routedModel = typeof modelRoute.selectedModel === "string" && modelRoute.selectedModel.length > 0 ? modelRoute.selectedModel : params.model;
|
|
467
|
+
const taskErrors = [
|
|
468
|
+
...(agent ? validateToolList(agent, requiredTools) : [`Unknown agent '${agentName}'`]),
|
|
469
|
+
...validateOutputContractId(outputContract),
|
|
470
|
+
];
|
|
471
|
+
if (taskErrors.length > 0 || !agent) {
|
|
472
|
+
failed += 1;
|
|
473
|
+
incrementStageFailure(stageName);
|
|
474
|
+
const failedRecord = { index, stage: stageName, itemId, agent: agentName, status: "failed_preflight", dispatcher: "not_dispatched", mocked: false, outputContractValidated: false, modelRouting: persistedModelRoute, errors: taskErrors, bodyStored: false, promptBodiesStored: false, outputBodiesStored: false };
|
|
475
|
+
stageResults.push(failedRecord);
|
|
476
|
+
writeFileSync(join(agenticResultsDir, `${safeFileStem(stageName)}-${safeFileStem(itemId)}.json`), JSON.stringify(failedRecord, null, 2), "utf8");
|
|
477
|
+
factoryLedger(runDir, { event: "agentic_task_failed_preflight", index, stage: stageName, itemId, errors: taskErrors });
|
|
478
|
+
break;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
const adaptiveEvidenceRefs = [params.input_manifest, `.pi/factories/${params.factory}/factory.json`, "package.json"];
|
|
482
|
+
const structuredTask = [
|
|
483
|
+
`ORIGINAL_USER_ASK: ${state.activeGoal?.originalUserAsk ?? "Factory run"}`,
|
|
484
|
+
`OUTPUT_CONTRACT: ${outputContract}`,
|
|
485
|
+
"",
|
|
486
|
+
`1. TASK: ${String(task.task ?? `Run factory stage ${stageName}`)}`,
|
|
487
|
+
`2. EXPECTED OUTCOME: ${String(task.expected_outcome ?? `Complete ${stageName}`)}`,
|
|
488
|
+
`3. REQUIRED TOOLS: ${requiredTools.join(", ")}`,
|
|
489
|
+
`4. MUST DO:\n${(Array.isArray(task.must_do) ? task.must_do : ["Cite evidence", "Respect sentinels"]).map((item) => ` - ${String(item)}`).join("\n")}`,
|
|
490
|
+
`5. MUST NOT DO:\n${(Array.isArray(task.must_not_do) ? task.must_not_do : ["No secrets", "No destructive commands", "No commits"]).map((item) => ` - ${String(item)}`).join("\n")}`,
|
|
491
|
+
`6. CONTEXT: ${String(task.context ?? `Factory run ${result.runId}, stage ${stageName}`)}`,
|
|
492
|
+
...(factoryAdaptiveLiveProofEnabled && index === 0 ? ["", buildFactoryAdaptiveProposalGuidance({ runId: result.runId, stageName, itemId, evidenceRefs: adaptiveEvidenceRefs })] : []),
|
|
493
|
+
"",
|
|
494
|
+
"FINAL FORMAT:",
|
|
495
|
+
"- result",
|
|
496
|
+
"- evidence",
|
|
497
|
+
"- risks/blockers",
|
|
498
|
+
"- compliance line",
|
|
499
|
+
"- Final line must be exactly: deliverable_delivered: yes",
|
|
500
|
+
].join("\n");
|
|
501
|
+
|
|
502
|
+
onUpdate?.({ content: [{ type: "text", text: `factory_run agentic stage ${index + 1}/${tasks.length}: ${stageName}` }], details: result });
|
|
503
|
+
factoryLedger(runDir, { event: "agentic_task_start", index, stage: stageName, itemId, agent: agent.name, outputContract, modelRouting: persistedModelRoute });
|
|
504
|
+
const structuredTaskHash = sha256(structuredTask);
|
|
505
|
+
const childResult = await runChildAgent(ctx, agent, structuredTask, ctx.cwd, signal, routedModel, requiredTools.join(","), undefined);
|
|
506
|
+
childResult.outputContract = outputContract;
|
|
507
|
+
applyChildGates(childResult, { repoRoot: ctx.cwd });
|
|
508
|
+
addUsage(aggregateUsage, childResult.usage);
|
|
509
|
+
|
|
510
|
+
const childOutputHash = childResult.output ? sha256(childResult.output) : undefined;
|
|
511
|
+
const chronicle = classifyChronicleCompletion({
|
|
512
|
+
kind: "factory",
|
|
513
|
+
runId: `${result.runId}-${stageName}-${itemId}`,
|
|
514
|
+
status: isFailed(childResult) ? "failed_validation" : "complete",
|
|
515
|
+
taskHash: structuredTaskHash,
|
|
516
|
+
outputHash: childOutputHash,
|
|
517
|
+
evidencePaths: [childResult.sessionPath].filter((path): path is string => typeof path === "string"),
|
|
518
|
+
assistantTurnSeen: childResult.usage.turns > 0 || childResult.output.trim().length > 0,
|
|
519
|
+
outputCaptured: Boolean(childOutputHash),
|
|
520
|
+
outputValidated: childResult.gatePassed === true,
|
|
521
|
+
evidenceChecked: childResult.gatePassed === true && outputHasEvidenceMarker(childResult.output),
|
|
522
|
+
preflightPassed: true,
|
|
523
|
+
budget: { advisory: strictBudgetGate.budgetEnforced !== true, enforced: strictBudgetGate.budgetEnforced === true },
|
|
524
|
+
errors: childResult.gateErrors ?? [],
|
|
525
|
+
});
|
|
526
|
+
const chronicleFailed = isRecord(chronicle) && (chronicle.complete !== true || chronicle.terminalFailure === true || (isRecord(chronicle.falseDoneGuard) && chronicle.falseDoneGuard.passed !== true));
|
|
527
|
+
const recordStatus = isFailed(childResult) || chronicleFailed ? "failed" : "complete";
|
|
528
|
+
const record = {
|
|
529
|
+
index,
|
|
530
|
+
stage: stageName,
|
|
531
|
+
itemId,
|
|
532
|
+
agent: agent.name,
|
|
533
|
+
status: recordStatus,
|
|
534
|
+
dispatcher: "live_child_pi",
|
|
535
|
+
mocked: false,
|
|
536
|
+
outputContract,
|
|
537
|
+
outputContractValidated: childResult.gatePassed === true,
|
|
538
|
+
modelRouting: persistedModelRoute,
|
|
539
|
+
gatePassed: childResult.gatePassed,
|
|
540
|
+
gateErrors: childResult.gateErrors ?? [],
|
|
541
|
+
budget: { advisory: strictBudgetGate.budgetEnforced !== true, enforced: strictBudgetGate.budgetEnforced === true, dispatchDecision: strictBudgetGate.dispatchDecision },
|
|
542
|
+
exitCode: childResult.exitCode,
|
|
543
|
+
stopReason: childResult.stopReason,
|
|
544
|
+
sessionPath: childResult.sessionPath,
|
|
545
|
+
taskHash: structuredTaskHash,
|
|
546
|
+
outputHash: childOutputHash,
|
|
547
|
+
chronicle,
|
|
548
|
+
usage: childResult.usage,
|
|
549
|
+
bodyStored: false,
|
|
550
|
+
promptBodiesStored: false,
|
|
551
|
+
outputBodiesStored: false,
|
|
552
|
+
};
|
|
553
|
+
stageResults.push(record);
|
|
554
|
+
writeFileSync(join(agenticResultsDir, `${safeFileStem(stageName)}-${safeFileStem(itemId)}.json`), JSON.stringify(record, null, 2), "utf8");
|
|
555
|
+
writeFileSync(join(checkpointsDir, `${safeFileStem(stageName)}-${safeFileStem(itemId)}.agentic.checkpoint.json`), JSON.stringify(record, null, 2), "utf8");
|
|
556
|
+
factoryLedger(runDir, { event: "agentic_task_end", ...record });
|
|
557
|
+
|
|
558
|
+
if (factoryAdaptiveLiveProofEnabled && !adaptiveProofAttempted && recordStatus === "complete") {
|
|
559
|
+
adaptiveProofAttempted = true;
|
|
560
|
+
const extraction = extractDelegationRequestsFromText(childResult.output);
|
|
561
|
+
adaptiveExtractionErrors.push(...extraction.errors.map((error) => ({ sourceStage: stageName, errorHash: sha256(error), bodyStored: false, promptBodiesStored: false, outputBodiesStored: false })));
|
|
562
|
+
const rawRequest = extraction.requests[0];
|
|
563
|
+
const parentRequest: DelegationRequestProposal | undefined = rawRequest ? {
|
|
564
|
+
...rawRequest,
|
|
565
|
+
requesterRole: `factory:${stageName}`,
|
|
566
|
+
referentRole: "factory-runner",
|
|
567
|
+
requesterDepth: 1,
|
|
568
|
+
targetDepth: 2,
|
|
569
|
+
requiredTools: rawRequest.requiredTools.filter((tool) => ["read", "grep", "find", "ls"].includes(tool)),
|
|
570
|
+
evidenceRefs: rawRequest.evidenceRefs.length > 0 ? rawRequest.evidenceRefs : adaptiveEvidenceRefs,
|
|
571
|
+
targetFileSet: rawRequest.targetFileSet && rawRequest.targetFileSet.length > 0 ? rawRequest.targetFileSet : adaptiveEvidenceRefs,
|
|
572
|
+
bodyStored: false,
|
|
573
|
+
promptBodiesStored: false,
|
|
574
|
+
outputBodiesStored: false,
|
|
575
|
+
} : undefined;
|
|
576
|
+
if (parentRequest && adaptiveGovernorState) {
|
|
577
|
+
adaptiveRequests.push(parentRequest);
|
|
578
|
+
const decision = decideDelegationRequest({ repoRoot: ctx.cwd, runId: result.runId, rootGoalHash: adaptiveRootGoalHash, parentTaskId: `${stageName}:${itemId}`, request: parentRequest, policy: adaptiveDelegationPolicy });
|
|
579
|
+
adaptiveDecisions.push(decision);
|
|
580
|
+
adaptiveGovernorState = updateGovernorState(adaptiveGovernorState, decision);
|
|
581
|
+
const contract = buildParentDispatchContractForDecision({ runId: result.runId, parentTaskId: `${stageName}:${itemId}`, request: parentRequest, decision, dispatchGate: "factory_live_readonly_proof" });
|
|
582
|
+
if (decision.dispatchAllowed === true && contract) {
|
|
583
|
+
adaptiveContracts.push(contract);
|
|
584
|
+
const adaptiveAgent = agentsByName.get(parentRequest.requestedAgent.toLowerCase());
|
|
585
|
+
const adaptiveTaskText = buildFactoryAdaptiveReadonlyTaskText({ requestId: decision.parentAssignedRequestId, request: parentRequest, runId: result.runId });
|
|
586
|
+
const adaptiveTaskHash = sha256(adaptiveTaskText);
|
|
587
|
+
if (!adaptiveAgent) {
|
|
588
|
+
adaptiveProofFailed = true;
|
|
589
|
+
incrementStageFailure("factory_adaptive_dispatch");
|
|
590
|
+
adaptiveDispatchRecords.push({ ...contract, status: "failed", liveDispatched: false, mocked: false, dispatcherKind: "not_dispatched", taskHash: adaptiveTaskHash, errorsHash: sha256("unknown adaptive agent"), bodyStored: false, promptBodiesStored: false, outputBodiesStored: false });
|
|
591
|
+
} else {
|
|
592
|
+
factoryLedger(runDir, { event: "factory_adaptive_task_start", requestId: decision.parentAssignedRequestId, agent: adaptiveAgent.name, outputContract: parentRequest.requestedOutputContract, taskHash: adaptiveTaskHash });
|
|
593
|
+
const adaptiveChildResult = await runChildAgent(ctx, adaptiveAgent, adaptiveTaskText, ctx.cwd, signal, routedModel, parentRequest.requiredTools.join(","), undefined);
|
|
594
|
+
adaptiveChildResult.outputContract = parentRequest.requestedOutputContract;
|
|
595
|
+
applyChildGates(adaptiveChildResult, { repoRoot: ctx.cwd });
|
|
596
|
+
addUsage(aggregateUsage, adaptiveChildResult.usage);
|
|
597
|
+
const adaptiveOutputHash = adaptiveChildResult.output ? sha256(adaptiveChildResult.output) : undefined;
|
|
598
|
+
const adaptiveComplete = !isFailed(adaptiveChildResult) && adaptiveChildResult.gatePassed === true;
|
|
599
|
+
if (!adaptiveComplete) {
|
|
600
|
+
adaptiveProofFailed = true;
|
|
601
|
+
incrementStageFailure("factory_adaptive_dispatch");
|
|
602
|
+
}
|
|
603
|
+
const dispatchRecord = {
|
|
604
|
+
...contract,
|
|
605
|
+
status: adaptiveComplete ? "completed" : "failed",
|
|
606
|
+
liveDispatched: true,
|
|
607
|
+
mocked: false,
|
|
608
|
+
dispatcherKind: "live_child_pi",
|
|
609
|
+
outputHash: adaptiveOutputHash,
|
|
610
|
+
outputContractValidated: adaptiveChildResult.gatePassed === true,
|
|
611
|
+
sessionPath: adaptiveChildResult.sessionPath,
|
|
612
|
+
gateErrorsHash: sha256((adaptiveChildResult.gateErrors ?? []).join("\n")),
|
|
613
|
+
usageHash: sha256(JSON.stringify(adaptiveChildResult.usage ?? {})),
|
|
614
|
+
bodyStored: false,
|
|
615
|
+
promptBodiesStored: false,
|
|
616
|
+
outputBodiesStored: false,
|
|
617
|
+
};
|
|
618
|
+
adaptiveDispatchRecords.push(dispatchRecord);
|
|
619
|
+
factoryLedger(runDir, { event: "factory_adaptive_task_end", requestId: decision.parentAssignedRequestId, status: dispatchRecord.status, outputHash: adaptiveOutputHash, outputContractValidated: adaptiveChildResult.gatePassed === true, sessionPath: adaptiveChildResult.sessionPath });
|
|
620
|
+
}
|
|
621
|
+
} else {
|
|
622
|
+
adaptiveProofFailed = true;
|
|
623
|
+
incrementStageFailure("factory_adaptive_dispatch");
|
|
624
|
+
adaptiveDispatchRecords.push({ ...(contract ?? { requestId: decision.parentAssignedRequestId }), status: "blocked", liveDispatched: false, mocked: false, dispatcherKind: "not_dispatched", dispatchAllowed: decision.dispatchAllowed, errorsHash: sha256(decision.reasons.join("\n")), bodyStored: false, promptBodiesStored: false, outputBodiesStored: false });
|
|
625
|
+
}
|
|
626
|
+
} else {
|
|
627
|
+
adaptiveProofFailed = true;
|
|
628
|
+
incrementStageFailure("factory_adaptive_dispatch");
|
|
629
|
+
adaptiveExtractionErrors.push({ sourceStage: stageName, errorHash: sha256("missing adaptive delegation request proposal"), bodyStored: false, promptBodiesStored: false, outputBodiesStored: false });
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
if (recordStatus !== "complete") {
|
|
634
|
+
failed += 1;
|
|
635
|
+
incrementStageFailure(stageName);
|
|
636
|
+
break;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
if (factoryAdaptiveLiveProofEnabled && (!adaptiveProofAttempted || adaptiveProofFailed || adaptiveDispatchRecords.length === 0)) failed += 1;
|
|
640
|
+
|
|
641
|
+
const agenticExecutionStatus = failed === 0 && tasks.length > 0 && stageResults.length === tasks.length ? "passed" : "failed";
|
|
642
|
+
const agenticCompleted = stageResults.filter((stage) => stage.status === "complete").length;
|
|
643
|
+
const validationPath = join(runDir, "validation.json");
|
|
644
|
+
const validation = existsSync(validationPath) && isRecord(parseJsonFile(validationPath)) ? (parseJsonFile(validationPath) as Record<string, unknown>) : {};
|
|
645
|
+
validation.status = agenticExecutionStatus === "passed" ? "passed" : "failed";
|
|
646
|
+
const mode = params.mode ?? "smoke";
|
|
647
|
+
const phaseSentinel = mode === "pilot" || mode === "batch" ? factoryPhaseSentinelForMode(mode) : factoryPhaseSentinelForMode("smoke");
|
|
648
|
+
|
|
649
|
+
if (agenticExecutionStatus === "passed") {
|
|
650
|
+
writeFileSync(join(runDir, phaseSentinel), `${mode} agentic passed ${new Date().toISOString()}\n`, "utf8");
|
|
651
|
+
writeFileSync(join(runDir, "DONE.sentinel"), `done ${new Date().toISOString()}\n`, "utf8");
|
|
652
|
+
if (Array.isArray(validation.requiredStagesPresent)) {
|
|
653
|
+
validation.requiredStagesPresent = validation.requiredStagesPresent.map((stage) => isRecord(stage) && (stage.stage === "sentinel" || stage.stage === "phase_sentinel") ? { ...stage, present: true } : stage);
|
|
654
|
+
}
|
|
655
|
+
factoryLedger(runDir, { event: "phase_sentinel", mode, execution: "agentic", sentinel: phaseSentinel, after: "agentic_validation" });
|
|
656
|
+
factoryLedger(runDir, { event: "done", execution: "agentic", sentinel: "DONE.sentinel" });
|
|
657
|
+
result = { ...result, status: "done", artifacts: [...new Set([...result.artifacts, "agentic-results.json", phaseSentinel, "DONE.sentinel"])] };
|
|
658
|
+
} else {
|
|
659
|
+
if (existsSync(join(runDir, phaseSentinel))) unlinkSync(join(runDir, phaseSentinel));
|
|
660
|
+
if (existsSync(join(runDir, "DONE.sentinel"))) unlinkSync(join(runDir, "DONE.sentinel"));
|
|
661
|
+
factoryLedger(runDir, { event: "agentic_execution_failed", failed });
|
|
662
|
+
result = { ...result, status: "agentic_failed", failed, artifacts: [...new Set([...result.artifacts, "agentic-results.json"])], errors: ["Agentic factory execution failed"] };
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
const liveDispatches = stageResults.filter((stage) => stage.dispatcher === "live_child_pi").length;
|
|
666
|
+
const mockedDispatches = stageResults.filter((stage) => stage.mocked === true).length;
|
|
667
|
+
const outputContractsValidated = stageResults.filter((stage) => stage.outputContractValidated === true).length;
|
|
668
|
+
const childSessionPaths = stageResults.filter((stage) => typeof stage.sessionPath === "string" && stage.sessionPath.length > 0).length;
|
|
669
|
+
const modelRoutedStages = stageResults.filter((stage) => isRecord(stage.modelRouting) && stage.modelRouting.routingApplied === true).length;
|
|
670
|
+
const modelRouterUsed = modelRoutedStages > 0;
|
|
671
|
+
const modelRoutingSummary = {
|
|
672
|
+
enabled: params.model_routing?.enabled === true,
|
|
673
|
+
modelRouterUsed,
|
|
674
|
+
routingApplied: modelRouterUsed,
|
|
675
|
+
routedStages: modelRoutedStages,
|
|
676
|
+
totalStages: stageResults.length,
|
|
677
|
+
selectedModelClasses: [...new Set(stageResults.map((stage) => isRecord(stage.modelRouting) ? stage.modelRouting.selectedModelClass : undefined).filter((value): value is string => typeof value === "string"))].sort(),
|
|
678
|
+
selectedModelStored: false,
|
|
679
|
+
bodyStored: false,
|
|
680
|
+
promptBodiesStored: false,
|
|
681
|
+
outputBodiesStored: false,
|
|
682
|
+
};
|
|
683
|
+
const { noMockReady, finalGate } = buildAgenticFactoryNoMockFinalGate({
|
|
684
|
+
status: agenticExecutionStatus,
|
|
685
|
+
tasks: tasks.length,
|
|
686
|
+
completed: agenticCompleted,
|
|
687
|
+
failed,
|
|
688
|
+
liveDispatches,
|
|
689
|
+
mockedDispatches,
|
|
690
|
+
outputContractsValidated,
|
|
691
|
+
childSessionPaths,
|
|
692
|
+
phaseSentinelWritten: existsSync(join(runDir, phaseSentinel)),
|
|
693
|
+
doneSentinelWritten: existsSync(join(runDir, "DONE.sentinel")),
|
|
694
|
+
});
|
|
695
|
+
const agenticExecution = {
|
|
696
|
+
schema: "zob.agentic-factory-execution.v1",
|
|
697
|
+
status: agenticExecutionStatus,
|
|
698
|
+
tasks: tasks.length,
|
|
699
|
+
completed: agenticCompleted,
|
|
700
|
+
failed,
|
|
701
|
+
dispatcher: liveDispatches > 0 && mockedDispatches === 0 ? "live_child_pi" : "not_live",
|
|
702
|
+
mocked: mockedDispatches > 0,
|
|
703
|
+
liveDispatches,
|
|
704
|
+
mockedDispatches,
|
|
705
|
+
outputContractsValidated,
|
|
706
|
+
childSessionPaths,
|
|
707
|
+
noMockReady,
|
|
708
|
+
finalGate,
|
|
709
|
+
modelRouting: modelRoutingSummary,
|
|
710
|
+
budgetGate: strictBudgetGate,
|
|
711
|
+
budgetEnforced: strictBudgetGate.budgetEnforced === true,
|
|
712
|
+
results: stageResults,
|
|
713
|
+
bodyStored: false,
|
|
714
|
+
promptBodiesStored: false,
|
|
715
|
+
outputBodiesStored: false,
|
|
716
|
+
};
|
|
717
|
+
if (adaptiveGovernorState && adaptiveDelegationPolicy.enabled) {
|
|
718
|
+
writeFileSync(join(runDir, "delegation-requests.json"), JSON.stringify({ schema: "zob.delegation-request-set.v1", runId: result.runId, mode: adaptiveDelegationPolicy.mode, dispatch: adaptiveDelegationPolicy.dispatch, requests: adaptiveRequests, extractionErrors: adaptiveExtractionErrors, bodyStored: false, promptBodiesStored: false, outputBodiesStored: false }, null, 2), "utf8");
|
|
719
|
+
writeFileSync(join(runDir, "delegation-decisions.json"), JSON.stringify({ schema: "zob.governor-decision-set.v1", runId: result.runId, decisions: adaptiveDecisions, bodyStored: false, promptBodiesStored: false, outputBodiesStored: false }, null, 2), "utf8");
|
|
720
|
+
writeFileSync(join(runDir, "delegation-governor-state.json"), JSON.stringify(adaptiveGovernorState, null, 2), "utf8");
|
|
721
|
+
writeFileSync(join(runDir, "delegation-dispatches.json"), JSON.stringify({ schema: "zob.parent-dispatch-contract-set.v1", runId: result.runId, dispatches: adaptiveDispatchRecords, dispatchContractsQueued: adaptiveContracts.length, liveDispatches: adaptiveDispatchRecords.filter((record) => record.liveDispatched === true).length, completed: adaptiveDispatchRecords.filter((record) => record.status === "completed").length, failed: adaptiveDispatchRecords.filter((record) => record.status === "failed").length, mockedDispatches: adaptiveDispatchRecords.filter((record) => record.mocked === true).length, liveChildPiDispatches: adaptiveDispatchRecords.filter((record) => record.dispatcherKind === "live_child_pi").length, adaptiveLiveDispatchEnabled: factoryAdaptiveLiveProofEnabled, liveFactoryAdaptiveDispatchEnabled: factoryAdaptiveLiveProofEnabled, requestedLiveFactoryAdaptiveDispatch: adaptiveDelegationPolicy.dispatch === true, bodyStored: false, promptBodiesStored: false, outputBodiesStored: false }, null, 2), "utf8");
|
|
722
|
+
}
|
|
723
|
+
writeFileSync(join(runDir, "agentic-results.json"), JSON.stringify(agenticExecution, null, 2), "utf8");
|
|
724
|
+
validation.budgetGate = strictBudgetGate;
|
|
725
|
+
validation.agenticExecution = { schema: agenticExecution.schema, status: agenticExecution.status, tasks: agenticExecution.tasks, completed: agenticExecution.completed, failed: agenticExecution.failed, dispatcher: agenticExecution.dispatcher, mocked: agenticExecution.mocked, liveDispatches, mockedDispatches, outputContractsValidated, childSessionPaths, budgetGate: strictBudgetGate, budgetEnforced: strictBudgetGate.budgetEnforced === true, modelRouting: modelRoutingSummary, noMockReady, finalGate };
|
|
726
|
+
if (isRecord(validation.adaptiveDelegation) && adaptiveDelegationPolicy.enabled) {
|
|
727
|
+
validation.adaptiveDelegation = {
|
|
728
|
+
...validation.adaptiveDelegation,
|
|
729
|
+
factoryIntegration: factoryAdaptiveLiveProofEnabled ? "p8_live_readonly_factory_adaptive_proof" : validation.adaptiveDelegation.factoryIntegration,
|
|
730
|
+
advisoryOnly: factoryAdaptiveLiveProofEnabled ? false : validation.adaptiveDelegation.advisoryOnly,
|
|
731
|
+
requestedLiveFactoryAdaptiveDispatch: adaptiveDelegationPolicy.dispatch === true,
|
|
732
|
+
adaptiveLiveDispatchEnabled: factoryAdaptiveLiveProofEnabled,
|
|
733
|
+
liveFactoryAdaptiveDispatchEnabled: factoryAdaptiveLiveProofEnabled,
|
|
734
|
+
noExecution: !factoryAdaptiveLiveProofEnabled,
|
|
735
|
+
requests: adaptiveRequests.length,
|
|
736
|
+
decisions: adaptiveDecisions.length,
|
|
737
|
+
dispatchContractsQueued: adaptiveContracts.length,
|
|
738
|
+
adaptiveDispatchesExecuted: adaptiveDispatchRecords.filter((record) => record.liveDispatched === true).length,
|
|
739
|
+
adaptiveDispatchesCompleted: adaptiveDispatchRecords.filter((record) => record.status === "completed").length,
|
|
740
|
+
adaptiveDispatchesFailed: adaptiveDispatchRecords.filter((record) => record.status === "failed").length,
|
|
741
|
+
adaptiveDispatchesMocked: adaptiveDispatchRecords.filter((record) => record.mocked === true).length,
|
|
742
|
+
adaptiveLiveChildPiDispatches: adaptiveDispatchRecords.filter((record) => record.dispatcherKind === "live_child_pi").length,
|
|
743
|
+
extractionErrors: adaptiveExtractionErrors.length,
|
|
744
|
+
bodyStored: false,
|
|
745
|
+
promptBodiesStored: false,
|
|
746
|
+
outputBodiesStored: false,
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
validation.phaseSentinel = { mode, artifact: phaseSentinel, written: existsSync(join(runDir, phaseSentinel)), validationRequired: true };
|
|
750
|
+
validation.sentinelWritten = existsSync(join(runDir, "DONE.sentinel"));
|
|
751
|
+
validation.completionArtifactsPresent = ["manifest.json", "ledger.jsonl", "agentic-plan.json", "final-report.md", phaseSentinel, "DONE.sentinel"].map((artifact) => ({ artifact, exists: existsSync(join(runDir, artifact)) }));
|
|
752
|
+
writeFileSync(validationPath, JSON.stringify(validation, null, 2), "utf8");
|
|
753
|
+
writeFileSync(join(runDir, "final-report.md"), [`# Factory Run Report`, ``, `- runId: ${result.runId}`, `- factory: ${params.factory}`, `- status: ${validation.status}`, `- execution: agentic`, `- agentic_tasks: ${agenticExecution.tasks}`, `- agentic_completed: ${agenticExecution.completed}`, `- agentic_failed: ${agenticExecution.failed}`, `- live_dispatches: ${liveDispatches}`, `- mocked_dispatches: ${mockedDispatches}`, `- strict_budget_gate: ${strictBudgetGate.budgetEnforced === true ? String(strictBudgetGate.dispatchDecision) : "advisory"}`, `- no_mock_readiness: ${noMockReady ? "passed" : "failed"}`, `- no_mock_reason: ${String(finalGate.reason)}`, `- phase_sentinel: ${existsSync(join(runDir, phaseSentinel)) ? phaseSentinel : "not written"}`, `- sentinel: ${existsSync(join(runDir, "DONE.sentinel")) ? "DONE.sentinel" : "not written"}`, ``].join("\n"), "utf8");
|
|
754
|
+
|
|
755
|
+
if (agenticExecution.status === "failed" && Object.keys(failuresByStage).length === 0) failuresByStage.agentic_execution = 1;
|
|
756
|
+
const expectedArtifacts = Array.isArray(validation.expectedArtifacts) ? validation.expectedArtifacts.filter((artifact): artifact is string => typeof artifact === "string") : [];
|
|
757
|
+
const generatedArtifacts = [...new Set(result.artifacts.filter((artifact) => artifact !== "telemetry.json"))];
|
|
758
|
+
const agenticEndedAtMs = Date.now();
|
|
759
|
+
writeFactoryTelemetrySummary(ctx.cwd, {
|
|
760
|
+
runId: result.runId,
|
|
761
|
+
runDir,
|
|
762
|
+
factory: params.factory,
|
|
763
|
+
mode: params.mode ?? "smoke",
|
|
764
|
+
execution: "agentic",
|
|
765
|
+
status: result.status,
|
|
766
|
+
itemCount: selectedItemCount,
|
|
767
|
+
processed: typeof validation.processed === "number" ? validation.processed : result.processed,
|
|
768
|
+
failed: initialItemFailed,
|
|
769
|
+
expectedArtifacts,
|
|
770
|
+
generatedArtifacts,
|
|
771
|
+
stageCount: isRecord(plan) && typeof plan.stageCount === "number" ? plan.stageCount : 0,
|
|
772
|
+
agenticTasks: tasks.length,
|
|
773
|
+
failuresByStage,
|
|
774
|
+
retryCount: 0,
|
|
775
|
+
usage: aggregateUsage,
|
|
776
|
+
wallTimeMs: agenticEndedAtMs - initialStartedAtMs,
|
|
777
|
+
startedAt: initialStartedAt,
|
|
778
|
+
endedAt: new Date(agenticEndedAtMs).toISOString(),
|
|
779
|
+
errors: result.errors,
|
|
780
|
+
budgetEnforced: strictBudgetGate.budgetEnforced === true,
|
|
781
|
+
modelRouterUsed,
|
|
782
|
+
});
|
|
783
|
+
result = { ...result, artifacts: [...new Set([...result.artifacts, "telemetry.json"])] };
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
pi.appendEntry("zob-factory-run", {
|
|
787
|
+
runId: result.runId,
|
|
788
|
+
factory: params.factory,
|
|
789
|
+
inputManifest: params.input_manifest,
|
|
790
|
+
mode: params.mode ?? "smoke",
|
|
791
|
+
execution: params.execution ?? "deterministic",
|
|
792
|
+
status: result.status,
|
|
793
|
+
processed: result.processed,
|
|
794
|
+
failed: result.failed,
|
|
795
|
+
artifacts: result.artifacts,
|
|
796
|
+
errors: result.errors,
|
|
797
|
+
});
|
|
798
|
+
const text = [
|
|
799
|
+
`factory_run ${result.status}: ${result.runId}`,
|
|
800
|
+
`runDir: ${result.runDir}`,
|
|
801
|
+
`execution: ${params.execution ?? "deterministic"}`,
|
|
802
|
+
`processed: ${result.processed}`,
|
|
803
|
+
`failed: ${result.failed}`,
|
|
804
|
+
result.artifacts.length > 0 ? `artifacts:\n- ${result.artifacts.join("\n- ")}` : "artifacts: none",
|
|
805
|
+
result.errors.length > 0 ? `errors:\n- ${result.errors.join("\n- ")}` : "errors: none",
|
|
806
|
+
].join("\n");
|
|
807
|
+
return { content: [{ type: "text", text }], details: result };
|
|
808
|
+
},
|
|
809
|
+
});
|
|
810
|
+
}
|