@mc-and-his-agents/loom-installer 0.1.1
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/README.md +47 -0
- package/dist/src/claude.js +157 -0
- package/dist/src/cli.js +35 -0
- package/dist/src/codex.js +191 -0
- package/dist/src/index.js +175 -0
- package/dist/src/payload.js +42 -0
- package/dist/src/types.js +1 -0
- package/dist/src/utils.js +84 -0
- package/dist/test/installer.test.js +167 -0
- package/package.json +46 -0
- package/payload/manifest.json +4294 -0
- package/payload/plugin/loom/.codex-plugin/plugin.json +37 -0
- package/payload/plugin/loom/skills/README.md +128 -0
- package/payload/plugin/loom/skills/distribution-and-adapter-contract.md +359 -0
- package/payload/plugin/loom/skills/install-layout.json +91 -0
- package/payload/plugin/loom/skills/loom-adopt/SKILL.md +80 -0
- package/payload/plugin/loom/skills/loom-adopt/agents/openai.yaml +4 -0
- package/payload/plugin/loom/skills/loom-adopt/contract.json +45 -0
- package/payload/plugin/loom/skills/loom-adopt/references/input-signals.md +17 -0
- package/payload/plugin/loom/skills/loom-adopt/references/output-contract.md +17 -0
- package/payload/plugin/loom/skills/loom-adopt/scripts/loom-adopt.py +14 -0
- package/payload/plugin/loom/skills/loom-handoff/SKILL.md +23 -0
- package/payload/plugin/loom/skills/loom-handoff/agents/openai.yaml +4 -0
- package/payload/plugin/loom/skills/loom-handoff/contract.json +53 -0
- package/payload/plugin/loom/skills/loom-handoff/references/input-signals.md +7 -0
- package/payload/plugin/loom/skills/loom-handoff/references/output-contract.md +42 -0
- package/payload/plugin/loom/skills/loom-handoff/scripts/loom-handoff.py +14 -0
- package/payload/plugin/loom/skills/loom-init/SKILL.md +246 -0
- package/payload/plugin/loom/skills/loom-init/agents/openai.yaml +4 -0
- package/payload/plugin/loom/skills/loom-init/contract.json +76 -0
- package/payload/plugin/loom/skills/loom-init/references/input-signals.md +16 -0
- package/payload/plugin/loom/skills/loom-init/references/intake-signals.md +155 -0
- package/payload/plugin/loom/skills/loom-init/references/output-contract.md +208 -0
- package/payload/plugin/loom/skills/loom-init/scripts/loom-init.py +14 -0
- package/payload/plugin/loom/skills/loom-merge-ready/SKILL.md +23 -0
- package/payload/plugin/loom/skills/loom-merge-ready/agents/openai.yaml +4 -0
- package/payload/plugin/loom/skills/loom-merge-ready/contract.json +49 -0
- package/payload/plugin/loom/skills/loom-merge-ready/references/input-signals.md +7 -0
- package/payload/plugin/loom/skills/loom-merge-ready/references/output-contract.md +34 -0
- package/payload/plugin/loom/skills/loom-merge-ready/scripts/loom-merge-ready.py +14 -0
- package/payload/plugin/loom/skills/loom-pre-review/SKILL.md +69 -0
- package/payload/plugin/loom/skills/loom-pre-review/agents/openai.yaml +4 -0
- package/payload/plugin/loom/skills/loom-pre-review/contract.json +41 -0
- package/payload/plugin/loom/skills/loom-pre-review/references/input-signals.md +14 -0
- package/payload/plugin/loom/skills/loom-pre-review/references/output-contract.md +20 -0
- package/payload/plugin/loom/skills/loom-pre-review/scripts/loom-pre-review.py +14 -0
- package/payload/plugin/loom/skills/loom-resume/SKILL.md +72 -0
- package/payload/plugin/loom/skills/loom-resume/agents/openai.yaml +4 -0
- package/payload/plugin/loom/skills/loom-resume/contract.json +47 -0
- package/payload/plugin/loom/skills/loom-resume/references/input-signals.md +15 -0
- package/payload/plugin/loom/skills/loom-resume/references/output-contract.md +58 -0
- package/payload/plugin/loom/skills/loom-resume/scripts/loom-resume.py +14 -0
- package/payload/plugin/loom/skills/loom-retire/SKILL.md +26 -0
- package/payload/plugin/loom/skills/loom-retire/agents/openai.yaml +4 -0
- package/payload/plugin/loom/skills/loom-retire/contract.json +41 -0
- package/payload/plugin/loom/skills/loom-retire/references/input-signals.md +7 -0
- package/payload/plugin/loom/skills/loom-retire/references/output-contract.md +13 -0
- package/payload/plugin/loom/skills/loom-retire/scripts/loom-retire.py +14 -0
- package/payload/plugin/loom/skills/loom-review/SKILL.md +95 -0
- package/payload/plugin/loom/skills/loom-review/agents/openai.yaml +4 -0
- package/payload/plugin/loom/skills/loom-review/contract.json +49 -0
- package/payload/plugin/loom/skills/loom-review/references/input-signals.md +15 -0
- package/payload/plugin/loom/skills/loom-review/references/output-contract.md +57 -0
- package/payload/plugin/loom/skills/loom-review/scripts/loom-review.py +14 -0
- package/payload/plugin/loom/skills/registry.json +64 -0
- package/payload/plugin/loom/skills/route-matrix.md +63 -0
- package/payload/plugin/loom/skills/shared/assets/github/PULL_REQUEST_TEMPLATE.md +22 -0
- package/payload/plugin/loom/skills/shared/assets/review/loom-review-result-schema.json +93 -0
- package/payload/plugin/loom/skills/shared/assets/templates/scaffold/plan.md +51 -0
- package/payload/plugin/loom/skills/shared/assets/templates/scaffold/spec.md +48 -0
- package/payload/plugin/loom/skills/shared/references/adoption/deep-existing-repo-default.md +64 -0
- package/payload/plugin/loom/skills/shared/references/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/plugin/loom/skills/shared/references/adoption/routing-and-checkpoints.md +88 -0
- package/payload/plugin/loom/skills/shared/references/governance/host-object-taxonomy.md +148 -0
- package/payload/plugin/loom/skills/shared/references/governance/issue-model.md +127 -0
- package/payload/plugin/loom/skills/shared/references/governance/maturity-and-closing.md +69 -0
- package/payload/plugin/loom/skills/shared/references/governance/principles.md +180 -0
- package/payload/plugin/loom/skills/shared/references/governance/review-model.md +109 -0
- package/payload/plugin/loom/skills/shared/references/governance/state-machine.md +163 -0
- package/payload/plugin/loom/skills/shared/references/governance/truth-and-sync-boundary.md +161 -0
- package/payload/plugin/loom/skills/shared/references/harness/automation-frontload.md +139 -0
- package/payload/plugin/loom/skills/shared/references/harness/closeout-gate.md +97 -0
- package/payload/plugin/loom/skills/shared/references/harness/execution-chain.md +56 -0
- package/payload/plugin/loom/skills/shared/references/harness/execution-context.md +71 -0
- package/payload/plugin/loom/skills/shared/references/harness/fact-chain-contract.md +160 -0
- package/payload/plugin/loom/skills/shared/references/harness/host-action-contract.md +128 -0
- package/payload/plugin/loom/skills/shared/references/harness/host-issue-binding.md +90 -0
- package/payload/plugin/loom/skills/shared/references/harness/host-lifecycle-boundary.md +56 -0
- package/payload/plugin/loom/skills/shared/references/harness/merge-checkpoint.md +95 -0
- package/payload/plugin/loom/skills/shared/references/harness/reconciliation-audit.md +64 -0
- package/payload/plugin/loom/skills/shared/references/harness/recovery-model.md +101 -0
- package/payload/plugin/loom/skills/shared/references/harness/review-execution.md +99 -0
- package/payload/plugin/loom/skills/shared/references/harness/runtime-state.md +103 -0
- package/payload/plugin/loom/skills/shared/references/harness/status-surface.md +121 -0
- package/payload/plugin/loom/skills/shared/references/harness/work-item-contract.md +104 -0
- package/payload/plugin/loom/skills/shared/references/harness/workspace-and-purity.md +73 -0
- package/payload/plugin/loom/skills/shared/references/harness/workspace-model.md +56 -0
- package/payload/plugin/loom/skills/shared/references/templates/pull-request.md +44 -0
- package/payload/plugin/loom/skills/shared/references/templates/review-record.md +35 -0
- package/payload/plugin/loom/skills/shared/references/templates/spec-suite.md +57 -0
- package/payload/plugin/loom/skills/shared/scripts/fact_chain_support.py +509 -0
- package/payload/plugin/loom/skills/shared/scripts/governance_surface.py +869 -0
- package/payload/plugin/loom/skills/shared/scripts/loom_check.py +4724 -0
- package/payload/plugin/loom/skills/shared/scripts/loom_flow.py +5390 -0
- package/payload/plugin/loom/skills/shared/scripts/loom_init.py +1966 -0
- package/payload/plugin/loom/skills/shared/scripts/runtime_paths.py +116 -0
- package/payload/plugin/loom/skills/shared/scripts/runtime_state.py +405 -0
- package/payload/plugin/loom/skills/upgrade-contract.json +29 -0
- package/payload/skills/loom-adopt/.loom-runtime/install-layout.json +77 -0
- package/payload/skills/loom-adopt/.loom-runtime/loom-adopt/SKILL.md +80 -0
- package/payload/skills/loom-adopt/.loom-runtime/loom-adopt/agents/openai.yaml +4 -0
- package/payload/skills/loom-adopt/.loom-runtime/loom-adopt/contract.json +45 -0
- package/payload/skills/loom-adopt/.loom-runtime/loom-adopt/references/input-signals.md +17 -0
- package/payload/skills/loom-adopt/.loom-runtime/loom-adopt/references/output-contract.md +17 -0
- package/payload/skills/loom-adopt/.loom-runtime/loom-adopt/scripts/loom-adopt.py +14 -0
- package/payload/skills/loom-adopt/.loom-runtime/loom-init/references/input-signals.md +16 -0
- package/payload/skills/loom-adopt/.loom-runtime/loom-init/references/intake-signals.md +155 -0
- package/payload/skills/loom-adopt/.loom-runtime/loom-init/references/output-contract.md +208 -0
- package/payload/skills/loom-adopt/.loom-runtime/registry.json +15 -0
- package/payload/skills/loom-adopt/.loom-runtime/route-matrix.md +63 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/assets/github/PULL_REQUEST_TEMPLATE.md +22 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/assets/review/loom-review-result-schema.json +93 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/assets/templates/scaffold/plan.md +51 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/assets/templates/scaffold/spec.md +48 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/governance/issue-model.md +127 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/governance/principles.md +180 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/governance/review-model.md +109 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/governance/state-machine.md +163 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/execution-chain.md +56 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/execution-context.md +71 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/recovery-model.md +101 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/review-execution.md +99 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/runtime-state.md +103 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/status-surface.md +121 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/harness/workspace-model.md +56 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/templates/pull-request.md +44 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/templates/review-record.md +35 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/templates/spec-suite.md +57 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/fact_chain_support.py +509 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/governance_surface.py +879 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/loom_check.py +4683 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/loom_flow.py +5390 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/loom_init.py +1966 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/runtime_paths.py +116 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/runtime_state.py +405 -0
- package/payload/skills/loom-adopt/.loom-runtime/upgrade-contract.json +29 -0
- package/payload/skills/loom-adopt/SKILL.md +80 -0
- package/payload/skills/loom-adopt/agents/openai.yaml +4 -0
- package/payload/skills/loom-adopt/contract.json +45 -0
- package/payload/skills/loom-adopt/references/input-signals.md +17 -0
- package/payload/skills/loom-adopt/references/loom-init/input-signals.md +16 -0
- package/payload/skills/loom-adopt/references/loom-init/intake-signals.md +155 -0
- package/payload/skills/loom-adopt/references/loom-init/output-contract.md +208 -0
- package/payload/skills/loom-adopt/references/output-contract.md +17 -0
- package/payload/skills/loom-adopt/references/route-matrix.md +63 -0
- package/payload/skills/loom-adopt/references/shared/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-adopt/references/shared/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-adopt/references/shared/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-adopt/references/shared/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-adopt/references/shared/governance/issue-model.md +127 -0
- package/payload/skills/loom-adopt/references/shared/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-adopt/references/shared/governance/principles.md +180 -0
- package/payload/skills/loom-adopt/references/shared/governance/review-model.md +109 -0
- package/payload/skills/loom-adopt/references/shared/governance/state-machine.md +163 -0
- package/payload/skills/loom-adopt/references/shared/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-adopt/references/shared/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-adopt/references/shared/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-adopt/references/shared/harness/execution-chain.md +56 -0
- package/payload/skills/loom-adopt/references/shared/harness/execution-context.md +71 -0
- package/payload/skills/loom-adopt/references/shared/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-adopt/references/shared/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-adopt/references/shared/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-adopt/references/shared/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-adopt/references/shared/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-adopt/references/shared/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-adopt/references/shared/harness/recovery-model.md +101 -0
- package/payload/skills/loom-adopt/references/shared/harness/review-execution.md +99 -0
- package/payload/skills/loom-adopt/references/shared/harness/runtime-state.md +103 -0
- package/payload/skills/loom-adopt/references/shared/harness/status-surface.md +121 -0
- package/payload/skills/loom-adopt/references/shared/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-adopt/references/shared/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-adopt/references/shared/harness/workspace-model.md +56 -0
- package/payload/skills/loom-adopt/references/shared/templates/pull-request.md +44 -0
- package/payload/skills/loom-adopt/references/shared/templates/review-record.md +35 -0
- package/payload/skills/loom-adopt/references/shared/templates/spec-suite.md +57 -0
- package/payload/skills/loom-adopt/scripts/loom-adopt.py +16 -0
- package/payload/skills/loom-handoff/.loom-runtime/install-layout.json +77 -0
- package/payload/skills/loom-handoff/.loom-runtime/loom-handoff/SKILL.md +23 -0
- package/payload/skills/loom-handoff/.loom-runtime/loom-handoff/agents/openai.yaml +4 -0
- package/payload/skills/loom-handoff/.loom-runtime/loom-handoff/contract.json +53 -0
- package/payload/skills/loom-handoff/.loom-runtime/loom-handoff/references/input-signals.md +7 -0
- package/payload/skills/loom-handoff/.loom-runtime/loom-handoff/references/output-contract.md +42 -0
- package/payload/skills/loom-handoff/.loom-runtime/loom-handoff/scripts/loom-handoff.py +14 -0
- package/payload/skills/loom-handoff/.loom-runtime/loom-init/references/input-signals.md +16 -0
- package/payload/skills/loom-handoff/.loom-runtime/loom-init/references/intake-signals.md +155 -0
- package/payload/skills/loom-handoff/.loom-runtime/loom-init/references/output-contract.md +208 -0
- package/payload/skills/loom-handoff/.loom-runtime/registry.json +15 -0
- package/payload/skills/loom-handoff/.loom-runtime/route-matrix.md +63 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/assets/github/PULL_REQUEST_TEMPLATE.md +22 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/assets/review/loom-review-result-schema.json +93 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/assets/templates/scaffold/plan.md +51 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/assets/templates/scaffold/spec.md +48 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/governance/issue-model.md +127 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/governance/principles.md +180 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/governance/review-model.md +109 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/governance/state-machine.md +163 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/execution-chain.md +56 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/execution-context.md +71 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/recovery-model.md +101 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/review-execution.md +99 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/runtime-state.md +103 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/status-surface.md +121 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/harness/workspace-model.md +56 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/templates/pull-request.md +44 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/templates/review-record.md +35 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/templates/spec-suite.md +57 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/fact_chain_support.py +509 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/governance_surface.py +879 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/loom_check.py +4683 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/loom_flow.py +5390 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/loom_init.py +1966 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/runtime_paths.py +116 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/runtime_state.py +405 -0
- package/payload/skills/loom-handoff/.loom-runtime/upgrade-contract.json +29 -0
- package/payload/skills/loom-handoff/SKILL.md +23 -0
- package/payload/skills/loom-handoff/agents/openai.yaml +4 -0
- package/payload/skills/loom-handoff/contract.json +53 -0
- package/payload/skills/loom-handoff/references/input-signals.md +7 -0
- package/payload/skills/loom-handoff/references/loom-init/input-signals.md +16 -0
- package/payload/skills/loom-handoff/references/loom-init/intake-signals.md +155 -0
- package/payload/skills/loom-handoff/references/loom-init/output-contract.md +208 -0
- package/payload/skills/loom-handoff/references/output-contract.md +42 -0
- package/payload/skills/loom-handoff/references/route-matrix.md +63 -0
- package/payload/skills/loom-handoff/references/shared/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-handoff/references/shared/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-handoff/references/shared/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-handoff/references/shared/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-handoff/references/shared/governance/issue-model.md +127 -0
- package/payload/skills/loom-handoff/references/shared/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-handoff/references/shared/governance/principles.md +180 -0
- package/payload/skills/loom-handoff/references/shared/governance/review-model.md +109 -0
- package/payload/skills/loom-handoff/references/shared/governance/state-machine.md +163 -0
- package/payload/skills/loom-handoff/references/shared/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-handoff/references/shared/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-handoff/references/shared/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-handoff/references/shared/harness/execution-chain.md +56 -0
- package/payload/skills/loom-handoff/references/shared/harness/execution-context.md +71 -0
- package/payload/skills/loom-handoff/references/shared/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-handoff/references/shared/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-handoff/references/shared/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-handoff/references/shared/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-handoff/references/shared/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-handoff/references/shared/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-handoff/references/shared/harness/recovery-model.md +101 -0
- package/payload/skills/loom-handoff/references/shared/harness/review-execution.md +99 -0
- package/payload/skills/loom-handoff/references/shared/harness/runtime-state.md +103 -0
- package/payload/skills/loom-handoff/references/shared/harness/status-surface.md +121 -0
- package/payload/skills/loom-handoff/references/shared/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-handoff/references/shared/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-handoff/references/shared/harness/workspace-model.md +56 -0
- package/payload/skills/loom-handoff/references/shared/templates/pull-request.md +44 -0
- package/payload/skills/loom-handoff/references/shared/templates/review-record.md +35 -0
- package/payload/skills/loom-handoff/references/shared/templates/spec-suite.md +57 -0
- package/payload/skills/loom-handoff/scripts/loom-handoff.py +16 -0
- package/payload/skills/loom-init/.loom-runtime/install-layout.json +77 -0
- package/payload/skills/loom-init/.loom-runtime/loom-init/SKILL.md +246 -0
- package/payload/skills/loom-init/.loom-runtime/loom-init/agents/openai.yaml +4 -0
- package/payload/skills/loom-init/.loom-runtime/loom-init/contract.json +76 -0
- package/payload/skills/loom-init/.loom-runtime/loom-init/references/input-signals.md +16 -0
- package/payload/skills/loom-init/.loom-runtime/loom-init/references/intake-signals.md +155 -0
- package/payload/skills/loom-init/.loom-runtime/loom-init/references/output-contract.md +208 -0
- package/payload/skills/loom-init/.loom-runtime/loom-init/scripts/loom-init.py +14 -0
- package/payload/skills/loom-init/.loom-runtime/registry.json +15 -0
- package/payload/skills/loom-init/.loom-runtime/route-matrix.md +63 -0
- package/payload/skills/loom-init/.loom-runtime/shared/assets/github/PULL_REQUEST_TEMPLATE.md +22 -0
- package/payload/skills/loom-init/.loom-runtime/shared/assets/review/loom-review-result-schema.json +93 -0
- package/payload/skills/loom-init/.loom-runtime/shared/assets/templates/scaffold/plan.md +51 -0
- package/payload/skills/loom-init/.loom-runtime/shared/assets/templates/scaffold/spec.md +48 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/governance/issue-model.md +127 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/governance/principles.md +180 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/governance/review-model.md +109 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/governance/state-machine.md +163 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/execution-chain.md +56 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/execution-context.md +71 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/recovery-model.md +101 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/review-execution.md +99 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/runtime-state.md +103 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/status-surface.md +121 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/harness/workspace-model.md +56 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/templates/pull-request.md +44 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/templates/review-record.md +35 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/templates/spec-suite.md +57 -0
- package/payload/skills/loom-init/.loom-runtime/shared/scripts/fact_chain_support.py +509 -0
- package/payload/skills/loom-init/.loom-runtime/shared/scripts/governance_surface.py +879 -0
- package/payload/skills/loom-init/.loom-runtime/shared/scripts/loom_check.py +4683 -0
- package/payload/skills/loom-init/.loom-runtime/shared/scripts/loom_flow.py +5390 -0
- package/payload/skills/loom-init/.loom-runtime/shared/scripts/loom_init.py +1966 -0
- package/payload/skills/loom-init/.loom-runtime/shared/scripts/runtime_paths.py +116 -0
- package/payload/skills/loom-init/.loom-runtime/shared/scripts/runtime_state.py +405 -0
- package/payload/skills/loom-init/.loom-runtime/upgrade-contract.json +29 -0
- package/payload/skills/loom-init/SKILL.md +246 -0
- package/payload/skills/loom-init/agents/openai.yaml +4 -0
- package/payload/skills/loom-init/contract.json +76 -0
- package/payload/skills/loom-init/references/input-signals.md +16 -0
- package/payload/skills/loom-init/references/intake-signals.md +155 -0
- package/payload/skills/loom-init/references/output-contract.md +208 -0
- package/payload/skills/loom-init/references/route-matrix.md +63 -0
- package/payload/skills/loom-init/references/shared/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-init/references/shared/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-init/references/shared/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-init/references/shared/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-init/references/shared/governance/issue-model.md +127 -0
- package/payload/skills/loom-init/references/shared/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-init/references/shared/governance/principles.md +180 -0
- package/payload/skills/loom-init/references/shared/governance/review-model.md +109 -0
- package/payload/skills/loom-init/references/shared/governance/state-machine.md +163 -0
- package/payload/skills/loom-init/references/shared/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-init/references/shared/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-init/references/shared/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-init/references/shared/harness/execution-chain.md +56 -0
- package/payload/skills/loom-init/references/shared/harness/execution-context.md +71 -0
- package/payload/skills/loom-init/references/shared/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-init/references/shared/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-init/references/shared/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-init/references/shared/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-init/references/shared/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-init/references/shared/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-init/references/shared/harness/recovery-model.md +101 -0
- package/payload/skills/loom-init/references/shared/harness/review-execution.md +99 -0
- package/payload/skills/loom-init/references/shared/harness/runtime-state.md +103 -0
- package/payload/skills/loom-init/references/shared/harness/status-surface.md +121 -0
- package/payload/skills/loom-init/references/shared/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-init/references/shared/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-init/references/shared/harness/workspace-model.md +56 -0
- package/payload/skills/loom-init/references/shared/templates/pull-request.md +44 -0
- package/payload/skills/loom-init/references/shared/templates/review-record.md +35 -0
- package/payload/skills/loom-init/references/shared/templates/spec-suite.md +57 -0
- package/payload/skills/loom-init/scripts/loom-init.py +16 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/install-layout.json +77 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-init/references/input-signals.md +16 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-init/references/intake-signals.md +155 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-init/references/output-contract.md +208 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-merge-ready/SKILL.md +23 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-merge-ready/agents/openai.yaml +4 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-merge-ready/contract.json +49 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-merge-ready/references/input-signals.md +7 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-merge-ready/references/output-contract.md +34 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-merge-ready/scripts/loom-merge-ready.py +14 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/registry.json +15 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/route-matrix.md +63 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/assets/github/PULL_REQUEST_TEMPLATE.md +22 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/assets/review/loom-review-result-schema.json +93 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/assets/templates/scaffold/plan.md +51 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/assets/templates/scaffold/spec.md +48 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/governance/issue-model.md +127 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/governance/principles.md +180 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/governance/review-model.md +109 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/governance/state-machine.md +163 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/execution-chain.md +56 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/execution-context.md +71 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/recovery-model.md +101 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/review-execution.md +99 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/runtime-state.md +103 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/status-surface.md +121 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/harness/workspace-model.md +56 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/templates/pull-request.md +44 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/templates/review-record.md +35 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/templates/spec-suite.md +57 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/fact_chain_support.py +509 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/governance_surface.py +879 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_check.py +4683 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_flow.py +5390 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_init.py +1966 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/runtime_paths.py +116 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/runtime_state.py +405 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/upgrade-contract.json +29 -0
- package/payload/skills/loom-merge-ready/SKILL.md +23 -0
- package/payload/skills/loom-merge-ready/agents/openai.yaml +4 -0
- package/payload/skills/loom-merge-ready/contract.json +49 -0
- package/payload/skills/loom-merge-ready/references/input-signals.md +7 -0
- package/payload/skills/loom-merge-ready/references/loom-init/input-signals.md +16 -0
- package/payload/skills/loom-merge-ready/references/loom-init/intake-signals.md +155 -0
- package/payload/skills/loom-merge-ready/references/loom-init/output-contract.md +208 -0
- package/payload/skills/loom-merge-ready/references/output-contract.md +34 -0
- package/payload/skills/loom-merge-ready/references/route-matrix.md +63 -0
- package/payload/skills/loom-merge-ready/references/shared/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-merge-ready/references/shared/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-merge-ready/references/shared/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-merge-ready/references/shared/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-merge-ready/references/shared/governance/issue-model.md +127 -0
- package/payload/skills/loom-merge-ready/references/shared/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-merge-ready/references/shared/governance/principles.md +180 -0
- package/payload/skills/loom-merge-ready/references/shared/governance/review-model.md +109 -0
- package/payload/skills/loom-merge-ready/references/shared/governance/state-machine.md +163 -0
- package/payload/skills/loom-merge-ready/references/shared/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/execution-chain.md +56 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/execution-context.md +71 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/recovery-model.md +101 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/review-execution.md +99 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/runtime-state.md +103 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/status-surface.md +121 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-merge-ready/references/shared/harness/workspace-model.md +56 -0
- package/payload/skills/loom-merge-ready/references/shared/templates/pull-request.md +44 -0
- package/payload/skills/loom-merge-ready/references/shared/templates/review-record.md +35 -0
- package/payload/skills/loom-merge-ready/references/shared/templates/spec-suite.md +57 -0
- package/payload/skills/loom-merge-ready/scripts/loom-merge-ready.py +16 -0
- package/payload/skills/loom-pre-review/.loom-runtime/install-layout.json +77 -0
- package/payload/skills/loom-pre-review/.loom-runtime/loom-init/references/input-signals.md +16 -0
- package/payload/skills/loom-pre-review/.loom-runtime/loom-init/references/intake-signals.md +155 -0
- package/payload/skills/loom-pre-review/.loom-runtime/loom-init/references/output-contract.md +208 -0
- package/payload/skills/loom-pre-review/.loom-runtime/loom-pre-review/SKILL.md +69 -0
- package/payload/skills/loom-pre-review/.loom-runtime/loom-pre-review/agents/openai.yaml +4 -0
- package/payload/skills/loom-pre-review/.loom-runtime/loom-pre-review/contract.json +41 -0
- package/payload/skills/loom-pre-review/.loom-runtime/loom-pre-review/references/input-signals.md +14 -0
- package/payload/skills/loom-pre-review/.loom-runtime/loom-pre-review/references/output-contract.md +20 -0
- package/payload/skills/loom-pre-review/.loom-runtime/loom-pre-review/scripts/loom-pre-review.py +14 -0
- package/payload/skills/loom-pre-review/.loom-runtime/registry.json +15 -0
- package/payload/skills/loom-pre-review/.loom-runtime/route-matrix.md +63 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/assets/github/PULL_REQUEST_TEMPLATE.md +22 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/assets/review/loom-review-result-schema.json +93 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/assets/templates/scaffold/plan.md +51 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/assets/templates/scaffold/spec.md +48 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/governance/issue-model.md +127 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/governance/principles.md +180 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/governance/review-model.md +109 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/governance/state-machine.md +163 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/execution-chain.md +56 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/execution-context.md +71 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/recovery-model.md +101 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/review-execution.md +99 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/runtime-state.md +103 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/status-surface.md +121 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/harness/workspace-model.md +56 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/templates/pull-request.md +44 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/templates/review-record.md +35 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/templates/spec-suite.md +57 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/fact_chain_support.py +509 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/governance_surface.py +879 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/loom_check.py +4683 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/loom_flow.py +5390 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/loom_init.py +1966 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/runtime_paths.py +116 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/runtime_state.py +405 -0
- package/payload/skills/loom-pre-review/.loom-runtime/upgrade-contract.json +29 -0
- package/payload/skills/loom-pre-review/SKILL.md +69 -0
- package/payload/skills/loom-pre-review/agents/openai.yaml +4 -0
- package/payload/skills/loom-pre-review/contract.json +41 -0
- package/payload/skills/loom-pre-review/references/input-signals.md +14 -0
- package/payload/skills/loom-pre-review/references/loom-init/input-signals.md +16 -0
- package/payload/skills/loom-pre-review/references/loom-init/intake-signals.md +155 -0
- package/payload/skills/loom-pre-review/references/loom-init/output-contract.md +208 -0
- package/payload/skills/loom-pre-review/references/output-contract.md +20 -0
- package/payload/skills/loom-pre-review/references/route-matrix.md +63 -0
- package/payload/skills/loom-pre-review/references/shared/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-pre-review/references/shared/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-pre-review/references/shared/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-pre-review/references/shared/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-pre-review/references/shared/governance/issue-model.md +127 -0
- package/payload/skills/loom-pre-review/references/shared/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-pre-review/references/shared/governance/principles.md +180 -0
- package/payload/skills/loom-pre-review/references/shared/governance/review-model.md +109 -0
- package/payload/skills/loom-pre-review/references/shared/governance/state-machine.md +163 -0
- package/payload/skills/loom-pre-review/references/shared/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-pre-review/references/shared/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-pre-review/references/shared/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-pre-review/references/shared/harness/execution-chain.md +56 -0
- package/payload/skills/loom-pre-review/references/shared/harness/execution-context.md +71 -0
- package/payload/skills/loom-pre-review/references/shared/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-pre-review/references/shared/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-pre-review/references/shared/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-pre-review/references/shared/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-pre-review/references/shared/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-pre-review/references/shared/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-pre-review/references/shared/harness/recovery-model.md +101 -0
- package/payload/skills/loom-pre-review/references/shared/harness/review-execution.md +99 -0
- package/payload/skills/loom-pre-review/references/shared/harness/runtime-state.md +103 -0
- package/payload/skills/loom-pre-review/references/shared/harness/status-surface.md +121 -0
- package/payload/skills/loom-pre-review/references/shared/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-pre-review/references/shared/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-pre-review/references/shared/harness/workspace-model.md +56 -0
- package/payload/skills/loom-pre-review/references/shared/templates/pull-request.md +44 -0
- package/payload/skills/loom-pre-review/references/shared/templates/review-record.md +35 -0
- package/payload/skills/loom-pre-review/references/shared/templates/spec-suite.md +57 -0
- package/payload/skills/loom-pre-review/scripts/loom-pre-review.py +16 -0
- package/payload/skills/loom-resume/.loom-runtime/install-layout.json +77 -0
- package/payload/skills/loom-resume/.loom-runtime/loom-init/references/input-signals.md +16 -0
- package/payload/skills/loom-resume/.loom-runtime/loom-init/references/intake-signals.md +155 -0
- package/payload/skills/loom-resume/.loom-runtime/loom-init/references/output-contract.md +208 -0
- package/payload/skills/loom-resume/.loom-runtime/loom-resume/SKILL.md +72 -0
- package/payload/skills/loom-resume/.loom-runtime/loom-resume/agents/openai.yaml +4 -0
- package/payload/skills/loom-resume/.loom-runtime/loom-resume/contract.json +47 -0
- package/payload/skills/loom-resume/.loom-runtime/loom-resume/references/input-signals.md +15 -0
- package/payload/skills/loom-resume/.loom-runtime/loom-resume/references/output-contract.md +58 -0
- package/payload/skills/loom-resume/.loom-runtime/loom-resume/scripts/loom-resume.py +14 -0
- package/payload/skills/loom-resume/.loom-runtime/registry.json +15 -0
- package/payload/skills/loom-resume/.loom-runtime/route-matrix.md +63 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/assets/github/PULL_REQUEST_TEMPLATE.md +22 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/assets/review/loom-review-result-schema.json +93 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/assets/templates/scaffold/plan.md +51 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/assets/templates/scaffold/spec.md +48 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/governance/issue-model.md +127 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/governance/principles.md +180 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/governance/review-model.md +109 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/governance/state-machine.md +163 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/execution-chain.md +56 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/execution-context.md +71 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/recovery-model.md +101 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/review-execution.md +99 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/runtime-state.md +103 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/status-surface.md +121 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/harness/workspace-model.md +56 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/templates/pull-request.md +44 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/templates/review-record.md +35 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/templates/spec-suite.md +57 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/scripts/fact_chain_support.py +509 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/scripts/governance_surface.py +879 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/scripts/loom_check.py +4683 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/scripts/loom_flow.py +5390 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/scripts/loom_init.py +1966 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/scripts/runtime_paths.py +116 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/scripts/runtime_state.py +405 -0
- package/payload/skills/loom-resume/.loom-runtime/upgrade-contract.json +29 -0
- package/payload/skills/loom-resume/SKILL.md +72 -0
- package/payload/skills/loom-resume/agents/openai.yaml +4 -0
- package/payload/skills/loom-resume/contract.json +47 -0
- package/payload/skills/loom-resume/references/input-signals.md +15 -0
- package/payload/skills/loom-resume/references/loom-init/input-signals.md +16 -0
- package/payload/skills/loom-resume/references/loom-init/intake-signals.md +155 -0
- package/payload/skills/loom-resume/references/loom-init/output-contract.md +208 -0
- package/payload/skills/loom-resume/references/output-contract.md +58 -0
- package/payload/skills/loom-resume/references/route-matrix.md +63 -0
- package/payload/skills/loom-resume/references/shared/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-resume/references/shared/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-resume/references/shared/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-resume/references/shared/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-resume/references/shared/governance/issue-model.md +127 -0
- package/payload/skills/loom-resume/references/shared/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-resume/references/shared/governance/principles.md +180 -0
- package/payload/skills/loom-resume/references/shared/governance/review-model.md +109 -0
- package/payload/skills/loom-resume/references/shared/governance/state-machine.md +163 -0
- package/payload/skills/loom-resume/references/shared/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-resume/references/shared/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-resume/references/shared/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-resume/references/shared/harness/execution-chain.md +56 -0
- package/payload/skills/loom-resume/references/shared/harness/execution-context.md +71 -0
- package/payload/skills/loom-resume/references/shared/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-resume/references/shared/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-resume/references/shared/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-resume/references/shared/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-resume/references/shared/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-resume/references/shared/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-resume/references/shared/harness/recovery-model.md +101 -0
- package/payload/skills/loom-resume/references/shared/harness/review-execution.md +99 -0
- package/payload/skills/loom-resume/references/shared/harness/runtime-state.md +103 -0
- package/payload/skills/loom-resume/references/shared/harness/status-surface.md +121 -0
- package/payload/skills/loom-resume/references/shared/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-resume/references/shared/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-resume/references/shared/harness/workspace-model.md +56 -0
- package/payload/skills/loom-resume/references/shared/templates/pull-request.md +44 -0
- package/payload/skills/loom-resume/references/shared/templates/review-record.md +35 -0
- package/payload/skills/loom-resume/references/shared/templates/spec-suite.md +57 -0
- package/payload/skills/loom-resume/scripts/loom-resume.py +16 -0
- package/payload/skills/loom-retire/.loom-runtime/install-layout.json +77 -0
- package/payload/skills/loom-retire/.loom-runtime/loom-init/references/input-signals.md +16 -0
- package/payload/skills/loom-retire/.loom-runtime/loom-init/references/intake-signals.md +155 -0
- package/payload/skills/loom-retire/.loom-runtime/loom-init/references/output-contract.md +208 -0
- package/payload/skills/loom-retire/.loom-runtime/loom-retire/SKILL.md +26 -0
- package/payload/skills/loom-retire/.loom-runtime/loom-retire/agents/openai.yaml +4 -0
- package/payload/skills/loom-retire/.loom-runtime/loom-retire/contract.json +41 -0
- package/payload/skills/loom-retire/.loom-runtime/loom-retire/references/input-signals.md +7 -0
- package/payload/skills/loom-retire/.loom-runtime/loom-retire/references/output-contract.md +13 -0
- package/payload/skills/loom-retire/.loom-runtime/loom-retire/scripts/loom-retire.py +14 -0
- package/payload/skills/loom-retire/.loom-runtime/registry.json +15 -0
- package/payload/skills/loom-retire/.loom-runtime/route-matrix.md +63 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/assets/github/PULL_REQUEST_TEMPLATE.md +22 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/assets/review/loom-review-result-schema.json +93 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/assets/templates/scaffold/plan.md +51 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/assets/templates/scaffold/spec.md +48 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/governance/issue-model.md +127 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/governance/principles.md +180 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/governance/review-model.md +109 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/governance/state-machine.md +163 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/execution-chain.md +56 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/execution-context.md +71 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/recovery-model.md +101 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/review-execution.md +99 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/runtime-state.md +103 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/status-surface.md +121 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/harness/workspace-model.md +56 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/templates/pull-request.md +44 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/templates/review-record.md +35 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/templates/spec-suite.md +57 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/scripts/fact_chain_support.py +509 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/scripts/governance_surface.py +879 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/scripts/loom_check.py +4683 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/scripts/loom_flow.py +5390 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/scripts/loom_init.py +1966 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/scripts/runtime_paths.py +116 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/scripts/runtime_state.py +405 -0
- package/payload/skills/loom-retire/.loom-runtime/upgrade-contract.json +29 -0
- package/payload/skills/loom-retire/SKILL.md +26 -0
- package/payload/skills/loom-retire/agents/openai.yaml +4 -0
- package/payload/skills/loom-retire/contract.json +41 -0
- package/payload/skills/loom-retire/references/input-signals.md +7 -0
- package/payload/skills/loom-retire/references/loom-init/input-signals.md +16 -0
- package/payload/skills/loom-retire/references/loom-init/intake-signals.md +155 -0
- package/payload/skills/loom-retire/references/loom-init/output-contract.md +208 -0
- package/payload/skills/loom-retire/references/output-contract.md +13 -0
- package/payload/skills/loom-retire/references/route-matrix.md +63 -0
- package/payload/skills/loom-retire/references/shared/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-retire/references/shared/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-retire/references/shared/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-retire/references/shared/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-retire/references/shared/governance/issue-model.md +127 -0
- package/payload/skills/loom-retire/references/shared/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-retire/references/shared/governance/principles.md +180 -0
- package/payload/skills/loom-retire/references/shared/governance/review-model.md +109 -0
- package/payload/skills/loom-retire/references/shared/governance/state-machine.md +163 -0
- package/payload/skills/loom-retire/references/shared/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-retire/references/shared/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-retire/references/shared/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-retire/references/shared/harness/execution-chain.md +56 -0
- package/payload/skills/loom-retire/references/shared/harness/execution-context.md +71 -0
- package/payload/skills/loom-retire/references/shared/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-retire/references/shared/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-retire/references/shared/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-retire/references/shared/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-retire/references/shared/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-retire/references/shared/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-retire/references/shared/harness/recovery-model.md +101 -0
- package/payload/skills/loom-retire/references/shared/harness/review-execution.md +99 -0
- package/payload/skills/loom-retire/references/shared/harness/runtime-state.md +103 -0
- package/payload/skills/loom-retire/references/shared/harness/status-surface.md +121 -0
- package/payload/skills/loom-retire/references/shared/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-retire/references/shared/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-retire/references/shared/harness/workspace-model.md +56 -0
- package/payload/skills/loom-retire/references/shared/templates/pull-request.md +44 -0
- package/payload/skills/loom-retire/references/shared/templates/review-record.md +35 -0
- package/payload/skills/loom-retire/references/shared/templates/spec-suite.md +57 -0
- package/payload/skills/loom-retire/scripts/loom-retire.py +16 -0
- package/payload/skills/loom-review/.loom-runtime/install-layout.json +77 -0
- package/payload/skills/loom-review/.loom-runtime/loom-init/references/input-signals.md +16 -0
- package/payload/skills/loom-review/.loom-runtime/loom-init/references/intake-signals.md +155 -0
- package/payload/skills/loom-review/.loom-runtime/loom-init/references/output-contract.md +208 -0
- package/payload/skills/loom-review/.loom-runtime/loom-review/SKILL.md +95 -0
- package/payload/skills/loom-review/.loom-runtime/loom-review/agents/openai.yaml +4 -0
- package/payload/skills/loom-review/.loom-runtime/loom-review/contract.json +49 -0
- package/payload/skills/loom-review/.loom-runtime/loom-review/references/input-signals.md +15 -0
- package/payload/skills/loom-review/.loom-runtime/loom-review/references/output-contract.md +57 -0
- package/payload/skills/loom-review/.loom-runtime/loom-review/scripts/loom-review.py +14 -0
- package/payload/skills/loom-review/.loom-runtime/registry.json +15 -0
- package/payload/skills/loom-review/.loom-runtime/route-matrix.md +63 -0
- package/payload/skills/loom-review/.loom-runtime/shared/assets/github/PULL_REQUEST_TEMPLATE.md +22 -0
- package/payload/skills/loom-review/.loom-runtime/shared/assets/review/loom-review-result-schema.json +93 -0
- package/payload/skills/loom-review/.loom-runtime/shared/assets/templates/scaffold/plan.md +51 -0
- package/payload/skills/loom-review/.loom-runtime/shared/assets/templates/scaffold/spec.md +48 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/governance/issue-model.md +127 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/governance/principles.md +180 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/governance/review-model.md +109 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/governance/state-machine.md +163 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/execution-chain.md +56 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/execution-context.md +71 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/recovery-model.md +101 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/review-execution.md +99 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/runtime-state.md +103 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/status-surface.md +121 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/harness/workspace-model.md +56 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/templates/pull-request.md +44 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/templates/review-record.md +35 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/templates/spec-suite.md +57 -0
- package/payload/skills/loom-review/.loom-runtime/shared/scripts/fact_chain_support.py +509 -0
- package/payload/skills/loom-review/.loom-runtime/shared/scripts/governance_surface.py +879 -0
- package/payload/skills/loom-review/.loom-runtime/shared/scripts/loom_check.py +4683 -0
- package/payload/skills/loom-review/.loom-runtime/shared/scripts/loom_flow.py +5390 -0
- package/payload/skills/loom-review/.loom-runtime/shared/scripts/loom_init.py +1966 -0
- package/payload/skills/loom-review/.loom-runtime/shared/scripts/runtime_paths.py +116 -0
- package/payload/skills/loom-review/.loom-runtime/shared/scripts/runtime_state.py +405 -0
- package/payload/skills/loom-review/.loom-runtime/upgrade-contract.json +29 -0
- package/payload/skills/loom-review/SKILL.md +95 -0
- package/payload/skills/loom-review/agents/openai.yaml +4 -0
- package/payload/skills/loom-review/contract.json +49 -0
- package/payload/skills/loom-review/references/input-signals.md +15 -0
- package/payload/skills/loom-review/references/loom-init/input-signals.md +16 -0
- package/payload/skills/loom-review/references/loom-init/intake-signals.md +155 -0
- package/payload/skills/loom-review/references/loom-init/output-contract.md +208 -0
- package/payload/skills/loom-review/references/output-contract.md +57 -0
- package/payload/skills/loom-review/references/route-matrix.md +63 -0
- package/payload/skills/loom-review/references/shared/adoption/deep-existing-repo-default.md +64 -0
- package/payload/skills/loom-review/references/shared/adoption/lightweight-retrofit-default.md +71 -0
- package/payload/skills/loom-review/references/shared/adoption/routing-and-checkpoints.md +88 -0
- package/payload/skills/loom-review/references/shared/governance/host-object-taxonomy.md +148 -0
- package/payload/skills/loom-review/references/shared/governance/issue-model.md +127 -0
- package/payload/skills/loom-review/references/shared/governance/maturity-and-closing.md +69 -0
- package/payload/skills/loom-review/references/shared/governance/principles.md +180 -0
- package/payload/skills/loom-review/references/shared/governance/review-model.md +109 -0
- package/payload/skills/loom-review/references/shared/governance/state-machine.md +163 -0
- package/payload/skills/loom-review/references/shared/governance/truth-and-sync-boundary.md +161 -0
- package/payload/skills/loom-review/references/shared/harness/automation-frontload.md +139 -0
- package/payload/skills/loom-review/references/shared/harness/closeout-gate.md +97 -0
- package/payload/skills/loom-review/references/shared/harness/execution-chain.md +56 -0
- package/payload/skills/loom-review/references/shared/harness/execution-context.md +71 -0
- package/payload/skills/loom-review/references/shared/harness/fact-chain-contract.md +160 -0
- package/payload/skills/loom-review/references/shared/harness/host-action-contract.md +128 -0
- package/payload/skills/loom-review/references/shared/harness/host-issue-binding.md +90 -0
- package/payload/skills/loom-review/references/shared/harness/host-lifecycle-boundary.md +56 -0
- package/payload/skills/loom-review/references/shared/harness/merge-checkpoint.md +95 -0
- package/payload/skills/loom-review/references/shared/harness/reconciliation-audit.md +64 -0
- package/payload/skills/loom-review/references/shared/harness/recovery-model.md +101 -0
- package/payload/skills/loom-review/references/shared/harness/review-execution.md +99 -0
- package/payload/skills/loom-review/references/shared/harness/runtime-state.md +103 -0
- package/payload/skills/loom-review/references/shared/harness/status-surface.md +121 -0
- package/payload/skills/loom-review/references/shared/harness/work-item-contract.md +104 -0
- package/payload/skills/loom-review/references/shared/harness/workspace-and-purity.md +73 -0
- package/payload/skills/loom-review/references/shared/harness/workspace-model.md +56 -0
- package/payload/skills/loom-review/references/shared/templates/pull-request.md +44 -0
- package/payload/skills/loom-review/references/shared/templates/review-record.md +35 -0
- package/payload/skills/loom-review/references/shared/templates/spec-suite.md +57 -0
- package/payload/skills/loom-review/scripts/loom-review.py +16 -0
|
@@ -0,0 +1,1966 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Minimal executable bootstrap entry for Loom adoption."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
import json
|
|
8
|
+
import re
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
from functools import lru_cache
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
from fact_chain_support import inspect_fact_chain
|
|
15
|
+
from governance_surface import build_governance_surface
|
|
16
|
+
from runtime_paths import registry_path, shared_asset
|
|
17
|
+
from runtime_state import detect_runtime_state
|
|
18
|
+
|
|
19
|
+
RUNTIME_SOURCE = "skills/shared/scripts/loom_init.py"
|
|
20
|
+
FLOW_RUNTIME_SOURCE = "skills/shared/scripts/loom_flow.py"
|
|
21
|
+
CHECK_RUNTIME_SOURCE = "skills/shared/scripts/loom_check.py"
|
|
22
|
+
FACT_CHAIN_RUNTIME_SOURCE = "skills/shared/scripts/fact_chain_support.py"
|
|
23
|
+
GOVERNANCE_RUNTIME_SOURCE = "skills/shared/scripts/governance_surface.py"
|
|
24
|
+
TOOL_VERSION = "1.3.0"
|
|
25
|
+
CONTRACT_VERSION = "1.3.0"
|
|
26
|
+
WORK_ITEM_ID = "INIT-0001"
|
|
27
|
+
|
|
28
|
+
ROOT_BOUNDARY_FILES = (
|
|
29
|
+
"AGENTS.md",
|
|
30
|
+
"WORKFLOW.md",
|
|
31
|
+
"docs/WORKFLOW.md",
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
CI_DIRS = (
|
|
35
|
+
".github/workflows",
|
|
36
|
+
".gitlab-ci.yml",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
CODE_DIR_HINTS = (
|
|
40
|
+
"src",
|
|
41
|
+
"app",
|
|
42
|
+
"lib",
|
|
43
|
+
"cmd",
|
|
44
|
+
"pkg",
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
GENERATED_ROOT_ENTRY = (
|
|
48
|
+
"# Loom Root Entry\n\n"
|
|
49
|
+
"This repository was initialized with Loom bootstrap artifacts.\n\n"
|
|
50
|
+
"Read `.loom/README.md` first, then `.loom/bootstrap/init-result.json` "
|
|
51
|
+
"for the current initialization truth.\n"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
SKILL_SIGNAL_RULES: dict[str, tuple[str, ...]] = {
|
|
55
|
+
"loom-adopt": (
|
|
56
|
+
"初始化",
|
|
57
|
+
"新项目",
|
|
58
|
+
"retrofit",
|
|
59
|
+
"adopt",
|
|
60
|
+
"adoption",
|
|
61
|
+
"bootstrap loom",
|
|
62
|
+
"bootstrap the repo",
|
|
63
|
+
"接入 loom",
|
|
64
|
+
"引入 loom",
|
|
65
|
+
),
|
|
66
|
+
"loom-resume": (
|
|
67
|
+
"恢复上下文",
|
|
68
|
+
"接手当前事项",
|
|
69
|
+
"继续推进",
|
|
70
|
+
"问下一步",
|
|
71
|
+
"resume",
|
|
72
|
+
"resume the current item",
|
|
73
|
+
"continue the current item",
|
|
74
|
+
"next step",
|
|
75
|
+
),
|
|
76
|
+
"loom-pre-review": (
|
|
77
|
+
"review 前",
|
|
78
|
+
"进入 review",
|
|
79
|
+
"pre-review",
|
|
80
|
+
"pre review",
|
|
81
|
+
"可 review",
|
|
82
|
+
"review readiness",
|
|
83
|
+
),
|
|
84
|
+
"loom-review": (
|
|
85
|
+
"正式 review",
|
|
86
|
+
"formal review",
|
|
87
|
+
"code review",
|
|
88
|
+
"spec review",
|
|
89
|
+
"语义审查",
|
|
90
|
+
"做审查",
|
|
91
|
+
"review 结论",
|
|
92
|
+
),
|
|
93
|
+
"loom-handoff": (
|
|
94
|
+
"交接",
|
|
95
|
+
"回写停点",
|
|
96
|
+
"移交当前事项",
|
|
97
|
+
"handoff",
|
|
98
|
+
"hand off",
|
|
99
|
+
"transfer the current item",
|
|
100
|
+
),
|
|
101
|
+
"loom-retire": (
|
|
102
|
+
"清理现场",
|
|
103
|
+
"退休现场",
|
|
104
|
+
"结束当前事项现场",
|
|
105
|
+
"retire",
|
|
106
|
+
"cleanup the workspace",
|
|
107
|
+
"clean up the workspace",
|
|
108
|
+
),
|
|
109
|
+
"loom-merge-ready": (
|
|
110
|
+
"merge-ready",
|
|
111
|
+
"merge ready",
|
|
112
|
+
"最终放行前预检",
|
|
113
|
+
"可合并",
|
|
114
|
+
"merge 前",
|
|
115
|
+
"pre-merge",
|
|
116
|
+
"pre merge",
|
|
117
|
+
"合并前检查",
|
|
118
|
+
"可以合并",
|
|
119
|
+
),
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def parse_args(argv: list[str]) -> argparse.Namespace:
|
|
124
|
+
parser = argparse.ArgumentParser(description="Bootstrap Loom into a target repository.")
|
|
125
|
+
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
126
|
+
|
|
127
|
+
bootstrap = subparsers.add_parser("bootstrap", help="Analyze and optionally scaffold a target repo")
|
|
128
|
+
bootstrap.add_argument("--target", required=True, help="Target repository root")
|
|
129
|
+
bootstrap.add_argument(
|
|
130
|
+
"--scenario",
|
|
131
|
+
default="auto",
|
|
132
|
+
choices=("auto", "new", "small-existing", "complex-existing"),
|
|
133
|
+
help="Override scenario detection",
|
|
134
|
+
)
|
|
135
|
+
bootstrap.add_argument("--intake", help="Optional intake JSON file")
|
|
136
|
+
bootstrap.add_argument(
|
|
137
|
+
"--output",
|
|
138
|
+
help="Output path for init-result.json relative to target root",
|
|
139
|
+
default=".loom/bootstrap/init-result.json",
|
|
140
|
+
)
|
|
141
|
+
bootstrap.add_argument("--write", action="store_true", help="Write bootstrap artifacts into the target repo")
|
|
142
|
+
bootstrap.add_argument("--verify", action="store_true", help="Verify written artifacts after scaffolding")
|
|
143
|
+
bootstrap.add_argument("--force", action="store_true", help="Overwrite Loom-managed artifacts when needed")
|
|
144
|
+
bootstrap.add_argument(
|
|
145
|
+
"--install-pr-template",
|
|
146
|
+
action="store_true",
|
|
147
|
+
help="Install the Loom PR template when the target repo does not already provide one",
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
verify = subparsers.add_parser("verify", help="Verify Loom bootstrap artifacts in a target repo")
|
|
151
|
+
verify.add_argument("--target", required=True, help="Target repository root")
|
|
152
|
+
verify.add_argument(
|
|
153
|
+
"--output",
|
|
154
|
+
help="Expected init-result.json path relative to target root",
|
|
155
|
+
default=".loom/bootstrap/init-result.json",
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
fact_chain = subparsers.add_parser("fact-chain", help="Read and validate the Loom fact chain in a target repo")
|
|
159
|
+
fact_chain.add_argument("--target", required=True, help="Target repository root")
|
|
160
|
+
fact_chain.add_argument(
|
|
161
|
+
"--output",
|
|
162
|
+
help="Expected init-result.json path relative to target root",
|
|
163
|
+
default=".loom/bootstrap/init-result.json",
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
runtime_state = subparsers.add_parser("runtime-state", help="Read the Loom runtime scene/carrier state")
|
|
167
|
+
runtime_state.add_argument("--target", required=True, help="Target repository root")
|
|
168
|
+
|
|
169
|
+
route = subparsers.add_parser("route", help="Route a Loom task to the root or a scenario skill")
|
|
170
|
+
route.add_argument("--target", required=True, help="Target repository root")
|
|
171
|
+
mode = route.add_mutually_exclusive_group(required=True)
|
|
172
|
+
mode.add_argument("--skill", help="Explicit skill id to use")
|
|
173
|
+
mode.add_argument("--task", help="Task text used for implicit routing")
|
|
174
|
+
|
|
175
|
+
return parser.parse_args(argv)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def read_json(path: Path) -> dict[str, object]:
|
|
179
|
+
return json.loads(path.read_text(encoding="utf-8"))
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def resolve_output_path(target_root: Path, raw_output: str) -> Path:
|
|
183
|
+
output_path = Path(raw_output)
|
|
184
|
+
if output_path.is_absolute():
|
|
185
|
+
raise RuntimeError("--output must be relative to the target root")
|
|
186
|
+
return target_root / output_path
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def runtime_state_payload(target_root: Path) -> dict[str, object]:
|
|
190
|
+
return detect_runtime_state(__file__, "loom-init", target_root=target_root)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def write_text(path: Path, content: str, force: bool) -> bool:
|
|
194
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
195
|
+
if path.exists():
|
|
196
|
+
current = path.read_text(encoding="utf-8")
|
|
197
|
+
if current == content:
|
|
198
|
+
return False
|
|
199
|
+
if not force:
|
|
200
|
+
raise RuntimeError(f"refusing to overwrite existing file without --force: {path}")
|
|
201
|
+
path.write_text(content, encoding="utf-8")
|
|
202
|
+
return True
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def write_json(path: Path, payload: object, force: bool) -> bool:
|
|
206
|
+
return write_text(path, json.dumps(payload, ensure_ascii=False, indent=2) + "\n", force=force)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def ensure_gitignore_has_loom(target_root: Path) -> bool:
|
|
210
|
+
gitignore = target_root / ".gitignore"
|
|
211
|
+
desired_line = ".loom/"
|
|
212
|
+
if gitignore.exists():
|
|
213
|
+
current = gitignore.read_text(encoding="utf-8")
|
|
214
|
+
lines = current.splitlines()
|
|
215
|
+
if desired_line in lines:
|
|
216
|
+
return False
|
|
217
|
+
new_content = current if current.endswith("\n") or not current else current + "\n"
|
|
218
|
+
new_content += desired_line + "\n"
|
|
219
|
+
else:
|
|
220
|
+
new_content = desired_line + "\n"
|
|
221
|
+
gitignore.write_text(new_content, encoding="utf-8")
|
|
222
|
+
return True
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def file_exists(root: Path, relative_path: str) -> bool:
|
|
226
|
+
return (root / relative_path).exists()
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def load_registry_skill_ids() -> tuple[tuple[str, ...] | None, str | None]:
|
|
230
|
+
try:
|
|
231
|
+
active_registry = registry_path(__file__)
|
|
232
|
+
except RuntimeError as exc:
|
|
233
|
+
return None, str(exc)
|
|
234
|
+
if not active_registry.exists():
|
|
235
|
+
return None, f"{active_registry} is missing"
|
|
236
|
+
try:
|
|
237
|
+
registry = read_json(active_registry)
|
|
238
|
+
except json.JSONDecodeError as exc:
|
|
239
|
+
return None, f"{active_registry} is invalid JSON: {exc.msg}"
|
|
240
|
+
entries = registry.get("entries")
|
|
241
|
+
if not isinstance(entries, list) or not entries:
|
|
242
|
+
return None, "installed registry must declare a non-empty entries list"
|
|
243
|
+
skill_ids = [
|
|
244
|
+
entry.get("id")
|
|
245
|
+
for entry in entries
|
|
246
|
+
if isinstance(entry, dict) and isinstance(entry.get("id"), str) and entry.get("id")
|
|
247
|
+
]
|
|
248
|
+
if not skill_ids:
|
|
249
|
+
return None, "installed registry must declare at least one valid skill id"
|
|
250
|
+
return tuple(skill_ids), None
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def match_route_signals(task: str) -> dict[str, list[str]]:
|
|
254
|
+
lowered = task.lower()
|
|
255
|
+
matches: dict[str, list[str]] = {}
|
|
256
|
+
for skill_id, keywords in SKILL_SIGNAL_RULES.items():
|
|
257
|
+
matched = [keyword for keyword in keywords if keyword in lowered]
|
|
258
|
+
if matched:
|
|
259
|
+
matches[skill_id] = matched
|
|
260
|
+
return matches
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def route_payload(
|
|
264
|
+
*,
|
|
265
|
+
result: str,
|
|
266
|
+
selected_skill: str,
|
|
267
|
+
mode: str,
|
|
268
|
+
matched_signals: list[str],
|
|
269
|
+
summary: str,
|
|
270
|
+
missing_inputs: list[str],
|
|
271
|
+
fallback_to: str,
|
|
272
|
+
governance_surface: dict[str, object] | None = None,
|
|
273
|
+
runtime_state: dict[str, object] | None = None,
|
|
274
|
+
) -> dict[str, object]:
|
|
275
|
+
payload = {
|
|
276
|
+
"command": "route",
|
|
277
|
+
"result": result,
|
|
278
|
+
"selected_skill": selected_skill,
|
|
279
|
+
"mode": mode,
|
|
280
|
+
"matched_signals": matched_signals,
|
|
281
|
+
"summary": summary,
|
|
282
|
+
"missing_inputs": missing_inputs,
|
|
283
|
+
"fallback_to": fallback_to,
|
|
284
|
+
}
|
|
285
|
+
if governance_surface is not None:
|
|
286
|
+
payload["governance_surface"] = governance_surface
|
|
287
|
+
if runtime_state is not None:
|
|
288
|
+
payload["runtime_state"] = runtime_state
|
|
289
|
+
return payload
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
@lru_cache(maxsize=None)
|
|
293
|
+
def bootstrap_manifest(root: Path) -> dict[str, object]:
|
|
294
|
+
manifest_path = root / ".loom/bootstrap/manifest.json"
|
|
295
|
+
if not manifest_path.exists():
|
|
296
|
+
return {}
|
|
297
|
+
try:
|
|
298
|
+
payload = read_json(manifest_path)
|
|
299
|
+
except json.JSONDecodeError:
|
|
300
|
+
return {}
|
|
301
|
+
return payload if isinstance(payload, dict) else {}
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
@lru_cache(maxsize=None)
|
|
305
|
+
def generated_paths(root: Path) -> tuple[str, ...]:
|
|
306
|
+
manifest = bootstrap_manifest(root)
|
|
307
|
+
paths: set[str] = {".loom"}
|
|
308
|
+
artifacts = manifest.get("artifacts")
|
|
309
|
+
if isinstance(artifacts, list):
|
|
310
|
+
for artifact in artifacts:
|
|
311
|
+
if isinstance(artifact, str) and artifact:
|
|
312
|
+
paths.add(artifact)
|
|
313
|
+
continue
|
|
314
|
+
if isinstance(artifact, dict):
|
|
315
|
+
artifact_path = artifact.get("path")
|
|
316
|
+
if isinstance(artifact_path, str) and artifact_path:
|
|
317
|
+
paths.add(artifact_path)
|
|
318
|
+
if file_exists(root, "AGENTS.md"):
|
|
319
|
+
try:
|
|
320
|
+
if (root / "AGENTS.md").read_text(encoding="utf-8") == GENERATED_ROOT_ENTRY:
|
|
321
|
+
paths.add("AGENTS.md")
|
|
322
|
+
except OSError:
|
|
323
|
+
pass
|
|
324
|
+
return tuple(sorted(paths))
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def is_generated_path(root: Path, path: Path) -> bool:
|
|
328
|
+
try:
|
|
329
|
+
relative = str(path.relative_to(root))
|
|
330
|
+
except ValueError:
|
|
331
|
+
return False
|
|
332
|
+
for generated in generated_paths(root):
|
|
333
|
+
if relative == generated or relative.startswith(f"{generated}/"):
|
|
334
|
+
return True
|
|
335
|
+
return False
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def count_meaningful_entries(root: Path) -> int:
|
|
339
|
+
ignored = {".git", ".DS_Store"}
|
|
340
|
+
count = 0
|
|
341
|
+
for path in root.rglob("*"):
|
|
342
|
+
if any(part in ignored for part in path.parts):
|
|
343
|
+
continue
|
|
344
|
+
if path.name == ".gitkeep":
|
|
345
|
+
continue
|
|
346
|
+
if is_generated_path(root, path):
|
|
347
|
+
continue
|
|
348
|
+
count += 1
|
|
349
|
+
return count
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
def detect_root_boundary(root: Path) -> str:
|
|
353
|
+
generated = generated_paths(root)
|
|
354
|
+
if any(file_exists(root, candidate) and candidate not in generated for candidate in ROOT_BOUNDARY_FILES):
|
|
355
|
+
return "clear"
|
|
356
|
+
if file_exists(root, "README.md"):
|
|
357
|
+
return "partial"
|
|
358
|
+
return "missing"
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
def has_make_target(makefile_path: Path, targets: tuple[str, ...]) -> bool:
|
|
362
|
+
if not makefile_path.exists():
|
|
363
|
+
return False
|
|
364
|
+
text = makefile_path.read_text(encoding="utf-8")
|
|
365
|
+
return any(re.search(rf"^{re.escape(target)}\s*:", text, re.MULTILINE) for target in targets)
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def detect_package_scripts(root: Path) -> dict[str, object]:
|
|
369
|
+
package_json = root / "package.json"
|
|
370
|
+
if not package_json.exists():
|
|
371
|
+
return {}
|
|
372
|
+
try:
|
|
373
|
+
data = read_json(package_json)
|
|
374
|
+
except json.JSONDecodeError:
|
|
375
|
+
return {}
|
|
376
|
+
scripts = data.get("scripts")
|
|
377
|
+
return scripts if isinstance(scripts, dict) else {}
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def detect_ci_or_tests(root: Path) -> bool:
|
|
381
|
+
if any(file_exists(root, candidate) for candidate in CI_DIRS):
|
|
382
|
+
return True
|
|
383
|
+
if (root / "tests").exists() or (root / "test").exists():
|
|
384
|
+
return True
|
|
385
|
+
if has_make_target(root / "Makefile", ("test", "check", "lint", "loom-check")):
|
|
386
|
+
return True
|
|
387
|
+
scripts = detect_package_scripts(root)
|
|
388
|
+
return any(name in scripts for name in ("test", "check", "lint"))
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
def detect_validation_entry(root: Path) -> bool:
|
|
392
|
+
if has_make_target(root / "Makefile", ("check", "test", "lint", "loom-check")):
|
|
393
|
+
return True
|
|
394
|
+
if file_exists(root, "justfile") or file_exists(root, "Taskfile.yml"):
|
|
395
|
+
return True
|
|
396
|
+
scripts = detect_package_scripts(root)
|
|
397
|
+
return any(name in scripts for name in ("check", "test", "lint"))
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def detect_primary_gap(root: Path, root_boundary_docs: str, validation_entry: bool) -> str:
|
|
401
|
+
if root_boundary_docs != "clear":
|
|
402
|
+
return "governance"
|
|
403
|
+
if not validation_entry:
|
|
404
|
+
return "execution-support"
|
|
405
|
+
if not file_exists(root, ".github/PULL_REQUEST_TEMPLATE.md"):
|
|
406
|
+
return "review"
|
|
407
|
+
if not (root / "specs").exists() and not (root / "docs/specs").exists():
|
|
408
|
+
return "spec-path"
|
|
409
|
+
return "execution-support"
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
def detect_recovery_pain(root: Path) -> bool:
|
|
413
|
+
markers = (
|
|
414
|
+
".loom/progress",
|
|
415
|
+
".loom/work-items",
|
|
416
|
+
"progress",
|
|
417
|
+
"checkpoint",
|
|
418
|
+
"exec-plan",
|
|
419
|
+
)
|
|
420
|
+
present = 0
|
|
421
|
+
for marker in markers:
|
|
422
|
+
if any(
|
|
423
|
+
path
|
|
424
|
+
for path in root.rglob("*")
|
|
425
|
+
if not is_generated_path(root, path) and marker in str(path.relative_to(root))
|
|
426
|
+
):
|
|
427
|
+
present += 1
|
|
428
|
+
return present >= 2
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def detect_shared_or_high_risk(root: Path) -> bool:
|
|
432
|
+
hints = ("contract", "schema", "proto", "api", "sdk", "skills", "governance")
|
|
433
|
+
for path in root.rglob("*"):
|
|
434
|
+
if ".git" in path.parts:
|
|
435
|
+
continue
|
|
436
|
+
if is_generated_path(root, path):
|
|
437
|
+
continue
|
|
438
|
+
lowered = path.name.lower()
|
|
439
|
+
if any(hint in lowered for hint in hints):
|
|
440
|
+
return True
|
|
441
|
+
return False
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
def git_dirty_count(root: Path) -> int:
|
|
445
|
+
if not (root / ".git").exists():
|
|
446
|
+
return 0
|
|
447
|
+
try:
|
|
448
|
+
result = subprocess.run(
|
|
449
|
+
["git", "status", "--short"],
|
|
450
|
+
cwd=root,
|
|
451
|
+
check=False,
|
|
452
|
+
capture_output=True,
|
|
453
|
+
text=True,
|
|
454
|
+
)
|
|
455
|
+
except FileNotFoundError:
|
|
456
|
+
return 0
|
|
457
|
+
if result.returncode != 0:
|
|
458
|
+
return 0
|
|
459
|
+
return len([line for line in result.stdout.splitlines() if line.strip()])
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def detect_purity(root: Path) -> str:
|
|
463
|
+
dirty = git_dirty_count(root)
|
|
464
|
+
if dirty >= 8:
|
|
465
|
+
return "severe"
|
|
466
|
+
if dirty >= 2:
|
|
467
|
+
return "mixed"
|
|
468
|
+
return "clean"
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
def detect_merge_review_overload(root: Path, validation_entry: bool) -> bool:
|
|
472
|
+
code_dirs = sum(1 for hint in CODE_DIR_HINTS if (root / hint).exists())
|
|
473
|
+
if code_dirs == 0:
|
|
474
|
+
return False
|
|
475
|
+
has_pr_template = file_exists(root, ".github/PULL_REQUEST_TEMPLATE.md")
|
|
476
|
+
has_workflow_doc = any(file_exists(root, candidate) for candidate in ("WORKFLOW.md", "docs/WORKFLOW.md"))
|
|
477
|
+
has_repo_scripts = (root / "scripts").exists()
|
|
478
|
+
has_repo_native_governance = (root / "docs" / "exec-plans").exists() or (root / "scripts" / "policy").exists()
|
|
479
|
+
return bool(validation_entry and has_pr_template and has_repo_scripts and (has_workflow_doc or has_repo_native_governance))
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
def detect_repository_type(root: Path) -> str:
|
|
483
|
+
meaningful_entries = count_meaningful_entries(root)
|
|
484
|
+
has_readme = file_exists(root, "README.md")
|
|
485
|
+
has_code = any((root / hint).exists() and not is_generated_path(root, root / hint) for hint in CODE_DIR_HINTS)
|
|
486
|
+
if meaningful_entries <= 2 and not has_readme and not has_code:
|
|
487
|
+
return "new"
|
|
488
|
+
return "existing"
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
def load_or_detect_intake(root: Path, intake_path: str | None) -> dict[str, object]:
|
|
492
|
+
if intake_path:
|
|
493
|
+
payload = read_json(Path(intake_path).expanduser().resolve())
|
|
494
|
+
payload.setdefault("schema_version", "loom-init-intake/v1")
|
|
495
|
+
return payload
|
|
496
|
+
|
|
497
|
+
repository_type = detect_repository_type(root)
|
|
498
|
+
root_boundary_docs = detect_root_boundary(root)
|
|
499
|
+
validation_entry = detect_validation_entry(root)
|
|
500
|
+
payload = {
|
|
501
|
+
"schema_version": "loom-init-intake/v1",
|
|
502
|
+
"repository_type": repository_type,
|
|
503
|
+
"root_boundary_docs": root_boundary_docs,
|
|
504
|
+
"ci_or_basic_tests": detect_ci_or_tests(root),
|
|
505
|
+
"repository_level_validation_entry": validation_entry,
|
|
506
|
+
"primary_gap_category": detect_primary_gap(root, root_boundary_docs, validation_entry),
|
|
507
|
+
"long_running_recovery_pain": detect_recovery_pain(root),
|
|
508
|
+
"shared_contract_or_high_risk_boundary": detect_shared_or_high_risk(root),
|
|
509
|
+
"purity_or_scope_signals": detect_purity(root),
|
|
510
|
+
"merge_review_semantic_overload": detect_merge_review_overload(root, validation_entry),
|
|
511
|
+
"notes": "autodetected by loom_init.py",
|
|
512
|
+
}
|
|
513
|
+
return payload
|
|
514
|
+
|
|
515
|
+
|
|
516
|
+
def classify_scenario(intake: dict[str, object], override: str) -> str:
|
|
517
|
+
if override != "auto":
|
|
518
|
+
return override
|
|
519
|
+
|
|
520
|
+
repository_type = intake["repository_type"]
|
|
521
|
+
root_boundary_docs = intake["root_boundary_docs"]
|
|
522
|
+
ci_or_basic_tests = bool(intake["ci_or_basic_tests"])
|
|
523
|
+
validation_entry = bool(intake["repository_level_validation_entry"])
|
|
524
|
+
primary_gap_category = str(intake["primary_gap_category"])
|
|
525
|
+
recovery_pain = bool(intake["long_running_recovery_pain"])
|
|
526
|
+
shared_boundary = bool(intake["shared_contract_or_high_risk_boundary"])
|
|
527
|
+
purity = str(intake["purity_or_scope_signals"])
|
|
528
|
+
merge_overload = bool(intake["merge_review_semantic_overload"])
|
|
529
|
+
|
|
530
|
+
if repository_type == "new":
|
|
531
|
+
return "new"
|
|
532
|
+
if (
|
|
533
|
+
root_boundary_docs == "clear"
|
|
534
|
+
and ci_or_basic_tests
|
|
535
|
+
and validation_entry
|
|
536
|
+
and primary_gap_category in {"governance", "review", "spec-path"}
|
|
537
|
+
and not recovery_pain
|
|
538
|
+
and not shared_boundary
|
|
539
|
+
and purity == "clean"
|
|
540
|
+
and not merge_overload
|
|
541
|
+
):
|
|
542
|
+
return "small-existing"
|
|
543
|
+
return "complex-existing"
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
def scenario_label(scenario: str) -> str:
|
|
547
|
+
return {
|
|
548
|
+
"new": "新项目",
|
|
549
|
+
"small-existing": "小型既有仓库",
|
|
550
|
+
"complex-existing": "复杂既有仓库",
|
|
551
|
+
}[scenario]
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
def intensity_label(scenario: str, intake: dict[str, object]) -> str:
|
|
555
|
+
if scenario in {"new", "small-existing"}:
|
|
556
|
+
return "轻量"
|
|
557
|
+
if bool(intake["shared_contract_or_high_risk_boundary"]) or bool(intake["long_running_recovery_pain"]):
|
|
558
|
+
return "强化"
|
|
559
|
+
return "标准"
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
def integration_mode(scenario: str) -> str:
|
|
563
|
+
return "root" if scenario == "new" else "companion"
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
def recovery_mode(scenario: str) -> str:
|
|
567
|
+
return "checkpoint-lite" if scenario in {"new", "small-existing"} else "standard"
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
def recommended_adoption_path(scenario: str, intake: dict[str, object]) -> str:
|
|
571
|
+
if scenario == "new":
|
|
572
|
+
return "minimal-bootstrap"
|
|
573
|
+
if scenario == "small-existing":
|
|
574
|
+
return "lightweight-retrofit"
|
|
575
|
+
if (
|
|
576
|
+
intake.get("repository_type") == "existing"
|
|
577
|
+
and intake.get("root_boundary_docs") == "clear"
|
|
578
|
+
and bool(intake.get("repository_level_validation_entry"))
|
|
579
|
+
and bool(intake.get("merge_review_semantic_overload"))
|
|
580
|
+
):
|
|
581
|
+
return "deep-existing-repo"
|
|
582
|
+
return "full-bootstrap"
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
def uses_attach_only_path(adoption_path: str) -> bool:
|
|
586
|
+
return adoption_path == "deep-existing-repo"
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
def rule_refs_for_capabilities(scenario: str, adoption_path: str) -> list[dict[str, object]]:
|
|
590
|
+
common = [
|
|
591
|
+
{
|
|
592
|
+
"name": "bootstrap/root",
|
|
593
|
+
"rules": [
|
|
594
|
+
"skills/loom-init/SKILL.md",
|
|
595
|
+
"skills/loom-init/references/intake-signals.md",
|
|
596
|
+
"skills/loom-init/references/output-contract.md",
|
|
597
|
+
],
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
"name": "formal-templates",
|
|
601
|
+
"rules": [
|
|
602
|
+
"skills/shared/references/templates/spec-suite.md",
|
|
603
|
+
"skills/shared/references/templates/pull-request.md",
|
|
604
|
+
],
|
|
605
|
+
},
|
|
606
|
+
]
|
|
607
|
+
if scenario == "new":
|
|
608
|
+
common.append(
|
|
609
|
+
{
|
|
610
|
+
"name": "minimal-governance-entry",
|
|
611
|
+
"rules": [
|
|
612
|
+
"skills/shared/references/governance/principles.md",
|
|
613
|
+
"skills/shared/references/governance/review-model.md",
|
|
614
|
+
],
|
|
615
|
+
}
|
|
616
|
+
)
|
|
617
|
+
elif scenario == "small-existing":
|
|
618
|
+
common.append(
|
|
619
|
+
{
|
|
620
|
+
"name": "lightweight-retrofit",
|
|
621
|
+
"rules": [
|
|
622
|
+
"skills/shared/references/adoption/lightweight-retrofit-default.md",
|
|
623
|
+
"skills/shared/references/adoption/routing-and-checkpoints.md",
|
|
624
|
+
],
|
|
625
|
+
}
|
|
626
|
+
)
|
|
627
|
+
elif uses_attach_only_path(adoption_path):
|
|
628
|
+
common.append(
|
|
629
|
+
{
|
|
630
|
+
"name": "deep-existing-repo",
|
|
631
|
+
"rules": [
|
|
632
|
+
"skills/shared/references/adoption/deep-existing-repo-default.md",
|
|
633
|
+
"skills/shared/references/adoption/routing-and-checkpoints.md",
|
|
634
|
+
"skills/shared/references/harness/host-action-contract.md",
|
|
635
|
+
],
|
|
636
|
+
}
|
|
637
|
+
)
|
|
638
|
+
else:
|
|
639
|
+
common.append(
|
|
640
|
+
{
|
|
641
|
+
"name": "execution-support",
|
|
642
|
+
"rules": [
|
|
643
|
+
"skills/shared/references/harness/work-item-contract.md",
|
|
644
|
+
"skills/shared/references/harness/recovery-model.md",
|
|
645
|
+
"skills/shared/references/harness/status-surface.md",
|
|
646
|
+
"skills/shared/references/harness/workspace-and-purity.md",
|
|
647
|
+
],
|
|
648
|
+
}
|
|
649
|
+
)
|
|
650
|
+
return common
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
def deferred_capabilities(scenario: str, adoption_path: str) -> list[dict[str, str]]:
|
|
654
|
+
if scenario == "new":
|
|
655
|
+
return [
|
|
656
|
+
{
|
|
657
|
+
"name": "full-status-surface",
|
|
658
|
+
"reason": "no runnable system or multi-lane environment is visible yet",
|
|
659
|
+
"upgrade_trigger": "a runtime lane, logs, metrics, or UI verification path becomes required",
|
|
660
|
+
},
|
|
661
|
+
{
|
|
662
|
+
"name": "merge-checkpoint-hardening",
|
|
663
|
+
"reason": "implementation has not entered regular merge flow yet",
|
|
664
|
+
"upgrade_trigger": "multiple contributors or repeated merge reviews begin to consume the same facts",
|
|
665
|
+
},
|
|
666
|
+
]
|
|
667
|
+
if scenario == "small-existing":
|
|
668
|
+
return [
|
|
669
|
+
{
|
|
670
|
+
"name": "standard-recovery",
|
|
671
|
+
"reason": "the repo still fits checkpoint-lite for low-cost recovery",
|
|
672
|
+
"upgrade_trigger": "recovery spans multiple rounds or more than one status carrier starts competing",
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
"name": "full-workspace-purity",
|
|
676
|
+
"reason": "lightweight retrofit is still the default path",
|
|
677
|
+
"upgrade_trigger": "mixed work, shared boundaries, or review overload becomes structural",
|
|
678
|
+
},
|
|
679
|
+
]
|
|
680
|
+
if uses_attach_only_path(adoption_path):
|
|
681
|
+
return [
|
|
682
|
+
{
|
|
683
|
+
"name": "loom-owned-recovery-carriers",
|
|
684
|
+
"reason": "the first attach-only round must preserve repo-native carriers instead of generating Loom-owned recovery/status placeholders",
|
|
685
|
+
"upgrade_trigger": "the repo needs Loom-owned recovery or status carriers to stabilize multi-round execution",
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
"name": "typed-repo-companion-and-interop",
|
|
689
|
+
"reason": "the first attach-only round only establishes the stable entry and read surface",
|
|
690
|
+
"upgrade_trigger": "the repo needs typed gates, metadata contracts, host adapters, or shadow parity",
|
|
691
|
+
},
|
|
692
|
+
]
|
|
693
|
+
return [
|
|
694
|
+
{
|
|
695
|
+
"name": "host-specific-skill-regression-matrix",
|
|
696
|
+
"reason": "Loom core should not absorb a full host test matrix",
|
|
697
|
+
"upgrade_trigger": "a host adapter or marketplace package is added",
|
|
698
|
+
}
|
|
699
|
+
]
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
def attach_only_artifact_paths(target_root: Path, install_pr_template: bool) -> list[str]:
|
|
703
|
+
artifacts = [
|
|
704
|
+
".loom/README.md",
|
|
705
|
+
".loom/bootstrap/intake.snapshot.json",
|
|
706
|
+
".loom/bootstrap/init-result.json",
|
|
707
|
+
".loom/bootstrap/manifest.json",
|
|
708
|
+
".loom/bootstrap/capability-map.md",
|
|
709
|
+
".loom/companion/README.md",
|
|
710
|
+
".loom/companion/checkpoints.md",
|
|
711
|
+
".loom/companion/review.md",
|
|
712
|
+
".loom/companion/merge-ready.md",
|
|
713
|
+
".loom/companion/closeout.md",
|
|
714
|
+
".loom/bin/loom_init.py",
|
|
715
|
+
".loom/bin/fact_chain_support.py",
|
|
716
|
+
".loom/bin/governance_surface.py",
|
|
717
|
+
".loom/bin/loom_flow.py",
|
|
718
|
+
".loom/bin/runtime_paths.py",
|
|
719
|
+
".loom/bin/runtime_state.py",
|
|
720
|
+
".loom/bin/loom_check.py",
|
|
721
|
+
]
|
|
722
|
+
if install_pr_template or not (target_root / ".github/PULL_REQUEST_TEMPLATE.md").exists():
|
|
723
|
+
artifacts.append(".github/PULL_REQUEST_TEMPLATE.md")
|
|
724
|
+
return artifacts
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
def initial_work_items(scenario: str, target_root: Path, adoption_path: str, install_pr_template: bool) -> list[dict[str, object]]:
|
|
728
|
+
if uses_attach_only_path(adoption_path):
|
|
729
|
+
return [
|
|
730
|
+
{
|
|
731
|
+
"id": WORK_ITEM_ID,
|
|
732
|
+
"goal": "Attach Loom to the existing governance stack without replacing root rules or host-owned actions",
|
|
733
|
+
"scope": "Establish attach metadata, companion entry, and repo-local validation without generating Loom-owned recovery/status carriers",
|
|
734
|
+
"execution_path": "recognize-and-attach",
|
|
735
|
+
"workspace_entry": ".",
|
|
736
|
+
"recovery_entry": "existing root rules and repo-native carriers",
|
|
737
|
+
"review_entry": ".loom/companion/review.md",
|
|
738
|
+
"validation_entry": "python3 .loom/bin/loom_init.py verify --target .",
|
|
739
|
+
"artifacts": attach_only_artifact_paths(target_root, install_pr_template),
|
|
740
|
+
"closing_condition": "The attach metadata, companion entry, and repo-local validation path are readable without generated Loom-owned recovery/status carriers",
|
|
741
|
+
"post_build_continuation": "Extend the attached repo companion and interop surfaces without rewriting the retained host stack",
|
|
742
|
+
"owner_for_checkpoint_lite": "repository owner or current attach operator",
|
|
743
|
+
}
|
|
744
|
+
]
|
|
745
|
+
artifacts = [
|
|
746
|
+
".loom/bootstrap/init-result.json",
|
|
747
|
+
".loom/work-items/INIT-0001.md",
|
|
748
|
+
".loom/progress/INIT-0001.md",
|
|
749
|
+
".loom/reviews/INIT-0001.json",
|
|
750
|
+
".loom/status/current.md",
|
|
751
|
+
".loom/bin/loom_init.py",
|
|
752
|
+
".loom/bin/fact_chain_support.py",
|
|
753
|
+
".loom/bin/governance_surface.py",
|
|
754
|
+
".loom/bin/loom_flow.py",
|
|
755
|
+
".loom/bin/runtime_paths.py",
|
|
756
|
+
".loom/bin/loom_check.py",
|
|
757
|
+
".loom/specs/INIT-0001/spec.md",
|
|
758
|
+
".loom/specs/INIT-0001/plan.md",
|
|
759
|
+
]
|
|
760
|
+
if not (target_root / ".github/PULL_REQUEST_TEMPLATE.md").exists():
|
|
761
|
+
artifacts.append(".github/PULL_REQUEST_TEMPLATE.md")
|
|
762
|
+
return [
|
|
763
|
+
{
|
|
764
|
+
"id": WORK_ITEM_ID,
|
|
765
|
+
"goal": "Bootstrap the first executable Loom path for this repository",
|
|
766
|
+
"scope": "Establish rule entry, first work item, progress carrier, spec/plan, and verification entry",
|
|
767
|
+
"execution_path": "bootstrap/root",
|
|
768
|
+
"workspace_entry": ".",
|
|
769
|
+
"recovery_entry": ".loom/progress/INIT-0001.md",
|
|
770
|
+
"review_entry": ".loom/reviews/INIT-0001.json",
|
|
771
|
+
"validation_entry": "python3 .loom/bin/loom_init.py verify --target .",
|
|
772
|
+
"artifacts": artifacts,
|
|
773
|
+
"closing_condition": "The generated entry, work item, recovery entry, and templates are readable and verified",
|
|
774
|
+
"post_build_continuation": "Promote the first real downstream issue after the bootstrap artifacts are accepted",
|
|
775
|
+
"owner_for_checkpoint_lite": "repository owner or current bootstrap operator",
|
|
776
|
+
}
|
|
777
|
+
]
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
def initial_artifacts(target_root: Path, install_pr_template: bool, adoption_path: str) -> list[dict[str, str]]:
|
|
781
|
+
artifacts = [
|
|
782
|
+
{
|
|
783
|
+
"path": ".loom/README.md",
|
|
784
|
+
"kind": "rule-entry",
|
|
785
|
+
"source": "generated",
|
|
786
|
+
},
|
|
787
|
+
{
|
|
788
|
+
"path": ".loom/bootstrap/intake.snapshot.json",
|
|
789
|
+
"kind": "intake",
|
|
790
|
+
"source": "generated",
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
"path": ".loom/bootstrap/init-result.json",
|
|
794
|
+
"kind": "init-result",
|
|
795
|
+
"source": "generated",
|
|
796
|
+
},
|
|
797
|
+
{
|
|
798
|
+
"path": ".loom/bootstrap/manifest.json",
|
|
799
|
+
"kind": "manifest",
|
|
800
|
+
"source": "generated",
|
|
801
|
+
},
|
|
802
|
+
{
|
|
803
|
+
"path": ".loom/bootstrap/capability-map.md",
|
|
804
|
+
"kind": "capability-map",
|
|
805
|
+
"source": "generated",
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
"path": ".loom/bin/loom_init.py",
|
|
809
|
+
"kind": "loom-tool",
|
|
810
|
+
"source": RUNTIME_SOURCE,
|
|
811
|
+
},
|
|
812
|
+
{
|
|
813
|
+
"path": ".loom/bin/fact_chain_support.py",
|
|
814
|
+
"kind": "loom-tool-support",
|
|
815
|
+
"source": FACT_CHAIN_RUNTIME_SOURCE,
|
|
816
|
+
},
|
|
817
|
+
{
|
|
818
|
+
"path": ".loom/bin/governance_surface.py",
|
|
819
|
+
"kind": "loom-tool-support",
|
|
820
|
+
"source": GOVERNANCE_RUNTIME_SOURCE,
|
|
821
|
+
},
|
|
822
|
+
{
|
|
823
|
+
"path": ".loom/bin/loom_flow.py",
|
|
824
|
+
"kind": "loom-tool",
|
|
825
|
+
"source": FLOW_RUNTIME_SOURCE,
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
"path": ".loom/bin/runtime_paths.py",
|
|
829
|
+
"kind": "loom-tool-support",
|
|
830
|
+
"source": "skills/shared/scripts/runtime_paths.py",
|
|
831
|
+
},
|
|
832
|
+
{
|
|
833
|
+
"path": ".loom/bin/runtime_state.py",
|
|
834
|
+
"kind": "loom-tool-support",
|
|
835
|
+
"source": "skills/shared/scripts/runtime_state.py",
|
|
836
|
+
},
|
|
837
|
+
{
|
|
838
|
+
"path": ".loom/bin/loom_check.py",
|
|
839
|
+
"kind": "loom-tool",
|
|
840
|
+
"source": CHECK_RUNTIME_SOURCE,
|
|
841
|
+
},
|
|
842
|
+
]
|
|
843
|
+
if uses_attach_only_path(adoption_path):
|
|
844
|
+
artifacts.extend(
|
|
845
|
+
[
|
|
846
|
+
{
|
|
847
|
+
"path": ".loom/companion/README.md",
|
|
848
|
+
"kind": "repo-companion-entry",
|
|
849
|
+
"source": "generated",
|
|
850
|
+
},
|
|
851
|
+
{
|
|
852
|
+
"path": ".loom/companion/checkpoints.md",
|
|
853
|
+
"kind": "repo-companion-doc",
|
|
854
|
+
"source": "generated",
|
|
855
|
+
},
|
|
856
|
+
{
|
|
857
|
+
"path": ".loom/companion/review.md",
|
|
858
|
+
"kind": "repo-companion-doc",
|
|
859
|
+
"source": "generated",
|
|
860
|
+
},
|
|
861
|
+
{
|
|
862
|
+
"path": ".loom/companion/merge-ready.md",
|
|
863
|
+
"kind": "repo-companion-doc",
|
|
864
|
+
"source": "generated",
|
|
865
|
+
},
|
|
866
|
+
{
|
|
867
|
+
"path": ".loom/companion/closeout.md",
|
|
868
|
+
"kind": "repo-companion-doc",
|
|
869
|
+
"source": "generated",
|
|
870
|
+
},
|
|
871
|
+
]
|
|
872
|
+
)
|
|
873
|
+
else:
|
|
874
|
+
artifacts.extend(
|
|
875
|
+
[
|
|
876
|
+
{
|
|
877
|
+
"path": "AGENTS.md",
|
|
878
|
+
"kind": "root-entry",
|
|
879
|
+
"source": "generated",
|
|
880
|
+
},
|
|
881
|
+
{
|
|
882
|
+
"path": ".loom/work-items/INIT-0001.md",
|
|
883
|
+
"kind": "work-item",
|
|
884
|
+
"source": "generated",
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
"path": ".loom/progress/INIT-0001.md",
|
|
888
|
+
"kind": "progress",
|
|
889
|
+
"source": "generated",
|
|
890
|
+
},
|
|
891
|
+
{
|
|
892
|
+
"path": ".loom/reviews/INIT-0001.json",
|
|
893
|
+
"kind": "review-entry",
|
|
894
|
+
"source": "generated",
|
|
895
|
+
},
|
|
896
|
+
{
|
|
897
|
+
"path": ".loom/status/current.md",
|
|
898
|
+
"kind": "status-surface",
|
|
899
|
+
"source": "generated",
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
"path": ".loom/specs/INIT-0001/spec.md",
|
|
903
|
+
"kind": "spec",
|
|
904
|
+
"source": "skills/shared/assets/templates/scaffold/spec.md",
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
"path": ".loom/specs/INIT-0001/plan.md",
|
|
908
|
+
"kind": "plan",
|
|
909
|
+
"source": "skills/shared/assets/templates/scaffold/plan.md",
|
|
910
|
+
},
|
|
911
|
+
]
|
|
912
|
+
)
|
|
913
|
+
if install_pr_template or not (target_root / ".github/PULL_REQUEST_TEMPLATE.md").exists():
|
|
914
|
+
artifacts.append(
|
|
915
|
+
{
|
|
916
|
+
"path": ".github/PULL_REQUEST_TEMPLATE.md",
|
|
917
|
+
"kind": "pr-template",
|
|
918
|
+
"source": "skills/shared/assets/github/PULL_REQUEST_TEMPLATE.md",
|
|
919
|
+
}
|
|
920
|
+
)
|
|
921
|
+
return artifacts
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
def build_result(target_root: Path, scenario: str, intake: dict[str, object], install_pr_template: bool) -> dict[str, object]:
|
|
925
|
+
adoption_path = recommended_adoption_path(scenario, intake)
|
|
926
|
+
attach_only = uses_attach_only_path(adoption_path)
|
|
927
|
+
main_problem = {
|
|
928
|
+
"new": "the repository has no controlled Loom entry yet",
|
|
929
|
+
"small-existing": "the repo has a baseline but still lacks a stable Loom adoption entry and explicit first artifacts",
|
|
930
|
+
"complex-existing": (
|
|
931
|
+
"the repo already has a mature governance stack, so Loom must attach to the existing root rules and retained host actions"
|
|
932
|
+
if attach_only
|
|
933
|
+
else "the repo needs execution support, recovery, and status carriers instead of more ad hoc guidance"
|
|
934
|
+
),
|
|
935
|
+
}[scenario]
|
|
936
|
+
|
|
937
|
+
reason = {
|
|
938
|
+
"new": "the repo is still establishing its first baseline, so the bootstrap should create the smallest stable entry and first artifacts",
|
|
939
|
+
"small-existing": "the repo already has a baseline, so Loom should enter through companion artifacts instead of rewriting the root",
|
|
940
|
+
"complex-existing": (
|
|
941
|
+
"the repo already has stable root rules and validation entry, so Loom should recognize and attach instead of materializing replacement recovery and status carriers"
|
|
942
|
+
if attach_only
|
|
943
|
+
else "the repo shows execution-support pressure, so the bootstrap must materialize recovery and status carriers immediately"
|
|
944
|
+
),
|
|
945
|
+
}[scenario]
|
|
946
|
+
|
|
947
|
+
result = {
|
|
948
|
+
"schema_version": "loom-init-output/v1",
|
|
949
|
+
"generator": {
|
|
950
|
+
"tool": RUNTIME_SOURCE,
|
|
951
|
+
"tool_version": TOOL_VERSION,
|
|
952
|
+
"root_entry": "loom-init",
|
|
953
|
+
"contract_version": CONTRACT_VERSION,
|
|
954
|
+
},
|
|
955
|
+
"run": {
|
|
956
|
+
"target": str(target_root),
|
|
957
|
+
"scenario": scenario_label(scenario),
|
|
958
|
+
"scenario_key": scenario,
|
|
959
|
+
"integration_mode": integration_mode(scenario),
|
|
960
|
+
"recovery_mode": recovery_mode(scenario),
|
|
961
|
+
},
|
|
962
|
+
"intake": intake,
|
|
963
|
+
"project_judgment": {
|
|
964
|
+
"scenario": scenario_label(scenario),
|
|
965
|
+
"intensity": intensity_label(scenario, intake),
|
|
966
|
+
"primary_structural_problem": main_problem,
|
|
967
|
+
"why_this_path": reason,
|
|
968
|
+
},
|
|
969
|
+
"recommended_adoption": {
|
|
970
|
+
"path": adoption_path,
|
|
971
|
+
"integration_mode": integration_mode(scenario),
|
|
972
|
+
"recovery_mode": recovery_mode(scenario),
|
|
973
|
+
"capabilities": rule_refs_for_capabilities(scenario, adoption_path),
|
|
974
|
+
},
|
|
975
|
+
"deferred_capabilities": deferred_capabilities(scenario, adoption_path),
|
|
976
|
+
"fact_chain": (
|
|
977
|
+
{
|
|
978
|
+
"mode": "repo-native attach-only",
|
|
979
|
+
"read_entry": "not_applicable",
|
|
980
|
+
"entry_points": {
|
|
981
|
+
"current_item_id": WORK_ITEM_ID,
|
|
982
|
+
"work_item": "not_applicable",
|
|
983
|
+
"recovery_entry": "not_applicable",
|
|
984
|
+
"status_surface": "not_applicable",
|
|
985
|
+
},
|
|
986
|
+
}
|
|
987
|
+
if attach_only
|
|
988
|
+
else {
|
|
989
|
+
"mode": "work-item + recovery-entry + derived status-surface",
|
|
990
|
+
"read_entry": "python3 .loom/bin/loom_init.py fact-chain --target .",
|
|
991
|
+
"entry_points": {
|
|
992
|
+
"current_item_id": WORK_ITEM_ID,
|
|
993
|
+
"work_item": ".loom/work-items/INIT-0001.md",
|
|
994
|
+
"recovery_entry": ".loom/progress/INIT-0001.md",
|
|
995
|
+
"status_surface": ".loom/status/current.md",
|
|
996
|
+
},
|
|
997
|
+
}
|
|
998
|
+
),
|
|
999
|
+
"initial_artifacts": initial_artifacts(target_root, install_pr_template, adoption_path),
|
|
1000
|
+
"initial_work_items": initial_work_items(scenario, target_root, adoption_path, install_pr_template),
|
|
1001
|
+
"validation_and_closing": {
|
|
1002
|
+
"validation_entry": "python3 .loom/bin/loom_init.py verify --target .",
|
|
1003
|
+
"checkpoint_relationship": (
|
|
1004
|
+
[
|
|
1005
|
+
"admission checkpoint confirms the attached companion entry and bootstrap metadata are readable",
|
|
1006
|
+
"build checkpoint confirms the attach-only surfaces and repo-local validation entry are internally consistent",
|
|
1007
|
+
"merge checkpoint should only pass after downstream repo truth, companion extensions, and release judgment align",
|
|
1008
|
+
]
|
|
1009
|
+
if attach_only
|
|
1010
|
+
else [
|
|
1011
|
+
"admission checkpoint confirms the bootstrap work item and first artifacts are readable",
|
|
1012
|
+
"build checkpoint confirms generated carriers and templates are internally consistent",
|
|
1013
|
+
"merge checkpoint should only pass after downstream repo truth, docs, and delivery state align",
|
|
1014
|
+
]
|
|
1015
|
+
),
|
|
1016
|
+
"clean_state": (
|
|
1017
|
+
"all generated attach-only Loom artifacts are readable, verified, and do not introduce Loom-owned recovery/status placeholders"
|
|
1018
|
+
if attach_only
|
|
1019
|
+
else "all generated Loom artifacts are readable, verified, and free of conflicting duplicates"
|
|
1020
|
+
),
|
|
1021
|
+
"close_when": (
|
|
1022
|
+
[
|
|
1023
|
+
"the target repo has a readable root rule entry and attached repo companion entry",
|
|
1024
|
+
"the attach-only bootstrap metadata and repo-local validation path are verifiable",
|
|
1025
|
+
"the bootstrap manifest does not declare Loom-owned recovery/status carriers for this path",
|
|
1026
|
+
]
|
|
1027
|
+
if attach_only
|
|
1028
|
+
else [
|
|
1029
|
+
"the target repo has a readable root or companion Loom entry",
|
|
1030
|
+
"the first work item, progress carrier, and spec/plan artifacts exist",
|
|
1031
|
+
"the bootstrap manifest and init-result are verifiable",
|
|
1032
|
+
]
|
|
1033
|
+
),
|
|
1034
|
+
},
|
|
1035
|
+
"runtime_state": runtime_state_payload(target_root),
|
|
1036
|
+
"governance_surface": build_governance_surface(
|
|
1037
|
+
target_root,
|
|
1038
|
+
bootstrap_mode=True,
|
|
1039
|
+
scenario_override=scenario,
|
|
1040
|
+
),
|
|
1041
|
+
}
|
|
1042
|
+
return result
|
|
1043
|
+
|
|
1044
|
+
|
|
1045
|
+
def render_loom_readme(result: dict[str, object]) -> str:
|
|
1046
|
+
run = result["run"]
|
|
1047
|
+
attach_only = uses_attach_only_path(str(result["recommended_adoption"]["path"]))
|
|
1048
|
+
path_lines = (
|
|
1049
|
+
"- Repo companion entry: `.loom/companion/README.md`\n"
|
|
1050
|
+
"- Companion checkpoints: `.loom/companion/checkpoints.md`\n"
|
|
1051
|
+
"- Companion review surface: `.loom/companion/review.md`\n"
|
|
1052
|
+
if attach_only
|
|
1053
|
+
else "- First work item: `.loom/work-items/INIT-0001.md`\n"
|
|
1054
|
+
"- Progress carrier: `.loom/progress/INIT-0001.md`\n"
|
|
1055
|
+
"- Status surface: `.loom/status/current.md`\n"
|
|
1056
|
+
)
|
|
1057
|
+
return (
|
|
1058
|
+
"# Loom Bootstrap\n\n"
|
|
1059
|
+
f"This directory was generated by `{RUNTIME_SOURCE}`.\n\n"
|
|
1060
|
+
"## Current Path\n\n"
|
|
1061
|
+
f"- Scenario: {run['scenario']}\n"
|
|
1062
|
+
f"- Recommended adoption path: {result['recommended_adoption']['path']}\n"
|
|
1063
|
+
f"- Integration mode: {run['integration_mode']}\n"
|
|
1064
|
+
f"- Recovery mode: {run['recovery_mode']}\n\n"
|
|
1065
|
+
"## Main Entry Points\n\n"
|
|
1066
|
+
"- Bootstrap manifest: `.loom/bootstrap/manifest.json`\n"
|
|
1067
|
+
"- Bootstrap result: `.loom/bootstrap/init-result.json`\n"
|
|
1068
|
+
f"{path_lines}"
|
|
1069
|
+
"- Runtime-state entry: `.loom/bin/loom_init.py runtime-state --target .`\n"
|
|
1070
|
+
"- Daily execution CLI: `.loom/bin/loom_flow.py`\n"
|
|
1071
|
+
"- Gate CLI: `.loom/bin/loom_check.py`\n"
|
|
1072
|
+
)
|
|
1073
|
+
|
|
1074
|
+
|
|
1075
|
+
def render_root_agents() -> str:
|
|
1076
|
+
return GENERATED_ROOT_ENTRY
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
def render_capability_map(result: dict[str, object]) -> str:
|
|
1080
|
+
lines = [
|
|
1081
|
+
"# Capability Map",
|
|
1082
|
+
"",
|
|
1083
|
+
"The bootstrap entry maps each enabled capability to Loom source-of-truth documents.",
|
|
1084
|
+
"",
|
|
1085
|
+
]
|
|
1086
|
+
for capability in result["recommended_adoption"]["capabilities"]:
|
|
1087
|
+
lines.append(f"## {capability['name']}")
|
|
1088
|
+
lines.append("")
|
|
1089
|
+
for rule in capability["rules"]:
|
|
1090
|
+
lines.append(f"- `{rule}`")
|
|
1091
|
+
lines.append("")
|
|
1092
|
+
return "\n".join(lines).rstrip() + "\n"
|
|
1093
|
+
|
|
1094
|
+
|
|
1095
|
+
def render_companion_readme(result: dict[str, object]) -> str:
|
|
1096
|
+
return (
|
|
1097
|
+
"# Repo Companion\n\n"
|
|
1098
|
+
"This companion entry attaches Loom to the existing repository governance surface.\n\n"
|
|
1099
|
+
"## Preserved Ownership\n\n"
|
|
1100
|
+
"- Root rules remain in the repository's existing boundary docs.\n"
|
|
1101
|
+
"- Retained host actions stay host-owned.\n"
|
|
1102
|
+
"- Repo-native carriers remain the source of truth until a later Loom interop slice stabilizes.\n\n"
|
|
1103
|
+
"## Loom Entry Surfaces\n\n"
|
|
1104
|
+
"- Review surface: `.loom/companion/review.md`\n"
|
|
1105
|
+
"- Merge-ready surface: `.loom/companion/merge-ready.md`\n"
|
|
1106
|
+
"- Closeout surface: `.loom/companion/closeout.md`\n"
|
|
1107
|
+
"- Checkpoints surface: `.loom/companion/checkpoints.md`\n"
|
|
1108
|
+
)
|
|
1109
|
+
|
|
1110
|
+
|
|
1111
|
+
def render_companion_checkpoints() -> str:
|
|
1112
|
+
return (
|
|
1113
|
+
"# Companion Checkpoints\n\n"
|
|
1114
|
+
"- Admission: read the existing root rules and repo-native admission surface before entering implementation.\n"
|
|
1115
|
+
"- Build: preserve retained host actions and repo-native carriers; do not assume Loom-owned recovery/status carriers exist.\n"
|
|
1116
|
+
"- Merge-ready: consume companion extensions and host-owned gates without re-implementing the host lifecycle.\n"
|
|
1117
|
+
)
|
|
1118
|
+
|
|
1119
|
+
|
|
1120
|
+
def render_companion_review() -> str:
|
|
1121
|
+
return (
|
|
1122
|
+
"# Companion Review Surface\n\n"
|
|
1123
|
+
"Use this file to attach repo-specific review requirements while keeping the repository's existing root rules authoritative.\n"
|
|
1124
|
+
)
|
|
1125
|
+
|
|
1126
|
+
|
|
1127
|
+
def render_companion_merge_ready() -> str:
|
|
1128
|
+
return (
|
|
1129
|
+
"# Companion Merge-Ready Surface\n\n"
|
|
1130
|
+
"Use this file to summarize repo-specific merge-ready expectations without taking over host-owned merge controls.\n"
|
|
1131
|
+
)
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
def render_companion_closeout() -> str:
|
|
1135
|
+
return (
|
|
1136
|
+
"# Companion Closeout Surface\n\n"
|
|
1137
|
+
"Use this file to attach repo-specific closeout expectations while preserving the host-owned closeout controls and repo-native truth.\n"
|
|
1138
|
+
)
|
|
1139
|
+
|
|
1140
|
+
|
|
1141
|
+
def render_work_item(result: dict[str, object]) -> str:
|
|
1142
|
+
item = result["initial_work_items"][0]
|
|
1143
|
+
return (
|
|
1144
|
+
f"# {item['id']}\n\n"
|
|
1145
|
+
"## Static Facts\n\n"
|
|
1146
|
+
f"- Item ID: {item['id']}\n"
|
|
1147
|
+
f"- Goal: {item['goal']}\n"
|
|
1148
|
+
f"- Scope: {item['scope']}\n"
|
|
1149
|
+
f"- Execution Path: {item['execution_path']}\n"
|
|
1150
|
+
f"- Workspace Entry: {item['workspace_entry']}\n"
|
|
1151
|
+
f"- Recovery Entry: {item['recovery_entry']}\n"
|
|
1152
|
+
f"- Review Entry: {item['review_entry']}\n"
|
|
1153
|
+
f"- Validation Entry: {item['validation_entry']}\n"
|
|
1154
|
+
f"- Closing Condition: {item['closing_condition']}\n\n"
|
|
1155
|
+
"## Associated Artifacts\n\n"
|
|
1156
|
+
+ "\n".join(f"- `{artifact}`" for artifact in item["artifacts"])
|
|
1157
|
+
+ "\n"
|
|
1158
|
+
)
|
|
1159
|
+
|
|
1160
|
+
|
|
1161
|
+
def render_progress(result: dict[str, object]) -> str:
|
|
1162
|
+
checkpoint = "admission checkpoint" if result["run"]["scenario_key"] != "complex-existing" else "build checkpoint"
|
|
1163
|
+
return (
|
|
1164
|
+
f"# {WORK_ITEM_ID} Progress\n\n"
|
|
1165
|
+
"## Dynamic Facts\n\n"
|
|
1166
|
+
f"- Item ID: {WORK_ITEM_ID}\n"
|
|
1167
|
+
f"- Current Checkpoint: {checkpoint}\n"
|
|
1168
|
+
"- Current Stop: Bootstrap artifacts have been generated and are awaiting downstream review.\n"
|
|
1169
|
+
"- Next Step: Accept the generated Loom entry and promote the first real repository work item.\n"
|
|
1170
|
+
"- Blockers: None recorded.\n"
|
|
1171
|
+
"- Latest Validation Summary: Bootstrap manifest exists; init-result JSON can be read mechanically; the first work item, status surface, and spec/plan artifacts exist.\n"
|
|
1172
|
+
"- Recovery Boundary: Bootstrap result at `.loom/bootstrap/init-result.json`; bootstrap manifest at `.loom/bootstrap/manifest.json`.\n"
|
|
1173
|
+
"- Current Lane: bootstrap verification only\n"
|
|
1174
|
+
)
|
|
1175
|
+
|
|
1176
|
+
|
|
1177
|
+
def render_review_entry(result: dict[str, object]) -> str:
|
|
1178
|
+
item = result["initial_work_items"][0]
|
|
1179
|
+
payload = {
|
|
1180
|
+
"schema_version": "loom-review/v1",
|
|
1181
|
+
"item_id": item["id"],
|
|
1182
|
+
"decision": "fallback",
|
|
1183
|
+
"kind": "general_review",
|
|
1184
|
+
"summary": "Bootstrap has not entered formal review yet.",
|
|
1185
|
+
"reviewer": "not yet assigned",
|
|
1186
|
+
"reviewed_head": "bootstrap-placeholder",
|
|
1187
|
+
"reviewed_validation_summary": "Bootstrap manifest exists; init-result JSON can be read mechanically; the first work item, status surface, and spec/plan artifacts exist.",
|
|
1188
|
+
"fallback_to": "admission",
|
|
1189
|
+
"blocking_issues": [
|
|
1190
|
+
"Formal review starts only after downstream work replaces the bootstrap placeholder item."
|
|
1191
|
+
],
|
|
1192
|
+
"follow_ups": [
|
|
1193
|
+
"Record the first real semantic review before asking merge checkpoint to consume reviewer judgment."
|
|
1194
|
+
],
|
|
1195
|
+
}
|
|
1196
|
+
return json.dumps(payload, ensure_ascii=False, indent=2) + "\n"
|
|
1197
|
+
|
|
1198
|
+
|
|
1199
|
+
def default_runtime_evidence(result: dict[str, object]) -> dict[str, str]:
|
|
1200
|
+
item = result["initial_work_items"][0]
|
|
1201
|
+
return {
|
|
1202
|
+
"run_entry": "not_applicable",
|
|
1203
|
+
"logs_entry": "not_applicable",
|
|
1204
|
+
"diagnostics_entry": "not_applicable",
|
|
1205
|
+
"verification_entry": str(item["validation_entry"]),
|
|
1206
|
+
"lane_entry": "not_applicable",
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
def render_status(result: dict[str, object]) -> str:
|
|
1211
|
+
item = result["initial_work_items"][0]
|
|
1212
|
+
fact_chain = result["fact_chain"]
|
|
1213
|
+
checkpoint = "admission checkpoint" if result["run"]["scenario_key"] != "complex-existing" else "build checkpoint"
|
|
1214
|
+
runtime_evidence = default_runtime_evidence(result)
|
|
1215
|
+
return (
|
|
1216
|
+
"# Current Status\n\n"
|
|
1217
|
+
"## Derived Fact Chain View\n\n"
|
|
1218
|
+
f"- Item ID: {item['id']}\n"
|
|
1219
|
+
f"- Goal: {item['goal']}\n"
|
|
1220
|
+
f"- Scope: {item['scope']}\n"
|
|
1221
|
+
f"- Execution Path: {item['execution_path']}\n"
|
|
1222
|
+
f"- Workspace Entry: {item['workspace_entry']}\n"
|
|
1223
|
+
f"- Recovery Entry: {item['recovery_entry']}\n"
|
|
1224
|
+
f"- Review Entry: {item['review_entry']}\n"
|
|
1225
|
+
f"- Validation Entry: {item['validation_entry']}\n"
|
|
1226
|
+
f"- Closing Condition: {item['closing_condition']}\n"
|
|
1227
|
+
f"- Current Checkpoint: {checkpoint}\n"
|
|
1228
|
+
"- Current Stop: Bootstrap artifacts have been generated and are awaiting downstream review.\n"
|
|
1229
|
+
"- Next Step: Accept the generated Loom entry and promote the first real repository work item.\n"
|
|
1230
|
+
"- Blockers: None recorded.\n"
|
|
1231
|
+
"- Latest Validation Summary: Bootstrap manifest exists; init-result JSON can be read mechanically; the first work item, status surface, and spec/plan artifacts exist.\n"
|
|
1232
|
+
"- Recovery Boundary: Bootstrap result at `.loom/bootstrap/init-result.json`; bootstrap manifest at `.loom/bootstrap/manifest.json`.\n"
|
|
1233
|
+
"- Current Lane: bootstrap verification only\n\n"
|
|
1234
|
+
"## Runtime Evidence\n\n"
|
|
1235
|
+
f"- Run Entry: {runtime_evidence['run_entry']}\n"
|
|
1236
|
+
f"- Logs Entry: {runtime_evidence['logs_entry']}\n"
|
|
1237
|
+
f"- Diagnostics Entry: {runtime_evidence['diagnostics_entry']}\n"
|
|
1238
|
+
f"- Verification Entry: {runtime_evidence['verification_entry']}\n"
|
|
1239
|
+
f"- Lane Entry: {runtime_evidence['lane_entry']}\n\n"
|
|
1240
|
+
"## Sources\n\n"
|
|
1241
|
+
f"- Static Truth: {fact_chain['entry_points']['work_item']}\n"
|
|
1242
|
+
f"- Dynamic Truth: {fact_chain['entry_points']['recovery_entry']}\n"
|
|
1243
|
+
"- Locator Truth: .loom/bootstrap/init-result.json\n"
|
|
1244
|
+
f"- Fact Chain CLI: {fact_chain['read_entry']}\n"
|
|
1245
|
+
)
|
|
1246
|
+
|
|
1247
|
+
|
|
1248
|
+
def copy_file(source: Path, target: Path, force: bool) -> bool:
|
|
1249
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
1250
|
+
content = source.read_text(encoding="utf-8")
|
|
1251
|
+
return write_text(target, content, force=force)
|
|
1252
|
+
|
|
1253
|
+
|
|
1254
|
+
def manifest_payload(result: dict[str, object]) -> dict[str, object]:
|
|
1255
|
+
return {
|
|
1256
|
+
"schema_version": "loom-bootstrap-manifest/v1",
|
|
1257
|
+
"tool": RUNTIME_SOURCE,
|
|
1258
|
+
"tool_version": TOOL_VERSION,
|
|
1259
|
+
"root_entry": "loom-init",
|
|
1260
|
+
"contract_version": CONTRACT_VERSION,
|
|
1261
|
+
"output": ".loom/bootstrap/init-result.json",
|
|
1262
|
+
"artifacts": result["initial_artifacts"],
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
def scaffold_target(
|
|
1267
|
+
target_root: Path,
|
|
1268
|
+
result: dict[str, object],
|
|
1269
|
+
output_path: Path,
|
|
1270
|
+
force: bool,
|
|
1271
|
+
install_pr_template: bool,
|
|
1272
|
+
) -> tuple[int, list[str]]:
|
|
1273
|
+
written = 0
|
|
1274
|
+
touched: list[str] = []
|
|
1275
|
+
attach_only = uses_attach_only_path(str(result["recommended_adoption"]["path"]))
|
|
1276
|
+
|
|
1277
|
+
writes: list[tuple[Path, str | dict[str, object], str]] = [
|
|
1278
|
+
(target_root / ".loom/README.md", render_loom_readme(result), "text"),
|
|
1279
|
+
(target_root / ".loom/bootstrap/intake.snapshot.json", result["intake"], "json"),
|
|
1280
|
+
(output_path, result, "json"),
|
|
1281
|
+
(target_root / ".loom/bootstrap/manifest.json", manifest_payload(result), "json"),
|
|
1282
|
+
(target_root / ".loom/bootstrap/capability-map.md", render_capability_map(result), "text"),
|
|
1283
|
+
]
|
|
1284
|
+
if attach_only:
|
|
1285
|
+
writes.extend(
|
|
1286
|
+
[
|
|
1287
|
+
(target_root / ".loom/companion/README.md", render_companion_readme(result), "text"),
|
|
1288
|
+
(target_root / ".loom/companion/checkpoints.md", render_companion_checkpoints(), "text"),
|
|
1289
|
+
(target_root / ".loom/companion/review.md", render_companion_review(), "text"),
|
|
1290
|
+
(target_root / ".loom/companion/merge-ready.md", render_companion_merge_ready(), "text"),
|
|
1291
|
+
(target_root / ".loom/companion/closeout.md", render_companion_closeout(), "text"),
|
|
1292
|
+
]
|
|
1293
|
+
)
|
|
1294
|
+
else:
|
|
1295
|
+
writes.extend(
|
|
1296
|
+
[
|
|
1297
|
+
(target_root / ".loom/work-items/INIT-0001.md", render_work_item(result), "text"),
|
|
1298
|
+
(target_root / ".loom/progress/INIT-0001.md", render_progress(result), "text"),
|
|
1299
|
+
(target_root / ".loom/reviews/INIT-0001.json", render_review_entry(result), "text"),
|
|
1300
|
+
(target_root / ".loom/status/current.md", render_status(result), "text"),
|
|
1301
|
+
]
|
|
1302
|
+
)
|
|
1303
|
+
|
|
1304
|
+
for path, payload, kind in writes:
|
|
1305
|
+
changed = write_json(path, payload, force=force) if kind == "json" else write_text(path, payload, force=force)
|
|
1306
|
+
if changed:
|
|
1307
|
+
written += 1
|
|
1308
|
+
touched.append(str(path.relative_to(target_root)))
|
|
1309
|
+
|
|
1310
|
+
for source, destination in (
|
|
1311
|
+
(Path(__file__), target_root / ".loom/bin/loom_init.py"),
|
|
1312
|
+
(Path(__file__).with_name("fact_chain_support.py"), target_root / ".loom/bin/fact_chain_support.py"),
|
|
1313
|
+
(Path(__file__).with_name("governance_surface.py"), target_root / ".loom/bin/governance_surface.py"),
|
|
1314
|
+
(Path(__file__).with_name("loom_flow.py"), target_root / ".loom/bin/loom_flow.py"),
|
|
1315
|
+
(Path(__file__).with_name("runtime_paths.py"), target_root / ".loom/bin/runtime_paths.py"),
|
|
1316
|
+
(Path(__file__).with_name("runtime_state.py"), target_root / ".loom/bin/runtime_state.py"),
|
|
1317
|
+
(Path(__file__).with_name("loom_check.py"), target_root / ".loom/bin/loom_check.py"),
|
|
1318
|
+
):
|
|
1319
|
+
if copy_file(source, destination, force=force):
|
|
1320
|
+
written += 1
|
|
1321
|
+
touched.append(str(destination.relative_to(target_root)))
|
|
1322
|
+
if not attach_only:
|
|
1323
|
+
for source, destination in (
|
|
1324
|
+
(shared_asset(__file__, "templates/scaffold/spec.md"), target_root / ".loom/specs/INIT-0001/spec.md"),
|
|
1325
|
+
(shared_asset(__file__, "templates/scaffold/plan.md"), target_root / ".loom/specs/INIT-0001/plan.md"),
|
|
1326
|
+
):
|
|
1327
|
+
if copy_file(source, destination, force=force):
|
|
1328
|
+
written += 1
|
|
1329
|
+
touched.append(str(destination.relative_to(target_root)))
|
|
1330
|
+
|
|
1331
|
+
pr_template_target = target_root / ".github/PULL_REQUEST_TEMPLATE.md"
|
|
1332
|
+
if install_pr_template or not pr_template_target.exists():
|
|
1333
|
+
if copy_file(shared_asset(__file__, "github/PULL_REQUEST_TEMPLATE.md"), pr_template_target, force=force):
|
|
1334
|
+
written += 1
|
|
1335
|
+
touched.append(str(pr_template_target.relative_to(target_root)))
|
|
1336
|
+
|
|
1337
|
+
root_agents = target_root / "AGENTS.md"
|
|
1338
|
+
if not attach_only and not root_agents.exists():
|
|
1339
|
+
if write_text(root_agents, render_root_agents(), force=force):
|
|
1340
|
+
written += 1
|
|
1341
|
+
touched.append(str(root_agents.relative_to(target_root)))
|
|
1342
|
+
|
|
1343
|
+
if ensure_gitignore_has_loom(target_root):
|
|
1344
|
+
written += 1
|
|
1345
|
+
touched.append(".gitignore")
|
|
1346
|
+
|
|
1347
|
+
return written, touched
|
|
1348
|
+
|
|
1349
|
+
|
|
1350
|
+
def verify_target(target_root: Path, output_path: Path) -> list[str]:
|
|
1351
|
+
errors: list[str] = []
|
|
1352
|
+
runtime_state = runtime_state_payload(target_root)
|
|
1353
|
+
if runtime_state["result"] != "pass":
|
|
1354
|
+
errors.extend(f"runtime-state: {message}" for message in runtime_state["missing_inputs"])
|
|
1355
|
+
|
|
1356
|
+
current_item_id: str | None = None
|
|
1357
|
+
attach_only = False
|
|
1358
|
+
required_paths: list[str] = []
|
|
1359
|
+
if output_path.exists():
|
|
1360
|
+
try:
|
|
1361
|
+
result = read_json(output_path)
|
|
1362
|
+
except json.JSONDecodeError as exc:
|
|
1363
|
+
errors.append(f"invalid init-result JSON: {exc.msg}")
|
|
1364
|
+
return errors
|
|
1365
|
+
adoption = result.get("recommended_adoption")
|
|
1366
|
+
if isinstance(adoption, dict):
|
|
1367
|
+
attach_only = uses_attach_only_path(str(adoption.get("path", "")))
|
|
1368
|
+
required_paths = [
|
|
1369
|
+
".loom/README.md",
|
|
1370
|
+
".loom/bootstrap/intake.snapshot.json",
|
|
1371
|
+
str(output_path.relative_to(target_root)),
|
|
1372
|
+
".loom/bootstrap/manifest.json",
|
|
1373
|
+
".loom/bootstrap/capability-map.md",
|
|
1374
|
+
".loom/bin/loom_init.py",
|
|
1375
|
+
".loom/bin/fact_chain_support.py",
|
|
1376
|
+
".loom/bin/governance_surface.py",
|
|
1377
|
+
".loom/bin/loom_flow.py",
|
|
1378
|
+
".loom/bin/runtime_paths.py",
|
|
1379
|
+
".loom/bin/runtime_state.py",
|
|
1380
|
+
".loom/bin/loom_check.py",
|
|
1381
|
+
]
|
|
1382
|
+
if attach_only:
|
|
1383
|
+
required_paths.extend(
|
|
1384
|
+
[
|
|
1385
|
+
".loom/companion/README.md",
|
|
1386
|
+
".loom/companion/checkpoints.md",
|
|
1387
|
+
".loom/companion/review.md",
|
|
1388
|
+
".loom/companion/merge-ready.md",
|
|
1389
|
+
".loom/companion/closeout.md",
|
|
1390
|
+
]
|
|
1391
|
+
)
|
|
1392
|
+
else:
|
|
1393
|
+
required_paths.extend(
|
|
1394
|
+
[
|
|
1395
|
+
"AGENTS.md",
|
|
1396
|
+
".loom/work-items/INIT-0001.md",
|
|
1397
|
+
".loom/progress/INIT-0001.md",
|
|
1398
|
+
".loom/reviews/INIT-0001.json",
|
|
1399
|
+
".loom/status/current.md",
|
|
1400
|
+
".loom/specs/INIT-0001/spec.md",
|
|
1401
|
+
".loom/specs/INIT-0001/plan.md",
|
|
1402
|
+
]
|
|
1403
|
+
)
|
|
1404
|
+
for key in (
|
|
1405
|
+
"project_judgment",
|
|
1406
|
+
"recommended_adoption",
|
|
1407
|
+
"deferred_capabilities",
|
|
1408
|
+
"fact_chain",
|
|
1409
|
+
"initial_artifacts",
|
|
1410
|
+
"initial_work_items",
|
|
1411
|
+
"runtime_state",
|
|
1412
|
+
"validation_and_closing",
|
|
1413
|
+
):
|
|
1414
|
+
if key not in result:
|
|
1415
|
+
errors.append(f"init-result is missing required section: {key}")
|
|
1416
|
+
initial_artifacts = result.get("initial_artifacts")
|
|
1417
|
+
if isinstance(initial_artifacts, list):
|
|
1418
|
+
for artifact in initial_artifacts:
|
|
1419
|
+
if not isinstance(artifact, dict):
|
|
1420
|
+
errors.append("every initial artifact must be an object")
|
|
1421
|
+
continue
|
|
1422
|
+
artifact_path = artifact.get("path")
|
|
1423
|
+
if not isinstance(artifact_path, str) or not artifact_path:
|
|
1424
|
+
errors.append("every initial artifact must declare a non-empty `path`")
|
|
1425
|
+
continue
|
|
1426
|
+
if not (target_root / artifact_path).exists():
|
|
1427
|
+
errors.append(f"declared initial artifact is missing on disk: {artifact_path}")
|
|
1428
|
+
initial_work_items = result.get("initial_work_items")
|
|
1429
|
+
validated_work_items: list[dict[str, object]] = []
|
|
1430
|
+
if isinstance(initial_work_items, list):
|
|
1431
|
+
for work_item in initial_work_items:
|
|
1432
|
+
if not isinstance(work_item, dict):
|
|
1433
|
+
errors.append("every initial work item must be an object")
|
|
1434
|
+
continue
|
|
1435
|
+
for field in (
|
|
1436
|
+
"id",
|
|
1437
|
+
"goal",
|
|
1438
|
+
"scope",
|
|
1439
|
+
"execution_path",
|
|
1440
|
+
"workspace_entry",
|
|
1441
|
+
"recovery_entry",
|
|
1442
|
+
"review_entry",
|
|
1443
|
+
"validation_entry",
|
|
1444
|
+
"closing_condition",
|
|
1445
|
+
):
|
|
1446
|
+
value = work_item.get(field)
|
|
1447
|
+
if not isinstance(value, str) or not value:
|
|
1448
|
+
errors.append(f"initial work item is missing required field: {field}")
|
|
1449
|
+
validated_work_items.append(work_item)
|
|
1450
|
+
if attach_only:
|
|
1451
|
+
fact_chain = result.get("fact_chain")
|
|
1452
|
+
if not isinstance(fact_chain, dict):
|
|
1453
|
+
errors.append("init-result is missing required section: fact_chain")
|
|
1454
|
+
else:
|
|
1455
|
+
if fact_chain.get("mode") != "repo-native attach-only":
|
|
1456
|
+
errors.append("deep-existing-repo init-result must keep `fact_chain.mode = repo-native attach-only`")
|
|
1457
|
+
if fact_chain.get("read_entry") != "not_applicable":
|
|
1458
|
+
errors.append("deep-existing-repo init-result must keep `fact_chain.read_entry = not_applicable`")
|
|
1459
|
+
entry_points = fact_chain.get("entry_points")
|
|
1460
|
+
if not isinstance(entry_points, dict):
|
|
1461
|
+
errors.append("deep-existing-repo init-result must include fact_chain.entry_points")
|
|
1462
|
+
else:
|
|
1463
|
+
for field in ("work_item", "recovery_entry", "status_surface"):
|
|
1464
|
+
if entry_points.get(field) != "not_applicable":
|
|
1465
|
+
errors.append(f"deep-existing-repo init-result must keep `fact_chain.entry_points.{field} = not_applicable`")
|
|
1466
|
+
declared_generated = {
|
|
1467
|
+
artifact.get("path")
|
|
1468
|
+
for artifact in result.get("initial_artifacts", [])
|
|
1469
|
+
if isinstance(artifact, dict) and isinstance(artifact.get("path"), str)
|
|
1470
|
+
}
|
|
1471
|
+
for forbidden in (".loom/work-items/INIT-0001.md", ".loom/progress/INIT-0001.md", ".loom/status/current.md"):
|
|
1472
|
+
if forbidden in declared_generated:
|
|
1473
|
+
errors.append(f"deep-existing-repo bootstrap must not declare generated carrier `{forbidden}`")
|
|
1474
|
+
|
|
1475
|
+
for relative in required_paths:
|
|
1476
|
+
if not (target_root / relative).exists():
|
|
1477
|
+
errors.append(f"missing required artifact: {relative}")
|
|
1478
|
+
|
|
1479
|
+
if not attach_only:
|
|
1480
|
+
fact_chain_report, fact_chain_errors = inspect_fact_chain(
|
|
1481
|
+
target_root,
|
|
1482
|
+
str(output_path.relative_to(target_root)),
|
|
1483
|
+
)
|
|
1484
|
+
if fact_chain_errors:
|
|
1485
|
+
errors.extend(f"fact-chain: {message}" for message in fact_chain_errors)
|
|
1486
|
+
elif not fact_chain_report:
|
|
1487
|
+
errors.append("fact-chain: no report was produced")
|
|
1488
|
+
elif output_path.exists():
|
|
1489
|
+
current_item_id = fact_chain_report["fact_chain"]["entry_points"]["current_item_id"]
|
|
1490
|
+
runtime_evidence_report = fact_chain_report.get("runtime_evidence")
|
|
1491
|
+
if not isinstance(runtime_evidence_report, dict):
|
|
1492
|
+
errors.append("fact-chain: missing runtime_evidence report")
|
|
1493
|
+
else:
|
|
1494
|
+
for field in (
|
|
1495
|
+
"run_entry",
|
|
1496
|
+
"logs_entry",
|
|
1497
|
+
"diagnostics_entry",
|
|
1498
|
+
"verification_entry",
|
|
1499
|
+
"lane_entry",
|
|
1500
|
+
):
|
|
1501
|
+
if field not in runtime_evidence_report:
|
|
1502
|
+
errors.append(f"fact-chain: runtime_evidence is missing `{field}`")
|
|
1503
|
+
matching_work_item = None
|
|
1504
|
+
for work_item in validated_work_items:
|
|
1505
|
+
if work_item.get("id") == current_item_id:
|
|
1506
|
+
matching_work_item = work_item
|
|
1507
|
+
break
|
|
1508
|
+
if matching_work_item is None:
|
|
1509
|
+
errors.append(f"init-result is missing the current work item `{current_item_id}`")
|
|
1510
|
+
else:
|
|
1511
|
+
expected_init_fields = {
|
|
1512
|
+
"recovery_entry": fact_chain_report["fact_chain"]["entry_points"]["recovery_entry"],
|
|
1513
|
+
"validation_entry": fact_chain_report["facts"]["validation_entry"]["value"],
|
|
1514
|
+
"workspace_entry": fact_chain_report["facts"]["workspace_entry"]["value"],
|
|
1515
|
+
}
|
|
1516
|
+
for field, expected_value in expected_init_fields.items():
|
|
1517
|
+
actual_value = matching_work_item.get(field)
|
|
1518
|
+
if actual_value != expected_value:
|
|
1519
|
+
errors.append(
|
|
1520
|
+
f"init-result work item `{current_item_id}` has inconsistent `{field}`: "
|
|
1521
|
+
f"expected `{expected_value}`, got `{actual_value}`"
|
|
1522
|
+
)
|
|
1523
|
+
|
|
1524
|
+
pr_template = target_root / ".github/PULL_REQUEST_TEMPLATE.md"
|
|
1525
|
+
if pr_template.exists():
|
|
1526
|
+
text = pr_template.read_text(encoding="utf-8")
|
|
1527
|
+
for needle in ("## Summary", "## Validation", "## Risks And Follow-ups", "## Related Work"):
|
|
1528
|
+
if needle not in text:
|
|
1529
|
+
errors.append(f"PR template is missing section: {needle}")
|
|
1530
|
+
|
|
1531
|
+
flow_tool = target_root / ".loom/bin/loom_flow.py"
|
|
1532
|
+
if flow_tool.exists():
|
|
1533
|
+
commands: list[tuple[str, list[str], set[str]]] = [
|
|
1534
|
+
(
|
|
1535
|
+
"loom-init runtime-state",
|
|
1536
|
+
["python3", ".loom/bin/loom_init.py", "runtime-state", "--target", "."],
|
|
1537
|
+
{"pass"},
|
|
1538
|
+
),
|
|
1539
|
+
]
|
|
1540
|
+
if not attach_only:
|
|
1541
|
+
commands.extend(
|
|
1542
|
+
[
|
|
1543
|
+
(
|
|
1544
|
+
"loom-flow fact-chain",
|
|
1545
|
+
["python3", ".loom/bin/loom_flow.py", "fact-chain", "--target", "."],
|
|
1546
|
+
{"pass"},
|
|
1547
|
+
),
|
|
1548
|
+
(
|
|
1549
|
+
"loom-flow runtime-evidence",
|
|
1550
|
+
["python3", ".loom/bin/loom_flow.py", "runtime-evidence", "--target", "."],
|
|
1551
|
+
{"pass"},
|
|
1552
|
+
),
|
|
1553
|
+
]
|
|
1554
|
+
)
|
|
1555
|
+
if current_item_id and not attach_only:
|
|
1556
|
+
commands.extend(
|
|
1557
|
+
[
|
|
1558
|
+
(
|
|
1559
|
+
"loom-flow checkpoint admission",
|
|
1560
|
+
[
|
|
1561
|
+
"python3",
|
|
1562
|
+
".loom/bin/loom_flow.py",
|
|
1563
|
+
"checkpoint",
|
|
1564
|
+
"admission",
|
|
1565
|
+
"--target",
|
|
1566
|
+
".",
|
|
1567
|
+
"--item",
|
|
1568
|
+
current_item_id,
|
|
1569
|
+
],
|
|
1570
|
+
{"pass", "block", "fallback"},
|
|
1571
|
+
),
|
|
1572
|
+
(
|
|
1573
|
+
"loom-flow runtime-state",
|
|
1574
|
+
[
|
|
1575
|
+
"python3",
|
|
1576
|
+
".loom/bin/loom_flow.py",
|
|
1577
|
+
"runtime-state",
|
|
1578
|
+
"--target",
|
|
1579
|
+
".",
|
|
1580
|
+
"--item",
|
|
1581
|
+
current_item_id,
|
|
1582
|
+
],
|
|
1583
|
+
{"pass"},
|
|
1584
|
+
),
|
|
1585
|
+
(
|
|
1586
|
+
"loom-flow state-check",
|
|
1587
|
+
[
|
|
1588
|
+
"python3",
|
|
1589
|
+
".loom/bin/loom_flow.py",
|
|
1590
|
+
"state-check",
|
|
1591
|
+
"--target",
|
|
1592
|
+
".",
|
|
1593
|
+
"--item",
|
|
1594
|
+
current_item_id,
|
|
1595
|
+
],
|
|
1596
|
+
{"pass", "block"},
|
|
1597
|
+
),
|
|
1598
|
+
(
|
|
1599
|
+
"loom-flow workspace locate",
|
|
1600
|
+
[
|
|
1601
|
+
"python3",
|
|
1602
|
+
".loom/bin/loom_flow.py",
|
|
1603
|
+
"workspace",
|
|
1604
|
+
"locate",
|
|
1605
|
+
"--target",
|
|
1606
|
+
".",
|
|
1607
|
+
"--item",
|
|
1608
|
+
current_item_id,
|
|
1609
|
+
],
|
|
1610
|
+
{"pass", "block"},
|
|
1611
|
+
),
|
|
1612
|
+
(
|
|
1613
|
+
"loom-flow flow pre-review",
|
|
1614
|
+
[
|
|
1615
|
+
"python3",
|
|
1616
|
+
".loom/bin/loom_flow.py",
|
|
1617
|
+
"flow",
|
|
1618
|
+
"pre-review",
|
|
1619
|
+
"--target",
|
|
1620
|
+
".",
|
|
1621
|
+
"--item",
|
|
1622
|
+
current_item_id,
|
|
1623
|
+
],
|
|
1624
|
+
{"pass", "block", "fallback"},
|
|
1625
|
+
),
|
|
1626
|
+
]
|
|
1627
|
+
)
|
|
1628
|
+
|
|
1629
|
+
for label, command, allowed in commands:
|
|
1630
|
+
result = subprocess.run(
|
|
1631
|
+
command,
|
|
1632
|
+
cwd=target_root,
|
|
1633
|
+
check=False,
|
|
1634
|
+
capture_output=True,
|
|
1635
|
+
text=True,
|
|
1636
|
+
)
|
|
1637
|
+
output = result.stdout.strip()
|
|
1638
|
+
if not output:
|
|
1639
|
+
detail = result.stderr.strip() or "no JSON output"
|
|
1640
|
+
errors.append(f"{label} failed: {detail}")
|
|
1641
|
+
continue
|
|
1642
|
+
try:
|
|
1643
|
+
payload = json.loads(output)
|
|
1644
|
+
except json.JSONDecodeError as exc:
|
|
1645
|
+
errors.append(f"{label} returned invalid JSON: {exc.msg}")
|
|
1646
|
+
continue
|
|
1647
|
+
if not isinstance(payload, dict):
|
|
1648
|
+
errors.append(f"{label} must return a JSON object")
|
|
1649
|
+
continue
|
|
1650
|
+
command_result = payload.get("result")
|
|
1651
|
+
if command_result not in allowed:
|
|
1652
|
+
errors.append(
|
|
1653
|
+
f"{label} returned unexpected result `{command_result}` (allowed: {', '.join(sorted(allowed))})"
|
|
1654
|
+
)
|
|
1655
|
+
|
|
1656
|
+
return errors
|
|
1657
|
+
|
|
1658
|
+
|
|
1659
|
+
def bootstrap(args: argparse.Namespace) -> int:
|
|
1660
|
+
target_root = Path(args.target).expanduser().resolve()
|
|
1661
|
+
if not target_root.exists():
|
|
1662
|
+
print(f"loom-init: target does not exist: {target_root}", file=sys.stderr)
|
|
1663
|
+
return 2
|
|
1664
|
+
if not target_root.is_dir():
|
|
1665
|
+
print(f"loom-init: target is not a directory: {target_root}", file=sys.stderr)
|
|
1666
|
+
return 2
|
|
1667
|
+
|
|
1668
|
+
intake = load_or_detect_intake(target_root, args.intake)
|
|
1669
|
+
scenario = classify_scenario(intake, args.scenario)
|
|
1670
|
+
result = build_result(target_root, scenario, intake, args.install_pr_template)
|
|
1671
|
+
try:
|
|
1672
|
+
output_path = resolve_output_path(target_root, args.output)
|
|
1673
|
+
except RuntimeError as exc:
|
|
1674
|
+
print(f"loom-init: {exc}", file=sys.stderr)
|
|
1675
|
+
return 2
|
|
1676
|
+
|
|
1677
|
+
if args.write:
|
|
1678
|
+
try:
|
|
1679
|
+
written, touched = scaffold_target(
|
|
1680
|
+
target_root=target_root,
|
|
1681
|
+
result=result,
|
|
1682
|
+
output_path=output_path,
|
|
1683
|
+
force=args.force,
|
|
1684
|
+
install_pr_template=args.install_pr_template,
|
|
1685
|
+
)
|
|
1686
|
+
except RuntimeError as exc:
|
|
1687
|
+
print(f"loom-init: {exc}", file=sys.stderr)
|
|
1688
|
+
return 2
|
|
1689
|
+
result["write"] = {
|
|
1690
|
+
"enabled": True,
|
|
1691
|
+
"written_files": written,
|
|
1692
|
+
"touched": touched,
|
|
1693
|
+
}
|
|
1694
|
+
result["governance_surface"] = build_governance_surface(
|
|
1695
|
+
target_root,
|
|
1696
|
+
bootstrap_mode=True,
|
|
1697
|
+
scenario_override=scenario,
|
|
1698
|
+
)
|
|
1699
|
+
if args.verify:
|
|
1700
|
+
errors = verify_target(target_root, output_path)
|
|
1701
|
+
result["verification"] = {"ok": not errors, "errors": errors}
|
|
1702
|
+
if errors:
|
|
1703
|
+
print(json.dumps(result, ensure_ascii=False, indent=2))
|
|
1704
|
+
return 1
|
|
1705
|
+
else:
|
|
1706
|
+
result["write"] = {"enabled": False, "written_files": 0, "touched": []}
|
|
1707
|
+
|
|
1708
|
+
print(json.dumps(result, ensure_ascii=False, indent=2))
|
|
1709
|
+
return 0
|
|
1710
|
+
|
|
1711
|
+
|
|
1712
|
+
def verify(args: argparse.Namespace) -> int:
|
|
1713
|
+
target_root = Path(args.target).expanduser().resolve()
|
|
1714
|
+
try:
|
|
1715
|
+
output_path = resolve_output_path(target_root, args.output)
|
|
1716
|
+
except RuntimeError as exc:
|
|
1717
|
+
print(f"loom-init: {exc}", file=sys.stderr)
|
|
1718
|
+
return 2
|
|
1719
|
+
runtime_state = runtime_state_payload(target_root)
|
|
1720
|
+
errors = verify_target(target_root, output_path)
|
|
1721
|
+
if errors:
|
|
1722
|
+
print(json.dumps({"ok": False, "errors": errors, "runtime_state": runtime_state}, ensure_ascii=False, indent=2))
|
|
1723
|
+
return 1
|
|
1724
|
+
print(
|
|
1725
|
+
json.dumps(
|
|
1726
|
+
{"ok": True, "target": str(target_root), "runtime_state": runtime_state},
|
|
1727
|
+
ensure_ascii=False,
|
|
1728
|
+
indent=2,
|
|
1729
|
+
)
|
|
1730
|
+
)
|
|
1731
|
+
return 0
|
|
1732
|
+
|
|
1733
|
+
|
|
1734
|
+
def fact_chain(args: argparse.Namespace) -> int:
|
|
1735
|
+
target_root = Path(args.target).expanduser().resolve()
|
|
1736
|
+
try:
|
|
1737
|
+
output_path = resolve_output_path(target_root, args.output)
|
|
1738
|
+
except RuntimeError as exc:
|
|
1739
|
+
print(f"loom-init: {exc}", file=sys.stderr)
|
|
1740
|
+
return 2
|
|
1741
|
+
if output_path.exists():
|
|
1742
|
+
try:
|
|
1743
|
+
result = read_json(output_path)
|
|
1744
|
+
except json.JSONDecodeError:
|
|
1745
|
+
result = {}
|
|
1746
|
+
adoption = result.get("recommended_adoption") if isinstance(result, dict) else None
|
|
1747
|
+
if isinstance(adoption, dict) and uses_attach_only_path(str(adoption.get("path", ""))):
|
|
1748
|
+
print(
|
|
1749
|
+
json.dumps(
|
|
1750
|
+
{
|
|
1751
|
+
"ok": False,
|
|
1752
|
+
"errors": ["fact-chain is not available for `deep-existing-repo` attach-only bootstrap output"],
|
|
1753
|
+
},
|
|
1754
|
+
ensure_ascii=False,
|
|
1755
|
+
indent=2,
|
|
1756
|
+
)
|
|
1757
|
+
)
|
|
1758
|
+
return 1
|
|
1759
|
+
|
|
1760
|
+
report, errors = inspect_fact_chain(target_root, str(output_path.relative_to(target_root)))
|
|
1761
|
+
if errors:
|
|
1762
|
+
print(json.dumps({"ok": False, "errors": errors}, ensure_ascii=False, indent=2))
|
|
1763
|
+
return 1
|
|
1764
|
+
print(json.dumps({"ok": True, **report}, ensure_ascii=False, indent=2))
|
|
1765
|
+
return 0
|
|
1766
|
+
|
|
1767
|
+
|
|
1768
|
+
def runtime_state(args: argparse.Namespace) -> int:
|
|
1769
|
+
target_root = Path(args.target).expanduser().resolve()
|
|
1770
|
+
payload = runtime_state_payload(target_root)
|
|
1771
|
+
print(
|
|
1772
|
+
json.dumps(
|
|
1773
|
+
{
|
|
1774
|
+
"command": "runtime-state",
|
|
1775
|
+
"result": payload["result"],
|
|
1776
|
+
"summary": payload["summary"],
|
|
1777
|
+
"missing_inputs": payload["missing_inputs"],
|
|
1778
|
+
"fallback_to": payload["fallback_to"],
|
|
1779
|
+
"runtime_state": payload,
|
|
1780
|
+
},
|
|
1781
|
+
ensure_ascii=False,
|
|
1782
|
+
indent=2,
|
|
1783
|
+
)
|
|
1784
|
+
)
|
|
1785
|
+
return 0 if payload["result"] == "pass" else 1
|
|
1786
|
+
|
|
1787
|
+
|
|
1788
|
+
def route(args: argparse.Namespace) -> int:
|
|
1789
|
+
target_root = Path(args.target).expanduser().resolve()
|
|
1790
|
+
if not target_root.exists():
|
|
1791
|
+
print(f"loom-init: target does not exist: {target_root}", file=sys.stderr)
|
|
1792
|
+
return 2
|
|
1793
|
+
if not target_root.is_dir():
|
|
1794
|
+
print(f"loom-init: target is not a directory: {target_root}", file=sys.stderr)
|
|
1795
|
+
return 2
|
|
1796
|
+
|
|
1797
|
+
runtime_state = runtime_state_payload(target_root)
|
|
1798
|
+
if runtime_state["result"] != "pass":
|
|
1799
|
+
print(
|
|
1800
|
+
json.dumps(
|
|
1801
|
+
route_payload(
|
|
1802
|
+
result="block",
|
|
1803
|
+
selected_skill="loom-init",
|
|
1804
|
+
mode="fallback",
|
|
1805
|
+
matched_signals=[],
|
|
1806
|
+
summary="cannot route because the Loom runtime state is inconsistent.",
|
|
1807
|
+
missing_inputs=list(runtime_state["missing_inputs"]),
|
|
1808
|
+
fallback_to=runtime_state["fallback_to"] or "loom-init",
|
|
1809
|
+
runtime_state=runtime_state,
|
|
1810
|
+
),
|
|
1811
|
+
ensure_ascii=False,
|
|
1812
|
+
indent=2,
|
|
1813
|
+
)
|
|
1814
|
+
)
|
|
1815
|
+
return 1
|
|
1816
|
+
|
|
1817
|
+
registry_skill_ids, registry_error = load_registry_skill_ids()
|
|
1818
|
+
if registry_error:
|
|
1819
|
+
print(
|
|
1820
|
+
json.dumps(
|
|
1821
|
+
route_payload(
|
|
1822
|
+
result="block",
|
|
1823
|
+
selected_skill="loom-init",
|
|
1824
|
+
mode="fallback",
|
|
1825
|
+
matched_signals=[],
|
|
1826
|
+
summary=f"cannot route because {registry_error}",
|
|
1827
|
+
missing_inputs=["a valid installed registry"],
|
|
1828
|
+
fallback_to="loom-init",
|
|
1829
|
+
runtime_state=runtime_state,
|
|
1830
|
+
),
|
|
1831
|
+
ensure_ascii=False,
|
|
1832
|
+
indent=2,
|
|
1833
|
+
)
|
|
1834
|
+
)
|
|
1835
|
+
return 1
|
|
1836
|
+
|
|
1837
|
+
known_skills = set(registry_skill_ids or ())
|
|
1838
|
+
governance_surface: dict[str, object] | None = None
|
|
1839
|
+
if target_root.exists() and target_root.is_dir():
|
|
1840
|
+
try:
|
|
1841
|
+
governance_surface = build_governance_surface(target_root)
|
|
1842
|
+
except OSError:
|
|
1843
|
+
governance_surface = None
|
|
1844
|
+
|
|
1845
|
+
if args.skill:
|
|
1846
|
+
if args.skill not in known_skills:
|
|
1847
|
+
print(
|
|
1848
|
+
json.dumps(
|
|
1849
|
+
route_payload(
|
|
1850
|
+
result="block",
|
|
1851
|
+
selected_skill="loom-init",
|
|
1852
|
+
mode="explicit",
|
|
1853
|
+
matched_signals=[],
|
|
1854
|
+
summary=f"unknown skill `{args.skill}`",
|
|
1855
|
+
missing_inputs=["a known skill id from the installed registry"],
|
|
1856
|
+
fallback_to="loom-init",
|
|
1857
|
+
runtime_state=runtime_state,
|
|
1858
|
+
),
|
|
1859
|
+
ensure_ascii=False,
|
|
1860
|
+
indent=2,
|
|
1861
|
+
)
|
|
1862
|
+
)
|
|
1863
|
+
return 1
|
|
1864
|
+
print(
|
|
1865
|
+
json.dumps(
|
|
1866
|
+
route_payload(
|
|
1867
|
+
result="pass",
|
|
1868
|
+
selected_skill=args.skill,
|
|
1869
|
+
mode="explicit",
|
|
1870
|
+
matched_signals=[],
|
|
1871
|
+
summary=f"explicit skill `{args.skill}` selected",
|
|
1872
|
+
missing_inputs=[],
|
|
1873
|
+
fallback_to="loom-init",
|
|
1874
|
+
governance_surface=governance_surface if args.skill in {"loom-adopt", "loom-resume"} else None,
|
|
1875
|
+
runtime_state=runtime_state,
|
|
1876
|
+
),
|
|
1877
|
+
ensure_ascii=False,
|
|
1878
|
+
indent=2,
|
|
1879
|
+
)
|
|
1880
|
+
)
|
|
1881
|
+
return 0
|
|
1882
|
+
|
|
1883
|
+
matches = match_route_signals(args.task)
|
|
1884
|
+
if len(matches) == 1:
|
|
1885
|
+
selected_skill, matched = next(iter(matches.items()))
|
|
1886
|
+
if selected_skill not in known_skills:
|
|
1887
|
+
print(
|
|
1888
|
+
json.dumps(
|
|
1889
|
+
route_payload(
|
|
1890
|
+
result="block",
|
|
1891
|
+
selected_skill="loom-init",
|
|
1892
|
+
mode="implicit",
|
|
1893
|
+
matched_signals=matched,
|
|
1894
|
+
summary=f"route table resolved to unknown registry skill `{selected_skill}`",
|
|
1895
|
+
missing_inputs=["a registry entry aligned with skills/route-matrix.md"],
|
|
1896
|
+
fallback_to="loom-init",
|
|
1897
|
+
runtime_state=runtime_state,
|
|
1898
|
+
),
|
|
1899
|
+
ensure_ascii=False,
|
|
1900
|
+
indent=2,
|
|
1901
|
+
)
|
|
1902
|
+
)
|
|
1903
|
+
return 1
|
|
1904
|
+
print(
|
|
1905
|
+
json.dumps(
|
|
1906
|
+
route_payload(
|
|
1907
|
+
result="pass",
|
|
1908
|
+
selected_skill=selected_skill,
|
|
1909
|
+
mode="implicit",
|
|
1910
|
+
matched_signals=matched,
|
|
1911
|
+
summary=f"task signals route to `{selected_skill}`",
|
|
1912
|
+
missing_inputs=[],
|
|
1913
|
+
fallback_to="loom-init",
|
|
1914
|
+
governance_surface=governance_surface if selected_skill in {"loom-adopt", "loom-resume"} else None,
|
|
1915
|
+
runtime_state=runtime_state,
|
|
1916
|
+
),
|
|
1917
|
+
ensure_ascii=False,
|
|
1918
|
+
indent=2,
|
|
1919
|
+
)
|
|
1920
|
+
)
|
|
1921
|
+
return 0
|
|
1922
|
+
|
|
1923
|
+
if not matches:
|
|
1924
|
+
payload = route_payload(
|
|
1925
|
+
result="fallback",
|
|
1926
|
+
selected_skill="loom-init",
|
|
1927
|
+
mode="fallback",
|
|
1928
|
+
matched_signals=[],
|
|
1929
|
+
summary="task signals are insufficient for stable routing",
|
|
1930
|
+
missing_inputs=["one stable scenario signal such as adopt, resume, pre-review, handoff, retire, or merge-ready"],
|
|
1931
|
+
fallback_to="loom-init",
|
|
1932
|
+
governance_surface=governance_surface if governance_surface is not None else None,
|
|
1933
|
+
runtime_state=runtime_state,
|
|
1934
|
+
)
|
|
1935
|
+
else:
|
|
1936
|
+
all_matches = sorted({signal for matched in matches.values() for signal in matched})
|
|
1937
|
+
payload = route_payload(
|
|
1938
|
+
result="fallback",
|
|
1939
|
+
selected_skill="loom-init",
|
|
1940
|
+
mode="fallback",
|
|
1941
|
+
matched_signals=all_matches,
|
|
1942
|
+
summary=f"task signals matched multiple scenario skills: {', '.join(sorted(matches))}",
|
|
1943
|
+
missing_inputs=["a single dominant scenario signal or an explicit --skill"],
|
|
1944
|
+
fallback_to="loom-init",
|
|
1945
|
+
governance_surface=governance_surface if governance_surface is not None else None,
|
|
1946
|
+
runtime_state=runtime_state,
|
|
1947
|
+
)
|
|
1948
|
+
print(json.dumps(payload, ensure_ascii=False, indent=2))
|
|
1949
|
+
return 0
|
|
1950
|
+
|
|
1951
|
+
|
|
1952
|
+
def main(argv: list[str]) -> int:
|
|
1953
|
+
args = parse_args(argv)
|
|
1954
|
+
if args.command == "bootstrap":
|
|
1955
|
+
return bootstrap(args)
|
|
1956
|
+
if args.command == "verify":
|
|
1957
|
+
return verify(args)
|
|
1958
|
+
if args.command == "fact-chain":
|
|
1959
|
+
return fact_chain(args)
|
|
1960
|
+
if args.command == "runtime-state":
|
|
1961
|
+
return runtime_state(args)
|
|
1962
|
+
return route(args)
|
|
1963
|
+
|
|
1964
|
+
|
|
1965
|
+
if __name__ == "__main__":
|
|
1966
|
+
sys.exit(main(sys.argv[1:]))
|