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,778 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
import { buildAutonomousRuntimeDryRun, validateAutonomousReadOnlySmokeRunArtifacts, validateAutonomousRuntimeDryRunArtifacts } from "./autonomous-runtime.js";
|
|
5
|
+
import { buildCapabilityIndex } from "./capabilities.js";
|
|
6
|
+
import { buildContextGbrainReadinessAudit } from "./context-gbrain.js";
|
|
7
|
+
import { loadFactoryDefinition, loadFactoryInputManifest, validateFactoryStages } from "./factory/validation.js";
|
|
8
|
+
import { validateStrictGoalSpecAnchor } from "./goal.js";
|
|
9
|
+
import { validateDelegationWriteScope } from "./safety.js";
|
|
10
|
+
import { sha256 } from "./utils/hashing.js";
|
|
11
|
+
import { parseJsonFile } from "./utils/json.js";
|
|
12
|
+
import { safeFileStem } from "./utils/paths.js";
|
|
13
|
+
import { isRecord } from "./utils/records.js";
|
|
14
|
+
|
|
15
|
+
export interface AutonomyReadinessAuditInput {
|
|
16
|
+
run_id?: string;
|
|
17
|
+
autonomous_dry_run_id?: string;
|
|
18
|
+
autonomous_readonly_smoke_run_id?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface FactoryRegistryReadinessInput {
|
|
22
|
+
run_id?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const FORBIDDEN_BODY_KEYS = new Set(["task", "prompt", "output", "body", "content", "patch", "diff"]);
|
|
26
|
+
|
|
27
|
+
const REGISTERED_FACTORY_CHAIN = {
|
|
28
|
+
smoke: "registered-agentic-factory-proof-smoke-v28",
|
|
29
|
+
pilot: "registered-agentic-factory-proof-pilot-v24",
|
|
30
|
+
batch: "registered-agentic-factory-proof-batch-v22",
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const REGISTERED_FACTORY_CURRENT_CHAIN_LOG = "reports/harness-registered-agentic-factory-current-chain-post-autonomous-p0-v28.log";
|
|
34
|
+
const RUN_ID_COLLATOR = new Intl.Collator("en", { numeric: true, sensitivity: "base" });
|
|
35
|
+
|
|
36
|
+
const REGISTERED_FACTORY_SOURCE_FINGERPRINT_BASE_FILES = [
|
|
37
|
+
"package.json",
|
|
38
|
+
"scripts/run-registered-agentic-factory-proof.mjs",
|
|
39
|
+
"scripts/verify-agentic-factory-proof.mjs",
|
|
40
|
+
"scripts/audit-agentic-factory-promotion.mjs",
|
|
41
|
+
"scripts/audit-agentic-factory-batch-promotion.mjs",
|
|
42
|
+
".pi/budget-policy.json",
|
|
43
|
+
".pi/model-routing.json",
|
|
44
|
+
".pi/extensions/zob-harness/index.ts",
|
|
45
|
+
".pi/extensions/zob-harness/src/runtime/tools-factory.ts",
|
|
46
|
+
".pi/extensions/zob-harness/src/budget-policy.ts",
|
|
47
|
+
".pi/extensions/zob-harness/src/model-routing.ts",
|
|
48
|
+
".pi/extensions/zob-harness/src/schemas.ts",
|
|
49
|
+
".pi/extensions/zob-harness/src/types.ts",
|
|
50
|
+
".pi/extensions/zob-harness/src/telemetry.ts",
|
|
51
|
+
".pi/extensions/zob-harness/src/factory/run.ts",
|
|
52
|
+
".pi/extensions/zob-harness/src/factory/agentic-plan.ts",
|
|
53
|
+
".pi/extensions/zob-harness/src/factory/validation.ts",
|
|
54
|
+
".pi/extensions/zob-harness/src/child-runner.ts",
|
|
55
|
+
".pi/extensions/zob-harness/src/output-contracts.ts",
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
function uniqueSorted(items: string[]): string[] {
|
|
59
|
+
return [...new Set(items)].sort();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function listRepoFilesUnder(repoRoot: string, relativeDir: string, predicate: (file: string) => boolean = () => true): string[] {
|
|
63
|
+
const absoluteDir = join(repoRoot, relativeDir);
|
|
64
|
+
if (!existsSync(absoluteDir)) return [];
|
|
65
|
+
const results: string[] = [];
|
|
66
|
+
const visit = (relativePath: string): void => {
|
|
67
|
+
for (const entry of readdirSync(join(repoRoot, relativePath))) {
|
|
68
|
+
const childRelative = `${relativePath}/${entry}`;
|
|
69
|
+
const childStat = statSync(join(repoRoot, childRelative));
|
|
70
|
+
if (childStat.isDirectory()) visit(childRelative);
|
|
71
|
+
else if (childStat.isFile() && predicate(childRelative)) results.push(childRelative);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
visit(relativeDir);
|
|
75
|
+
return results;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function registeredFactoryManifestModes(mode: "smoke" | "pilot" | "batch"): Array<"smoke" | "pilot" | "batch"> {
|
|
79
|
+
if (mode === "smoke") return ["smoke"];
|
|
80
|
+
if (mode === "pilot") return ["smoke", "pilot"];
|
|
81
|
+
return ["smoke", "pilot", "batch"];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function registeredFactorySourceFingerprintFiles(repoRoot: string, factoryName: string, mode: "smoke" | "pilot" | "batch"): string[] | undefined {
|
|
85
|
+
const factoryJsonPath = `.pi/factories/${factoryName}/factory.json`;
|
|
86
|
+
const factoryPath = join(repoRoot, factoryJsonPath);
|
|
87
|
+
if (!existsSync(factoryPath)) return undefined;
|
|
88
|
+
const definition = readRecord(factoryPath);
|
|
89
|
+
const stages = Array.isArray(definition?.stages) ? definition.stages.filter(isRecord) : [];
|
|
90
|
+
const stageFiles = stages.flatMap((stage) => [
|
|
91
|
+
typeof stage.agent === "string" ? `.pi/agents/${stage.agent}.md` : undefined,
|
|
92
|
+
typeof stage.outputContract === "string" ? `.pi/output-contracts/${stage.outputContract}.json` : undefined,
|
|
93
|
+
]).filter((item): item is string => typeof item === "string");
|
|
94
|
+
const manifestFiles = registeredFactoryManifestModes(mode).map((manifestMode) => `.pi/factories/${factoryName}/${manifestMode}-manifest.json`);
|
|
95
|
+
const extensionSourceFiles = listRepoFilesUnder(repoRoot, ".pi/extensions/zob-harness/src", (file) => file.endsWith(".ts"));
|
|
96
|
+
return uniqueSorted([...REGISTERED_FACTORY_SOURCE_FINGERPRINT_BASE_FILES, ...extensionSourceFiles, factoryJsonPath, ...manifestFiles, ...stageFiles]);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function registeredFactoryCurrentFileHashes(repoRoot: string, factoryName: string, mode: "smoke" | "pilot" | "batch"): Record<string, string> | undefined {
|
|
100
|
+
const files = registeredFactorySourceFingerprintFiles(repoRoot, factoryName, mode);
|
|
101
|
+
if (!files) return undefined;
|
|
102
|
+
const hashes: Record<string, string> = {};
|
|
103
|
+
for (const file of files) {
|
|
104
|
+
const absolute = join(repoRoot, file);
|
|
105
|
+
if (!existsSync(absolute)) return undefined;
|
|
106
|
+
hashes[file] = sha256(readFileSync(absolute, "utf8"));
|
|
107
|
+
}
|
|
108
|
+
return hashes;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function parseJsonRecordDetail(value: unknown): Record<string, unknown> | undefined {
|
|
112
|
+
if (isRecord(value)) return value;
|
|
113
|
+
if (typeof value !== "string") return undefined;
|
|
114
|
+
try {
|
|
115
|
+
const parsed = JSON.parse(value);
|
|
116
|
+
return isRecord(parsed) ? parsed : undefined;
|
|
117
|
+
} catch {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function registeredInvocationFreshSource(invocation: Record<string, unknown> | undefined, mode: "smoke" | "pilot" | "batch"): boolean {
|
|
123
|
+
if (!invocation || invocation.schema !== "zob.registered-agentic-factory-proof-invocation.v1") return false;
|
|
124
|
+
if (invocation.mode !== mode || invocation.execution !== "agentic") return false;
|
|
125
|
+
const factoryName = typeof invocation.factory === "string" ? invocation.factory : undefined;
|
|
126
|
+
const sourceFingerprint = isRecord(invocation.sourceFingerprint) ? invocation.sourceFingerprint : undefined;
|
|
127
|
+
const storedFileHashes = isRecord(sourceFingerprint?.fileHashes) ? sourceFingerprint.fileHashes : undefined;
|
|
128
|
+
const storedHash = typeof sourceFingerprint?.fingerprintHash === "string" ? sourceFingerprint.fingerprintHash : undefined;
|
|
129
|
+
if (!factoryName || sourceFingerprint?.schema !== "zob.registered-agentic-factory-source-fingerprint.v1" || sourceFingerprint.algorithm !== "sha256" || sourceFingerprint.factory !== factoryName || sourceFingerprint.mode !== mode || !storedFileHashes || !storedHash) return false;
|
|
130
|
+
if (Object.values(storedFileHashes).some((hash) => typeof hash !== "string" || !/^[a-f0-9]{64}$/.test(hash))) return false;
|
|
131
|
+
return storedHash === sha256(JSON.stringify(storedFileHashes));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function stringHashRecord(value: unknown): Record<string, string> | undefined {
|
|
135
|
+
if (!isRecord(value)) return undefined;
|
|
136
|
+
const entries = Object.entries(value);
|
|
137
|
+
if (entries.some(([, hash]) => typeof hash !== "string" || !/^[a-f0-9]{64}$/.test(hash))) return undefined;
|
|
138
|
+
return Object.fromEntries(entries) as Record<string, string>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function hashRecordsEqual(left: Record<string, string> | undefined, right: Record<string, string> | undefined): boolean {
|
|
142
|
+
if (!left || !right) return false;
|
|
143
|
+
const leftKeys = Object.keys(left).sort();
|
|
144
|
+
const rightKeys = Object.keys(right).sort();
|
|
145
|
+
return JSON.stringify(leftKeys) === JSON.stringify(rightKeys) && leftKeys.every((key) => left[key] === right[key]);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function registeredFreshSourceProofPassed(repoRoot: string, runId: string, verification: Record<string, unknown> | undefined, invocation: Record<string, unknown> | undefined, mode: "smoke" | "pilot" | "batch"): boolean {
|
|
149
|
+
if (!registeredInvocationFreshSource(invocation, mode)) return false;
|
|
150
|
+
if (invocation?.runId !== runId || invocation.bodyStored !== false || invocation.promptBodiesStored !== false || invocation.outputBodiesStored !== false) return false;
|
|
151
|
+
const factoryName = typeof invocation.factory === "string" ? invocation.factory : undefined;
|
|
152
|
+
const sourceFingerprint = isRecord(invocation.sourceFingerprint) ? invocation.sourceFingerprint : undefined;
|
|
153
|
+
const storedFileHashes = stringHashRecord(sourceFingerprint?.fileHashes);
|
|
154
|
+
const currentFileHashes = factoryName ? registeredFactoryCurrentFileHashes(repoRoot, factoryName, mode) : undefined;
|
|
155
|
+
const fingerprintHash = typeof sourceFingerprint?.fingerprintHash === "string" ? sourceFingerprint.fingerprintHash : undefined;
|
|
156
|
+
const currentFingerprintHash = currentFileHashes ? sha256(JSON.stringify(currentFileHashes)) : undefined;
|
|
157
|
+
const checks = Array.isArray(verification?.checks) ? verification.checks.filter(isRecord) : [];
|
|
158
|
+
const freshSource = checks.find((item) => item.name === "registered_tool_invocation_fresh_source");
|
|
159
|
+
const detail = parseJsonRecordDetail(freshSource?.detail);
|
|
160
|
+
return verification?.verdict === "PASS"
|
|
161
|
+
&& verification.no_ship === false
|
|
162
|
+
&& Array.isArray(verification.failedChecks)
|
|
163
|
+
&& verification.failedChecks.length === 0
|
|
164
|
+
&& freshSource?.passed === true
|
|
165
|
+
&& detail?.runId === runId
|
|
166
|
+
&& detail.status === "done"
|
|
167
|
+
&& detail.fingerprintHash === fingerprintHash
|
|
168
|
+
&& detail.expectedFingerprintHash === currentFingerprintHash
|
|
169
|
+
&& fingerprintHash === currentFingerprintHash
|
|
170
|
+
&& hashRecordsEqual(storedFileHashes, currentFileHashes);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function registeredChainLogPassed(path: string, requiredRunIds: string[]): boolean {
|
|
174
|
+
if (!existsSync(path)) return false;
|
|
175
|
+
try {
|
|
176
|
+
const text = readFileSync(path, "utf8");
|
|
177
|
+
return requiredRunIds.every((runId) => text.includes(runId)) && (text.includes("ALL_CHAINS_DONE") || text.includes("ALL_15_VERIFIED"));
|
|
178
|
+
} catch {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function hasForbiddenBodyKeys(value: unknown): boolean {
|
|
184
|
+
if (!value || typeof value !== "object") return false;
|
|
185
|
+
if (Array.isArray(value)) return value.some(hasForbiddenBodyKeys);
|
|
186
|
+
return Object.entries(value as Record<string, unknown>).some(([key, child]) => FORBIDDEN_BODY_KEYS.has(key) || hasForbiddenBodyKeys(child));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function readRecord(path: string): Record<string, unknown> | undefined {
|
|
190
|
+
if (!existsSync(path)) return undefined;
|
|
191
|
+
try {
|
|
192
|
+
const parsed = parseJsonFile(path);
|
|
193
|
+
return isRecord(parsed) ? parsed : undefined;
|
|
194
|
+
} catch {
|
|
195
|
+
return undefined;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function artifact(path: string): Record<string, unknown> {
|
|
200
|
+
if (!existsSync(path)) return { path, present: false };
|
|
201
|
+
return { path, present: true, hash: sha256(readFileSync(path, "utf8")) };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function check(name: string, passed: boolean, detail: Record<string, unknown> = {}): Record<string, unknown> {
|
|
205
|
+
return { name, passed, detail };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function verificationPassed(repoRoot: string, runId: string, mode: "smoke" | "pilot" | "batch"): Record<string, unknown> {
|
|
209
|
+
const runDir = join(repoRoot, "reports", "factory-runs", runId);
|
|
210
|
+
const verificationPath = join(runDir, "agentic-factory-proof-verification.json");
|
|
211
|
+
const validationPath = join(runDir, "validation.json");
|
|
212
|
+
const invocationPath = join(runDir, "registered-agentic-factory-proof-invocation.json");
|
|
213
|
+
const verification = readRecord(verificationPath);
|
|
214
|
+
const validation = readRecord(validationPath);
|
|
215
|
+
const invocation = readRecord(invocationPath);
|
|
216
|
+
const checks = Array.isArray(verification?.checks) ? verification.checks.filter(isRecord) : [];
|
|
217
|
+
const freshSource = checks.find((item) => item.name === "registered_tool_invocation_fresh_source");
|
|
218
|
+
const currentFreshSource = registeredFreshSourceProofPassed(repoRoot, runId, verification, invocation, mode);
|
|
219
|
+
const agenticExecution = isRecord(validation?.agenticExecution) ? validation.agenticExecution : undefined;
|
|
220
|
+
const finalGate = isRecord(agenticExecution?.finalGate) ? agenticExecution.finalGate : undefined;
|
|
221
|
+
return {
|
|
222
|
+
runId,
|
|
223
|
+
mode,
|
|
224
|
+
verification: artifact(verificationPath),
|
|
225
|
+
validation: artifact(validationPath),
|
|
226
|
+
invocation: artifact(invocationPath),
|
|
227
|
+
passed: verification?.verdict === "PASS"
|
|
228
|
+
&& verification.no_ship === false
|
|
229
|
+
&& Array.isArray(verification.failedChecks)
|
|
230
|
+
&& verification.failedChecks.length === 0
|
|
231
|
+
&& validation?.status === "passed"
|
|
232
|
+
&& validation.mode === mode
|
|
233
|
+
&& validation.execution === "agentic"
|
|
234
|
+
&& agenticExecution?.dispatcher === "live_child_pi"
|
|
235
|
+
&& agenticExecution.mocked === false
|
|
236
|
+
&& agenticExecution.mockedDispatches === 0
|
|
237
|
+
&& agenticExecution.noMockReady === true
|
|
238
|
+
&& finalGate?.passed === true
|
|
239
|
+
&& finalGate.no_ship === false
|
|
240
|
+
&& freshSource?.passed === true
|
|
241
|
+
&& currentFreshSource === true
|
|
242
|
+
&& invocation?.bodyStored === false
|
|
243
|
+
&& invocation.promptBodiesStored === false
|
|
244
|
+
&& invocation.outputBodiesStored === false,
|
|
245
|
+
liveDispatches: agenticExecution?.liveDispatches,
|
|
246
|
+
mockedDispatches: agenticExecution?.mockedDispatches,
|
|
247
|
+
contractsValidated: agenticExecution?.outputContractsValidated,
|
|
248
|
+
childSessionPaths: agenticExecution?.childSessionPaths,
|
|
249
|
+
freshSourcePassed: freshSource?.passed === true,
|
|
250
|
+
currentFreshSourcePassed: currentFreshSource,
|
|
251
|
+
phaseSentinel: validation?.phaseSentinel,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function exactFailedChecks(value: unknown, expected: string[]): boolean {
|
|
256
|
+
return Array.isArray(value)
|
|
257
|
+
&& value.every((item) => typeof item === "string")
|
|
258
|
+
&& JSON.stringify([...value].sort()) === JSON.stringify([...expected].sort());
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function runRecordTimestamp(run: Record<string, unknown>): number {
|
|
262
|
+
if (typeof run.verificationGeneratedAt === "string") {
|
|
263
|
+
const parsed = Date.parse(run.verificationGeneratedAt);
|
|
264
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
265
|
+
}
|
|
266
|
+
return 0;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function compareRunRecords(left: Record<string, unknown>, right: Record<string, unknown>): number {
|
|
270
|
+
const leftTimestamp = runRecordTimestamp(left);
|
|
271
|
+
const rightTimestamp = runRecordTimestamp(right);
|
|
272
|
+
if (leftTimestamp !== rightTimestamp) return leftTimestamp - rightTimestamp;
|
|
273
|
+
const leftRunId = typeof left.runId === "string" ? left.runId : "";
|
|
274
|
+
const rightRunId = typeof right.runId === "string" ? right.runId : "";
|
|
275
|
+
return RUN_ID_COLLATOR.compare(leftRunId, rightRunId);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function listFactoryNames(repoRoot: string): string[] {
|
|
279
|
+
const dir = join(repoRoot, ".pi", "factories");
|
|
280
|
+
if (!existsSync(dir)) return [];
|
|
281
|
+
return readdirSync(dir).filter((name) => existsSync(join(dir, name, "factory.json"))).sort();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function manifestSummary(repoRoot: string, factoryName: string, mode: "smoke" | "pilot" | "batch"): Record<string, unknown> {
|
|
285
|
+
const relativePath = `.pi/factories/${factoryName}/${mode}-manifest.json`;
|
|
286
|
+
const loaded = loadFactoryInputManifest(repoRoot, relativePath);
|
|
287
|
+
return {
|
|
288
|
+
mode,
|
|
289
|
+
path: relativePath,
|
|
290
|
+
present: existsSync(join(repoRoot, relativePath)),
|
|
291
|
+
valid: loaded.errors.length === 0 && loaded.manifest?.factory === factoryName,
|
|
292
|
+
itemCount: loaded.manifest?.items.length ?? 0,
|
|
293
|
+
errors: loaded.errors,
|
|
294
|
+
manifestHash: existsSync(join(repoRoot, relativePath)) ? sha256(readFileSync(join(repoRoot, relativePath), "utf8")) : undefined,
|
|
295
|
+
bodyStored: false,
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function factoryRunCoverage(repoRoot: string, factoryName: string): Record<string, unknown> {
|
|
300
|
+
const root = join(repoRoot, "reports", "factory-runs");
|
|
301
|
+
const byMode: Record<string, Array<Record<string, unknown>>> = { smoke: [], pilot: [], batch: [] };
|
|
302
|
+
if (existsSync(root)) {
|
|
303
|
+
for (const runId of readdirSync(root).sort(RUN_ID_COLLATOR.compare)) {
|
|
304
|
+
const validationPath = join(root, runId, "validation.json");
|
|
305
|
+
if (!existsSync(validationPath)) continue;
|
|
306
|
+
const validation = readRecord(validationPath);
|
|
307
|
+
if (validation?.factory !== factoryName) continue;
|
|
308
|
+
const mode = typeof validation.mode === "string" ? validation.mode : "unknown";
|
|
309
|
+
if (!Array.isArray(byMode[mode])) continue;
|
|
310
|
+
const verificationPath = join(root, runId, "agentic-factory-proof-verification.json");
|
|
311
|
+
const verification = readRecord(verificationPath);
|
|
312
|
+
const checks = Array.isArray(verification?.checks) ? verification.checks.filter(isRecord) : [];
|
|
313
|
+
const freshSource = checks.find((item) => item.name === "registered_tool_invocation_fresh_source");
|
|
314
|
+
const invocation = readRecord(join(root, runId, "registered-agentic-factory-proof-invocation.json"));
|
|
315
|
+
const currentFreshSource = mode === "smoke" || mode === "pilot" || mode === "batch" ? registeredFreshSourceProofPassed(repoRoot, runId, verification, invocation, mode) : false;
|
|
316
|
+
const agenticExecution = isRecord(validation.agenticExecution) ? validation.agenticExecution : undefined;
|
|
317
|
+
const finalGate = isRecord(agenticExecution?.finalGate) ? agenticExecution.finalGate : undefined;
|
|
318
|
+
const budgetGate = isRecord(agenticExecution?.budgetGate) ? agenticExecution.budgetGate : isRecord(validation.budgetGate) ? validation.budgetGate : undefined;
|
|
319
|
+
const modelRouting = isRecord(agenticExecution?.modelRouting) ? agenticExecution.modelRouting : undefined;
|
|
320
|
+
const phaseSentinel = isRecord(validation.phaseSentinel) ? validation.phaseSentinel : undefined;
|
|
321
|
+
const pilotGate = isRecord(validation.pilotGate) ? validation.pilotGate : undefined;
|
|
322
|
+
const batchGate = isRecord(validation.batchGate) ? validation.batchGate : undefined;
|
|
323
|
+
const prerequisiteRunId = mode === "pilot" && typeof pilotGate?.smokeRunId === "string" ? pilotGate.smokeRunId : mode === "batch" && typeof batchGate?.pilotRunId === "string" ? batchGate.pilotRunId : undefined;
|
|
324
|
+
const phaseArtifact = typeof phaseSentinel?.artifact === "string" ? phaseSentinel.artifact : mode === "smoke" ? "SMOKE_PASSED.sentinel" : mode === "pilot" ? "PILOT_PASSED.sentinel" : mode === "batch" ? "BATCH_PASSED.sentinel" : undefined;
|
|
325
|
+
const entry = {
|
|
326
|
+
runId,
|
|
327
|
+
mode,
|
|
328
|
+
prerequisiteRunId,
|
|
329
|
+
verificationGeneratedAt: typeof verification?.generatedAt === "string" ? verification.generatedAt : undefined,
|
|
330
|
+
execution: validation.execution,
|
|
331
|
+
status: validation.status,
|
|
332
|
+
passed: validation.status === "passed" && validation.sentinelWritten === true && phaseSentinel?.written === true,
|
|
333
|
+
agentic: validation.execution === "agentic",
|
|
334
|
+
noMockReady: agenticExecution?.noMockReady === true && finalGate?.passed === true && finalGate.no_ship === false,
|
|
335
|
+
registeredFreshSource: freshSource?.passed === true && currentFreshSource === true,
|
|
336
|
+
storedRegisteredFreshSource: freshSource?.passed === true,
|
|
337
|
+
currentRegisteredFreshSource: currentFreshSource,
|
|
338
|
+
verificationPassed: verification?.verdict === "PASS" && verification.no_ship === false && Array.isArray(verification.failedChecks) && verification.failedChecks.length === 0,
|
|
339
|
+
strictBudgetEnforced: budgetGate?.schema === "zob.strict-budget-dispatch-gate.v1" && budgetGate.strictEnabled === true && budgetGate.budgetEnforced === true && budgetGate.passed === true && budgetGate.dispatchDecision === "allow_strict" && budgetGate.wouldBlockDispatch === false && budgetGate.childDispatchAllowed === true && agenticExecution?.budgetEnforced === true,
|
|
340
|
+
modelRoutingApplied: modelRouting?.enabled === true && modelRouting.modelRouterUsed === true && modelRouting.routingApplied === true && modelRouting.routedStages === agenticExecution?.tasks && modelRouting.totalStages === agenticExecution?.tasks && modelRouting.selectedModelStored === false,
|
|
341
|
+
phaseSentinel: phaseArtifact,
|
|
342
|
+
phaseSentinelPresent: typeof phaseArtifact === "string" && existsSync(join(root, runId, phaseArtifact)),
|
|
343
|
+
doneSentinelPresent: existsSync(join(root, runId, "DONE.sentinel")),
|
|
344
|
+
bodyStored: false,
|
|
345
|
+
};
|
|
346
|
+
byMode[mode].push(entry);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
const latestByMode = Object.fromEntries(Object.entries(byMode).map(([mode, runs]) => [mode, [...runs].sort(compareRunRecords).at(-1)]));
|
|
350
|
+
const registeredProofReady = (run: unknown): boolean => isRecord(run)
|
|
351
|
+
&& run.passed === true
|
|
352
|
+
&& run.agentic === true
|
|
353
|
+
&& run.noMockReady === true
|
|
354
|
+
&& run.registeredFreshSource === true
|
|
355
|
+
&& run.verificationPassed === true
|
|
356
|
+
&& run.phaseSentinelPresent === true
|
|
357
|
+
&& run.doneSentinelPresent === true;
|
|
358
|
+
const strictRoutingProofReady = (run: unknown): boolean => registeredProofReady(run)
|
|
359
|
+
&& isRecord(run)
|
|
360
|
+
&& run.strictBudgetEnforced === true
|
|
361
|
+
&& run.modelRoutingApplied === true;
|
|
362
|
+
const runById = new Map<string, Record<string, unknown>>();
|
|
363
|
+
for (const run of Object.values(byMode).flat()) {
|
|
364
|
+
if (typeof run.runId === "string") runById.set(run.runId, run);
|
|
365
|
+
}
|
|
366
|
+
let linkedRegisteredChain: { smoke: Record<string, unknown>; pilot: Record<string, unknown>; batch: Record<string, unknown> } | undefined;
|
|
367
|
+
let linkedStrictRoutingChain: { smoke: Record<string, unknown>; pilot: Record<string, unknown>; batch: Record<string, unknown> } | undefined;
|
|
368
|
+
for (const batch of [...byMode.batch].sort(compareRunRecords).reverse()) {
|
|
369
|
+
const pilotRunId = typeof batch.prerequisiteRunId === "string" ? batch.prerequisiteRunId : undefined;
|
|
370
|
+
const pilot = pilotRunId ? runById.get(pilotRunId) : undefined;
|
|
371
|
+
const smokeRunId = typeof pilot?.prerequisiteRunId === "string" ? pilot.prerequisiteRunId : undefined;
|
|
372
|
+
const smoke = smokeRunId ? runById.get(smokeRunId) : undefined;
|
|
373
|
+
if (smoke && pilot && strictRoutingProofReady(smoke) && strictRoutingProofReady(pilot) && strictRoutingProofReady(batch)) {
|
|
374
|
+
linkedStrictRoutingChain = { smoke, pilot, batch };
|
|
375
|
+
linkedRegisteredChain = linkedRegisteredChain ?? { smoke, pilot, batch };
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
if (!linkedRegisteredChain && smoke && pilot && registeredProofReady(smoke) && registeredProofReady(pilot) && registeredProofReady(batch)) {
|
|
379
|
+
linkedRegisteredChain = { smoke, pilot, batch };
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
const bestByMode = linkedRegisteredChain ? {
|
|
383
|
+
smoke: linkedRegisteredChain.smoke,
|
|
384
|
+
pilot: linkedRegisteredChain.pilot,
|
|
385
|
+
batch: linkedRegisteredChain.batch,
|
|
386
|
+
} : Object.fromEntries(Object.entries(byMode).map(([mode, runs]) => {
|
|
387
|
+
const sortedRuns = [...runs].sort(compareRunRecords);
|
|
388
|
+
const preferred = [...sortedRuns].reverse().find((run) => registeredProofReady(run))
|
|
389
|
+
?? [...sortedRuns].reverse().find((run) => run.passed === true)
|
|
390
|
+
?? sortedRuns.at(-1);
|
|
391
|
+
return [mode, preferred];
|
|
392
|
+
}));
|
|
393
|
+
const bestStrictRoutingByMode = linkedStrictRoutingChain ? {
|
|
394
|
+
smoke: linkedStrictRoutingChain.smoke,
|
|
395
|
+
pilot: linkedStrictRoutingChain.pilot,
|
|
396
|
+
batch: linkedStrictRoutingChain.batch,
|
|
397
|
+
} : Object.fromEntries(Object.entries(byMode).map(([mode, runs]) => {
|
|
398
|
+
const sortedRuns = [...runs].sort(compareRunRecords);
|
|
399
|
+
const preferred = [...sortedRuns].reverse().find((run) => strictRoutingProofReady(run));
|
|
400
|
+
return [mode, preferred];
|
|
401
|
+
}));
|
|
402
|
+
const registeredProofChain = linkedRegisteredChain ? {
|
|
403
|
+
smokeRunId: linkedRegisteredChain.smoke.runId,
|
|
404
|
+
pilotRunId: linkedRegisteredChain.pilot.runId,
|
|
405
|
+
batchRunId: linkedRegisteredChain.batch.runId,
|
|
406
|
+
linked: true,
|
|
407
|
+
durableVerifierFreshSource: true,
|
|
408
|
+
bodyStored: false,
|
|
409
|
+
} : undefined;
|
|
410
|
+
const strictRoutingProofChain = linkedStrictRoutingChain ? {
|
|
411
|
+
smokeRunId: linkedStrictRoutingChain.smoke.runId,
|
|
412
|
+
pilotRunId: linkedStrictRoutingChain.pilot.runId,
|
|
413
|
+
batchRunId: linkedStrictRoutingChain.batch.runId,
|
|
414
|
+
linked: true,
|
|
415
|
+
strictBudgetEnforced: true,
|
|
416
|
+
modelRoutingApplied: true,
|
|
417
|
+
durableVerifierFreshSource: true,
|
|
418
|
+
bodyStored: false,
|
|
419
|
+
} : undefined;
|
|
420
|
+
return { byMode, latestByMode, bestByMode, bestStrictRoutingByMode, registeredProofChain, strictRoutingProofChain };
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
function proofPlanForFactory(factoryName: string, manifests: Record<string, Record<string, unknown>>, readiness: Record<string, unknown>): Record<string, unknown> {
|
|
424
|
+
const requiredModes = ["smoke", "pilot", "batch"];
|
|
425
|
+
const missingManifests = requiredModes.filter((mode) => !isRecord(manifests[mode]) || manifests[mode].valid !== true);
|
|
426
|
+
const missingProofs = [
|
|
427
|
+
...(readiness.registeredSmokeReady === true ? [] : ["registered_current_source_agentic_smoke"]),
|
|
428
|
+
...(readiness.registeredPilotReady === true ? [] : ["registered_current_source_agentic_pilot"]),
|
|
429
|
+
...(readiness.registeredBatchReady === true ? [] : ["registered_current_source_agentic_batch"]),
|
|
430
|
+
];
|
|
431
|
+
const missingStrictRoutingProofs = [
|
|
432
|
+
...(readiness.strictRoutingSmokeReady === true ? [] : ["strict_budget_model_routing_agentic_smoke"]),
|
|
433
|
+
...(readiness.strictRoutingPilotReady === true ? [] : ["strict_budget_model_routing_agentic_pilot"]),
|
|
434
|
+
...(readiness.strictRoutingBatchReady === true ? [] : ["strict_budget_model_routing_agentic_batch"]),
|
|
435
|
+
];
|
|
436
|
+
const completeForRegisteredPath = readiness.registeredAgenticBatchReady === true;
|
|
437
|
+
return {
|
|
438
|
+
factory: factoryName,
|
|
439
|
+
completeForRegisteredPath,
|
|
440
|
+
completeForStrictBudgetModelRoutingPath: readiness.strictBudgetModelRoutingAgenticBatchReady === true,
|
|
441
|
+
arbitraryAutonomyReady: false,
|
|
442
|
+
nextProofMode: completeForRegisteredPath ? "none_single_path_ready" : missingManifests.includes("smoke") || missingProofs.includes("registered_current_source_agentic_smoke") ? "smoke" : missingManifests.includes("pilot") || missingProofs.includes("registered_current_source_agentic_pilot") ? "pilot" : "batch",
|
|
443
|
+
missingManifests,
|
|
444
|
+
missingProofs: completeForRegisteredPath ? [] : missingProofs,
|
|
445
|
+
missingStrictBudgetModelRoutingProofs: readiness.strictBudgetModelRoutingAgenticBatchReady === true ? [] : missingStrictRoutingProofs,
|
|
446
|
+
requiredEvidence: [
|
|
447
|
+
"registered factory_run invocation through tool entrypoint",
|
|
448
|
+
"agentic-factory-proof-verification PASS/no_ship=false",
|
|
449
|
+
"registered_tool_invocation_fresh_source passed",
|
|
450
|
+
"persisted oracle review PASS/no_ship=false before promotion",
|
|
451
|
+
"phase sentinel and DONE.sentinel",
|
|
452
|
+
"body-free/hash-only child result metadata",
|
|
453
|
+
"strict_budget_enforced_allow_gate verifier check for strict-routing scope",
|
|
454
|
+
"live_model_routing_applied verifier check for strict-routing scope",
|
|
455
|
+
],
|
|
456
|
+
noShipUntilComplete: !completeForRegisteredPath,
|
|
457
|
+
bodyStored: false,
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
function buildFactoryRegistryReadiness(repoRoot: string): Record<string, unknown> {
|
|
462
|
+
const factories = listFactoryNames(repoRoot).map((factoryName) => {
|
|
463
|
+
const loaded = loadFactoryDefinition(repoRoot, factoryName);
|
|
464
|
+
const definition = loaded.definition;
|
|
465
|
+
const stageErrors = validateFactoryStages(repoRoot, definition);
|
|
466
|
+
const stages = definition?.stages ?? [];
|
|
467
|
+
const manifests = {
|
|
468
|
+
smoke: manifestSummary(repoRoot, factoryName, "smoke"),
|
|
469
|
+
pilot: manifestSummary(repoRoot, factoryName, "pilot"),
|
|
470
|
+
batch: manifestSummary(repoRoot, factoryName, "batch"),
|
|
471
|
+
};
|
|
472
|
+
const coverage = factoryRunCoverage(repoRoot, factoryName);
|
|
473
|
+
const bestByMode = isRecord(coverage.bestByMode) ? coverage.bestByMode : {};
|
|
474
|
+
const bestStrictRoutingByMode = isRecord(coverage.bestStrictRoutingByMode) ? coverage.bestStrictRoutingByMode : {};
|
|
475
|
+
const smokeReady = isRecord(bestByMode.smoke) && bestByMode.smoke.passed === true;
|
|
476
|
+
const pilotReady = isRecord(bestByMode.pilot) && bestByMode.pilot.passed === true;
|
|
477
|
+
const batchReady = isRecord(bestByMode.batch) && bestByMode.batch.passed === true;
|
|
478
|
+
const registeredProofReady = (run: unknown): boolean => isRecord(run)
|
|
479
|
+
&& run.passed === true
|
|
480
|
+
&& run.agentic === true
|
|
481
|
+
&& run.noMockReady === true
|
|
482
|
+
&& run.registeredFreshSource === true
|
|
483
|
+
&& run.verificationPassed === true
|
|
484
|
+
&& run.phaseSentinelPresent === true
|
|
485
|
+
&& run.doneSentinelPresent === true;
|
|
486
|
+
const strictRoutingProofReady = (run: unknown): boolean => registeredProofReady(run)
|
|
487
|
+
&& isRecord(run)
|
|
488
|
+
&& run.strictBudgetEnforced === true
|
|
489
|
+
&& run.modelRoutingApplied === true;
|
|
490
|
+
const registeredSmokeReady = registeredProofReady(bestByMode.smoke);
|
|
491
|
+
const registeredPilotReady = registeredProofReady(bestByMode.pilot);
|
|
492
|
+
const registeredBatchReady = registeredProofReady(bestByMode.batch);
|
|
493
|
+
const registeredAgenticBatchReady = registeredSmokeReady && registeredPilotReady && registeredBatchReady;
|
|
494
|
+
const strictRoutingSmokeReady = strictRoutingProofReady(bestStrictRoutingByMode.smoke);
|
|
495
|
+
const strictRoutingPilotReady = strictRoutingProofReady(bestStrictRoutingByMode.pilot);
|
|
496
|
+
const strictRoutingBatchReady = strictRoutingProofReady(bestStrictRoutingByMode.batch);
|
|
497
|
+
const strictBudgetModelRoutingAgenticBatchReady = strictRoutingSmokeReady && strictRoutingPilotReady && strictRoutingBatchReady;
|
|
498
|
+
const readiness = {
|
|
499
|
+
smokeValidated: smokeReady,
|
|
500
|
+
pilotValidated: pilotReady,
|
|
501
|
+
batchValidated: batchReady,
|
|
502
|
+
registeredSmokeReady,
|
|
503
|
+
registeredPilotReady,
|
|
504
|
+
registeredBatchReady,
|
|
505
|
+
registeredAgenticBatchReady,
|
|
506
|
+
strictRoutingSmokeReady,
|
|
507
|
+
strictRoutingPilotReady,
|
|
508
|
+
strictRoutingBatchReady,
|
|
509
|
+
strictBudgetModelRoutingAgenticBatchReady,
|
|
510
|
+
arbitraryAutonomyReady: false,
|
|
511
|
+
noShipReason: strictBudgetModelRoutingAgenticBatchReady ? "registered factory path proven with strict budget and live model routing; arbitrary autonomy still requires full registry proof matrix" : registeredAgenticBatchReady ? "registered factory path proven without strict budget/model-routing proof for all phases" : "missing registered current-source smoke/pilot/batch proof chain",
|
|
512
|
+
};
|
|
513
|
+
return {
|
|
514
|
+
name: factoryName,
|
|
515
|
+
definition: {
|
|
516
|
+
path: `.pi/factories/${factoryName}/factory.json`,
|
|
517
|
+
valid: loaded.errors.length === 0 && stageErrors.length === 0,
|
|
518
|
+
errors: [...loaded.errors, ...stageErrors],
|
|
519
|
+
definitionHash: existsSync(join(repoRoot, ".pi", "factories", factoryName, "factory.json")) ? sha256(readFileSync(join(repoRoot, ".pi", "factories", factoryName, "factory.json"), "utf8")) : undefined,
|
|
520
|
+
descriptionHash: definition?.description ? sha256(definition.description) : undefined,
|
|
521
|
+
stageCount: stages.length,
|
|
522
|
+
stageAgents: [...new Set(stages.map((stage) => stage.agent))].sort(),
|
|
523
|
+
outputContracts: [...new Set(stages.map((stage) => stage.outputContract))].sort(),
|
|
524
|
+
},
|
|
525
|
+
manifests,
|
|
526
|
+
coverage,
|
|
527
|
+
readiness,
|
|
528
|
+
proofPlan: proofPlanForFactory(factoryName, manifests, readiness),
|
|
529
|
+
bodyStored: false,
|
|
530
|
+
};
|
|
531
|
+
});
|
|
532
|
+
const missingRegisteredBatchProof = factories.filter((factory) => !isRecord(factory.readiness) || factory.readiness.registeredAgenticBatchReady !== true).map((factory) => factory.name);
|
|
533
|
+
const missingStrictRoutingBatchProof = factories.filter((factory) => !isRecord(factory.readiness) || factory.readiness.strictBudgetModelRoutingAgenticBatchReady !== true).map((factory) => factory.name);
|
|
534
|
+
const unproven = missingRegisteredBatchProof;
|
|
535
|
+
const arbitraryAutonomyUnproven = factories.filter((factory) => !isRecord(factory.readiness) || factory.readiness.arbitraryAutonomyReady !== true).map((factory) => factory.name);
|
|
536
|
+
const registeredMatrixComplete = missingRegisteredBatchProof.length === 0;
|
|
537
|
+
const strictBudgetModelRoutingMatrixComplete = missingStrictRoutingBatchProof.length === 0;
|
|
538
|
+
return {
|
|
539
|
+
schema: "zob.factory-registry-readiness.v1",
|
|
540
|
+
factoryCount: factories.length,
|
|
541
|
+
factories,
|
|
542
|
+
registryIndexed: factories.length > 0,
|
|
543
|
+
registeredAgenticBatchReadyFactories: factories.filter((factory) => isRecord(factory.readiness) && factory.readiness.registeredAgenticBatchReady === true).map((factory) => factory.name),
|
|
544
|
+
strictBudgetModelRoutingAgenticBatchReadyFactories: factories.filter((factory) => isRecord(factory.readiness) && factory.readiness.strictBudgetModelRoutingAgenticBatchReady === true).map((factory) => factory.name),
|
|
545
|
+
strictBudgetModelRoutingMatrixComplete,
|
|
546
|
+
arbitraryFactoryAutonomyReady: false,
|
|
547
|
+
arbitraryFactoryNoShip: true,
|
|
548
|
+
unprovenFactories: unproven,
|
|
549
|
+
arbitraryAutonomyUnprovenFactories: arbitraryAutonomyUnproven,
|
|
550
|
+
factoriesMissingRegisteredBatchProof: missingRegisteredBatchProof,
|
|
551
|
+
factoriesMissingStrictBudgetModelRoutingProof: missingStrictRoutingBatchProof,
|
|
552
|
+
proofPlan: factories.map((factory) => factory.proofPlan),
|
|
553
|
+
blockers: [
|
|
554
|
+
...(registeredMatrixComplete ? [] : [
|
|
555
|
+
"not_all_factories_have_registered_current_source_agentic_smoke_pilot_batch_proofs",
|
|
556
|
+
"registered_batch_proof_matrix_incomplete_for_all_factories",
|
|
557
|
+
]),
|
|
558
|
+
...(strictBudgetModelRoutingMatrixComplete ? [] : [
|
|
559
|
+
"not_all_factories_have_strict_budget_model_routing_smoke_pilot_batch_proofs",
|
|
560
|
+
"strict_budget_model_routing_proof_matrix_incomplete_for_all_factories",
|
|
561
|
+
]),
|
|
562
|
+
"arbitrary_factory_autonomy_requires_spec_context_and_factory_selection_gate",
|
|
563
|
+
"factory_specific_oracle_reviews_required_for_new_or_unproven_paths",
|
|
564
|
+
],
|
|
565
|
+
noExecution: true,
|
|
566
|
+
childDispatchAllowed: false,
|
|
567
|
+
daemonStarted: false,
|
|
568
|
+
networkAccessed: false,
|
|
569
|
+
productionWritesPerformed: false,
|
|
570
|
+
autoApply: false,
|
|
571
|
+
bodyStored: false,
|
|
572
|
+
promptBodiesStored: false,
|
|
573
|
+
outputBodiesStored: false,
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
export function buildFactoryRegistryReadinessAudit(repoRoot: string, input: FactoryRegistryReadinessInput = {}): Record<string, unknown> {
|
|
578
|
+
const report = {
|
|
579
|
+
...buildFactoryRegistryReadiness(repoRoot),
|
|
580
|
+
runId: input.run_id,
|
|
581
|
+
generatedAt: new Date().toISOString(),
|
|
582
|
+
};
|
|
583
|
+
if (hasForbiddenBodyKeys(report)) throw new Error("Factory registry readiness audit would store forbidden body keys");
|
|
584
|
+
return report;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
export function writeFactoryRegistryReadinessAuditReport(repoRoot: string, runId = "factory-registry-readiness", input: FactoryRegistryReadinessInput = {}): string {
|
|
588
|
+
const dir = join(repoRoot, "reports");
|
|
589
|
+
mkdirSync(dir, { recursive: true });
|
|
590
|
+
const outputPath = join(dir, `${safeFileStem(runId)}.json`);
|
|
591
|
+
writeFileSync(outputPath, JSON.stringify(buildFactoryRegistryReadinessAudit(repoRoot, { ...input, run_id: runId }), null, 2), "utf8");
|
|
592
|
+
return outputPath;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
export function buildAutonomyReadinessAudit(repoRoot: string, input: AutonomyReadinessAuditInput = {}): Record<string, unknown> {
|
|
596
|
+
const smoke = verificationPassed(repoRoot, REGISTERED_FACTORY_CHAIN.smoke, "smoke");
|
|
597
|
+
const pilot = verificationPassed(repoRoot, REGISTERED_FACTORY_CHAIN.pilot, "pilot");
|
|
598
|
+
const batch = verificationPassed(repoRoot, REGISTERED_FACTORY_CHAIN.batch, "batch");
|
|
599
|
+
const batchOraclePath = join(repoRoot, "reports", "factory-runs", REGISTERED_FACTORY_CHAIN.batch, "oracle-review-pass.json");
|
|
600
|
+
const batchOracle = readRecord(batchOraclePath);
|
|
601
|
+
const currentChainLogPath = join(repoRoot, REGISTERED_FACTORY_CURRENT_CHAIN_LOG);
|
|
602
|
+
const sandboxIsolatedPath = join(repoRoot, "reports", "sandbox-isolated-execution-smoke.json");
|
|
603
|
+
const sandboxDiffReviewPath = join(repoRoot, "reports", "sandbox-diff-review-gate-smoke.json");
|
|
604
|
+
const sandboxApplySimulationPath = join(repoRoot, "reports", "sandbox-apply-simulation-smoke.json");
|
|
605
|
+
const sandboxManualApplyPreflightPath = join(repoRoot, "reports", "sandbox-manual-apply-preflight-smoke.json");
|
|
606
|
+
const modelRoutingPath = join(repoRoot, "reports", "model-routing-readiness-audit-smoke.json");
|
|
607
|
+
const budgetPath = join(repoRoot, "reports", "budget-readiness-audit-smoke.json");
|
|
608
|
+
const daemonPath = join(repoRoot, "reports", "daemon-readiness-smoke.json");
|
|
609
|
+
const daemonPolicyPath = join(repoRoot, "reports", "daemon-policy-readiness-smoke.json");
|
|
610
|
+
const sandboxIsolated = readRecord(sandboxIsolatedPath);
|
|
611
|
+
const sandboxDiffReview = readRecord(sandboxDiffReviewPath);
|
|
612
|
+
const sandboxApplySimulation = readRecord(sandboxApplySimulationPath);
|
|
613
|
+
const sandboxManualApplyPreflight = readRecord(sandboxManualApplyPreflightPath);
|
|
614
|
+
const modelRouting = readRecord(modelRoutingPath);
|
|
615
|
+
const budget = readRecord(budgetPath);
|
|
616
|
+
const daemon = readRecord(daemonPath);
|
|
617
|
+
const daemonPolicy = readRecord(daemonPolicyPath);
|
|
618
|
+
const currentChainLogPassed = registeredChainLogPassed(currentChainLogPath, [REGISTERED_FACTORY_CHAIN.smoke, REGISTERED_FACTORY_CHAIN.pilot, REGISTERED_FACTORY_CHAIN.batch]);
|
|
619
|
+
const capabilities = buildCapabilityIndex(repoRoot);
|
|
620
|
+
const capabilityCounts = isRecord(capabilities.counts) ? capabilities.counts : undefined;
|
|
621
|
+
const capabilityByKind = isRecord(capabilityCounts?.byKind) ? capabilityCounts.byKind : {};
|
|
622
|
+
const factoryRegistry = buildFactoryRegistryReadinessAudit(repoRoot, { run_id: input.run_id ? `${input.run_id}-factory-registry` : undefined });
|
|
623
|
+
const contextGbrain = buildContextGbrainReadinessAudit(repoRoot, { runId: input.run_id ? `${input.run_id}-context-gbrain` : "autonomy-readiness-context-gbrain" });
|
|
624
|
+
const autonomousDryRun = buildAutonomousRuntimeDryRun(repoRoot, {
|
|
625
|
+
runId: input.run_id ? `${input.run_id}-autonomous-dry-run` : "autonomy-readiness-autonomous-dry-run",
|
|
626
|
+
userNeed: "Plan a no-apply autonomous factory dry-run with context citations and oracle gates.",
|
|
627
|
+
acceptanceCriteria: ["context_scope validates", "model routing plan is metadata-only", "factory selection is metadata-only", "smoke/pilot/batch proof plan is present"],
|
|
628
|
+
expectedArtifacts: ["dry-run-report.json", "validation evidence summary"],
|
|
629
|
+
allowedPaths: ["docs/", ".pi/extensions/zob-harness/src/"],
|
|
630
|
+
applyPolicy: "no_apply",
|
|
631
|
+
budgetProfile: "strict_requested",
|
|
632
|
+
risk: "medium",
|
|
633
|
+
});
|
|
634
|
+
const autonomousDryRunArtifactValidation = input.autonomous_dry_run_id ? validateAutonomousRuntimeDryRunArtifacts(repoRoot, input.autonomous_dry_run_id) : undefined;
|
|
635
|
+
const autonomousDryRunArtifactValidatorPassed = isRecord(autonomousDryRunArtifactValidation)
|
|
636
|
+
&& autonomousDryRunArtifactValidation.valid === true
|
|
637
|
+
&& autonomousDryRunArtifactValidation.noExecution === true
|
|
638
|
+
&& autonomousDryRunArtifactValidation.childDispatchAllowed === false
|
|
639
|
+
&& autonomousDryRunArtifactValidation.networkAccessed === false
|
|
640
|
+
&& autonomousDryRunArtifactValidation.globalAutonomyNoShip === true;
|
|
641
|
+
const autonomousReadOnlySmokeValidation = input.autonomous_readonly_smoke_run_id ? validateAutonomousReadOnlySmokeRunArtifacts(repoRoot, input.autonomous_readonly_smoke_run_id) : undefined;
|
|
642
|
+
const autonomousReadOnlySmokeRunDir = input.autonomous_readonly_smoke_run_id ? join(repoRoot, "reports", "autonomous-runs", safeFileStem(input.autonomous_readonly_smoke_run_id)) : undefined;
|
|
643
|
+
const autonomousCompletionGate = autonomousReadOnlySmokeRunDir ? readRecord(join(autonomousReadOnlySmokeRunDir, "completion-gate.json")) : undefined;
|
|
644
|
+
const autonomousFinalNoShipOracle = autonomousReadOnlySmokeRunDir ? readRecord(join(autonomousReadOnlySmokeRunDir, "final-no-ship-oracle.json")) : undefined;
|
|
645
|
+
const autonomousFinalE2EProofPlan = autonomousReadOnlySmokeRunDir ? readRecord(join(autonomousReadOnlySmokeRunDir, "final-e2e-proof-plan.json")) : undefined;
|
|
646
|
+
const autonomousReadOnlySmokeCompletionGatePassed = isRecord(autonomousReadOnlySmokeValidation)
|
|
647
|
+
&& autonomousReadOnlySmokeValidation.valid === true
|
|
648
|
+
&& autonomousReadOnlySmokeValidation.globalAutonomyReady === false
|
|
649
|
+
&& autonomousReadOnlySmokeValidation.globalAutonomyNoShip === true
|
|
650
|
+
&& autonomousReadOnlySmokeValidation.childDispatchAllowed === false
|
|
651
|
+
&& autonomousReadOnlySmokeValidation.productionWritesPerformed === false
|
|
652
|
+
&& autonomousReadOnlySmokeValidation.autoApply === false
|
|
653
|
+
&& autonomousCompletionGate?.schema === "zob.autonomous-completion-gate.v1"
|
|
654
|
+
&& autonomousCompletionGate.status === "blocked_for_goal_completion"
|
|
655
|
+
&& autonomousCompletionGate.updateGoalAllowed === false
|
|
656
|
+
&& autonomousCompletionGate.completionReady === false
|
|
657
|
+
&& autonomousCompletionGate.globalAutonomyReady === false
|
|
658
|
+
&& autonomousCompletionGate.globalAutonomyNoShip === true
|
|
659
|
+
&& isRecord(autonomousCompletionGate.decision)
|
|
660
|
+
&& autonomousCompletionGate.decision.updateGoalStatusCompleteAllowed === false
|
|
661
|
+
&& autonomousCompletionGate.decision.writeGlobalReadySentinelAllowed === false
|
|
662
|
+
&& autonomousFinalNoShipOracle?.schema === "zob.autonomous-final-no-ship-oracle.v1"
|
|
663
|
+
&& autonomousFinalNoShipOracle.verdict === "FAIL"
|
|
664
|
+
&& autonomousFinalNoShipOracle.no_ship === true
|
|
665
|
+
&& autonomousFinalNoShipOracle.globalAutonomyReady === false
|
|
666
|
+
&& autonomousFinalNoShipOracle.globalAutonomyNoShip === true
|
|
667
|
+
&& autonomousFinalE2EProofPlan?.schema === "zob.autonomous-final-e2e-proof-plan.v1"
|
|
668
|
+
&& autonomousFinalE2EProofPlan.status === "blocked_for_final_e2e_proof"
|
|
669
|
+
&& autonomousFinalE2EProofPlan.finalE2EProofReady === false
|
|
670
|
+
&& autonomousFinalE2EProofPlan.no_ship === true
|
|
671
|
+
&& autonomousFinalE2EProofPlan.globalAutonomyReady === false
|
|
672
|
+
&& autonomousFinalE2EProofPlan.globalAutonomyNoShip === true;
|
|
673
|
+
const strictGoalSpecGate = validateStrictGoalSpecAnchor({ kind: "orchestrate_run", goal: "Autonomy readiness strict spec smoke", originalUserAsk: "Verify strict goal/spec anchors before autonomous dispatch." }).length === 0
|
|
674
|
+
&& validateStrictGoalSpecAnchor({ kind: "delegate_write", taskText: "1. TASK: edit\n2. EXPECTED OUTCOME: scoped change\n3. REQUIRED TOOLS: read, edit\n4. MUST DO:\n- cite evidence\n5. MUST NOT DO:\n- no secrets\n6. CONTEXT: smoke", requiredTools: ["read", "edit"] }).some((error) => error.includes("ORIGINAL_USER_ASK"));
|
|
675
|
+
|
|
676
|
+
const delegateAgentWriteScopeGate = validateDelegationWriteScope("delegate_agent", ["read", "edit"], []).some((error) => error.includes("requires non-empty allowed_paths"))
|
|
677
|
+
&& validateDelegationWriteScope("delegate_agent", ["read", "edit"], ["docs/"]).length === 0;
|
|
678
|
+
const contextGbrainNoShipRules = [
|
|
679
|
+
"context_scope_required_before_context_injection",
|
|
680
|
+
"citation_required_for_context_pack_facts",
|
|
681
|
+
"gbrain_writeback_proposal_only",
|
|
682
|
+
"no_raw_conversation_history_injection",
|
|
683
|
+
"forbidden_source_scope_blocks_secret_paths",
|
|
684
|
+
];
|
|
685
|
+
|
|
686
|
+
const capabilityChecks = [
|
|
687
|
+
check("registered_agentic_factory_current_source_chain", smoke.passed === true && pilot.passed === true && batch.passed === true && batchOracle?.verdict === "PASS" && batchOracle.no_ship === false && currentChainLogPassed, { smokeRunId: REGISTERED_FACTORY_CHAIN.smoke, pilotRunId: REGISTERED_FACTORY_CHAIN.pilot, batchRunId: REGISTERED_FACTORY_CHAIN.batch, currentChainLogPassed }),
|
|
688
|
+
check("sandbox_isolated_diff_review_apply_simulation_and_manual_preflight", sandboxIsolated?.status === "executed_in_sandbox" && sandboxIsolated.productionWritesPerformed === false && sandboxIsolated.autoApply === false && sandboxDiffReview?.status === "diff_review_passed" && sandboxDiffReview.reviewPassed === true && sandboxDiffReview.productionWritesPerformed === false && sandboxDiffReview.autoApply === false && sandboxApplySimulation?.status === "simulated_apply_in_temp_workspace" && sandboxApplySimulation.simulatedApplyPerformed === true && sandboxApplySimulation.productionWritesPerformed === false && sandboxApplySimulation.autoApply === false && sandboxApplySimulation.tempTargetWorkspaceWritten === true && sandboxManualApplyPreflight?.status === "manual_apply_preflight_passed" && sandboxManualApplyPreflight.manualApplyPreflightPassed === true && sandboxManualApplyPreflight.executionAllowedByThisTool === false && sandboxManualApplyPreflight.productionWritesPerformed === false && sandboxManualApplyPreflight.autoApply === false, { isolated: sandboxIsolatedPath, diffReview: sandboxDiffReviewPath, applySimulation: sandboxApplySimulationPath, manualApplyPreflight: sandboxManualApplyPreflightPath }),
|
|
689
|
+
check("model_routing_gate_available_default_blocked", modelRouting?.auditPassed === true && modelRouting.liveRoutingNoShip === true && exactFailedChecks(modelRouting.failedChecks, ["live_routing_global_default_enabled"]) && modelRouting.liveRoutingDispatchGateAvailable === true && modelRouting.modelRouterUsed === false && modelRouting.routingApplied === false && modelRouting.childDispatchAllowed === false, { report: modelRoutingPath }),
|
|
690
|
+
check("budget_policy_strict_gate_default_blocked", budget?.auditPassed === true && budget.strictBudgetNoShip === true && exactFailedChecks(budget.failedChecks, ["strict_budget_global_default_enabled"]) && budget.strictBudgetDispatchGateAvailable === true && budget.budgetEnforced === false && budget.strictEnabled === false && budget.wouldBlockDispatch === false, { report: budgetPath }),
|
|
691
|
+
check("daemon_readiness_dry_run_only", daemon?.readyForManualOneShot === true && daemon.no_ship === false && daemon.autoStartDaemon === false && daemon.continuousLoop === false && daemon.daemonStarted === false && daemon.noExecution === true, { report: daemonPath }),
|
|
692
|
+
check("daemon_policy_manual_one_shot_no_ship", daemonPolicy?.auditPassed === true && daemonPolicy.readyForManualOneShotOnly === true && daemonPolicy.alwaysOnDaemonReady === false && daemonPolicy.alwaysOnDaemonNoShip === true && daemonPolicy.autoStartDaemon === false && daemonPolicy.continuousLoop === false && daemonPolicy.daemonStarted === false && daemonPolicy.noExecution === true, { report: daemonPolicyPath }),
|
|
693
|
+
check("delegate_agent_write_scope_gate_available", delegateAgentWriteScopeGate, { writeEditRequiresAllowedPaths: delegateAgentWriteScopeGate }),
|
|
694
|
+
check("strict_goal_spec_gate_enforced_p0", strictGoalSpecGate, { acceptedAnchors: ["active GoalState", "orchestrate goal+original_user_ask", "factory definition+manifest", "delegate write original_user_ask"], enforcement: "runtime_tool_anchor_or_goal_required_for_write_factory_orchestrate" }),
|
|
695
|
+
check("context_gbrain_runtime_scope_enforcement_p0", contextGbrain.verdict === "PASS" && contextGbrain.no_ship === false && contextGbrain.gbrainImportEnabled === false && contextGbrain.gbrainEmbedEnabled === false && contextGbrain.gbrainSyncEnabled === false && contextGbrain.gbrainWriteEnabled === false, { rules: contextGbrainNoShipRules, readiness: { verdict: contextGbrain.verdict, failedChecks: contextGbrain.failedChecks }, enforcement: "runtime_context_scope_citations_bounded_pack_writeback_proposal_only" }),
|
|
696
|
+
check("autonomous_runtime_dry_run_loop_p0", autonomousDryRun.status === "dry_run_plan_ready" && isRecord(autonomousDryRun.modelRoutingPlan) && autonomousDryRun.modelRoutingPlan.routingPlanReady === true && autonomousDryRun.modelRoutingPlan.liveRoutingEnabled === false && autonomousDryRun.modelRoutingPlan.childDispatchAllowed === false && autonomousDryRun.noExecution === true && autonomousDryRun.childDispatchAllowed === false && autonomousDryRun.globalAutonomyNoShip === true && autonomousDryRun.productionWritesPerformed === false && autonomousDryRun.autoApply === false, { runId: autonomousDryRun.runId, status: autonomousDryRun.status, selectedFactory: isRecord(autonomousDryRun.factorySelection) ? autonomousDryRun.factorySelection.selectedFactory : undefined, proofPlan: "spec_lock_context_scope_model_routing_factory_selection_smoke_oracle_pilot_oracle_batch_final_report" }),
|
|
697
|
+
...(input.autonomous_dry_run_id ? [check("autonomous_runtime_dry_run_artifact_validator_p0", autonomousDryRunArtifactValidatorPassed, { runId: input.autonomous_dry_run_id, valid: isRecord(autonomousDryRunArtifactValidation) ? autonomousDryRunArtifactValidation.valid : false, failedChecks: isRecord(autonomousDryRunArtifactValidation) ? autonomousDryRunArtifactValidation.failedChecks : ["artifact_validation_not_available"], noExecution: isRecord(autonomousDryRunArtifactValidation) ? autonomousDryRunArtifactValidation.noExecution : undefined, networkAccessed: isRecord(autonomousDryRunArtifactValidation) ? autonomousDryRunArtifactValidation.networkAccessed : undefined })] : []),
|
|
698
|
+
...(input.autonomous_readonly_smoke_run_id ? [check("autonomous_readonly_smoke_completion_gate_p0", autonomousReadOnlySmokeCompletionGatePassed, { runId: input.autonomous_readonly_smoke_run_id, valid: isRecord(autonomousReadOnlySmokeValidation) ? autonomousReadOnlySmokeValidation.valid : false, failedChecks: isRecord(autonomousReadOnlySmokeValidation) ? autonomousReadOnlySmokeValidation.failedChecks : ["artifact_validation_not_available"], completionGateStatus: autonomousCompletionGate?.status, updateGoalAllowed: autonomousCompletionGate?.updateGoalAllowed, finalNoShipOracleVerdict: autonomousFinalNoShipOracle?.verdict, finalNoShip: autonomousFinalNoShipOracle?.no_ship, finalE2EProofStatus: autonomousFinalE2EProofPlan?.status, globalAutonomyReady: autonomousCompletionGate?.globalAutonomyReady, globalAutonomyNoShip: autonomousCompletionGate?.globalAutonomyNoShip })] : []),
|
|
699
|
+
check("capability_index_available", Number(capabilityByKind.agent ?? 0) > 0 && Number(capabilityByKind.factory ?? 0) > 0 && Number(capabilityByKind.chain ?? 0) > 0 && Number(capabilityByKind.output_contract ?? 0) > 0 && capabilities.noExecution === true, { counts: capabilityCounts }),
|
|
700
|
+
check("factory_registry_indexed_with_arbitrary_autonomy_blocked", factoryRegistry.registryIndexed === true && factoryRegistry.arbitraryFactoryAutonomyReady === false && factoryRegistry.arbitraryFactoryNoShip === true, { factoryCount: factoryRegistry.factoryCount, registeredAgenticBatchReadyFactories: factoryRegistry.registeredAgenticBatchReadyFactories, unprovenFactories: factoryRegistry.unprovenFactories }),
|
|
701
|
+
];
|
|
702
|
+
const evidenceReady = capabilityChecks.every((item) => item.passed === true);
|
|
703
|
+
const factoriesMissingRegisteredBatchProof = Array.isArray(factoryRegistry.factoriesMissingRegisteredBatchProof) ? factoryRegistry.factoriesMissingRegisteredBatchProof : [];
|
|
704
|
+
const registeredFactoryMatrixComplete = factoriesMissingRegisteredBatchProof.length === 0;
|
|
705
|
+
const globalBlockers = [
|
|
706
|
+
"global_autonomy_not_proven_for_arbitrary_factories",
|
|
707
|
+
"always_on_daemon_not_implemented",
|
|
708
|
+
"global_live_model_routing_not_enabled",
|
|
709
|
+
"global_strict_budget_enforcement_not_enabled",
|
|
710
|
+
"production_write_apply_not_enabled",
|
|
711
|
+
"auto_apply_not_enabled",
|
|
712
|
+
"sandbox_writes_remain_manual_apply_only",
|
|
713
|
+
...(input.autonomous_readonly_smoke_run_id ? ["autonomous_completion_gate_blocks_goal_completion"] : []),
|
|
714
|
+
...(registeredFactoryMatrixComplete ? [] : ["registered_agentic_factory_batch_proof_matrix_incomplete"]),
|
|
715
|
+
];
|
|
716
|
+
const report = {
|
|
717
|
+
schema: "zob.autonomy-readiness-audit.v1",
|
|
718
|
+
runId: input.run_id,
|
|
719
|
+
evidenceReady,
|
|
720
|
+
status: "blocked_for_global_autonomy",
|
|
721
|
+
globalAutonomyReady: false,
|
|
722
|
+
globalAutonomyNoShip: true,
|
|
723
|
+
globalBlockers,
|
|
724
|
+
capabilityChecks,
|
|
725
|
+
factoryRegistry,
|
|
726
|
+
evidence: {
|
|
727
|
+
registeredFactory: { smoke, pilot, batch, batchOracle: artifact(batchOraclePath), currentChainLog: artifact(currentChainLogPath) },
|
|
728
|
+
sandbox: { isolatedExecution: artifact(sandboxIsolatedPath), diffReviewGate: artifact(sandboxDiffReviewPath), applySimulation: artifact(sandboxApplySimulationPath), manualApplyPreflight: artifact(sandboxManualApplyPreflightPath) },
|
|
729
|
+
modelRouting: artifact(modelRoutingPath),
|
|
730
|
+
budget: artifact(budgetPath),
|
|
731
|
+
daemon: artifact(daemonPath),
|
|
732
|
+
daemonPolicy: artifact(daemonPolicyPath),
|
|
733
|
+
safety: {
|
|
734
|
+
delegateAgentWriteScopeGateAvailable: delegateAgentWriteScopeGate,
|
|
735
|
+
strictGoalSpecRequiredForAutonomy: strictGoalSpecGate,
|
|
736
|
+
contextGbrainNoShipRules,
|
|
737
|
+
autonomousRuntimeDryRunP0: { status: autonomousDryRun.status, noExecution: autonomousDryRun.noExecution, childDispatchAllowed: autonomousDryRun.childDispatchAllowed, globalAutonomyNoShip: autonomousDryRun.globalAutonomyNoShip },
|
|
738
|
+
autonomousRuntimeDryRunArtifactValidatorP0: isRecord(autonomousDryRunArtifactValidation) ? { runId: input.autonomous_dry_run_id, valid: autonomousDryRunArtifactValidation.valid, failedChecks: autonomousDryRunArtifactValidation.failedChecks, noExecution: autonomousDryRunArtifactValidation.noExecution, networkAccessed: autonomousDryRunArtifactValidation.networkAccessed, globalAutonomyNoShip: autonomousDryRunArtifactValidation.globalAutonomyNoShip } : undefined,
|
|
739
|
+
autonomousReadOnlySmokeCompletionGateP0: input.autonomous_readonly_smoke_run_id && autonomousReadOnlySmokeRunDir ? { runId: input.autonomous_readonly_smoke_run_id, valid: isRecord(autonomousReadOnlySmokeValidation) ? autonomousReadOnlySmokeValidation.valid : false, failedChecks: isRecord(autonomousReadOnlySmokeValidation) ? autonomousReadOnlySmokeValidation.failedChecks : ["artifact_validation_not_available"], completionGate: artifact(join(autonomousReadOnlySmokeRunDir, "completion-gate.json")), finalNoShipOracle: artifact(join(autonomousReadOnlySmokeRunDir, "final-no-ship-oracle.json")), finalE2EProofPlan: artifact(join(autonomousReadOnlySmokeRunDir, "final-e2e-proof-plan.json")), updateGoalAllowed: autonomousCompletionGate?.updateGoalAllowed, globalAutonomyReady: autonomousCompletionGate?.globalAutonomyReady, globalAutonomyNoShip: autonomousCompletionGate?.globalAutonomyNoShip } : undefined,
|
|
740
|
+
contextGbrainP0: { verdict: contextGbrain.verdict, no_ship: contextGbrain.no_ship, failedChecks: contextGbrain.failedChecks },
|
|
741
|
+
},
|
|
742
|
+
capabilityIndex: { counts: capabilityCounts },
|
|
743
|
+
factoryRegistry: { factoryCount: factoryRegistry.factoryCount, arbitraryFactoryAutonomyReady: factoryRegistry.arbitraryFactoryAutonomyReady, arbitraryFactoryNoShip: factoryRegistry.arbitraryFactoryNoShip },
|
|
744
|
+
},
|
|
745
|
+
invariants: {
|
|
746
|
+
auditOnly: true,
|
|
747
|
+
noExecution: true,
|
|
748
|
+
childDispatchAllowed: false,
|
|
749
|
+
daemonStarted: false,
|
|
750
|
+
autoStartDaemon: false,
|
|
751
|
+
continuousLoop: false,
|
|
752
|
+
cronEnabled: false,
|
|
753
|
+
liveRoutingEnabled: false,
|
|
754
|
+
modelRouterUsed: false,
|
|
755
|
+
routingApplied: false,
|
|
756
|
+
budgetEnforced: false,
|
|
757
|
+
strictEnabled: false,
|
|
758
|
+
wouldBlockDispatch: false,
|
|
759
|
+
productionWritesPerformed: false,
|
|
760
|
+
autoApply: false,
|
|
761
|
+
networkAccessed: false,
|
|
762
|
+
},
|
|
763
|
+
bodyStored: false,
|
|
764
|
+
promptBodiesStored: false,
|
|
765
|
+
outputBodiesStored: false,
|
|
766
|
+
generatedAt: new Date().toISOString(),
|
|
767
|
+
};
|
|
768
|
+
if (hasForbiddenBodyKeys(report)) throw new Error("Autonomy readiness audit would store forbidden body keys");
|
|
769
|
+
return report;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
export function writeAutonomyReadinessAuditReport(repoRoot: string, runId = "autonomy-readiness", input: AutonomyReadinessAuditInput = {}): string {
|
|
773
|
+
const dir = join(repoRoot, "reports");
|
|
774
|
+
mkdirSync(dir, { recursive: true });
|
|
775
|
+
const outputPath = join(dir, `${safeFileStem(runId)}.json`);
|
|
776
|
+
writeFileSync(outputPath, JSON.stringify(buildAutonomyReadinessAudit(repoRoot, { ...input, run_id: runId }), null, 2), "utf8");
|
|
777
|
+
return outputPath;
|
|
778
|
+
}
|