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,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
4
|
+
|
|
5
|
+
const repoRoot = process.cwd();
|
|
6
|
+
|
|
7
|
+
function usage() {
|
|
8
|
+
console.error(`Usage:
|
|
9
|
+
node scripts/project-dna/emit-ontology.mjs --scan-dir <repo-relative-scan-dir> [--source <repo-relative-ontology-json>] [--out <repo-relative-json>]
|
|
10
|
+
|
|
11
|
+
Copies the controlled ProjectDNA ontology into a reports scan directory. No source scan, no backend write.`);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function parseArgs(argv) {
|
|
15
|
+
const out = { source: ".pi/factories/project-dna/pi-agentic-ontology.json" };
|
|
16
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
17
|
+
const arg = argv[i];
|
|
18
|
+
if (arg === "--scan-dir") out.scanDir = argv[++i];
|
|
19
|
+
else if (arg === "--source") out.source = argv[++i];
|
|
20
|
+
else if (arg === "--out") out.out = argv[++i];
|
|
21
|
+
else if (arg === "--help" || arg === "-h") out.help = true;
|
|
22
|
+
else throw new Error(`unknown argument: ${arg}`);
|
|
23
|
+
}
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function resolveRepoPath(input, label, allowMissing = false) {
|
|
28
|
+
if (!input || isAbsolute(input)) throw new Error(`${label} must be repo-relative`);
|
|
29
|
+
const resolved = resolve(repoRoot, input);
|
|
30
|
+
const rel = relative(repoRoot, resolved);
|
|
31
|
+
if (rel.startsWith("..") || rel === "") throw new Error(`${label} must stay inside repo and not be repo root`);
|
|
32
|
+
if (!allowMissing && !existsSync(resolved)) throw new Error(`${label} not found: ${input}`);
|
|
33
|
+
return resolved;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function assertReportPath(input, label) {
|
|
37
|
+
const normalized = input.split(sep).join("/");
|
|
38
|
+
if (!normalized.startsWith("reports/project-dna-scans/")) throw new Error(`${label} must stay under reports/project-dna-scans`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function main() {
|
|
42
|
+
const args = parseArgs(process.argv.slice(2));
|
|
43
|
+
if (args.help || !args.scanDir) {
|
|
44
|
+
usage();
|
|
45
|
+
if (!args.help) process.exit(2);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
assertReportPath(args.scanDir, "--scan-dir");
|
|
49
|
+
const scanDir = resolveRepoPath(args.scanDir, "--scan-dir", true);
|
|
50
|
+
const sourcePath = resolveRepoPath(args.source, "--source");
|
|
51
|
+
const outRel = args.out ?? `${args.scanDir.replace(/\/$/, "")}/ontology.json`;
|
|
52
|
+
assertReportPath(outRel, "--out");
|
|
53
|
+
const outPath = resolveRepoPath(outRel, "--out", true);
|
|
54
|
+
if (!relative(scanDir, outPath) || relative(scanDir, outPath).startsWith("..")) throw new Error("--out must stay inside --scan-dir");
|
|
55
|
+
const ontology = JSON.parse(readFileSync(sourcePath, "utf8"));
|
|
56
|
+
if (ontology.schema !== "zob.project-dna-ontology.v1") throw new Error("ontology schema mismatch");
|
|
57
|
+
const emitted = {
|
|
58
|
+
...ontology,
|
|
59
|
+
emitted_from: relative(repoRoot, sourcePath).split(sep).join("/"),
|
|
60
|
+
scan_dir: relative(repoRoot, scanDir).split(sep).join("/"),
|
|
61
|
+
source_project_modified: false,
|
|
62
|
+
knowledge_backend_write_enabled: false,
|
|
63
|
+
durable_promotion_allowed: false,
|
|
64
|
+
};
|
|
65
|
+
mkdirSync(dirname(outPath), { recursive: true });
|
|
66
|
+
writeFileSync(outPath, `${JSON.stringify(emitted, null, 2)}\n`, "utf8");
|
|
67
|
+
console.log(JSON.stringify({ schema: "zob.project-dna-ontology-emission.v1", out: relative(repoRoot, outPath).split(sep).join("/"), concept_count: emitted.concepts.length, source_project_modified: false, knowledge_backend_write_enabled: false }, null, 2));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
main();
|
|
72
|
+
} catch (error) {
|
|
73
|
+
console.error(JSON.stringify({ schema: "zob.project-dna-ontology-emission-error.v1", error: error instanceof Error ? error.message : String(error), source_project_modified: false, knowledge_backend_write_enabled: false }, null, 2));
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
4
|
+
|
|
5
|
+
const repoRoot = process.cwd();
|
|
6
|
+
|
|
7
|
+
function usage() {
|
|
8
|
+
console.error(`Usage:
|
|
9
|
+
node scripts/project-dna/generate-sample.mjs --sample-spec <repo-relative-json> --out-dir <repo-relative-quarantine-dir>
|
|
10
|
+
|
|
11
|
+
Generates a tiny dependency-free neutral sample project in a quarantine/report path. It does not copy source files or run package installs.`);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function parseArgs(argv) {
|
|
15
|
+
const out = {};
|
|
16
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
17
|
+
const arg = argv[i];
|
|
18
|
+
if (arg === "--sample-spec") out.sampleSpec = argv[++i];
|
|
19
|
+
else if (arg === "--out-dir") out.outDir = argv[++i];
|
|
20
|
+
else if (arg === "--help" || arg === "-h") out.help = true;
|
|
21
|
+
else throw new Error(`unknown argument: ${arg}`);
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function resolveRepoPath(input, label) {
|
|
27
|
+
if (!input || isAbsolute(input)) throw new Error(`${label} must be repo-relative`);
|
|
28
|
+
const resolved = resolve(repoRoot, input);
|
|
29
|
+
const rel = relative(repoRoot, resolved);
|
|
30
|
+
if (rel.startsWith("..") || rel === "") throw new Error(`${label} must stay inside repo and not be repo root`);
|
|
31
|
+
return resolved;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function assertQuarantineOutDir(outDir) {
|
|
35
|
+
const rel = relative(repoRoot, outDir).split(sep).join("/");
|
|
36
|
+
const allowed = rel.startsWith("reports/project-dna-scans/") || rel.startsWith("reports/factory-runs/");
|
|
37
|
+
if (!allowed || !rel.includes("/quarantine/")) {
|
|
38
|
+
throw new Error("--out-dir must be a repo-local reports/.../quarantine/... path");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function safePackageName(value) {
|
|
43
|
+
return String(value ?? "project-dna-sample")
|
|
44
|
+
.toLowerCase()
|
|
45
|
+
.replace(/[^a-z0-9._-]+/g, "-")
|
|
46
|
+
.replace(/^-+|-+$/g, "")
|
|
47
|
+
.slice(0, 80) || "project-dna-sample";
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function writeText(path, content) {
|
|
51
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
52
|
+
writeFileSync(path, `${content.trim()}\n`, "utf8");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function main() {
|
|
56
|
+
const args = parseArgs(process.argv.slice(2));
|
|
57
|
+
if (args.help || !args.sampleSpec || !args.outDir) {
|
|
58
|
+
usage();
|
|
59
|
+
if (!args.help) process.exit(2);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const specPath = resolveRepoPath(args.sampleSpec, "--sample-spec");
|
|
63
|
+
const outDir = resolveRepoPath(args.outDir, "--out-dir");
|
|
64
|
+
assertQuarantineOutDir(outDir);
|
|
65
|
+
if (!existsSync(specPath)) throw new Error(`sample spec not found: ${args.sampleSpec}`);
|
|
66
|
+
const spec = JSON.parse(readFileSync(specPath, "utf8"));
|
|
67
|
+
if (spec.schema !== "zob.project-dna-sample-spec.v1") throw new Error("sample spec schema must be zob.project-dna-sample-spec.v1");
|
|
68
|
+
if (spec.safety?.sample_code_generated !== false) throw new Error("sample spec must start as spec_only/no generated code");
|
|
69
|
+
|
|
70
|
+
const packageName = safePackageName(spec.sample_name);
|
|
71
|
+
const sourceId = String(spec.source_id ?? "unknown-source");
|
|
72
|
+
const neutralDomain = String(spec.neutral_domain ?? "neutral-domain");
|
|
73
|
+
const requiredModules = Array.isArray(spec.required_modules) && spec.required_modules.length > 0 ? spec.required_modules : ["example-module", "tests"];
|
|
74
|
+
const citations = Array.isArray(spec.citations) ? spec.citations.slice(0, 12) : [];
|
|
75
|
+
|
|
76
|
+
writeText(join(outDir, "package.json"), JSON.stringify({
|
|
77
|
+
name: packageName,
|
|
78
|
+
version: "0.0.0-project-dna-sample",
|
|
79
|
+
private: true,
|
|
80
|
+
type: "module",
|
|
81
|
+
description: `Neutral ProjectDNA sample generated from ${sourceId} metadata for ${neutralDomain}.`,
|
|
82
|
+
scripts: {
|
|
83
|
+
check: "node scripts/validate-sample.mjs",
|
|
84
|
+
test: "node test/sample.test.mjs",
|
|
85
|
+
build: "node scripts/validate-sample.mjs"
|
|
86
|
+
},
|
|
87
|
+
dependencies: {},
|
|
88
|
+
devDependencies: {},
|
|
89
|
+
projectDna: {
|
|
90
|
+
source_id: sourceId,
|
|
91
|
+
neutral_domain: neutralDomain,
|
|
92
|
+
copy_policy: "structure_and_patterns_only",
|
|
93
|
+
generated_from_scan_metadata_only: true,
|
|
94
|
+
source_files_copied: false,
|
|
95
|
+
source_project_modified: false,
|
|
96
|
+
knowledge_backend_write_enabled: false
|
|
97
|
+
}
|
|
98
|
+
}, null, 2));
|
|
99
|
+
|
|
100
|
+
writeText(join(outDir, "README.md"), `# ${packageName}
|
|
101
|
+
|
|
102
|
+
Neutral ProjectDNA sample generated in quarantine.
|
|
103
|
+
|
|
104
|
+
- source_id: \`${sourceId}\`
|
|
105
|
+
- neutral_domain: \`${neutralDomain}\`
|
|
106
|
+
- generation: metadata-only structure/pattern sample
|
|
107
|
+
- source files copied: false
|
|
108
|
+
- source project modified: false
|
|
109
|
+
- external knowledge-backend write: false
|
|
110
|
+
|
|
111
|
+
## Preserved signals
|
|
112
|
+
|
|
113
|
+
${(spec.preserve ?? []).slice(0, 20).map((item) => `- ${item}`).join("\n") || "- No preserve signals detected."}
|
|
114
|
+
|
|
115
|
+
## Citations to inspect before use
|
|
116
|
+
|
|
117
|
+
${citations.map((citation) => `- \`${citation}\``).join("\n") || "- Gap: no citations in sample spec."}
|
|
118
|
+
|
|
119
|
+
## Validation
|
|
120
|
+
|
|
121
|
+
\`npm run check\`, \`npm test\`, and \`npm run build\` are dependency-free local Node checks.
|
|
122
|
+
`);
|
|
123
|
+
|
|
124
|
+
writeText(join(outDir, "src/config/index.mjs"), `export const projectDnaConfig = Object.freeze({
|
|
125
|
+
sourceId: ${JSON.stringify(sourceId)},
|
|
126
|
+
neutralDomain: ${JSON.stringify(neutralDomain)},
|
|
127
|
+
generatedFromScanMetadataOnly: true,
|
|
128
|
+
sourceFilesCopied: false,
|
|
129
|
+
sourceProjectModified: false,
|
|
130
|
+
knowledgeBackendWriteEnabled: false,
|
|
131
|
+
});
|
|
132
|
+
`);
|
|
133
|
+
|
|
134
|
+
writeText(join(outDir, "src/example-module/index.mjs"), `import { projectDnaConfig } from "../config/index.mjs";
|
|
135
|
+
|
|
136
|
+
export function describeProjectDnaSample(input = {}) {
|
|
137
|
+
const name = typeof input.name === "string" && input.name.length > 0 ? input.name : "example";
|
|
138
|
+
return {
|
|
139
|
+
id: ` + "`${projectDnaConfig.neutralDomain}:${name}`" + `,
|
|
140
|
+
sourceId: projectDnaConfig.sourceId,
|
|
141
|
+
neutralDomain: projectDnaConfig.neutralDomain,
|
|
142
|
+
rules: [
|
|
143
|
+
"read cited source/sample files before implementation",
|
|
144
|
+
"keep context bounded",
|
|
145
|
+
"do not copy product-specific logic",
|
|
146
|
+
"keep writeback proposal-only"
|
|
147
|
+
],
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
`);
|
|
151
|
+
|
|
152
|
+
writeText(join(outDir, "src/tools/example-tool.mjs"), `export const exampleTool = Object.freeze({
|
|
153
|
+
name: "project-dna-example-tool",
|
|
154
|
+
description: "Dependency-free Pi-like tool descriptor generated from ProjectDNA metadata.",
|
|
155
|
+
input_schema: {
|
|
156
|
+
type: "object",
|
|
157
|
+
properties: {
|
|
158
|
+
name: { type: "string" }
|
|
159
|
+
},
|
|
160
|
+
additionalProperties: false
|
|
161
|
+
},
|
|
162
|
+
async run(input = {}) {
|
|
163
|
+
const name = typeof input.name === "string" && input.name.length > 0 ? input.name : "world";
|
|
164
|
+
return { ok: true, greeting: ` + "`hello ${name}`" + ` };
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
`);
|
|
168
|
+
|
|
169
|
+
writeText(join(outDir, "src/extension.mjs"), `import { describeProjectDnaSample } from "./example-module/index.mjs";
|
|
170
|
+
import { exampleTool } from "./tools/example-tool.mjs";
|
|
171
|
+
|
|
172
|
+
export function createProjectDnaExtension() {
|
|
173
|
+
return {
|
|
174
|
+
name: "project-dna-sample-extension",
|
|
175
|
+
summary: describeProjectDnaSample({ name: "extension" }),
|
|
176
|
+
tools: [exampleTool],
|
|
177
|
+
prompts: [".pi/skills/example-skill/SKILL.md"],
|
|
178
|
+
agents: [".pi/agents/example-agent.md"],
|
|
179
|
+
safety: {
|
|
180
|
+
sourceFilesCopied: false,
|
|
181
|
+
sourceProjectModified: false,
|
|
182
|
+
knowledgeBackendWriteEnabled: false,
|
|
183
|
+
writebackPolicy: "proposal_only"
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
`);
|
|
188
|
+
|
|
189
|
+
writeText(join(outDir, ".pi/agents/example-agent.md"), `---
|
|
190
|
+
name: example-agent
|
|
191
|
+
description: Example dependency-free Pi-like agent generated by ProjectDNA sample quarantine.
|
|
192
|
+
tools: read,grep,find,ls
|
|
193
|
+
---
|
|
194
|
+
You are an example ProjectDNA sample agent.
|
|
195
|
+
|
|
196
|
+
Rules:
|
|
197
|
+
- Use bounded cited context only.
|
|
198
|
+
- Do not read secrets or generated/vendor folders.
|
|
199
|
+
- Keep writeback proposal-only.
|
|
200
|
+
`);
|
|
201
|
+
|
|
202
|
+
writeText(join(outDir, ".pi/skills/example-skill/SKILL.md"), `---
|
|
203
|
+
name: example-skill
|
|
204
|
+
description: Example ProjectDNA sample skill. Use for dependency-free Pi-like scaffold smoke tests.
|
|
205
|
+
---
|
|
206
|
+
# Example Skill
|
|
207
|
+
|
|
208
|
+
This skill is generated from ProjectDNA metadata only. It demonstrates folder shape, not copied product logic.
|
|
209
|
+
`);
|
|
210
|
+
|
|
211
|
+
writeText(join(outDir, "test/sample.test.mjs"), `import assert from "node:assert/strict";
|
|
212
|
+
import { describeProjectDnaSample } from "../src/example-module/index.mjs";
|
|
213
|
+
import { createProjectDnaExtension } from "../src/extension.mjs";
|
|
214
|
+
import { exampleTool } from "../src/tools/example-tool.mjs";
|
|
215
|
+
|
|
216
|
+
const result = describeProjectDnaSample({ name: "smoke" });
|
|
217
|
+
assert.equal(result.sourceId, ${JSON.stringify(sourceId)});
|
|
218
|
+
assert.equal(result.neutralDomain, ${JSON.stringify(neutralDomain)});
|
|
219
|
+
assert.ok(result.id.includes("smoke"));
|
|
220
|
+
assert.ok(result.rules.includes("keep context bounded"));
|
|
221
|
+
|
|
222
|
+
const extension = createProjectDnaExtension();
|
|
223
|
+
assert.equal(extension.name, "project-dna-sample-extension");
|
|
224
|
+
assert.equal(extension.safety.sourceFilesCopied, false);
|
|
225
|
+
assert.equal(extension.tools[0].name, exampleTool.name);
|
|
226
|
+
const toolResult = await exampleTool.run({ name: "agentic" });
|
|
227
|
+
assert.equal(toolResult.greeting, "hello agentic");
|
|
228
|
+
console.log("ProjectDNA Pi-like neutral sample test passed");
|
|
229
|
+
`);
|
|
230
|
+
|
|
231
|
+
writeText(join(outDir, "scripts/validate-sample.mjs"), `import { existsSync, readFileSync } from "node:fs";
|
|
232
|
+
import { join } from "node:path";
|
|
233
|
+
|
|
234
|
+
const root = process.cwd();
|
|
235
|
+
const required = [
|
|
236
|
+
"package.json",
|
|
237
|
+
"README.md",
|
|
238
|
+
"src/config/index.mjs",
|
|
239
|
+
"src/example-module/index.mjs",
|
|
240
|
+
"src/tools/example-tool.mjs",
|
|
241
|
+
"src/extension.mjs",
|
|
242
|
+
".pi/agents/example-agent.md",
|
|
243
|
+
".pi/skills/example-skill/SKILL.md",
|
|
244
|
+
"test/sample.test.mjs",
|
|
245
|
+
];
|
|
246
|
+
const missing = required.filter((path) => !existsSync(join(root, path)));
|
|
247
|
+
if (missing.length > 0) {
|
|
248
|
+
console.error(JSON.stringify({ valid: false, missing }, null, 2));
|
|
249
|
+
process.exit(1);
|
|
250
|
+
}
|
|
251
|
+
const pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
|
|
252
|
+
const errors = [];
|
|
253
|
+
if (pkg.projectDna?.source_files_copied !== false) errors.push("source_files_copied must be false");
|
|
254
|
+
if (pkg.projectDna?.source_project_modified !== false) errors.push("source_project_modified must be false");
|
|
255
|
+
if (pkg.projectDna?.knowledge_backend_write_enabled !== false) errors.push("knowledge_backend_write_enabled must be false");
|
|
256
|
+
if (Object.keys(pkg.dependencies ?? {}).length !== 0) errors.push("sample must stay dependency-free in P1 smoke");
|
|
257
|
+
if (errors.length > 0) {
|
|
258
|
+
console.error(JSON.stringify({ valid: false, errors }, null, 2));
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
console.log(JSON.stringify({ valid: true, files: required, dependencyFree: true }, null, 2));
|
|
262
|
+
`);
|
|
263
|
+
|
|
264
|
+
const summary = {
|
|
265
|
+
schema: "zob.project-dna-sample-generation-summary.v1",
|
|
266
|
+
source_id: sourceId,
|
|
267
|
+
sample_name: packageName,
|
|
268
|
+
neutral_domain: neutralDomain,
|
|
269
|
+
out_dir: relative(repoRoot, outDir).split(sep).join("/"),
|
|
270
|
+
required_modules: requiredModules,
|
|
271
|
+
generated_files: [
|
|
272
|
+
"package.json",
|
|
273
|
+
"README.md",
|
|
274
|
+
"src/config/index.mjs",
|
|
275
|
+
"src/example-module/index.mjs",
|
|
276
|
+
"src/tools/example-tool.mjs",
|
|
277
|
+
"src/extension.mjs",
|
|
278
|
+
".pi/agents/example-agent.md",
|
|
279
|
+
".pi/skills/example-skill/SKILL.md",
|
|
280
|
+
"test/sample.test.mjs",
|
|
281
|
+
"scripts/validate-sample.mjs"
|
|
282
|
+
],
|
|
283
|
+
quarantine_only: true,
|
|
284
|
+
source_files_copied: false,
|
|
285
|
+
source_project_modified: false,
|
|
286
|
+
knowledge_backend_write_enabled: false,
|
|
287
|
+
promotion: {
|
|
288
|
+
writeback_policy: "proposal_only",
|
|
289
|
+
oracle_required: true,
|
|
290
|
+
human_approval_required: true
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
writeText(join(outDir, "project-dna-sample-summary.json"), JSON.stringify(summary, null, 2));
|
|
294
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
try {
|
|
298
|
+
main();
|
|
299
|
+
} catch (error) {
|
|
300
|
+
console.error(JSON.stringify({ schema: "zob.project-dna-sample-generation-error.v1", error: error instanceof Error ? error.message : String(error), source_project_modified: false, knowledge_backend_write_enabled: false }, null, 2));
|
|
301
|
+
process.exit(1);
|
|
302
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
4
|
+
|
|
5
|
+
const repoRoot = process.cwd();
|
|
6
|
+
|
|
7
|
+
function usage() {
|
|
8
|
+
console.error(`Usage:
|
|
9
|
+
node scripts/project-dna/oracle-review-smoke.mjs --scan-dir <repo-relative-scan-dir> --benchmark <repo-relative-json> [--out <repo-relative-json>]
|
|
10
|
+
|
|
11
|
+
Writes a structural oracle review for ProjectDNA smoke artifacts. This is not durable promotion approval.`);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function parseArgs(argv) {
|
|
15
|
+
const out = {};
|
|
16
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
17
|
+
const arg = argv[i];
|
|
18
|
+
if (arg === "--scan-dir") out.scanDir = argv[++i];
|
|
19
|
+
else if (arg === "--benchmark") out.benchmark = argv[++i];
|
|
20
|
+
else if (arg === "--out") out.out = argv[++i];
|
|
21
|
+
else if (arg === "--help" || arg === "-h") out.help = true;
|
|
22
|
+
else throw new Error(`unknown argument: ${arg}`);
|
|
23
|
+
}
|
|
24
|
+
return out;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function resolveRepoPath(input, label, allowMissing = false) {
|
|
28
|
+
if (!input || isAbsolute(input)) throw new Error(`${label} must be repo-relative`);
|
|
29
|
+
const resolved = resolve(repoRoot, input);
|
|
30
|
+
const rel = relative(repoRoot, resolved);
|
|
31
|
+
if (rel.startsWith("..") || rel === "") throw new Error(`${label} must stay inside repo and not be repo root`);
|
|
32
|
+
if (!allowMissing && !existsSync(resolved)) throw new Error(`${label} not found: ${input}`);
|
|
33
|
+
return resolved;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function readJson(path) {
|
|
37
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function main() {
|
|
41
|
+
const args = parseArgs(process.argv.slice(2));
|
|
42
|
+
if (args.help || !args.scanDir || !args.benchmark) {
|
|
43
|
+
usage();
|
|
44
|
+
if (!args.help) process.exit(2);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const scanDir = resolveRepoPath(args.scanDir, "--scan-dir");
|
|
48
|
+
const benchmarkPath = resolveRepoPath(args.benchmark, "--benchmark");
|
|
49
|
+
const scanDirRel = relative(repoRoot, scanDir).split(sep).join("/");
|
|
50
|
+
const outPath = resolveRepoPath(args.out ?? `${scanDirRel}/oracle/project-dna-smoke-oracle-review.json`, "--out", true);
|
|
51
|
+
mkdirSync(dirname(outPath), { recursive: true });
|
|
52
|
+
|
|
53
|
+
const benchmark = readJson(benchmarkPath);
|
|
54
|
+
const scanSummary = readJson(join(scanDir, "scan-summary.json"));
|
|
55
|
+
const contextPack = readJson(join(scanDir, "context-pack-smoke.json"));
|
|
56
|
+
const sampleSummaryPath = join(scanDir, "quarantine", "sample-project", "project-dna-sample-summary.json");
|
|
57
|
+
const sampleSummary = existsSync(sampleSummaryPath) ? readJson(sampleSummaryPath) : undefined;
|
|
58
|
+
const queryResultPath = join(scanDir, "query-result-smoke.json");
|
|
59
|
+
const queryResult = existsSync(queryResultPath) ? readJson(queryResultPath) : undefined;
|
|
60
|
+
const ontologyPath = join(scanDir, "ontology.json");
|
|
61
|
+
const ontology = existsSync(ontologyPath) ? readJson(ontologyPath) : undefined;
|
|
62
|
+
const goldenCasesPath = join(scanDir, "golden-cases-smoke.json");
|
|
63
|
+
const goldenCases = existsSync(goldenCasesPath) ? readJson(goldenCasesPath) : undefined;
|
|
64
|
+
const queryStewardPath = join(scanDir, "query-steward-smoke.json");
|
|
65
|
+
const querySteward = existsSync(queryStewardPath) ? readJson(queryStewardPath) : undefined;
|
|
66
|
+
|
|
67
|
+
const blocking = [];
|
|
68
|
+
const notes = [];
|
|
69
|
+
if (benchmark.schema !== "zob.project-dna-benchmark-smoke.v1") blocking.push("benchmark schema mismatch");
|
|
70
|
+
if (benchmark.status !== "passed") blocking.push("benchmark status is not passed");
|
|
71
|
+
if (benchmark.benchmark_kind !== "golden-agentic-5of5-smoke") blocking.push("benchmark must use golden-agentic-5of5-smoke cases");
|
|
72
|
+
if (benchmark.metrics?.cases_total < 5) blocking.push("benchmark must include at least five golden cases");
|
|
73
|
+
if (benchmark.metrics?.cases_passed !== benchmark.metrics?.cases_total) blocking.push("all golden benchmark cases must pass");
|
|
74
|
+
if (benchmark.gates?.source_project_modified !== false) blocking.push("benchmark must prove source_project_modified=false");
|
|
75
|
+
if (benchmark.gates?.knowledge_backend_write_enabled !== false) blocking.push("benchmark must prove knowledge_backend_write_enabled=false");
|
|
76
|
+
if (benchmark.gates?.promotion_allowed !== false) blocking.push("benchmark smoke must not allow durable promotion");
|
|
77
|
+
if (scanSummary.source_project_modified !== false) blocking.push("scan summary source_project_modified must be false");
|
|
78
|
+
if (scanSummary.knowledge_backend_write_enabled !== false) blocking.push("scan summary knowledge_backend_write_enabled must be false");
|
|
79
|
+
if (contextPack.loading_rules?.citation_required !== true) blocking.push("context pack must require citations");
|
|
80
|
+
if (contextPack.loading_rules?.agent_loads_entire_project !== false) blocking.push("context pack must not load entire project");
|
|
81
|
+
if (!sampleSummary) blocking.push("sample summary missing");
|
|
82
|
+
else {
|
|
83
|
+
if (sampleSummary.quarantine_only !== true) blocking.push("sample summary must be quarantine_only=true");
|
|
84
|
+
if (sampleSummary.source_files_copied !== false) blocking.push("sample summary source_files_copied must be false");
|
|
85
|
+
if (sampleSummary.knowledge_backend_write_enabled !== false) blocking.push("sample summary knowledge_backend_write_enabled must be false");
|
|
86
|
+
}
|
|
87
|
+
if (!queryResult) notes.push("query-result-smoke.json missing; benchmark cases still provide query artifacts");
|
|
88
|
+
else {
|
|
89
|
+
if (queryResult.raw_query_persisted !== false) blocking.push("query result must not persist raw query");
|
|
90
|
+
if (queryResult.loading_rules?.bounded_context_only !== true) blocking.push("query result must be bounded_context_only");
|
|
91
|
+
if (queryResult.query_steward?.used !== true) blocking.push("query result must record query_steward.used=true");
|
|
92
|
+
}
|
|
93
|
+
if (!ontology) blocking.push("ontology.json missing for 5/5 agentic smoke");
|
|
94
|
+
else {
|
|
95
|
+
if (ontology.schema !== "zob.project-dna-ontology.v1") blocking.push("ontology schema mismatch");
|
|
96
|
+
if (ontology.knowledge_backend_write_enabled !== false) blocking.push("ontology must keep knowledge_backend_write_enabled=false");
|
|
97
|
+
if (ontology.promotion_policy !== "proposal_only") blocking.push("ontology promotion_policy must be proposal_only");
|
|
98
|
+
}
|
|
99
|
+
if (!goldenCases) blocking.push("golden-cases-smoke.json missing for 5/5 agentic smoke");
|
|
100
|
+
else {
|
|
101
|
+
if (goldenCases.schema !== "zob.project-dna-golden-suite.v1") blocking.push("golden cases schema mismatch");
|
|
102
|
+
if (!Array.isArray(goldenCases.cases) || goldenCases.cases.length < 5) blocking.push("golden cases must include at least five cases");
|
|
103
|
+
if (goldenCases.knowledge_backend_write_enabled !== false) blocking.push("golden cases backend write flag must be false");
|
|
104
|
+
}
|
|
105
|
+
if (!querySteward) blocking.push("query-steward-smoke.json missing for 5/5 agentic smoke");
|
|
106
|
+
else {
|
|
107
|
+
if (querySteward.schema !== "zob.project-dna-query-steward-report.v1") blocking.push("query steward schema mismatch");
|
|
108
|
+
if (querySteward.raw_query_persisted !== false) blocking.push("query steward must not persist raw query");
|
|
109
|
+
if (querySteward.controlled_expansion?.stored_raw_terms !== false) blocking.push("query steward must not persist raw expansion terms");
|
|
110
|
+
if (querySteward.loading_rules?.bounded_context_only !== true) blocking.push("query steward must be bounded_context_only");
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const review = {
|
|
114
|
+
schema: "zob.oracle-review.v1",
|
|
115
|
+
reviewedRunId: "project-dna-smoke-local-artifacts",
|
|
116
|
+
verdict: blocking.length === 0 ? "PASS" : "FAIL",
|
|
117
|
+
no_ship: blocking.length > 0,
|
|
118
|
+
evidence: blocking.length === 0
|
|
119
|
+
? "ProjectDNA 5/5 agentic smoke artifacts passed deterministic scan/query-steward/ontology/golden/sample benchmark and remain proposal-only with no external knowledge-backend writes."
|
|
120
|
+
: "ProjectDNA 5/5 agentic smoke artifacts failed structural oracle checks.",
|
|
121
|
+
reviewer: "project-dna-structural-oracle",
|
|
122
|
+
blocking_issues: blocking,
|
|
123
|
+
non_blocking_notes: notes,
|
|
124
|
+
evidence_refs: [
|
|
125
|
+
`${scanDirRel}/scan-summary.json`,
|
|
126
|
+
relative(repoRoot, benchmarkPath).split(sep).join("/"),
|
|
127
|
+
`${scanDirRel}/context-pack-smoke.json`,
|
|
128
|
+
`${scanDirRel}/ontology.json`,
|
|
129
|
+
`${scanDirRel}/golden-cases-smoke.json`,
|
|
130
|
+
`${scanDirRel}/query-steward-smoke.json`,
|
|
131
|
+
`${scanDirRel}/quarantine/sample-project/project-dna-sample-summary.json`,
|
|
132
|
+
`${scanDirRel}/query-result-smoke.json`
|
|
133
|
+
],
|
|
134
|
+
promotion: {
|
|
135
|
+
durable_promotion_allowed: false,
|
|
136
|
+
reason: "Smoke oracle covers scaffold readiness only. Durable knowledge/sample promotion still requires human approval and a real-project run review.",
|
|
137
|
+
human_approval_required: true,
|
|
138
|
+
writeback_policy: "proposal_only"
|
|
139
|
+
},
|
|
140
|
+
safety: {
|
|
141
|
+
source_project_modified: false,
|
|
142
|
+
knowledge_backend_write_enabled: false,
|
|
143
|
+
secrets_read: false,
|
|
144
|
+
production_writes_performed: false
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
writeFileSync(outPath, `${JSON.stringify(review, null, 2)}\n`, "utf8");
|
|
148
|
+
console.log(JSON.stringify(review, null, 2));
|
|
149
|
+
if (blocking.length > 0) process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
main();
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.error(JSON.stringify({ schema: "zob.project-dna-oracle-review-error.v1", error: error instanceof Error ? error.message : String(error), source_project_modified: false, knowledge_backend_write_enabled: false }, null, 2));
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|