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,383 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { basename, join } from "node:path";
|
|
4
|
+
|
|
5
|
+
const repoRoot = process.cwd();
|
|
6
|
+
const errors = [];
|
|
7
|
+
const warnings = [];
|
|
8
|
+
|
|
9
|
+
function rel(path) {
|
|
10
|
+
return path.replace(repoRoot + "/", "");
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function requireFile(path) {
|
|
14
|
+
const full = join(repoRoot, path);
|
|
15
|
+
if (!existsSync(full)) {
|
|
16
|
+
errors.push(`missing required file: ${path}`);
|
|
17
|
+
return "";
|
|
18
|
+
}
|
|
19
|
+
return readFileSync(full, "utf8");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function readJson(path) {
|
|
23
|
+
const text = requireFile(path);
|
|
24
|
+
if (!text) return undefined;
|
|
25
|
+
try {
|
|
26
|
+
return JSON.parse(text);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
errors.push(`invalid JSON in ${path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function isSafeArtifactName(value) {
|
|
34
|
+
return typeof value === "string"
|
|
35
|
+
&& value.length > 0
|
|
36
|
+
&& value === basename(value)
|
|
37
|
+
&& !value.includes("..")
|
|
38
|
+
&& !value.includes("/")
|
|
39
|
+
&& !value.includes("\\")
|
|
40
|
+
&& /^[a-zA-Z0-9._-]+$/.test(value);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function assert(condition, message) {
|
|
44
|
+
if (!condition) errors.push(message);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function assertIncludes(text, needle, path) {
|
|
48
|
+
if (!text.includes(needle)) errors.push(`${path} must include: ${needle}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const requiredFiles = [
|
|
52
|
+
"docs/ZOB_PROJECT_DNA_CODE_KNOWLEDGE_GRAPH_PLAN.md",
|
|
53
|
+
"docs/ZOB_COMPUTE_PROFILE_ROUTING_PLAN.md",
|
|
54
|
+
".pi/skills/zob-compute-profile/SKILL.md",
|
|
55
|
+
".pi/skills/zob-project-dna/SKILL.md",
|
|
56
|
+
".pi/prompts/compute-preview.md",
|
|
57
|
+
".pi/prompts/compute-plan.md",
|
|
58
|
+
".pi/prompts/project-dna.md",
|
|
59
|
+
".pi/factories/project-dna/README.md",
|
|
60
|
+
".pi/factories/project-dna/factory.json",
|
|
61
|
+
".pi/factories/project-dna/smoke-manifest.json",
|
|
62
|
+
".pi/factories/project-dna/pilot-manifest.json",
|
|
63
|
+
".pi/factories/project-dna/batch-manifest.json",
|
|
64
|
+
".pi/factories/project-dna/example-project-dna-manifest.json",
|
|
65
|
+
".pi/factories/project-dna/example-project-dna-manifest-v2.json",
|
|
66
|
+
".pi/factories/project-dna/schemas/manifest.schema.json",
|
|
67
|
+
".pi/factories/project-dna/schemas/manifest-v2.schema.json",
|
|
68
|
+
".pi/factories/project-dna/schemas/project-fingerprint.schema.json",
|
|
69
|
+
".pi/factories/project-dna/schemas/code-knowledge-graph.schema.json",
|
|
70
|
+
".pi/factories/project-dna/schemas/context-pack.schema.json",
|
|
71
|
+
".pi/factories/project-dna/schemas/ontology.schema.json",
|
|
72
|
+
".pi/factories/project-dna/schemas/golden-case.schema.json",
|
|
73
|
+
".pi/factories/project-dna/schemas/query-steward-report.schema.json",
|
|
74
|
+
".pi/factories/project-dna/schemas/benchmark-suite.schema.json",
|
|
75
|
+
".pi/factories/project-dna/pi-agentic-ontology.json",
|
|
76
|
+
".pi/factories/project-dna/golden-cases-smoke.json",
|
|
77
|
+
".pi/agents/project-dna-ontology-steward.md",
|
|
78
|
+
".pi/agents/project-dna-query-steward.md",
|
|
79
|
+
".pi/agents/project-dna-test-linker.md",
|
|
80
|
+
".pi/agents/project-dna-golden-evaluator.md",
|
|
81
|
+
"scripts/compute-profile/preview.mjs",
|
|
82
|
+
"scripts/compute-profile/validate-preview.mjs",
|
|
83
|
+
".pi/compute-profiles/defaults.json",
|
|
84
|
+
".pi/compute-profiles/overrides.json",
|
|
85
|
+
".pi/compute-profiles/risk-rules.json",
|
|
86
|
+
"scripts/compute-profile/plan-workflow.mjs",
|
|
87
|
+
"scripts/compute-profile/validate-workflow.mjs",
|
|
88
|
+
"scripts/compute-profile/validate-policy.mjs",
|
|
89
|
+
"scripts/compute-profile/summarize.mjs",
|
|
90
|
+
"scripts/compute-profile/regression-smoke.mjs",
|
|
91
|
+
"scripts/project-dna/scan.mjs",
|
|
92
|
+
"scripts/project-dna/plan-workflow.mjs",
|
|
93
|
+
"scripts/project-dna/validate-workflow.mjs",
|
|
94
|
+
"scripts/project-dna/validate-scan-artifacts.mjs",
|
|
95
|
+
"scripts/project-dna/build-capsules.mjs",
|
|
96
|
+
"scripts/project-dna/build-sample-spec.mjs",
|
|
97
|
+
"scripts/project-dna/generate-sample.mjs",
|
|
98
|
+
"scripts/project-dna/validate-sample-project.mjs",
|
|
99
|
+
"scripts/project-dna/query-context.mjs",
|
|
100
|
+
"scripts/project-dna/emit-ontology.mjs",
|
|
101
|
+
"scripts/project-dna/validate-ontology.mjs",
|
|
102
|
+
"scripts/project-dna/emit-golden-cases.mjs",
|
|
103
|
+
"scripts/project-dna/validate-golden-cases.mjs",
|
|
104
|
+
"scripts/project-dna/query-steward.mjs",
|
|
105
|
+
"scripts/project-dna/validate-5of5.mjs",
|
|
106
|
+
".pi/extensions/zob-harness/src/project-dna.ts",
|
|
107
|
+
".pi/extensions/zob-harness/src/runtime/tools-project-dna.ts",
|
|
108
|
+
"scripts/project-dna/bench-smoke.mjs",
|
|
109
|
+
"scripts/project-dna/oracle-review-smoke.mjs",
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
for (const file of requiredFiles) requireFile(file);
|
|
113
|
+
|
|
114
|
+
const factory = readJson(".pi/factories/project-dna/factory.json");
|
|
115
|
+
if (factory) {
|
|
116
|
+
assert(factory.name === "project-dna", "factory name must be project-dna");
|
|
117
|
+
assert(factory.defaultMode === "smoke", "factory defaultMode must be smoke");
|
|
118
|
+
assert(factory.autoPromotion === false, "factory autoPromotion must be false");
|
|
119
|
+
assert(factory.manualPromotionRequired === true, "factory manualPromotionRequired must be true");
|
|
120
|
+
assert(Array.isArray(factory.requiredStages), "factory requiredStages must be an array");
|
|
121
|
+
for (const stage of factory.requiredStages ?? []) {
|
|
122
|
+
assert(["manifest_loaded", "agentic_plan_written", "item_processed", "validation", "sentinel"].includes(stage), `unexpected ProjectDNA required stage: ${stage}`);
|
|
123
|
+
}
|
|
124
|
+
assert(Array.isArray(factory.expectedArtifacts) && factory.expectedArtifacts.length >= 3, "factory expectedArtifacts must list ProjectDNA artifacts");
|
|
125
|
+
for (const artifact of factory.expectedArtifacts ?? []) {
|
|
126
|
+
assert(isSafeArtifactName(artifact), `expected artifact must be a safe basename: ${artifact}`);
|
|
127
|
+
}
|
|
128
|
+
const stageTypes = new Set((factory.stages ?? []).map((stage) => stage.type));
|
|
129
|
+
assert(stageTypes.has("map"), "factory must include a map stage");
|
|
130
|
+
assert(stageTypes.has("reduce"), "factory must include a reduce stage");
|
|
131
|
+
assert(stageTypes.has("validate"), "factory must include a validate stage");
|
|
132
|
+
for (const stage of factory.stages ?? []) {
|
|
133
|
+
assert(Array.isArray(stage.requiredTools), `stage ${stage.name} requiredTools must be an array`);
|
|
134
|
+
for (const tool of stage.requiredTools ?? []) {
|
|
135
|
+
assert(["read", "grep", "find", "ls"].includes(tool), `stage ${stage.name} must stay read-only; found tool ${tool}`);
|
|
136
|
+
}
|
|
137
|
+
assert((stage.mustNotDo ?? []).some((rule) => /secret/i.test(rule)), `stage ${stage.name} must forbid secrets`);
|
|
138
|
+
assert((stage.mustNotDo ?? []).some((rule) => /external knowledge[- ]backend/.test(rule)), `stage ${stage.name} must forbid unapproved external knowledge-backend writes/imports`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
for (const manifestPath of ["smoke-manifest.json", "pilot-manifest.json", "batch-manifest.json"].map((name) => `.pi/factories/project-dna/${name}`)) {
|
|
143
|
+
const manifest = readJson(manifestPath);
|
|
144
|
+
if (!manifest) continue;
|
|
145
|
+
assert(manifest.factory === "project-dna", `${manifestPath} factory must be project-dna`);
|
|
146
|
+
assert(Array.isArray(manifest.items) && manifest.items.length > 0, `${manifestPath} must include at least one item`);
|
|
147
|
+
for (const item of manifest.items ?? []) {
|
|
148
|
+
assert(typeof item.id === "string" && item.id.length > 0, `${manifestPath} item requires id`);
|
|
149
|
+
assert(typeof item.path === "string" && item.path.length > 0, `${manifestPath} item requires path`);
|
|
150
|
+
if (typeof item.path === "string" && !existsSync(join(repoRoot, item.path))) {
|
|
151
|
+
errors.push(`${manifestPath} item path does not exist: ${item.path}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const projectDnaExampleManifest = readJson(".pi/factories/project-dna/example-project-dna-manifest.json");
|
|
157
|
+
if (projectDnaExampleManifest) {
|
|
158
|
+
assert(projectDnaExampleManifest.schema === "zob.project-dna-manifest.v1", "example ProjectDNA manifest schema mismatch");
|
|
159
|
+
assert(projectDnaExampleManifest.source_project?.source_id === "project-dna-factory", "example ProjectDNA manifest source_id mismatch");
|
|
160
|
+
assert(["auto", "low", "medium", "high", "xhigh", "max"].includes(projectDnaExampleManifest.compute_profile), "example ProjectDNA manifest compute_profile invalid or missing");
|
|
161
|
+
assert(projectDnaExampleManifest.compute_caps?.maxAgents <= 30, "example ProjectDNA manifest compute_caps.maxAgents must stay <= 30");
|
|
162
|
+
assert(projectDnaExampleManifest.promotion?.writeback_policy === "proposal_only", "example ProjectDNA manifest must be proposal_only");
|
|
163
|
+
for (const allowedPath of projectDnaExampleManifest.read_policy?.allowed_paths ?? []) {
|
|
164
|
+
if (!existsSync(join(repoRoot, allowedPath))) errors.push(`example ProjectDNA manifest allowed path does not exist: ${allowedPath}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const projectDnaExampleManifestV2 = readJson(".pi/factories/project-dna/example-project-dna-manifest-v2.json");
|
|
169
|
+
if (projectDnaExampleManifestV2) {
|
|
170
|
+
assert(projectDnaExampleManifestV2.schema === "zob.project-dna-manifest.v2", "example ProjectDNA manifest v2 schema mismatch");
|
|
171
|
+
assert(typeof projectDnaExampleManifestV2.user_note === "string" && projectDnaExampleManifestV2.user_note.length > 0, "example ProjectDNA manifest v2 user_note required");
|
|
172
|
+
assert(projectDnaExampleManifestV2.capture_goal?.source_id === "project-dna-factory", "example ProjectDNA manifest v2 capture_goal.source_id mismatch");
|
|
173
|
+
assert(projectDnaExampleManifestV2.capture_goal?.bounded_context_only === true, "example ProjectDNA manifest v2 must be bounded context only");
|
|
174
|
+
assert(projectDnaExampleManifestV2.capture_goal?.citation_required === true, "example ProjectDNA manifest v2 must require citations");
|
|
175
|
+
assert(["auto", "low", "medium", "high", "xhigh", "max"].includes(projectDnaExampleManifestV2.requested_compute_profile), "example ProjectDNA manifest v2 requested_compute_profile invalid or missing");
|
|
176
|
+
assert(["full_capture", "architecture_only", "targeted_capture", "sample_first", "context_only"].includes(projectDnaExampleManifestV2.capture_mode_policy?.semantic_mode), "example ProjectDNA manifest v2 semantic_mode invalid or missing");
|
|
177
|
+
assert(projectDnaExampleManifestV2.capture_mode_policy?.semantic_mode === "architecture_only", "example ProjectDNA manifest v2 semantic_mode should be architecture_only for smoke");
|
|
178
|
+
assert(projectDnaExampleManifestV2.capture_mode_policy?.metadata_only === true, "example ProjectDNA manifest v2 must be metadata-only");
|
|
179
|
+
assert(projectDnaExampleManifestV2.capture_mode_policy?.parent_owned_dispatch === true, "example ProjectDNA manifest v2 must keep parent-owned dispatch");
|
|
180
|
+
assert(projectDnaExampleManifestV2.capture_mode_policy?.child_direct_dispatch_allowed === false, "example ProjectDNA manifest v2 must reject child direct dispatch");
|
|
181
|
+
assert(projectDnaExampleManifestV2.capture_mode_policy?.source_mutation_allowed === false, "example ProjectDNA manifest v2 must reject source mutation");
|
|
182
|
+
assert(projectDnaExampleManifestV2.capture_mode_policy?.knowledge_backend_write_allowed === false, "example ProjectDNA manifest v2 must reject backend writes");
|
|
183
|
+
assert(projectDnaExampleManifestV2.compute_caps?.maxAgents <= 30, "example ProjectDNA manifest v2 compute_caps.maxAgents must stay <= 30");
|
|
184
|
+
assert(projectDnaExampleManifestV2.read_policy?.forbid_secret_like_paths === true, "example ProjectDNA manifest v2 must forbid secret-like paths");
|
|
185
|
+
assert(projectDnaExampleManifestV2.read_policy?.external_project_scan_allowed === false, "example ProjectDNA manifest v2 must reject external project scan");
|
|
186
|
+
assert(projectDnaExampleManifestV2.sample_project?.quarantine_required === true, "example ProjectDNA manifest v2 sample project must require quarantine");
|
|
187
|
+
assert(projectDnaExampleManifestV2.promotion?.writeback_policy === "proposal_only", "example ProjectDNA manifest v2 must be proposal_only");
|
|
188
|
+
assert(projectDnaExampleManifestV2.promotion?.durable_promotion_allowed === false, "example ProjectDNA manifest v2 must reject durable promotion");
|
|
189
|
+
for (const allowedPath of projectDnaExampleManifestV2.read_policy?.allowed_paths ?? []) {
|
|
190
|
+
if (!existsSync(join(repoRoot, allowedPath))) errors.push(`example ProjectDNA manifest v2 allowed path does not exist: ${allowedPath}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
for (const schemaPath of [
|
|
195
|
+
".pi/factories/project-dna/schemas/manifest.schema.json",
|
|
196
|
+
".pi/factories/project-dna/schemas/manifest-v2.schema.json",
|
|
197
|
+
".pi/factories/project-dna/schemas/project-fingerprint.schema.json",
|
|
198
|
+
".pi/factories/project-dna/schemas/code-knowledge-graph.schema.json",
|
|
199
|
+
".pi/factories/project-dna/schemas/context-pack.schema.json",
|
|
200
|
+
".pi/factories/project-dna/schemas/ontology.schema.json",
|
|
201
|
+
".pi/factories/project-dna/schemas/golden-case.schema.json",
|
|
202
|
+
".pi/factories/project-dna/schemas/query-steward-report.schema.json",
|
|
203
|
+
".pi/factories/project-dna/schemas/benchmark-suite.schema.json",
|
|
204
|
+
]) {
|
|
205
|
+
const schema = readJson(schemaPath);
|
|
206
|
+
if (!schema) continue;
|
|
207
|
+
const hasSchemaId = typeof schema.$id === "string" && schema.$id.length > 0;
|
|
208
|
+
assert(hasSchemaId, `${schemaPath} should have a non-empty $id`);
|
|
209
|
+
if (hasSchemaId && !schema.$id.includes("project") && !schema.$id.includes("code-knowledge-graph")) {
|
|
210
|
+
warnings.push(`${schemaPath} $id is present but does not include project/code-knowledge-graph: ${schema.$id}`);
|
|
211
|
+
}
|
|
212
|
+
assert(schema.type === "object", `${schemaPath} root type must be object`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const computeSkillText = requireFile(".pi/skills/zob-compute-profile/SKILL.md");
|
|
216
|
+
assertIncludes(computeSkillText, "xhigh", ".pi/skills/zob-compute-profile/SKILL.md");
|
|
217
|
+
assertIncludes(computeSkillText, "No-ship rules", ".pi/skills/zob-compute-profile/SKILL.md");
|
|
218
|
+
assertIncludes(computeSkillText, "child direct dispatch", ".pi/skills/zob-compute-profile/SKILL.md");
|
|
219
|
+
|
|
220
|
+
const skillText = requireFile(".pi/skills/zob-project-dna/SKILL.md");
|
|
221
|
+
assertIncludes(skillText, "ProjectDNA", ".pi/skills/zob-project-dna/SKILL.md");
|
|
222
|
+
assertIncludes(skillText, "No external knowledge backend import", ".pi/skills/zob-project-dna/SKILL.md");
|
|
223
|
+
assertIncludes(skillText, "No-ship rules", ".pi/skills/zob-project-dna/SKILL.md");
|
|
224
|
+
assertIncludes(skillText, "quarantine", ".pi/skills/zob-project-dna/SKILL.md");
|
|
225
|
+
assertIncludes(skillText, "5/5", ".pi/skills/zob-project-dna/SKILL.md");
|
|
226
|
+
assertIncludes(skillText, "Query Steward", ".pi/skills/zob-project-dna/SKILL.md");
|
|
227
|
+
|
|
228
|
+
const computePreviewPrompt = requireFile(".pi/prompts/compute-preview.md");
|
|
229
|
+
assertIncludes(computePreviewPrompt, "zob-compute-profile", ".pi/prompts/compute-preview.md");
|
|
230
|
+
assertIncludes(computePreviewPrompt, "xhigh", ".pi/prompts/compute-preview.md");
|
|
231
|
+
|
|
232
|
+
const promptText = requireFile(".pi/prompts/project-dna.md");
|
|
233
|
+
assertIncludes(promptText, "zob-project-dna", ".pi/prompts/project-dna.md");
|
|
234
|
+
assertIncludes(promptText, "context", ".pi/prompts/project-dna.md");
|
|
235
|
+
assertIncludes(promptText, "factory_run", ".pi/prompts/project-dna.md");
|
|
236
|
+
assertIncludes(promptText, "5/5", ".pi/prompts/project-dna.md");
|
|
237
|
+
assertIncludes(promptText, "Query Steward", ".pi/prompts/project-dna.md");
|
|
238
|
+
|
|
239
|
+
const computePreviewScript = requireFile("scripts/compute-profile/preview.mjs");
|
|
240
|
+
assertIncludes(computePreviewScript, "zob.compute-preview.v1", "scripts/compute-profile/preview.mjs");
|
|
241
|
+
assertIncludes(computePreviewScript, "childDispatchAllowed: false", "scripts/compute-profile/preview.mjs");
|
|
242
|
+
assertIncludes(computePreviewScript, "knowledgeBackendWriteEnabled: false", "scripts/compute-profile/preview.mjs");
|
|
243
|
+
|
|
244
|
+
const computeValidateScript = requireFile("scripts/compute-profile/validate-preview.mjs");
|
|
245
|
+
assertIncludes(computeValidateScript, "zob.compute-profile-validation.v1", "scripts/compute-profile/validate-preview.mjs");
|
|
246
|
+
assertIncludes(computeValidateScript, "childDispatchAllowed", "scripts/compute-profile/validate-preview.mjs");
|
|
247
|
+
|
|
248
|
+
const computeWorkflowScript = requireFile("scripts/compute-profile/plan-workflow.mjs");
|
|
249
|
+
assertIncludes(computeWorkflowScript, "zob.compute-workflow-shape.v1", "scripts/compute-profile/plan-workflow.mjs");
|
|
250
|
+
assertIncludes(computeWorkflowScript, "childDirectDispatch: false", "scripts/compute-profile/plan-workflow.mjs");
|
|
251
|
+
|
|
252
|
+
const computePolicyScript = requireFile("scripts/compute-profile/validate-policy.mjs");
|
|
253
|
+
assertIncludes(computePolicyScript, "zob.compute-profile-policy-validation.v1", "scripts/compute-profile/validate-policy.mjs");
|
|
254
|
+
assertIncludes(computePolicyScript, "max profile must require human approval", "scripts/compute-profile/validate-policy.mjs");
|
|
255
|
+
|
|
256
|
+
const computeSummaryScript = requireFile("scripts/compute-profile/summarize.mjs");
|
|
257
|
+
assertIncludes(computeSummaryScript, "zob.compute-mission-control-summary.v1", "scripts/compute-profile/summarize.mjs");
|
|
258
|
+
assertIncludes(computeSummaryScript, "fullHudWidgetWiringBlocker", "scripts/compute-profile/summarize.mjs");
|
|
259
|
+
|
|
260
|
+
const computeRegressionScript = requireFile("scripts/compute-profile/regression-smoke.mjs");
|
|
261
|
+
assertIncludes(computeRegressionScript, "zob.compute-profile-regression-smoke.v1", "scripts/compute-profile/regression-smoke.mjs");
|
|
262
|
+
assertIncludes(computeRegressionScript, "max must require human approval", "scripts/compute-profile/regression-smoke.mjs");
|
|
263
|
+
|
|
264
|
+
const projectDnaWorkflowPlannerScript = requireFile("scripts/project-dna/plan-workflow.mjs");
|
|
265
|
+
assertIncludes(projectDnaWorkflowPlannerScript, "zob.project-dna-agentic-plan.v1", "scripts/project-dna/plan-workflow.mjs");
|
|
266
|
+
assertIncludes(projectDnaWorkflowPlannerScript, "effectiveCaptureMode", "scripts/project-dna/plan-workflow.mjs");
|
|
267
|
+
assertIncludes(projectDnaWorkflowPlannerScript, "repo-scout", "scripts/project-dna/plan-workflow.mjs");
|
|
268
|
+
assertIncludes(projectDnaWorkflowPlannerScript, "architecture-cartographer", "scripts/project-dna/plan-workflow.mjs");
|
|
269
|
+
assertIncludes(projectDnaWorkflowPlannerScript, "project-dna-query-steward", "scripts/project-dna/plan-workflow.mjs");
|
|
270
|
+
assertIncludes(projectDnaWorkflowPlannerScript, "project-dna-golden-evaluator", "scripts/project-dna/plan-workflow.mjs");
|
|
271
|
+
assertIncludes(projectDnaWorkflowPlannerScript, "childDirectDispatch: false", "scripts/project-dna/plan-workflow.mjs");
|
|
272
|
+
assertIncludes(projectDnaWorkflowPlannerScript, "knowledgeBackendWriteEnabled: false", "scripts/project-dna/plan-workflow.mjs");
|
|
273
|
+
assertIncludes(projectDnaWorkflowPlannerScript, "rawBodiesStored: false", "scripts/project-dna/plan-workflow.mjs");
|
|
274
|
+
|
|
275
|
+
const projectDnaWorkflowValidatorScript = requireFile("scripts/project-dna/validate-workflow.mjs");
|
|
276
|
+
assertIncludes(projectDnaWorkflowValidatorScript, "zob.project-dna-agentic-plan-validation.v1", "scripts/project-dna/validate-workflow.mjs");
|
|
277
|
+
assertIncludes(projectDnaWorkflowValidatorScript, "effectiveCaptureMode", "scripts/project-dna/validate-workflow.mjs");
|
|
278
|
+
assertIncludes(projectDnaWorkflowValidatorScript, "raw key forbidden", "scripts/project-dna/validate-workflow.mjs");
|
|
279
|
+
assertIncludes(projectDnaWorkflowValidatorScript, "childDirectDispatch", "scripts/project-dna/validate-workflow.mjs");
|
|
280
|
+
|
|
281
|
+
const packageJson = readJson("package.json");
|
|
282
|
+
if (packageJson) {
|
|
283
|
+
assert(typeof packageJson.scripts?.["plan:project-dna-workflow:smoke"] === "string", "package.json must include plan:project-dna-workflow:smoke");
|
|
284
|
+
assert(typeof packageJson.scripts?.["validate:project-dna-workflow:smoke"] === "string", "package.json must include validate:project-dna-workflow:smoke");
|
|
285
|
+
assert(typeof packageJson.scripts?.["emit:project-dna-ontology:smoke"] === "string", "package.json must include emit:project-dna-ontology:smoke");
|
|
286
|
+
assert(typeof packageJson.scripts?.["validate:project-dna-ontology:smoke"] === "string", "package.json must include validate:project-dna-ontology:smoke");
|
|
287
|
+
assert(typeof packageJson.scripts?.["emit:project-dna-golden-cases:smoke"] === "string", "package.json must include emit:project-dna-golden-cases:smoke");
|
|
288
|
+
assert(typeof packageJson.scripts?.["validate:project-dna-golden-cases:smoke"] === "string", "package.json must include validate:project-dna-golden-cases:smoke");
|
|
289
|
+
assert(typeof packageJson.scripts?.["steward:project-dna-query:smoke"] === "string", "package.json must include steward:project-dna-query:smoke");
|
|
290
|
+
assert(typeof packageJson.scripts?.["validate:project-dna-5of5:smoke"] === "string", "package.json must include validate:project-dna-5of5:smoke");
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const scanScript = requireFile("scripts/project-dna/scan.mjs");
|
|
294
|
+
assertIncludes(scanScript, "DEFAULT_FORBIDDEN", "scripts/project-dna/scan.mjs");
|
|
295
|
+
assertIncludes(scanScript, "assertSourceAllowedByManifest", "scripts/project-dna/scan.mjs");
|
|
296
|
+
assertIncludes(scanScript, "source_project_modified: false", "scripts/project-dna/scan.mjs");
|
|
297
|
+
assertIncludes(scanScript, "knowledge_backend_write_enabled: false", "scripts/project-dna/scan.mjs");
|
|
298
|
+
|
|
299
|
+
const scanValidatorScript = requireFile("scripts/project-dna/validate-scan-artifacts.mjs");
|
|
300
|
+
assertIncludes(scanValidatorScript, "citation line range outside file-map lines", "scripts/project-dna/validate-scan-artifacts.mjs");
|
|
301
|
+
assertIncludes(scanValidatorScript, "source_project_modified: false", "scripts/project-dna/validate-scan-artifacts.mjs");
|
|
302
|
+
assertIncludes(scanValidatorScript, "knowledge_backend_write_enabled: false", "scripts/project-dna/validate-scan-artifacts.mjs");
|
|
303
|
+
|
|
304
|
+
const capsuleScript = requireFile("scripts/project-dna/build-capsules.mjs");
|
|
305
|
+
assertIncludes(capsuleScript, "scan_metadata_only: true", "scripts/project-dna/build-capsules.mjs");
|
|
306
|
+
assertIncludes(capsuleScript, "source_project_modified: false", "scripts/project-dna/build-capsules.mjs");
|
|
307
|
+
assertIncludes(capsuleScript, "knowledge_backend_write_enabled: false", "scripts/project-dna/build-capsules.mjs");
|
|
308
|
+
|
|
309
|
+
const sampleSpecScript = requireFile("scripts/project-dna/build-sample-spec.mjs");
|
|
310
|
+
assertIncludes(sampleSpecScript, "spec_only_no_code_generated", "scripts/project-dna/build-sample-spec.mjs");
|
|
311
|
+
assertIncludes(sampleSpecScript, "sample_code_generated: false", "scripts/project-dna/build-sample-spec.mjs");
|
|
312
|
+
assertIncludes(sampleSpecScript, "source_project_modified: false", "scripts/project-dna/build-sample-spec.mjs");
|
|
313
|
+
assertIncludes(sampleSpecScript, "knowledge_backend_write_enabled: false", "scripts/project-dna/build-sample-spec.mjs");
|
|
314
|
+
|
|
315
|
+
const sampleGeneratorScript = requireFile("scripts/project-dna/generate-sample.mjs");
|
|
316
|
+
assertIncludes(sampleGeneratorScript, "assertQuarantineOutDir", "scripts/project-dna/generate-sample.mjs");
|
|
317
|
+
assertIncludes(sampleGeneratorScript, "source_files_copied: false", "scripts/project-dna/generate-sample.mjs");
|
|
318
|
+
assertIncludes(sampleGeneratorScript, "source_project_modified: false", "scripts/project-dna/generate-sample.mjs");
|
|
319
|
+
assertIncludes(sampleGeneratorScript, "knowledge_backend_write_enabled: false", "scripts/project-dna/generate-sample.mjs");
|
|
320
|
+
|
|
321
|
+
const sampleValidatorScript = requireFile("scripts/project-dna/validate-sample-project.mjs");
|
|
322
|
+
assertIncludes(sampleValidatorScript, "quarantine_only", "scripts/project-dna/validate-sample-project.mjs");
|
|
323
|
+
assertIncludes(sampleValidatorScript, "node --check", "scripts/project-dna/validate-sample-project.mjs");
|
|
324
|
+
assertIncludes(sampleValidatorScript, "source_project_modified: false", "scripts/project-dna/validate-sample-project.mjs");
|
|
325
|
+
assertIncludes(sampleValidatorScript, "knowledge_backend_write_enabled: false", "scripts/project-dna/validate-sample-project.mjs");
|
|
326
|
+
|
|
327
|
+
const queryScript = requireFile("scripts/project-dna/query-context.mjs");
|
|
328
|
+
assertIncludes(queryScript, "query_stored: false", "scripts/project-dna/query-context.mjs");
|
|
329
|
+
assertIncludes(queryScript, "query_steward", "scripts/project-dna/query-context.mjs");
|
|
330
|
+
assertIncludes(queryScript, "bounded_context_only", "scripts/project-dna/query-context.mjs");
|
|
331
|
+
assertIncludes(queryScript, "agent_loads_entire_project: false", "scripts/project-dna/query-context.mjs");
|
|
332
|
+
assertIncludes(queryScript, "knowledge_backend_write_enabled: false", "scripts/project-dna/query-context.mjs");
|
|
333
|
+
|
|
334
|
+
const runtimeProjectDna = requireFile(".pi/extensions/zob-harness/src/project-dna.ts");
|
|
335
|
+
assertIncludes(runtimeProjectDna, "zob.project-dna-agentic-plan.v1", ".pi/extensions/zob-harness/src/project-dna.ts");
|
|
336
|
+
assertIncludes(runtimeProjectDna, "zob.project-dna-query-result.v1", ".pi/extensions/zob-harness/src/project-dna.ts");
|
|
337
|
+
assertIncludes(runtimeProjectDna, "zob.project-dna-federated-query-result.v1", ".pi/extensions/zob-harness/src/project-dna.ts");
|
|
338
|
+
assertIncludes(runtimeProjectDna, "knowledge_backend_write_enabled: false", ".pi/extensions/zob-harness/src/project-dna.ts");
|
|
339
|
+
assertIncludes(runtimeProjectDna, "durable_promotion_allowed: false", ".pi/extensions/zob-harness/src/project-dna.ts");
|
|
340
|
+
|
|
341
|
+
const runtimeProjectDnaTools = requireFile(".pi/extensions/zob-harness/src/runtime/tools-project-dna.ts");
|
|
342
|
+
assertIncludes(runtimeProjectDnaTools, "zob_project_dna_plan_workflow", ".pi/extensions/zob-harness/src/runtime/tools-project-dna.ts");
|
|
343
|
+
assertIncludes(runtimeProjectDnaTools, "zob_project_dna_query", ".pi/extensions/zob-harness/src/runtime/tools-project-dna.ts");
|
|
344
|
+
assertIncludes(runtimeProjectDnaTools, "zob_project_dna_federated_query", ".pi/extensions/zob-harness/src/runtime/tools-project-dna.ts");
|
|
345
|
+
assertIncludes(runtimeProjectDnaTools, "zob_project_dna_writeback_proposal", ".pi/extensions/zob-harness/src/runtime/tools-project-dna.ts");
|
|
346
|
+
|
|
347
|
+
const ontologyEmitterScript = requireFile("scripts/project-dna/emit-ontology.mjs");
|
|
348
|
+
assertIncludes(ontologyEmitterScript, "zob.project-dna-ontology-emission.v1", "scripts/project-dna/emit-ontology.mjs");
|
|
349
|
+
const ontologyValidatorScript = requireFile("scripts/project-dna/validate-ontology.mjs");
|
|
350
|
+
assertIncludes(ontologyValidatorScript, "zob.project-dna-ontology-validation.v1", "scripts/project-dna/validate-ontology.mjs");
|
|
351
|
+
const goldenEmitterScript = requireFile("scripts/project-dna/emit-golden-cases.mjs");
|
|
352
|
+
assertIncludes(goldenEmitterScript, "zob.project-dna-golden-cases-emission.v1", "scripts/project-dna/emit-golden-cases.mjs");
|
|
353
|
+
const goldenValidatorScript = requireFile("scripts/project-dna/validate-golden-cases.mjs");
|
|
354
|
+
assertIncludes(goldenValidatorScript, "zob.project-dna-golden-suite-validation.v1", "scripts/project-dna/validate-golden-cases.mjs");
|
|
355
|
+
const queryStewardScript = requireFile("scripts/project-dna/query-steward.mjs");
|
|
356
|
+
assertIncludes(queryStewardScript, "zob.project-dna-query-steward-report.v1", "scripts/project-dna/query-steward.mjs");
|
|
357
|
+
const fiveOfFiveValidatorScript = requireFile("scripts/project-dna/validate-5of5.mjs");
|
|
358
|
+
assertIncludes(fiveOfFiveValidatorScript, "zob.project-dna-5of5-validation.v1", "scripts/project-dna/validate-5of5.mjs");
|
|
359
|
+
|
|
360
|
+
const benchScript = requireFile("scripts/project-dna/bench-smoke.mjs");
|
|
361
|
+
assertIncludes(benchScript, "golden-agentic-5of5-smoke", "scripts/project-dna/bench-smoke.mjs");
|
|
362
|
+
assertIncludes(benchScript, "llm_judge_used: false", "scripts/project-dna/bench-smoke.mjs");
|
|
363
|
+
assertIncludes(benchScript, "promotion_allowed: false", "scripts/project-dna/bench-smoke.mjs");
|
|
364
|
+
assertIncludes(benchScript, "knowledge_backend_write_enabled: false", "scripts/project-dna/bench-smoke.mjs");
|
|
365
|
+
|
|
366
|
+
const oracleReviewScript = requireFile("scripts/project-dna/oracle-review-smoke.mjs");
|
|
367
|
+
assertIncludes(oracleReviewScript, "durable_promotion_allowed: false", "scripts/project-dna/oracle-review-smoke.mjs");
|
|
368
|
+
assertIncludes(oracleReviewScript, "writeback_policy: \"proposal_only\"", "scripts/project-dna/oracle-review-smoke.mjs");
|
|
369
|
+
assertIncludes(oracleReviewScript, "knowledge_backend_write_enabled: false", "scripts/project-dna/oracle-review-smoke.mjs");
|
|
370
|
+
|
|
371
|
+
const result = {
|
|
372
|
+
schema: "zob.project-dna-scaffold-validation.v1",
|
|
373
|
+
valid: errors.length === 0,
|
|
374
|
+
checkedFiles: requiredFiles.map((path) => rel(join(repoRoot, path))),
|
|
375
|
+
errors,
|
|
376
|
+
warnings,
|
|
377
|
+
noExternalProjectScanned: true,
|
|
378
|
+
sourceProjectModified: false,
|
|
379
|
+
knowledgeBackendWriteEnabled: false,
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
console.log(JSON.stringify(result, null, 2));
|
|
383
|
+
if (errors.length > 0) process.exit(1);
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
4
|
+
|
|
5
|
+
const repoRoot = process.cwd();
|
|
6
|
+
const REQUIRED = [
|
|
7
|
+
"scan-summary.json",
|
|
8
|
+
"project-fingerprint.json",
|
|
9
|
+
"dependency-map.json",
|
|
10
|
+
"file-map.json",
|
|
11
|
+
"symbol-map.json",
|
|
12
|
+
"import-graph.json",
|
|
13
|
+
"architecture-map.json",
|
|
14
|
+
"route-map.json",
|
|
15
|
+
"queue-map.json",
|
|
16
|
+
"config-map.json",
|
|
17
|
+
"test-map.json",
|
|
18
|
+
"db-map.json",
|
|
19
|
+
"code-knowledge-graph.json",
|
|
20
|
+
"context-pack-smoke.json",
|
|
21
|
+
"skipped-files.json",
|
|
22
|
+
];
|
|
23
|
+
const FORBIDDEN_BODY_KEYS = new Set(["body", "content", "prompt", "task", "output", "message", "rawConversation", "conversationHistory", "snippet"]);
|
|
24
|
+
|
|
25
|
+
function usage() {
|
|
26
|
+
console.error("Usage: node scripts/project-dna/validate-scan-artifacts.mjs --scan-dir <repo-relative-scan-dir>");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function parseArgs(argv) {
|
|
30
|
+
const out = {};
|
|
31
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
32
|
+
const arg = argv[i];
|
|
33
|
+
if (arg === "--scan-dir") out.scanDir = argv[++i];
|
|
34
|
+
else if (arg === "--help" || arg === "-h") out.help = true;
|
|
35
|
+
else throw new Error(`unknown argument: ${arg}`);
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function resolveRepoDir(input) {
|
|
41
|
+
if (!input || isAbsolute(input)) throw new Error("--scan-dir must be repo-relative");
|
|
42
|
+
const resolved = resolve(repoRoot, input);
|
|
43
|
+
const rel = relative(repoRoot, resolved);
|
|
44
|
+
if (rel.startsWith("..") || rel === "") throw new Error("--scan-dir must stay inside repo and not be repo root");
|
|
45
|
+
return resolved;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function readJson(scanDir, name, errors) {
|
|
49
|
+
const path = join(scanDir, name);
|
|
50
|
+
if (!existsSync(path)) {
|
|
51
|
+
errors.push(`missing artifact: ${name}`);
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
56
|
+
} catch (error) {
|
|
57
|
+
errors.push(`invalid JSON in ${name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function hasForbiddenBodyKey(value, path = "$", hits = []) {
|
|
63
|
+
if (!value || typeof value !== "object") return hits;
|
|
64
|
+
if (Array.isArray(value)) {
|
|
65
|
+
value.forEach((child, index) => hasForbiddenBodyKey(child, `${path}[${index}]`, hits));
|
|
66
|
+
return hits;
|
|
67
|
+
}
|
|
68
|
+
for (const [key, child] of Object.entries(value)) {
|
|
69
|
+
if (FORBIDDEN_BODY_KEYS.has(key)) hits.push(`${path}.${key}`);
|
|
70
|
+
hasForbiddenBodyKey(child, `${path}.${key}`, hits);
|
|
71
|
+
}
|
|
72
|
+
return hits;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function collectCitations(value, out = []) {
|
|
76
|
+
if (typeof value === "string") {
|
|
77
|
+
if (/^[^\s:]+:L\d+(?:-L?\d+)?$/.test(value)) out.push(value);
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
if (!value || typeof value !== "object") return out;
|
|
81
|
+
if (Array.isArray(value)) {
|
|
82
|
+
for (const item of value) collectCitations(item, out);
|
|
83
|
+
return out;
|
|
84
|
+
}
|
|
85
|
+
for (const [key, child] of Object.entries(value)) {
|
|
86
|
+
if (key.toLowerCase().includes("citation")) collectCitations(child, out);
|
|
87
|
+
else if (typeof child === "object") collectCitations(child, out);
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function parseCitation(citation) {
|
|
93
|
+
const match = /^(.+):L(\d+)(?:-L?(\d+))?$/.exec(citation);
|
|
94
|
+
if (!match) return undefined;
|
|
95
|
+
const start = Number(match[2]);
|
|
96
|
+
const end = match[3] ? Number(match[3]) : start;
|
|
97
|
+
return { path: match[1], start, end };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function main() {
|
|
101
|
+
const args = parseArgs(process.argv.slice(2));
|
|
102
|
+
if (args.help || !args.scanDir) {
|
|
103
|
+
usage();
|
|
104
|
+
if (!args.help) process.exit(2);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const errors = [];
|
|
108
|
+
const warnings = [];
|
|
109
|
+
const scanDir = resolveRepoDir(args.scanDir);
|
|
110
|
+
const artifacts = Object.fromEntries(REQUIRED.map((name) => [name, readJson(scanDir, name, errors)]));
|
|
111
|
+
if (errors.length === 0) {
|
|
112
|
+
const summary = artifacts["scan-summary.json"];
|
|
113
|
+
const fingerprint = artifacts["project-fingerprint.json"];
|
|
114
|
+
const fileMap = artifacts["file-map.json"];
|
|
115
|
+
const graph = artifacts["code-knowledge-graph.json"];
|
|
116
|
+
const contextPack = artifacts["context-pack-smoke.json"];
|
|
117
|
+
const routeMap = artifacts["route-map.json"];
|
|
118
|
+
const queueMap = artifacts["queue-map.json"];
|
|
119
|
+
const configMap = artifacts["config-map.json"];
|
|
120
|
+
const testMap = artifacts["test-map.json"];
|
|
121
|
+
const dbMap = artifacts["db-map.json"];
|
|
122
|
+
|
|
123
|
+
if (summary.schema !== "zob.project-dna-scan-summary.v1") errors.push("scan-summary schema mismatch");
|
|
124
|
+
if (summary.source_project_modified !== false) errors.push("scan summary must set source_project_modified=false");
|
|
125
|
+
if (summary.knowledge_backend_write_enabled !== false) errors.push("scan summary must set knowledge_backend_write_enabled=false");
|
|
126
|
+
if (fingerprint.schema !== "zob.project-fingerprint.v1") errors.push("project-fingerprint schema mismatch");
|
|
127
|
+
if (fingerprint.secret_scan?.secret_like_artifacts_included !== false) errors.push("project-fingerprint must report secret_like_artifacts_included=false");
|
|
128
|
+
if (fileMap.schema !== "zob.file-map.v1") errors.push("file-map schema mismatch");
|
|
129
|
+
if (routeMap.schema !== "zob.route-map.v1") errors.push("route-map schema mismatch");
|
|
130
|
+
if (queueMap.schema !== "zob.queue-map.v1") errors.push("queue-map schema mismatch");
|
|
131
|
+
if (configMap.schema !== "zob.config-map.v1") errors.push("config-map schema mismatch");
|
|
132
|
+
if (testMap.schema !== "zob.test-map.v1") errors.push("test-map schema mismatch");
|
|
133
|
+
if (dbMap.schema !== "zob.db-map.v1") errors.push("db-map schema mismatch");
|
|
134
|
+
if (graph.schema !== "zob.code-knowledge-graph.v1") errors.push("code-knowledge-graph schema mismatch");
|
|
135
|
+
if (graph.citation_required !== true) errors.push("code-knowledge-graph must require citations");
|
|
136
|
+
if (graph.promotion?.writeback_policy !== "proposal_only") errors.push("code-knowledge-graph promotion must be proposal_only");
|
|
137
|
+
if (contextPack.schema !== "zob.project-dna-context-pack.v1") errors.push("context-pack schema mismatch");
|
|
138
|
+
if (contextPack.query_stored !== false) errors.push("context-pack must not store raw query");
|
|
139
|
+
if (contextPack.loading_rules?.bounded_context_only !== true) errors.push("context-pack must be bounded_context_only");
|
|
140
|
+
if (contextPack.loading_rules?.citation_required !== true) errors.push("context-pack must require citations");
|
|
141
|
+
if (contextPack.loading_rules?.agent_loads_entire_project !== false) errors.push("context-pack must not load entire project");
|
|
142
|
+
|
|
143
|
+
for (const [name, artifact] of Object.entries(artifacts)) {
|
|
144
|
+
const bodyHits = hasForbiddenBodyKey(artifact);
|
|
145
|
+
if (bodyHits.length > 0) errors.push(`${name} contains forbidden raw/body-like keys: ${bodyHits.slice(0, 10).join(", ")}`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const fileLines = new Map((fileMap.files ?? []).map((file) => [file.path, file.lines]));
|
|
149
|
+
const allCitations = [...new Set(Object.values(artifacts).flatMap((artifact) => collectCitations(artifact)))].sort();
|
|
150
|
+
for (const citation of allCitations) {
|
|
151
|
+
const parsed = parseCitation(citation);
|
|
152
|
+
if (!parsed) {
|
|
153
|
+
errors.push(`invalid citation format: ${citation}`);
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
const lines = fileLines.get(parsed.path);
|
|
157
|
+
if (typeof lines !== "number") {
|
|
158
|
+
errors.push(`citation path not present in file-map: ${citation}`);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (parsed.start < 1 || parsed.end < parsed.start || parsed.end > lines) {
|
|
162
|
+
errors.push(`citation line range outside file-map lines (${lines}): ${citation}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (allCitations.length === 0) warnings.push("no L-line citations found in scan artifacts");
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const result = {
|
|
169
|
+
schema: "zob.project-dna-scan-validation.v1",
|
|
170
|
+
scan_dir: relative(repoRoot, scanDir),
|
|
171
|
+
valid: errors.length === 0,
|
|
172
|
+
errors,
|
|
173
|
+
warnings,
|
|
174
|
+
artifacts_checked: REQUIRED,
|
|
175
|
+
source_project_modified: false,
|
|
176
|
+
knowledge_backend_write_enabled: false,
|
|
177
|
+
};
|
|
178
|
+
console.log(JSON.stringify(result, null, 2));
|
|
179
|
+
if (errors.length > 0) process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
main();
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.error(JSON.stringify({ schema: "zob.project-dna-scan-validation-error.v1", error: error instanceof Error ? error.message : String(error), source_project_modified: false, knowledge_backend_write_enabled: false }, null, 2));
|
|
186
|
+
process.exit(1);
|
|
187
|
+
}
|