@kontourai/flow-agents 4.0.0 → 4.2.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/.github/workflows/ci.yml +8 -0
- package/CHANGELOG.md +34 -0
- package/CONTEXT.md +5 -0
- package/agents/tool-security-reviewer.json +1 -1
- package/build/src/cli/init.js +35 -3
- package/build/src/cli/kit.js +95 -2
- package/build/src/cli/pull-work-provider.js +7 -1
- package/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/build/src/cli/workflow.js +5 -1
- package/build/src/flow-kit/provision.d.ts +23 -0
- package/build/src/flow-kit/provision.js +99 -0
- package/build/src/flow-kit/validate.d.ts +52 -0
- package/build/src/flow-kit/validate.js +214 -9
- package/build/src/runtime-adapters.js +1 -1
- package/context/contracts/execution-contract.md +30 -1
- package/context/contracts/review-contract.md +4 -0
- package/context/contracts/trigger-guards.md +73 -0
- package/context/scripts/telemetry/lib/config.sh +29 -0
- package/context/settings/backlog-provider-settings.json +1 -1
- package/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/base/build/package.json +1 -1
- package/dist/base/build/src/cli/init.js +35 -3
- package/dist/base/build/src/cli/kit.js +95 -2
- package/dist/base/build/src/cli/pull-work-provider.js +7 -1
- package/dist/base/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/dist/base/build/src/cli/workflow.js +5 -1
- package/dist/base/build/src/flow-kit/provision.d.ts +23 -0
- package/dist/base/build/src/flow-kit/provision.js +99 -0
- package/dist/base/build/src/flow-kit/validate.d.ts +52 -0
- package/dist/base/build/src/flow-kit/validate.js +214 -9
- package/dist/base/build/src/runtime-adapters.js +1 -1
- package/dist/base/context/contracts/execution-contract.md +30 -1
- package/dist/base/context/contracts/review-contract.md +4 -0
- package/dist/base/context/contracts/trigger-guards.md +73 -0
- package/dist/base/context/scripts/telemetry/lib/config.sh +29 -0
- package/dist/base/context/settings/backlog-provider-settings.json +1 -1
- package/dist/base/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/base/docs/adr/0023-kit-provisioning.md +47 -0
- package/dist/base/docs/adr/index.md +1 -0
- package/dist/base/docs/architecture-engine-and-kits.md +17 -0
- package/dist/base/docs/context-map.md +3 -0
- package/dist/base/docs/decisions/backlog-readiness-source.md +89 -0
- package/dist/base/docs/decisions/index.md +1 -0
- package/dist/base/docs/developer-architecture.md +3 -3
- package/dist/base/docs/flow-kit-repository-contract.md +34 -3
- package/dist/base/docs/kit-authoring-guide.md +1 -1
- package/dist/base/docs/veritas-integration.md +12 -0
- package/dist/base/evals/ci/run-baseline.sh +4 -0
- package/dist/base/evals/integration/test_kit_provisioning.sh +112 -0
- package/dist/base/evals/integration/test_liveness_console_relay.sh +91 -1
- package/dist/base/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/dist/base/evals/integration/test_pull_work_provider.sh +18 -0
- package/dist/base/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/dist/base/evals/integration/test_workflow_artifacts.sh +257 -0
- package/dist/base/evals/static/test_package.sh +6 -0
- package/dist/base/evals/static/test_workflow_skills.sh +16 -0
- package/dist/base/install.sh +1 -1
- package/dist/base/kits/builder/flows/publish-learn.flow.json +9 -1
- package/dist/base/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/dist/base/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/dist/base/kits/builder/skills/review-work/SKILL.md +11 -0
- package/dist/base/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/dist/base/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/dist/base/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/dist/base/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/dist/base/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/dist/base/kits/veritas-governance/docs/README.md +141 -10
- package/dist/base/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/dist/base/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/dist/base/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/dist/base/kits/veritas-governance/kit.json +65 -0
- package/dist/base/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/dist/base/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/dist/base/schemas/backlog-provider-settings.schema.json +1 -1
- package/dist/base/schemas/workflow-waves.schema.json +347 -0
- package/dist/base/scripts/check-layer-boundary.mjs +98 -0
- package/dist/base/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/dist/base/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/dist/base/scripts/hooks/lib/liveness-write.js +109 -9
- package/dist/base/scripts/liveness/relay.sh +23 -11
- package/dist/base/scripts/telemetry/lib/config.sh +29 -0
- package/dist/catalog.json +2 -0
- package/dist/claude-code/.claude/agents/tool-security-reviewer.md +2 -1
- package/dist/claude-code/.claude/skills/consult-standards/SKILL.md +73 -0
- package/dist/claude-code/.claude/skills/execute-plan/SKILL.md +4 -3
- package/dist/claude-code/.claude/skills/pull-work/SKILL.md +12 -0
- package/dist/claude-code/.claude/skills/review-work/SKILL.md +11 -0
- package/dist/claude-code/.claude/skills/standards-authoring/SKILL.md +87 -0
- package/dist/claude-code/build/package.json +1 -1
- package/dist/claude-code/build/src/cli/init.js +35 -3
- package/dist/claude-code/build/src/cli/kit.js +95 -2
- package/dist/claude-code/build/src/cli/pull-work-provider.js +7 -1
- package/dist/claude-code/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/dist/claude-code/build/src/cli/workflow.js +5 -1
- package/dist/claude-code/build/src/flow-kit/provision.d.ts +23 -0
- package/dist/claude-code/build/src/flow-kit/provision.js +99 -0
- package/dist/claude-code/build/src/flow-kit/validate.d.ts +52 -0
- package/dist/claude-code/build/src/flow-kit/validate.js +214 -9
- package/dist/claude-code/build/src/runtime-adapters.js +1 -1
- package/dist/claude-code/context/contracts/execution-contract.md +30 -1
- package/dist/claude-code/context/contracts/review-contract.md +4 -0
- package/dist/claude-code/context/contracts/trigger-guards.md +73 -0
- package/dist/claude-code/context/scripts/telemetry/lib/config.sh +29 -0
- package/dist/claude-code/context/settings/backlog-provider-settings.json +1 -1
- package/dist/claude-code/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/claude-code/docs/adr/0023-kit-provisioning.md +47 -0
- package/dist/claude-code/docs/adr/index.md +1 -0
- package/dist/claude-code/docs/architecture-engine-and-kits.md +17 -0
- package/dist/claude-code/docs/context-map.md +3 -0
- package/dist/claude-code/docs/decisions/backlog-readiness-source.md +89 -0
- package/dist/claude-code/docs/decisions/index.md +1 -0
- package/dist/claude-code/docs/developer-architecture.md +3 -3
- package/dist/claude-code/docs/flow-kit-repository-contract.md +34 -3
- package/dist/claude-code/docs/kit-authoring-guide.md +1 -1
- package/dist/claude-code/docs/veritas-integration.md +12 -0
- package/dist/claude-code/evals/ci/run-baseline.sh +4 -0
- package/dist/claude-code/evals/integration/test_kit_provisioning.sh +112 -0
- package/dist/claude-code/evals/integration/test_liveness_console_relay.sh +91 -1
- package/dist/claude-code/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/dist/claude-code/evals/integration/test_pull_work_provider.sh +18 -0
- package/dist/claude-code/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/dist/claude-code/evals/integration/test_workflow_artifacts.sh +257 -0
- package/dist/claude-code/evals/static/test_package.sh +6 -0
- package/dist/claude-code/evals/static/test_workflow_skills.sh +16 -0
- package/dist/claude-code/install.sh +1 -1
- package/dist/claude-code/kits/builder/flows/publish-learn.flow.json +9 -1
- package/dist/claude-code/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/dist/claude-code/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/dist/claude-code/kits/builder/skills/review-work/SKILL.md +11 -0
- package/dist/claude-code/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/dist/claude-code/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/dist/claude-code/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/dist/claude-code/kits/veritas-governance/docs/README.md +141 -10
- package/dist/claude-code/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/dist/claude-code/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/dist/claude-code/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/dist/claude-code/kits/veritas-governance/kit.json +65 -0
- package/dist/claude-code/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/dist/claude-code/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/dist/claude-code/schemas/backlog-provider-settings.schema.json +1 -1
- package/dist/claude-code/schemas/workflow-waves.schema.json +347 -0
- package/dist/claude-code/scripts/check-layer-boundary.mjs +98 -0
- package/dist/claude-code/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/dist/claude-code/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/dist/claude-code/scripts/hooks/lib/liveness-write.js +109 -9
- package/dist/claude-code/scripts/liveness/relay.sh +23 -11
- package/dist/claude-code/scripts/telemetry/lib/config.sh +29 -0
- package/dist/codex/.agents/skills/builder-shape/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/consult-standards/SKILL.md +73 -0
- package/dist/codex/.agents/skills/deliver/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/design-probe/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/execute-plan/SKILL.md +4 -3
- package/dist/codex/.agents/skills/execute-plan/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/fix-bug/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/idea-to-backlog/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/plan-work/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/pull-work/SKILL.md +12 -0
- package/dist/codex/.agents/skills/pull-work/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/review-work/SKILL.md +11 -0
- package/dist/codex/.agents/skills/review-work/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/standards-authoring/SKILL.md +87 -0
- package/dist/codex/.agents/skills/tdd-workflow/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.agents/skills/verify-work/context/contracts/execution-contract.md +30 -1
- package/dist/codex/.codex/agents/tool-security-reviewer.toml +1 -1
- package/dist/codex/build/package.json +1 -1
- package/dist/codex/build/src/cli/init.js +35 -3
- package/dist/codex/build/src/cli/kit.js +95 -2
- package/dist/codex/build/src/cli/pull-work-provider.js +7 -1
- package/dist/codex/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/dist/codex/build/src/cli/workflow.js +5 -1
- package/dist/codex/build/src/flow-kit/provision.d.ts +23 -0
- package/dist/codex/build/src/flow-kit/provision.js +99 -0
- package/dist/codex/build/src/flow-kit/validate.d.ts +52 -0
- package/dist/codex/build/src/flow-kit/validate.js +214 -9
- package/dist/codex/build/src/runtime-adapters.js +1 -1
- package/dist/codex/context/contracts/execution-contract.md +30 -1
- package/dist/codex/context/contracts/review-contract.md +4 -0
- package/dist/codex/context/contracts/trigger-guards.md +73 -0
- package/dist/codex/context/scripts/telemetry/lib/config.sh +29 -0
- package/dist/codex/context/settings/backlog-provider-settings.json +1 -1
- package/dist/codex/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/codex/docs/adr/0023-kit-provisioning.md +47 -0
- package/dist/codex/docs/adr/index.md +1 -0
- package/dist/codex/docs/architecture-engine-and-kits.md +17 -0
- package/dist/codex/docs/context-map.md +3 -0
- package/dist/codex/docs/decisions/backlog-readiness-source.md +89 -0
- package/dist/codex/docs/decisions/index.md +1 -0
- package/dist/codex/docs/developer-architecture.md +3 -3
- package/dist/codex/docs/flow-kit-repository-contract.md +34 -3
- package/dist/codex/docs/kit-authoring-guide.md +1 -1
- package/dist/codex/docs/veritas-integration.md +12 -0
- package/dist/codex/evals/ci/run-baseline.sh +4 -0
- package/dist/codex/evals/integration/test_kit_provisioning.sh +112 -0
- package/dist/codex/evals/integration/test_liveness_console_relay.sh +91 -1
- package/dist/codex/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/dist/codex/evals/integration/test_pull_work_provider.sh +18 -0
- package/dist/codex/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/dist/codex/evals/integration/test_workflow_artifacts.sh +257 -0
- package/dist/codex/evals/static/test_package.sh +6 -0
- package/dist/codex/evals/static/test_workflow_skills.sh +16 -0
- package/dist/codex/install.sh +1 -1
- package/dist/codex/kits/builder/flows/publish-learn.flow.json +9 -1
- package/dist/codex/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/dist/codex/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/dist/codex/kits/builder/skills/review-work/SKILL.md +11 -0
- package/dist/codex/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/dist/codex/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/dist/codex/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/dist/codex/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/dist/codex/kits/veritas-governance/docs/README.md +141 -10
- package/dist/codex/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/dist/codex/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/dist/codex/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/dist/codex/kits/veritas-governance/kit.json +65 -0
- package/dist/codex/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/dist/codex/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/dist/codex/schemas/backlog-provider-settings.schema.json +1 -1
- package/dist/codex/schemas/workflow-waves.schema.json +347 -0
- package/dist/codex/scripts/check-layer-boundary.mjs +98 -0
- package/dist/codex/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/dist/codex/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/dist/codex/scripts/hooks/lib/liveness-write.js +109 -9
- package/dist/codex/scripts/liveness/relay.sh +23 -11
- package/dist/codex/scripts/telemetry/lib/config.sh +29 -0
- package/dist/kiro/agents/tool-security-reviewer.json +1 -1
- package/dist/kiro/build/package.json +1 -1
- package/dist/kiro/build/src/cli/init.js +35 -3
- package/dist/kiro/build/src/cli/kit.js +95 -2
- package/dist/kiro/build/src/cli/pull-work-provider.js +7 -1
- package/dist/kiro/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/dist/kiro/build/src/cli/workflow.js +5 -1
- package/dist/kiro/build/src/flow-kit/provision.d.ts +23 -0
- package/dist/kiro/build/src/flow-kit/provision.js +99 -0
- package/dist/kiro/build/src/flow-kit/validate.d.ts +52 -0
- package/dist/kiro/build/src/flow-kit/validate.js +214 -9
- package/dist/kiro/build/src/runtime-adapters.js +1 -1
- package/dist/kiro/context/contracts/execution-contract.md +30 -1
- package/dist/kiro/context/contracts/review-contract.md +4 -0
- package/dist/kiro/context/contracts/trigger-guards.md +73 -0
- package/dist/kiro/context/scripts/telemetry/lib/config.sh +29 -0
- package/dist/kiro/context/settings/backlog-provider-settings.json +1 -1
- package/dist/kiro/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/kiro/docs/adr/0023-kit-provisioning.md +47 -0
- package/dist/kiro/docs/adr/index.md +1 -0
- package/dist/kiro/docs/architecture-engine-and-kits.md +17 -0
- package/dist/kiro/docs/context-map.md +3 -0
- package/dist/kiro/docs/decisions/backlog-readiness-source.md +89 -0
- package/dist/kiro/docs/decisions/index.md +1 -0
- package/dist/kiro/docs/developer-architecture.md +3 -3
- package/dist/kiro/docs/flow-kit-repository-contract.md +34 -3
- package/dist/kiro/docs/kit-authoring-guide.md +1 -1
- package/dist/kiro/docs/veritas-integration.md +12 -0
- package/dist/kiro/evals/ci/run-baseline.sh +4 -0
- package/dist/kiro/evals/integration/test_kit_provisioning.sh +112 -0
- package/dist/kiro/evals/integration/test_liveness_console_relay.sh +91 -1
- package/dist/kiro/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/dist/kiro/evals/integration/test_pull_work_provider.sh +18 -0
- package/dist/kiro/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/dist/kiro/evals/integration/test_workflow_artifacts.sh +257 -0
- package/dist/kiro/evals/static/test_package.sh +6 -0
- package/dist/kiro/evals/static/test_workflow_skills.sh +16 -0
- package/dist/kiro/install.sh +1 -1
- package/dist/kiro/kits/builder/flows/publish-learn.flow.json +9 -1
- package/dist/kiro/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/dist/kiro/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/dist/kiro/kits/builder/skills/review-work/SKILL.md +11 -0
- package/dist/kiro/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/dist/kiro/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/dist/kiro/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/dist/kiro/kits/veritas-governance/docs/README.md +141 -10
- package/dist/kiro/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/dist/kiro/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/dist/kiro/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/dist/kiro/kits/veritas-governance/kit.json +65 -0
- package/dist/kiro/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/dist/kiro/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/dist/kiro/schemas/backlog-provider-settings.schema.json +1 -1
- package/dist/kiro/schemas/workflow-waves.schema.json +347 -0
- package/dist/kiro/scripts/check-layer-boundary.mjs +98 -0
- package/dist/kiro/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/dist/kiro/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/dist/kiro/scripts/hooks/lib/liveness-write.js +109 -9
- package/dist/kiro/scripts/liveness/relay.sh +23 -11
- package/dist/kiro/scripts/telemetry/lib/config.sh +29 -0
- package/dist/opencode/.opencode/agents/tool-security-reviewer.md +2 -1
- package/dist/opencode/.opencode/skills/consult-standards/SKILL.md +73 -0
- package/dist/opencode/.opencode/skills/execute-plan/SKILL.md +4 -3
- package/dist/opencode/.opencode/skills/pull-work/SKILL.md +12 -0
- package/dist/opencode/.opencode/skills/review-work/SKILL.md +11 -0
- package/dist/opencode/.opencode/skills/standards-authoring/SKILL.md +87 -0
- package/dist/opencode/build/package.json +1 -1
- package/dist/opencode/build/src/cli/init.js +35 -3
- package/dist/opencode/build/src/cli/kit.js +95 -2
- package/dist/opencode/build/src/cli/pull-work-provider.js +7 -1
- package/dist/opencode/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/dist/opencode/build/src/cli/workflow.js +5 -1
- package/dist/opencode/build/src/flow-kit/provision.d.ts +23 -0
- package/dist/opencode/build/src/flow-kit/provision.js +99 -0
- package/dist/opencode/build/src/flow-kit/validate.d.ts +52 -0
- package/dist/opencode/build/src/flow-kit/validate.js +214 -9
- package/dist/opencode/build/src/runtime-adapters.js +1 -1
- package/dist/opencode/context/contracts/execution-contract.md +30 -1
- package/dist/opencode/context/contracts/review-contract.md +4 -0
- package/dist/opencode/context/contracts/trigger-guards.md +73 -0
- package/dist/opencode/context/scripts/telemetry/lib/config.sh +29 -0
- package/dist/opencode/context/settings/backlog-provider-settings.json +1 -1
- package/dist/opencode/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/opencode/docs/adr/0023-kit-provisioning.md +47 -0
- package/dist/opencode/docs/adr/index.md +1 -0
- package/dist/opencode/docs/architecture-engine-and-kits.md +17 -0
- package/dist/opencode/docs/context-map.md +3 -0
- package/dist/opencode/docs/decisions/backlog-readiness-source.md +89 -0
- package/dist/opencode/docs/decisions/index.md +1 -0
- package/dist/opencode/docs/developer-architecture.md +3 -3
- package/dist/opencode/docs/flow-kit-repository-contract.md +34 -3
- package/dist/opencode/docs/kit-authoring-guide.md +1 -1
- package/dist/opencode/docs/veritas-integration.md +12 -0
- package/dist/opencode/evals/ci/run-baseline.sh +4 -0
- package/dist/opencode/evals/integration/test_kit_provisioning.sh +112 -0
- package/dist/opencode/evals/integration/test_liveness_console_relay.sh +91 -1
- package/dist/opencode/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/dist/opencode/evals/integration/test_pull_work_provider.sh +18 -0
- package/dist/opencode/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/dist/opencode/evals/integration/test_workflow_artifacts.sh +257 -0
- package/dist/opencode/evals/static/test_package.sh +6 -0
- package/dist/opencode/evals/static/test_workflow_skills.sh +16 -0
- package/dist/opencode/install.sh +1 -1
- package/dist/opencode/kits/builder/flows/publish-learn.flow.json +9 -1
- package/dist/opencode/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/dist/opencode/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/dist/opencode/kits/builder/skills/review-work/SKILL.md +11 -0
- package/dist/opencode/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/dist/opencode/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/dist/opencode/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/dist/opencode/kits/veritas-governance/docs/README.md +141 -10
- package/dist/opencode/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/dist/opencode/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/dist/opencode/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/dist/opencode/kits/veritas-governance/kit.json +65 -0
- package/dist/opencode/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/dist/opencode/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/dist/opencode/schemas/backlog-provider-settings.schema.json +1 -1
- package/dist/opencode/schemas/workflow-waves.schema.json +347 -0
- package/dist/opencode/scripts/check-layer-boundary.mjs +98 -0
- package/dist/opencode/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/dist/opencode/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/dist/opencode/scripts/hooks/lib/liveness-write.js +109 -9
- package/dist/opencode/scripts/liveness/relay.sh +23 -11
- package/dist/opencode/scripts/telemetry/lib/config.sh +29 -0
- package/dist/pi/.pi/skills/consult-standards/SKILL.md +73 -0
- package/dist/pi/.pi/skills/execute-plan/SKILL.md +4 -3
- package/dist/pi/.pi/skills/pull-work/SKILL.md +12 -0
- package/dist/pi/.pi/skills/review-work/SKILL.md +11 -0
- package/dist/pi/.pi/skills/standards-authoring/SKILL.md +87 -0
- package/dist/pi/build/package.json +1 -1
- package/dist/pi/build/src/cli/init.js +35 -3
- package/dist/pi/build/src/cli/kit.js +95 -2
- package/dist/pi/build/src/cli/pull-work-provider.js +7 -1
- package/dist/pi/build/src/cli/validate-workflow-artifacts.js +53 -0
- package/dist/pi/build/src/cli/workflow.js +5 -1
- package/dist/pi/build/src/flow-kit/provision.d.ts +23 -0
- package/dist/pi/build/src/flow-kit/provision.js +99 -0
- package/dist/pi/build/src/flow-kit/validate.d.ts +52 -0
- package/dist/pi/build/src/flow-kit/validate.js +214 -9
- package/dist/pi/build/src/runtime-adapters.js +1 -1
- package/dist/pi/context/contracts/execution-contract.md +30 -1
- package/dist/pi/context/contracts/review-contract.md +4 -0
- package/dist/pi/context/contracts/trigger-guards.md +73 -0
- package/dist/pi/context/scripts/telemetry/lib/config.sh +29 -0
- package/dist/pi/context/settings/backlog-provider-settings.json +1 -1
- package/dist/pi/context/settings/workspace-backlog-provider-settings.example.json +1 -1
- package/dist/pi/docs/adr/0023-kit-provisioning.md +47 -0
- package/dist/pi/docs/adr/index.md +1 -0
- package/dist/pi/docs/architecture-engine-and-kits.md +17 -0
- package/dist/pi/docs/context-map.md +3 -0
- package/dist/pi/docs/decisions/backlog-readiness-source.md +89 -0
- package/dist/pi/docs/decisions/index.md +1 -0
- package/dist/pi/docs/developer-architecture.md +3 -3
- package/dist/pi/docs/flow-kit-repository-contract.md +34 -3
- package/dist/pi/docs/kit-authoring-guide.md +1 -1
- package/dist/pi/docs/veritas-integration.md +12 -0
- package/dist/pi/evals/ci/run-baseline.sh +4 -0
- package/dist/pi/evals/integration/test_kit_provisioning.sh +112 -0
- package/dist/pi/evals/integration/test_liveness_console_relay.sh +91 -1
- package/dist/pi/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/dist/pi/evals/integration/test_pull_work_provider.sh +18 -0
- package/dist/pi/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/dist/pi/evals/integration/test_workflow_artifacts.sh +257 -0
- package/dist/pi/evals/static/test_package.sh +6 -0
- package/dist/pi/evals/static/test_workflow_skills.sh +16 -0
- package/dist/pi/install.sh +1 -1
- package/dist/pi/kits/builder/flows/publish-learn.flow.json +9 -1
- package/dist/pi/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/dist/pi/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/dist/pi/kits/builder/skills/review-work/SKILL.md +11 -0
- package/dist/pi/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/dist/pi/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/dist/pi/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/dist/pi/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/dist/pi/kits/veritas-governance/docs/README.md +141 -10
- package/dist/pi/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/dist/pi/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/dist/pi/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/dist/pi/kits/veritas-governance/kit.json +65 -0
- package/dist/pi/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/dist/pi/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/dist/pi/schemas/backlog-provider-settings.schema.json +1 -1
- package/dist/pi/schemas/workflow-waves.schema.json +347 -0
- package/dist/pi/scripts/check-layer-boundary.mjs +98 -0
- package/dist/pi/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/dist/pi/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/dist/pi/scripts/hooks/lib/liveness-write.js +109 -9
- package/dist/pi/scripts/liveness/relay.sh +23 -11
- package/dist/pi/scripts/telemetry/lib/config.sh +29 -0
- package/docs/adr/0023-kit-provisioning.md +47 -0
- package/docs/adr/index.md +1 -0
- package/docs/architecture-engine-and-kits.md +17 -0
- package/docs/context-map.md +3 -0
- package/docs/decisions/backlog-readiness-source.md +89 -0
- package/docs/decisions/index.md +1 -0
- package/docs/developer-architecture.md +3 -3
- package/docs/flow-kit-repository-contract.md +34 -3
- package/docs/kit-authoring-guide.md +1 -1
- package/docs/veritas-integration.md +12 -0
- package/evals/ci/run-baseline.sh +4 -0
- package/evals/integration/test_kit_provisioning.sh +112 -0
- package/evals/integration/test_liveness_console_relay.sh +91 -1
- package/evals/integration/test_liveness_heartbeat.sh +66 -0
- package/evals/integration/test_pull_work_provider.sh +18 -0
- package/evals/integration/test_veritas_governance_kit.sh +256 -0
- package/evals/integration/test_workflow_artifacts.sh +257 -0
- package/evals/static/test_package.sh +6 -0
- package/evals/static/test_workflow_skills.sh +16 -0
- package/kits/builder/flows/publish-learn.flow.json +9 -1
- package/kits/builder/skills/execute-plan/SKILL.md +4 -3
- package/kits/builder/skills/pull-work/SKILL.md +12 -0
- package/kits/builder/skills/review-work/SKILL.md +11 -0
- package/kits/veritas-governance/adapter/readiness-to-trust-bundle.mjs +19 -20
- package/kits/veritas-governance/assets/starter-hooks/githooks/post-commit +13 -0
- package/kits/veritas-governance/assets/starter-hooks/githooks/pre-push +13 -0
- package/kits/veritas-governance/assets/starter-standards/veritas/GOVERNANCE.md +23 -0
- package/kits/veritas-governance/assets/starter-standards/veritas/README.md +58 -0
- package/kits/veritas-governance/assets/starter-standards/veritas/authority/default.authority-settings.json +30 -0
- package/kits/veritas-governance/assets/starter-standards/veritas/repo-map.json +115 -0
- package/kits/veritas-governance/assets/starter-standards/veritas/repo-standards/default.repo-standards.json +54 -0
- package/kits/veritas-governance/assets/starter-standards/veritas.claims.json +179 -0
- package/kits/veritas-governance/docs/README.md +141 -10
- package/kits/veritas-governance/fixtures/standards-authoring/approved.trust-bundle.json +74 -0
- package/kits/veritas-governance/fixtures/standards-authoring/not-approved.trust-bundle.json +74 -0
- package/kits/veritas-governance/flows/standards-authoring.flow.json +35 -0
- package/kits/veritas-governance/kit.json +65 -0
- package/kits/veritas-governance/skills/consult-standards/SKILL.md +73 -0
- package/kits/veritas-governance/skills/standards-authoring/SKILL.md +87 -0
- package/package.json +2 -1
- package/schemas/backlog-provider-settings.schema.json +1 -1
- package/schemas/workflow-waves.schema.json +347 -0
- package/scripts/check-layer-boundary.mjs +98 -0
- package/scripts/hooks/claude-telemetry-hook.js +6 -0
- package/scripts/hooks/lib/liveness-heartbeat.js +42 -1
- package/scripts/hooks/lib/liveness-write.js +109 -9
- package/scripts/liveness/relay.sh +23 -11
- package/scripts/telemetry/lib/config.sh +29 -0
- package/src/cli/builder-flow-runtime.test.mjs +86 -0
- package/src/cli/flow-resolver-composition.test.mjs +20 -1
- package/src/cli/init.ts +31 -3
- package/src/cli/kit-metadata-security.test.mjs +163 -1
- package/src/cli/kit-provisioning.test.mjs +122 -0
- package/src/cli/kit.ts +83 -2
- package/src/cli/pull-work-provider.ts +7 -1
- package/src/cli/validate-waves.test.mjs +134 -0
- package/src/cli/validate-workflow-artifacts.ts +47 -0
- package/src/cli/workflow.ts +7 -1
- package/src/flow-kit/provision.ts +118 -0
- package/src/flow-kit/validate.ts +233 -10
- package/src/runtime-adapters.ts +1 -1
package/src/cli/kit.ts
CHANGED
|
@@ -6,7 +6,8 @@ import * as path from "node:path";
|
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { parseArgs, flagBool, flagString } from "../lib/args.js";
|
|
8
8
|
import { assertPathContained, assertPathsDisjoint, atomicWriteJson, copyDirAtomic, ensureSafeDirectory, isoNow, readJson, walkFiles } from "../lib/fs.js";
|
|
9
|
-
import { assertKitRepository, deriveKitTargets, parseKitDependencies } from "../flow-kit/validate.js";
|
|
9
|
+
import { assertKitRepository, deriveKitTargets, parseKitDependencies, validateKitRepositoryDiagnostics } from "../flow-kit/validate.js";
|
|
10
|
+
import { provisionKit, ProvisionConflictError } from "../flow-kit/provision.js";
|
|
10
11
|
import { activateCodexLocal, activateStrandsLocal } from "../runtime-adapters.js";
|
|
11
12
|
import { defaultCodexHome } from "../lib/local-artifact-root.js";
|
|
12
13
|
import { root } from "../tools/common.js";
|
|
@@ -35,6 +36,17 @@ function resolveCatalogKitSource(source: string): string | null {
|
|
|
35
36
|
return path.resolve(path.dirname(repoCatalogPath), "..", rel);
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
function resolveProvisionKitSource(source: string, dest: string): string | null {
|
|
40
|
+
const localPath = path.resolve(source);
|
|
41
|
+
if (fs.existsSync(localPath)) return localPath;
|
|
42
|
+
const installed = loadRegistry(dest).kits.find((entry) => entry.id === source);
|
|
43
|
+
if (installed) {
|
|
44
|
+
const installedSource = installedPath(dest, source);
|
|
45
|
+
if (fs.existsSync(installedSource)) return installedSource;
|
|
46
|
+
}
|
|
47
|
+
return resolveCatalogKitSource(source);
|
|
48
|
+
}
|
|
49
|
+
|
|
38
50
|
function loadRegistry(dest: string): { schema_version: string; kits: Record<string, unknown>[] } {
|
|
39
51
|
const file = registryPath(dest);
|
|
40
52
|
if (!fs.existsSync(file)) return { schema_version: "1.0", kits: [] };
|
|
@@ -64,6 +76,17 @@ function warnUninstalledDependencies(manifest: Record<string, unknown>, manifest
|
|
|
64
76
|
}
|
|
65
77
|
}
|
|
66
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Print non-blocking kit-validation warnings (e.g. an agent-spawning trigger surface
|
|
81
|
+
* declared without complete guard config — context/contracts/trigger-guards.md).
|
|
82
|
+
* Shared by BOTH install source forms (local path and git clone) so the standing
|
|
83
|
+
* warning contract cannot silently diverge between them. Same non-blocking
|
|
84
|
+
* `warning:` convention as warnUninstalledDependencies above.
|
|
85
|
+
*/
|
|
86
|
+
async function printKitValidationWarnings(kitDir: string): Promise<void> {
|
|
87
|
+
for (const warning of (await validateKitRepositoryDiagnostics(kitDir)).warnings) console.log(`warning: ${warning}`);
|
|
88
|
+
}
|
|
89
|
+
|
|
67
90
|
function contentHash(root: string): string {
|
|
68
91
|
const hash = crypto.createHash("sha256");
|
|
69
92
|
for (const file of walkFiles(root)) {
|
|
@@ -126,6 +149,7 @@ async function installLocalSource(source: string, argv: string[]): Promise<numbe
|
|
|
126
149
|
let manifest: Record<string, unknown>;
|
|
127
150
|
try {
|
|
128
151
|
manifest = await assertKitRepository(source);
|
|
152
|
+
await printKitValidationWarnings(source);
|
|
129
153
|
} catch (error) {
|
|
130
154
|
console.log("Flow Kit repository validation failed:");
|
|
131
155
|
for (const diagnostic of ((error as Error & { diagnostics?: string[] }).diagnostics ?? [(error as Error).message])) console.log(` - ${diagnostic}`);
|
|
@@ -213,6 +237,7 @@ async function installGitSource(rawUrl: string, argv: string[]): Promise<number>
|
|
|
213
237
|
let manifest: Record<string, unknown>;
|
|
214
238
|
try {
|
|
215
239
|
manifest = await assertKitRepository(tmpBase);
|
|
240
|
+
await printKitValidationWarnings(tmpBase);
|
|
216
241
|
} catch (error) {
|
|
217
242
|
console.log("Flow Kit repository validation failed:");
|
|
218
243
|
for (const diagnostic of ((error as Error & { diagnostics?: string[] }).diagnostics ?? [(error as Error).message])) {
|
|
@@ -325,6 +350,60 @@ function activate(argv: string[]): number {
|
|
|
325
350
|
return Array.isArray(result.errors) && result.errors.length ? 1 : 0;
|
|
326
351
|
}
|
|
327
352
|
|
|
353
|
+
async function validate(argv: string[]): Promise<number> {
|
|
354
|
+
const args = parseArgs(argv);
|
|
355
|
+
const kitDir = path.resolve(args.positionals[0] ?? ".");
|
|
356
|
+
const diagnostics = await validateKitRepositoryDiagnostics(kitDir);
|
|
357
|
+
for (const warning of diagnostics.warnings) console.log(`warning: ${warning}`);
|
|
358
|
+
if (diagnostics.errors.length) {
|
|
359
|
+
console.log("Flow Kit repository validation failed:");
|
|
360
|
+
for (const error of diagnostics.errors) console.log(` - ${error}`);
|
|
361
|
+
return 1;
|
|
362
|
+
}
|
|
363
|
+
console.log(`Flow Kit repository validation passed: ${kitDir}`);
|
|
364
|
+
return 0;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
async function provision(argv: string[]): Promise<number> {
|
|
368
|
+
const args = parseArgs(argv);
|
|
369
|
+
const source = args.positionals[0];
|
|
370
|
+
if (!source) {
|
|
371
|
+
console.error("provision: missing <kit-id-or-path> argument");
|
|
372
|
+
console.error("usage: flow-agents kit provision <kit-id-or-path> [--target <dir>] [--force] [--dry-run]");
|
|
373
|
+
return 2;
|
|
374
|
+
}
|
|
375
|
+
const dest = resolveDest(args.flags);
|
|
376
|
+
const kitDir = resolveProvisionKitSource(source, dest);
|
|
377
|
+
if (!kitDir) {
|
|
378
|
+
console.error(`provision: kit '${source}' was not found as a local path, installed kit, or catalog kit`);
|
|
379
|
+
return 1;
|
|
380
|
+
}
|
|
381
|
+
const target = path.resolve(flagString(args.flags, "target", process.cwd()) ?? process.cwd());
|
|
382
|
+
try {
|
|
383
|
+
const result = await provisionKit(kitDir, target, {
|
|
384
|
+
force: flagBool(args.flags, "force"),
|
|
385
|
+
dryRun: flagBool(args.flags, "dry-run"),
|
|
386
|
+
});
|
|
387
|
+
for (const file of result.files) console.log(`${result.dry_run ? "would provision" : "provisioned"}: ${file.source} -> ${file.destination}`);
|
|
388
|
+
if (result.dry_run) console.log(`dry-run: ${result.files.length} file(s) declared by kit '${result.kit_id}'; no files written`);
|
|
389
|
+
else if (result.files.length === 0) console.log(`kit '${result.kit_id}' declares no provisions`);
|
|
390
|
+
else console.log(`provisioned ${result.files.length} file(s) from kit '${result.kit_id}' into ${target}`);
|
|
391
|
+
return 0;
|
|
392
|
+
} catch (error) {
|
|
393
|
+
if (error instanceof ProvisionConflictError) {
|
|
394
|
+
console.error(`provision: ${error.message}; rerun with --force to overwrite`);
|
|
395
|
+
for (const conflict of error.conflicts) console.error(`conflict: ${conflict.target} (${conflict.destination})`);
|
|
396
|
+
return 1;
|
|
397
|
+
}
|
|
398
|
+
const diagnostics = (error as Error & { diagnostics?: string[] }).diagnostics;
|
|
399
|
+
if (diagnostics?.length) {
|
|
400
|
+
console.error("Flow Kit repository validation failed:");
|
|
401
|
+
for (const diagnostic of diagnostics) console.error(` - ${diagnostic}`);
|
|
402
|
+
} else console.error(`provision: ${(error as Error).message}`);
|
|
403
|
+
return 1;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
328
407
|
/**
|
|
329
408
|
* inspect <kit-dir> [--json]
|
|
330
409
|
*
|
|
@@ -373,8 +452,10 @@ export async function main(argv = process.argv.slice(2)): Promise<number> {
|
|
|
373
452
|
if (command === "list") return list(rest);
|
|
374
453
|
if (command === "status") return status(rest);
|
|
375
454
|
if (command === "activate") return activate(rest);
|
|
455
|
+
if (command === "validate") return await validate(rest);
|
|
456
|
+
if (command === "provision") return await provision(rest);
|
|
376
457
|
if (command === "inspect") return await inspect(rest);
|
|
377
|
-
console.error("usage: flow-agents kit <install|activate|inspect|list|status> ...");
|
|
458
|
+
console.error("usage: flow-agents kit <install|activate|validate|provision|inspect|list|status> ...");
|
|
378
459
|
return 2;
|
|
379
460
|
}
|
|
380
461
|
|
|
@@ -849,7 +849,13 @@ export function main(argv = process.argv.slice(2)): number {
|
|
|
849
849
|
const freshness = revisionFreshness(item, freshnessInputs);
|
|
850
850
|
return { ...item, dependency_impacts: dependencyImpacts(item, resolved), revision_freshness: freshness, readiness: applyFreshnessToReadiness(classify(item, settings, resolved), freshness) };
|
|
851
851
|
});
|
|
852
|
-
|
|
852
|
+
// A configured BoardProvider is the canonical readiness source (docs/decisions/backlog-readiness-source.md).
|
|
853
|
+
// Reaching this issue-level listing path with a board configured is a bypass that must be loud, never silent.
|
|
854
|
+
const bypassedBoard = asRecord(asRecord(settings.board_provider)?.board);
|
|
855
|
+
const warnings = bypassedBoard
|
|
856
|
+
? [{ code: "board_provider_bypassed", message: "A BoardProvider is configured but this pass used WorkItemProvider issue-level listing; board-driven selection is the canonical readiness source. Surface this bypass in the pull-work artifact instead of treating issue listing as a silent fallback." }]
|
|
857
|
+
: [];
|
|
858
|
+
console.log(JSON.stringify({ items, warnings }, null, 2));
|
|
853
859
|
return 0;
|
|
854
860
|
}
|
|
855
861
|
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
// Unit tests for waves.json wave-manifest reconciliation validation (#663 slice 1).
|
|
2
|
+
//
|
|
3
|
+
// validate-workflow-artifacts.ts is a CLI script (no exported helpers), so these
|
|
4
|
+
// node:test units drive the built validator as a child process against temp fixture
|
|
5
|
+
// directories — the same black-box surface CI's workflow-artifact-integration lane
|
|
6
|
+
// uses, but fast and countable as unit executions. They pin the load-bearing
|
|
7
|
+
// behavior of the reconcile-against-manifest contract:
|
|
8
|
+
// - a reconciled wave with an explicit not_reported worker is VALID DATA
|
|
9
|
+
// ("2 of 3 reported; worker-3 not_reported") — visibility, not a block;
|
|
10
|
+
// - a silent drop (complete claim over a missing worker record) FAILS with
|
|
11
|
+
// messages naming the dropped worker, the count mismatch, and the impossible
|
|
12
|
+
// complete claim.
|
|
13
|
+
//
|
|
14
|
+
// Run: `node --test src/cli/validate-waves.test.mjs` (requires `npm run build`).
|
|
15
|
+
import test from "node:test";
|
|
16
|
+
import assert from "node:assert/strict";
|
|
17
|
+
import { spawnSync } from "node:child_process";
|
|
18
|
+
import fs from "node:fs";
|
|
19
|
+
import os from "node:os";
|
|
20
|
+
import path from "node:path";
|
|
21
|
+
import { fileURLToPath } from "node:url";
|
|
22
|
+
|
|
23
|
+
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
24
|
+
const validator = path.join(repoRoot, "build", "src", "cli", "validate-workflow-artifacts.js");
|
|
25
|
+
|
|
26
|
+
function runValidator(wavesPayload) {
|
|
27
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "waves-unit-"));
|
|
28
|
+
try {
|
|
29
|
+
fs.writeFileSync(path.join(dir, "waves.json"), JSON.stringify(wavesPayload, null, 2));
|
|
30
|
+
const result = spawnSync(process.execPath, [validator, dir], { encoding: "utf8" });
|
|
31
|
+
return { status: result.status, output: `${result.stdout}\n${result.stderr}` };
|
|
32
|
+
} finally {
|
|
33
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function manifest(waveOverrides) {
|
|
38
|
+
return {
|
|
39
|
+
schema_version: "1.0",
|
|
40
|
+
task_slug: "waves-unit",
|
|
41
|
+
waves: [
|
|
42
|
+
{
|
|
43
|
+
wave_id: "execute-wave-1",
|
|
44
|
+
step: "execute",
|
|
45
|
+
declared_at: "2026-07-16T00:00:00Z",
|
|
46
|
+
expected_workers: [
|
|
47
|
+
{ worker_id: "worker-1", task: "task one" },
|
|
48
|
+
{ worker_id: "worker-2", task: "task two" },
|
|
49
|
+
{ worker_id: "worker-3", task: "task three" },
|
|
50
|
+
],
|
|
51
|
+
...waveOverrides,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
test("fully reported wave reconciles complete and validates", () => {
|
|
58
|
+
const { status, output } = runValidator(manifest({
|
|
59
|
+
worker_results: [
|
|
60
|
+
{ worker_id: "worker-1", status: "completed", summary: "done", recorded_at: "2026-07-16T01:00:00Z" },
|
|
61
|
+
{ worker_id: "worker-2", status: "failed", summary: "tests failing", recorded_at: "2026-07-16T01:00:00Z" },
|
|
62
|
+
{ worker_id: "worker-3", status: "blocked", summary: "blocked on approval", recorded_at: "2026-07-16T01:00:00Z" },
|
|
63
|
+
],
|
|
64
|
+
reconciliation: {
|
|
65
|
+
status: "complete",
|
|
66
|
+
expected_count: 3,
|
|
67
|
+
reported_count: 3,
|
|
68
|
+
summary: "3 of 3 reported; no workers not_reported",
|
|
69
|
+
reconciled_at: "2026-07-16T01:05:00Z",
|
|
70
|
+
},
|
|
71
|
+
}));
|
|
72
|
+
assert.equal(status, 0, output);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test("2 of 3 reported with explicit not_reported worker is valid data, not a block", () => {
|
|
76
|
+
const { status, output } = runValidator(manifest({
|
|
77
|
+
worker_results: [
|
|
78
|
+
{ worker_id: "worker-1", status: "completed", summary: "done", recorded_at: "2026-07-16T01:00:00Z" },
|
|
79
|
+
{ worker_id: "worker-2", status: "completed", summary: "done", recorded_at: "2026-07-16T01:00:00Z" },
|
|
80
|
+
{ worker_id: "worker-3", status: "not_reported", summary: "no terminal report by wave close; routed to re-dispatch", recorded_at: "2026-07-16T01:05:00Z" },
|
|
81
|
+
],
|
|
82
|
+
reconciliation: {
|
|
83
|
+
status: "incomplete",
|
|
84
|
+
expected_count: 3,
|
|
85
|
+
reported_count: 2,
|
|
86
|
+
summary: "2 of 3 reported; worker-3 not_reported",
|
|
87
|
+
reconciled_at: "2026-07-16T01:05:00Z",
|
|
88
|
+
},
|
|
89
|
+
}));
|
|
90
|
+
assert.equal(status, 0, output);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test("silent drop behind a complete claim fails naming the missing worker", () => {
|
|
94
|
+
const { status, output } = runValidator(manifest({
|
|
95
|
+
worker_results: [
|
|
96
|
+
{ worker_id: "worker-1", status: "completed", summary: "done", recorded_at: "2026-07-16T01:00:00Z" },
|
|
97
|
+
{ worker_id: "worker-2", status: "completed", summary: "done", recorded_at: "2026-07-16T01:00:00Z" },
|
|
98
|
+
],
|
|
99
|
+
reconciliation: {
|
|
100
|
+
status: "complete",
|
|
101
|
+
expected_count: 3,
|
|
102
|
+
reported_count: 3,
|
|
103
|
+
summary: "3 of 3 reported",
|
|
104
|
+
reconciled_at: "2026-07-16T01:05:00Z",
|
|
105
|
+
},
|
|
106
|
+
}));
|
|
107
|
+
assert.equal(status, 1);
|
|
108
|
+
assert.match(output, /worker worker-3 has no terminal status record/);
|
|
109
|
+
assert.match(output, /reported_count is 3 but 2 of 3 expected workers/);
|
|
110
|
+
assert.match(output, /complete requires every expected worker/);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test("duplicate terminal records and undeclared reporters are rejected", () => {
|
|
114
|
+
const { status, output } = runValidator(manifest({
|
|
115
|
+
worker_results: [
|
|
116
|
+
{ worker_id: "worker-1", status: "completed", summary: "done", recorded_at: "2026-07-16T01:00:00Z" },
|
|
117
|
+
{ worker_id: "worker-1", status: "failed", summary: "again", recorded_at: "2026-07-16T01:01:00Z" },
|
|
118
|
+
{ worker_id: "worker-9", status: "completed", summary: "surprise", recorded_at: "2026-07-16T01:00:00Z" },
|
|
119
|
+
],
|
|
120
|
+
}));
|
|
121
|
+
assert.equal(status, 1);
|
|
122
|
+
assert.match(output, /more than one terminal status record for worker worker-1/);
|
|
123
|
+
assert.match(output, /worker worker-9 that is not declared in expected_workers/);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
test("unknown terminal status fails against the schema enum", () => {
|
|
127
|
+
const { status, output } = runValidator(manifest({
|
|
128
|
+
worker_results: [
|
|
129
|
+
{ worker_id: "worker-1", status: "maybe-done", summary: "unclear", recorded_at: "2026-07-16T01:00:00Z" },
|
|
130
|
+
],
|
|
131
|
+
}));
|
|
132
|
+
assert.equal(status, 1);
|
|
133
|
+
assert.match(output, /status must be one of: completed, failed, blocked, not_reported/);
|
|
134
|
+
});
|
|
@@ -21,6 +21,7 @@ const sidecarSchemas: Record<string, string> = {
|
|
|
21
21
|
"critique.json": "schemas/workflow-critique.schema.json",
|
|
22
22
|
"release.json": "schemas/workflow-release.schema.json",
|
|
23
23
|
"learning.json": "schemas/workflow-learning.schema.json",
|
|
24
|
+
"waves.json": "schemas/workflow-waves.schema.json",
|
|
24
25
|
};
|
|
25
26
|
// Runtime coordination records live below a session but are not workflow
|
|
26
27
|
// sidecars. Recursing into them would validate continuation-driver/state.json
|
|
@@ -321,12 +322,58 @@ function validateSidecar(file: string): { issues: Issue[]; warnings: Issue[] } {
|
|
|
321
322
|
if (Array.isArray(value.post_deploy_checks) && value.post_deploy_checks.some((c: any) => !["planned", "pass"].includes(c.status))) issues.push({ path: file, message: "deploy decision requires post_deploy_checks to be planned or pass" });
|
|
322
323
|
}
|
|
323
324
|
}
|
|
325
|
+
if (path.basename(file) === "waves.json") {
|
|
326
|
+
validateWaves(file, value, issues);
|
|
327
|
+
}
|
|
324
328
|
if (path.basename(file) === "state.json" && value && typeof value === "object" && !Array.isArray(value) && !("branch" in value)) {
|
|
325
329
|
warnings.push({ path: file, message: "state.json has no branch field (legacy/pre-#289 session) — re-run `ensure-session` to backfill agent/<actor>/<slug>." });
|
|
326
330
|
}
|
|
327
331
|
return { issues, warnings };
|
|
328
332
|
}
|
|
329
333
|
|
|
334
|
+
// #663 slice 1: wave-result reconciliation is machine-checkable, not prose. The schema
|
|
335
|
+
// (schemas/workflow-waves.schema.json) validates the shape; these semantic checks enforce the
|
|
336
|
+
// cross-record arithmetic the mini schema engine cannot express: exactly one terminal status
|
|
337
|
+
// record per declared worker, no undeclared reporters, reconciliation counts that match the
|
|
338
|
+
// records, and a `complete` claim that is impossible while any expected worker lacks a
|
|
339
|
+
// worker-landed terminal status. Missing workers must be recorded explicitly as not_reported —
|
|
340
|
+
// a reconciled wave never silently absorbs a dropped worker. Enforcement here is data-level
|
|
341
|
+
// validation only; stop-hook refusal of wave completion is #663 part 3 (slice 2).
|
|
342
|
+
function validateWaves(file: string, value: any, issues: Issue[]): void {
|
|
343
|
+
const waves = Array.isArray(value?.waves) ? value.waves : [];
|
|
344
|
+
waves.forEach((wave: any, index: number) => {
|
|
345
|
+
const loc = `waves.json.waves[${index}]`;
|
|
346
|
+
const expected: any[] = Array.isArray(wave?.expected_workers) ? wave.expected_workers : [];
|
|
347
|
+
const results: any[] = Array.isArray(wave?.worker_results) ? wave.worker_results : [];
|
|
348
|
+
const expectedIds = expected.map((w) => w?.worker_id).filter((id) => typeof id === "string" && id.length > 0);
|
|
349
|
+
const expectedIdSet = new Set(expectedIds);
|
|
350
|
+
if (expectedIdSet.size !== expectedIds.length) issues.push({ path: file, message: `${loc}.expected_workers must declare unique worker_id values` });
|
|
351
|
+
const resultIds = results.map((r) => r?.worker_id).filter((id) => typeof id === "string" && id.length > 0);
|
|
352
|
+
const seen = new Set<string>();
|
|
353
|
+
for (const id of resultIds) {
|
|
354
|
+
if (seen.has(id)) issues.push({ path: file, message: `${loc}.worker_results has more than one terminal status record for worker ${id}; each worker lands exactly one` });
|
|
355
|
+
seen.add(id);
|
|
356
|
+
if (!expectedIdSet.has(id)) issues.push({ path: file, message: `${loc}.worker_results records worker ${id} that is not declared in expected_workers; declare every worker in the manifest before dispatch` });
|
|
357
|
+
}
|
|
358
|
+
const reconciliation = wave?.reconciliation;
|
|
359
|
+
if (!reconciliation || typeof reconciliation !== "object" || Array.isArray(reconciliation)) return;
|
|
360
|
+
const expectedCount = expectedIds.length;
|
|
361
|
+
const reportedIds = new Set(results.filter((r) => ["completed", "failed", "blocked"].includes(r?.status) && expectedIdSet.has(r?.worker_id)).map((r) => r.worker_id as string));
|
|
362
|
+
const reportedCount = reportedIds.size;
|
|
363
|
+
if (reconciliation.expected_count !== expectedCount) issues.push({ path: file, message: `${loc}.reconciliation.expected_count is ${reconciliation.expected_count} but expected_workers declares ${expectedCount}` });
|
|
364
|
+
if (reconciliation.reported_count !== reportedCount) issues.push({ path: file, message: `${loc}.reconciliation.reported_count is ${reconciliation.reported_count} but ${reportedCount} of ${expectedCount} expected workers have a worker-landed terminal status (completed|failed|blocked)` });
|
|
365
|
+
const missing = expectedIds.filter((id) => !results.some((r) => r?.worker_id === id));
|
|
366
|
+
for (const id of missing) issues.push({ path: file, message: `${loc} is reconciled but worker ${id} has no terminal status record; record it explicitly as not_reported — never silently absorb a missing worker` });
|
|
367
|
+
const notReported = results.filter((r) => r?.status === "not_reported" && expectedIdSet.has(r?.worker_id));
|
|
368
|
+
if (reconciliation.status === "complete" && (missing.length > 0 || notReported.length > 0 || reportedCount !== expectedCount)) {
|
|
369
|
+
issues.push({ path: file, message: `${loc}.reconciliation.status complete requires every expected worker to have a worker-landed terminal status; got ${reportedCount} of ${expectedCount} reported` });
|
|
370
|
+
}
|
|
371
|
+
if (reconciliation.status === "incomplete" && missing.length === 0 && notReported.length === 0 && reportedCount === expectedCount) {
|
|
372
|
+
issues.push({ path: file, message: `${loc}.reconciliation.status incomplete contradicts the records: all ${expectedCount} expected workers reported` });
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
|
|
330
377
|
function validateLearningCorrections(file: string, status: unknown, records: any[], issues: Issue[]): void {
|
|
331
378
|
records.forEach((record, index) => {
|
|
332
379
|
const correction = record?.correction;
|
package/src/cli/workflow.ts
CHANGED
|
@@ -717,7 +717,13 @@ function assertDistinctReviewActor(sessionDir: string, slug: string): ReturnType
|
|
|
717
717
|
const assignment = readActiveAssignment(sessionDir, slug);
|
|
718
718
|
const caller = resolveCurrentAssignmentActor();
|
|
719
719
|
if (assignment.actor_key === caller.actorKey) {
|
|
720
|
-
throw new Error(
|
|
720
|
+
throw new Error(
|
|
721
|
+
"workflow critique requires a reviewer identity distinct from the active implementation assignment actor. " +
|
|
722
|
+
"The reviewer identity is derived from the runtime actor, so an orchestrator that implemented and now reviews " +
|
|
723
|
+
"resolves to the same actor. To record an independent review, run the reviewer under a distinct actor: set " +
|
|
724
|
+
"FLOW_AGENTS_ACTOR=<reviewer-id> on the reviewing process, or run the reviewer in a separate runtime session " +
|
|
725
|
+
"(the runtime session id seeds the actor).",
|
|
726
|
+
);
|
|
721
727
|
}
|
|
722
728
|
return caller;
|
|
723
729
|
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import * as crypto from "node:crypto";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { atomicCopyFile, atomicWriteJson, canonicalProspectivePath, walkFiles } from "../lib/fs.js";
|
|
5
|
+
import { PROVISION_MANIFEST_DIR, assertKitRepository, type KitProvisionEntry } from "./validate.js";
|
|
6
|
+
|
|
7
|
+
export type ProvisionedFile = { id: string; target: string };
|
|
8
|
+
|
|
9
|
+
export type ProvisionPlanEntry = ProvisionedFile & {
|
|
10
|
+
source: string;
|
|
11
|
+
destination: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type ProvisionResult = {
|
|
15
|
+
kit_id: string;
|
|
16
|
+
kit_hash?: string;
|
|
17
|
+
files: ProvisionPlanEntry[];
|
|
18
|
+
manifest_path?: string;
|
|
19
|
+
dry_run: boolean;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export class ProvisionConflictError extends Error {
|
|
23
|
+
readonly conflicts: ProvisionPlanEntry[];
|
|
24
|
+
|
|
25
|
+
constructor(conflicts: ProvisionPlanEntry[]) {
|
|
26
|
+
super(`provisioning conflicts with ${conflicts.length} existing destination(s)`);
|
|
27
|
+
this.name = "ProvisionConflictError";
|
|
28
|
+
this.conflicts = conflicts;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function kitContentHash(kitDir: string): string {
|
|
33
|
+
const hash = crypto.createHash("sha256");
|
|
34
|
+
for (const file of walkFiles(kitDir)) {
|
|
35
|
+
const rel = path.relative(kitDir, file).split(path.sep).join("/");
|
|
36
|
+
if (rel.split("/").some((part) => [".git", "__pycache__", ".pytest_cache"].includes(part))) continue;
|
|
37
|
+
hash.update(rel);
|
|
38
|
+
hash.update("\0");
|
|
39
|
+
hash.update(fs.readFileSync(file));
|
|
40
|
+
hash.update("\0");
|
|
41
|
+
}
|
|
42
|
+
return `sha256:${hash.digest("hex")}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function isContained(root: string, candidate: string): boolean {
|
|
46
|
+
const relative = path.relative(root, candidate);
|
|
47
|
+
return relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function assertSafeDestination(rootReal: string, destination: string): void {
|
|
51
|
+
const prospective = canonicalProspectivePath(destination);
|
|
52
|
+
if (!isContained(rootReal, prospective)) throw new Error(`provision target escapes consumer repository: ${destination}`);
|
|
53
|
+
if (!fs.existsSync(destination)) return;
|
|
54
|
+
const stat = fs.lstatSync(destination);
|
|
55
|
+
if (stat.isSymbolicLink()) throw new Error(`refusing provision target symlink: ${destination}`);
|
|
56
|
+
if (!stat.isFile()) throw new Error(`provision target is not a regular file: ${destination}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function manifestProvisions(manifest: Record<string, unknown>): KitProvisionEntry[] {
|
|
60
|
+
if (!Array.isArray(manifest.provisions)) return [];
|
|
61
|
+
return manifest.provisions.map((entry) => {
|
|
62
|
+
const record = entry as Record<string, unknown>;
|
|
63
|
+
return {
|
|
64
|
+
id: String(record.id),
|
|
65
|
+
path: String(record.path),
|
|
66
|
+
target: path.posix.normalize(String(record.target).replace(/\\/g, "/")),
|
|
67
|
+
...(typeof record.description === "string" ? { description: record.description } : {}),
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export async function provisionKit(
|
|
73
|
+
kitDir: string,
|
|
74
|
+
targetDir: string,
|
|
75
|
+
options: { force?: boolean; dryRun?: boolean } = {},
|
|
76
|
+
): Promise<ProvisionResult> {
|
|
77
|
+
const kitRoot = fs.realpathSync(path.resolve(kitDir));
|
|
78
|
+
const targetPath = path.resolve(targetDir);
|
|
79
|
+
if (!fs.existsSync(targetPath) || !fs.statSync(targetPath).isDirectory()) {
|
|
80
|
+
throw new Error(`provision target must exist and be a directory: ${targetPath}`);
|
|
81
|
+
}
|
|
82
|
+
const targetRoot = fs.realpathSync(targetPath);
|
|
83
|
+
const manifest = await assertKitRepository(kitRoot);
|
|
84
|
+
const kitId = String(manifest.id);
|
|
85
|
+
const files = manifestProvisions(manifest).map((entry) => ({
|
|
86
|
+
id: entry.id,
|
|
87
|
+
target: entry.target,
|
|
88
|
+
source: path.resolve(kitRoot, entry.path),
|
|
89
|
+
destination: path.resolve(targetRoot, ...entry.target.split("/")),
|
|
90
|
+
}));
|
|
91
|
+
|
|
92
|
+
for (const file of files) assertSafeDestination(targetRoot, file.destination);
|
|
93
|
+
// Defense in depth against a source swapped to a link after validation: re-assert the
|
|
94
|
+
// link-resolved source stays inside the kit before we read and copy its bytes.
|
|
95
|
+
for (const file of files) {
|
|
96
|
+
const realSource = fs.realpathSync(file.source);
|
|
97
|
+
if (realSource !== kitRoot && !realSource.startsWith(`${kitRoot}${path.sep}`)) {
|
|
98
|
+
throw new Error(`provision source escapes the kit directory: ${file.id}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const conflicts = options.force ? [] : files.filter((file) => fs.existsSync(file.destination));
|
|
102
|
+
if (conflicts.length) throw new ProvisionConflictError(conflicts);
|
|
103
|
+
|
|
104
|
+
const kitHash = kitContentHash(kitRoot);
|
|
105
|
+
if (options.dryRun || files.length === 0) return { kit_id: kitId, kit_hash: kitHash, files, dry_run: Boolean(options.dryRun) };
|
|
106
|
+
|
|
107
|
+
const manifestPath = path.join(targetRoot, ...PROVISION_MANIFEST_DIR.split("/"), `${kitId}.json`);
|
|
108
|
+
assertSafeDestination(targetRoot, manifestPath);
|
|
109
|
+
for (const file of files) atomicCopyFile(targetRoot, file.source, file.destination);
|
|
110
|
+
atomicWriteJson(targetRoot, manifestPath, {
|
|
111
|
+
schema_version: "1.0",
|
|
112
|
+
kit_id: kitId,
|
|
113
|
+
kit_hash: kitHash,
|
|
114
|
+
provisioned_at: new Date().toISOString(),
|
|
115
|
+
files: files.map(({ id, target }) => ({ id, target })),
|
|
116
|
+
});
|
|
117
|
+
return { kit_id: kitId, kit_hash: kitHash, files, manifest_path: manifestPath, dry_run: false };
|
|
118
|
+
}
|