@mc-and-his-agents/loom-installer 0.1.111 → 0.1.113
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/package.json +1 -1
- package/payload/manifest.json +425 -425
- package/payload/plugin/loom/skills/loom-adopt/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/plugin/loom/skills/loom-adopt/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/plugin/loom/skills/loom-adopt/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/plugin/loom/skills/loom-adopt/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/plugin/loom/skills/loom-adopt/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/plugin/loom/skills/loom-adopt/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/plugin/loom/skills/loom-adopt/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/plugin/loom/skills/loom-adopt/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/plugin/loom/skills/loom-adopt/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/plugin/loom/skills/loom-adopt/SKILL.md +1 -0
- package/payload/plugin/loom/skills/loom-build/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/plugin/loom/skills/loom-build/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/plugin/loom/skills/loom-build/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/plugin/loom/skills/loom-build/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/plugin/loom/skills/loom-build/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/plugin/loom/skills/loom-build/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/plugin/loom/skills/loom-build/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/plugin/loom/skills/loom-build/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/plugin/loom/skills/loom-build/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/plugin/loom/skills/loom-handoff/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/plugin/loom/skills/loom-handoff/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/plugin/loom/skills/loom-handoff/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/plugin/loom/skills/loom-handoff/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/plugin/loom/skills/loom-handoff/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/plugin/loom/skills/loom-handoff/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/plugin/loom/skills/loom-handoff/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/plugin/loom/skills/loom-handoff/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/plugin/loom/skills/loom-handoff/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/plugin/loom/skills/loom-init/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/plugin/loom/skills/loom-init/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/plugin/loom/skills/loom-init/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/plugin/loom/skills/loom-init/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/plugin/loom/skills/loom-init/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/plugin/loom/skills/loom-init/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/plugin/loom/skills/loom-init/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/plugin/loom/skills/loom-init/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/plugin/loom/skills/loom-init/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/plugin/loom/skills/loom-init/SKILL.md +2 -0
- package/payload/plugin/loom/skills/loom-init/contract.json +4 -0
- package/payload/plugin/loom/skills/loom-init/references/output-contract.md +13 -1
- package/payload/plugin/loom/skills/loom-merge-ready/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/plugin/loom/skills/loom-merge-ready/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/plugin/loom/skills/loom-merge-ready/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/plugin/loom/skills/loom-merge-ready/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/plugin/loom/skills/loom-merge-ready/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/plugin/loom/skills/loom-merge-ready/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/plugin/loom/skills/loom-merge-ready/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/plugin/loom/skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/plugin/loom/skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/plugin/loom/skills/loom-pre-review/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/plugin/loom/skills/loom-pre-review/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/plugin/loom/skills/loom-pre-review/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/plugin/loom/skills/loom-pre-review/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/plugin/loom/skills/loom-pre-review/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/plugin/loom/skills/loom-pre-review/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/plugin/loom/skills/loom-pre-review/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/plugin/loom/skills/loom-pre-review/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/plugin/loom/skills/loom-pre-review/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/plugin/loom/skills/loom-resume/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/plugin/loom/skills/loom-resume/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/plugin/loom/skills/loom-resume/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/plugin/loom/skills/loom-resume/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/plugin/loom/skills/loom-resume/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/plugin/loom/skills/loom-resume/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/plugin/loom/skills/loom-resume/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/plugin/loom/skills/loom-resume/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/plugin/loom/skills/loom-resume/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/plugin/loom/skills/loom-retire/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/plugin/loom/skills/loom-retire/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/plugin/loom/skills/loom-retire/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/plugin/loom/skills/loom-retire/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/plugin/loom/skills/loom-retire/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/plugin/loom/skills/loom-retire/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/plugin/loom/skills/loom-retire/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/plugin/loom/skills/loom-retire/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/plugin/loom/skills/loom-retire/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/plugin/loom/skills/loom-review/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/plugin/loom/skills/loom-review/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/plugin/loom/skills/loom-review/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/plugin/loom/skills/loom-review/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/plugin/loom/skills/loom-review/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/plugin/loom/skills/loom-review/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/plugin/loom/skills/loom-review/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/plugin/loom/skills/loom-review/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/plugin/loom/skills/loom-review/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/plugin/loom/skills/loom-spec-review/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/plugin/loom/skills/loom-spec-review/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/plugin/loom/skills/loom-spec-review/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/plugin/loom/skills/loom-spec-review/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/plugin/loom/skills/loom-spec-review/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/plugin/loom/skills/loom-spec-review/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/plugin/loom/skills/loom-spec-review/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/plugin/loom/skills/loom-spec-review/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/plugin/loom/skills/loom-spec-review/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/plugin/loom/skills/loom-story/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/plugin/loom/skills/loom-story/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/plugin/loom/skills/loom-story/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/plugin/loom/skills/loom-story/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/plugin/loom/skills/loom-story/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/plugin/loom/skills/loom-story/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/plugin/loom/skills/loom-story/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/plugin/loom/skills/loom-story/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/plugin/loom/skills/loom-story/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/plugin/loom/skills/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/plugin/loom/skills/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/plugin/loom/skills/shared/scripts/governance_surface.py +1 -0
- package/payload/plugin/loom/skills/shared/scripts/loom_check.py +148 -0
- package/payload/plugin/loom/skills/shared/scripts/loom_init.py +523 -215
- package/payload/skills/loom-adopt/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/skills/loom-adopt/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/skills/loom-adopt/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/skills/loom-adopt/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/skills/loom-adopt/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/skills/loom-adopt/SKILL.md +1 -0
- package/payload/skills/loom-build/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/skills/loom-build/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/skills/loom-build/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/skills/loom-build/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/skills/loom-build/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/skills/loom-build/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/skills/loom-build/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/skills/loom-build/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/skills/loom-build/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/skills/loom-handoff/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/skills/loom-handoff/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/skills/loom-handoff/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/skills/loom-handoff/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/skills/loom-handoff/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/skills/loom-init/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/skills/loom-init/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/skills/loom-init/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/skills/loom-init/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/skills/loom-init/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/skills/loom-init/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/skills/loom-init/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/skills/loom-init/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/skills/loom-init/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/skills/loom-init/SKILL.md +2 -0
- package/payload/skills/loom-init/contract.json +4 -0
- package/payload/skills/loom-init/references/output-contract.md +13 -1
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/skills/loom-merge-ready/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/skills/loom-pre-review/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/skills/loom-pre-review/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/skills/loom-pre-review/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/skills/loom-pre-review/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/skills/loom-pre-review/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/skills/loom-resume/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/skills/loom-resume/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/skills/loom-resume/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/skills/loom-resume/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/skills/loom-resume/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/skills/loom-resume/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/skills/loom-resume/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/skills/loom-retire/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/skills/loom-retire/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/skills/loom-retire/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/skills/loom-retire/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/skills/loom-retire/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/skills/loom-retire/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/skills/loom-retire/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/skills/loom-review/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/skills/loom-review/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/skills/loom-review/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/skills/loom-review/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/skills/loom-review/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/skills/loom-review/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/skills/loom-review/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/skills/loom-review/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/skills/loom-review/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/skills/loom-spec-review/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/skills/loom-spec-review/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/skills/loom-spec-review/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/skills/loom-spec-review/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/skills/loom-spec-review/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/skills/loom-spec-review/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/skills/loom-spec-review/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/skills/loom-spec-review/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/skills/loom-spec-review/.loom-runtime/shared/scripts/loom_init.py +523 -215
- package/payload/skills/loom-story/.loom-runtime/loom-adopt/SKILL.md +1 -0
- package/payload/skills/loom-story/.loom-runtime/loom-init/SKILL.md +2 -0
- package/payload/skills/loom-story/.loom-runtime/loom-init/contract.json +4 -0
- package/payload/skills/loom-story/.loom-runtime/loom-init/references/output-contract.md +13 -1
- package/payload/skills/loom-story/.loom-runtime/shared/references/adoption/deep-existing-repo-default.md +4 -0
- package/payload/skills/loom-story/.loom-runtime/shared/references/adoption/repo-companion-contract.md +3 -1
- package/payload/skills/loom-story/.loom-runtime/shared/scripts/governance_surface.py +1 -0
- package/payload/skills/loom-story/.loom-runtime/shared/scripts/loom_check.py +148 -0
- package/payload/skills/loom-story/.loom-runtime/shared/scripts/loom_init.py +523 -215
|
@@ -57,6 +57,7 @@ description: 负责把仓库接入 Loom 的初始化场景入口。Use when Code
|
|
|
57
57
|
2. `judge`
|
|
58
58
|
- 判断这是 `新项目`、`小型既有仓库` 还是 `复杂既有仓库`
|
|
59
59
|
- 消费或输出 `adoption_intent`;当 intent 不明确且写入会创建重执行控制面时,先停在 decision prompt / dry-run,不静默写入
|
|
60
|
+
- 输出 `scaffold_profile`,并按该 profile 列出 required、planned、intentionally absent 与 forbidden authored carriers
|
|
60
61
|
- 输出本轮启用能力、暂不启用能力、升级触发条件、source locator、write target 与 validation command
|
|
61
62
|
3. `write`
|
|
62
63
|
- 只有用户要求实际落盘时才执行 `bootstrap --write`
|
|
@@ -66,6 +66,8 @@ description: Loom 的 root entry。负责初始化新项目或既有仓库,并
|
|
|
66
66
|
|
|
67
67
|
`--intent` 用来表达采用意图,而不是仓库静态分类。未显式给出 intent 时,dry-run 仍会输出推荐路径、风险摘要和计划写入载体;如果实际写入会创建重执行控制面,必须先显式选择 `execution-control` 或 `strong-governance`。
|
|
68
68
|
|
|
69
|
+
每个 intent 会收敛到一个 `scaffold_profile`。`observe-only` 与 `skill-install-only` 不写 adoption carriers;`attach-only` 只写 companion/read surfaces,并显式禁止 `.loom/work-items/**`、`.loom/progress/**`、`.loom/status/current.md`、`.loom/reviews/**`、`.loom/specs/**` 等 Loom-authored truth carriers;`light-governance` 写 companion、review/spec 与 PR 最小闭环但不写 Loom-owned work/progress/status;`execution-control` 与 `strong-governance` 才写 Loom-owned execution carriers。
|
|
70
|
+
|
|
69
71
|
## 1. 读取顺序
|
|
70
72
|
|
|
71
73
|
按以下顺序读取材料:
|
|
@@ -31,11 +31,15 @@
|
|
|
31
31
|
"required_sections": [
|
|
32
32
|
"project_judgment",
|
|
33
33
|
"recommended_adoption",
|
|
34
|
+
"scaffold_profile",
|
|
34
35
|
"adoption_intent",
|
|
35
36
|
"detected_repository_mode",
|
|
36
37
|
"risk_summary",
|
|
38
|
+
"required_carriers",
|
|
37
39
|
"planned_writes",
|
|
40
|
+
"forbidden_authored_carriers",
|
|
38
41
|
"deferred_capabilities",
|
|
42
|
+
"upgrade_triggers",
|
|
39
43
|
"fact_chain",
|
|
40
44
|
"initial_artifacts",
|
|
41
45
|
"initial_work_items",
|
|
@@ -30,6 +30,13 @@
|
|
|
30
30
|
- `effective`
|
|
31
31
|
- `source`
|
|
32
32
|
- `requires_explicit_confirmation`
|
|
33
|
+
- `scaffold_profile`
|
|
34
|
+
- `name`
|
|
35
|
+
- `writes_artifacts`
|
|
36
|
+
- `writes_work_item_carriers`
|
|
37
|
+
- `description`
|
|
38
|
+
- `required_carriers`
|
|
39
|
+
- `forbidden_authored_carriers`
|
|
33
40
|
- 本轮启用的能力清单
|
|
34
41
|
- 每项能力分别映射到哪些 `governance`、`harness`、`templates`、`adoption` 规则
|
|
35
42
|
- 这次采用的是最小装配、轻量 retrofit 还是更完整装配
|
|
@@ -46,6 +53,7 @@
|
|
|
46
53
|
- 当前不引入哪些 Loom 能力
|
|
47
54
|
- 不引入的原因是什么
|
|
48
55
|
- 这些能力未来的升级触发条件是什么
|
|
56
|
+
- 顶层 `upgrade_triggers` 必须把 deferred capability 映射回当前 `scaffold_profile`
|
|
49
57
|
|
|
50
58
|
### 4. 首批工件
|
|
51
59
|
|
|
@@ -53,8 +61,10 @@
|
|
|
53
61
|
|
|
54
62
|
- `detected_repository_mode`:静态检测到的仓库模式和 scenario
|
|
55
63
|
- `risk_summary`:是否会写入重执行控制面、是否保护 repo-owned truth、是否需要显式 intent
|
|
64
|
+
- `required_carriers`:本 profile 必须落盘或保持可读的稳定载体
|
|
56
65
|
- `planned_writes`:dry-run / write 即将落盘的稳定载体集合
|
|
57
|
-
- `
|
|
66
|
+
- `forbidden_authored_carriers`:本 profile 明确禁止生成、声明或保留的 Loom-authored truth carrier
|
|
67
|
+
- `intentionally_absent`:因 attach-only、light-governance、observe-only 或 skill-install-only 而明确不生成的载体
|
|
58
68
|
- 初始能力清单的承载位置
|
|
59
69
|
- 首批 `Work Item` 或等价事项清单的承载位置
|
|
60
70
|
- 恢复主入口是什么
|
|
@@ -113,6 +123,8 @@
|
|
|
113
123
|
- attach-only 必备工件是什么
|
|
114
124
|
- 哪些 repo-native carriers 继续保留
|
|
115
125
|
- 哪些 Loom-owned carriers 本轮不会生成
|
|
126
|
+
- `forbidden_authored_carriers` 必须至少包含 `.loom/work-items/**`、`.loom/progress/**`、`.loom/status/current.md`、`.loom/reviews/**`、`.loom/specs/**`
|
|
127
|
+
- verify 必须同时检查磁盘存在、`init-result` 声明、`planned_writes`、manifest artifacts 与 write touched,不得让 forbidden carrier 形成第二事实链
|
|
116
128
|
|
|
117
129
|
`init-result` 只允许承接 locator-only 信息,不并行复制实时停点、下一步、阻断项或最近验证摘要。
|
|
118
130
|
|
|
@@ -57,9 +57,13 @@
|
|
|
57
57
|
- `.loom/work-items/*`
|
|
58
58
|
- `.loom/progress/*`
|
|
59
59
|
- `.loom/status/current.md`
|
|
60
|
+
- `.loom/reviews/*`
|
|
61
|
+
- `.loom/specs/*`
|
|
60
62
|
- Loom-owned recovery/status carriers 的 bootstrap placeholder
|
|
61
63
|
- 对 branch / PR / worktree / merge / ruleset 的底层宿主重写
|
|
62
64
|
|
|
65
|
+
若上述 Loom-authored carriers 已存在、被 `init-result` / manifest 声明为 generated,或出现在 attach-only planned writes 中,verify 必须 fail closed。执行者只能迁移到宿主 truth locator、删除 competing carrier,或显式升级 intent 到 `execution-control`。
|
|
66
|
+
|
|
63
67
|
## 6. 升级信号
|
|
64
68
|
|
|
65
69
|
以下任一条件出现时,不应继续停留在 attach-only 默认路径:
|
|
@@ -162,6 +162,7 @@
|
|
|
162
162
|
- `policy_locators`
|
|
163
163
|
- `hook_locators`
|
|
164
164
|
- `release_targets`
|
|
165
|
+
- `host_truth_locators`
|
|
165
166
|
|
|
166
167
|
稳定约束:
|
|
167
168
|
|
|
@@ -171,8 +172,9 @@
|
|
|
171
172
|
- `policy_locators` 只在 `v2` 合法
|
|
172
173
|
- `hook_locators` 只在 `v2` 合法
|
|
173
174
|
- `release_targets` 只在 `v2` 合法
|
|
175
|
+
- `host_truth_locators` 只在 `v2` 合法,且只能声明宿主事实源 locator,例如 GitHub Issue、GitHub Project、PR review / guardian、PR metadata 与 issue state
|
|
174
176
|
- `v2` 不改变 `repo_specific_requirements` 与 `specialized_gates` 的既有纪律
|
|
175
|
-
- `v2` 不把 repo runtime state、review summary、validation status 或 retained host action result 写入 `repo-interface.json`
|
|
177
|
+
- `v2` 不把 repo runtime state、progress/current stop、review verdict、review summary、validation status、closeout result 或 retained host action result 写入 `repo-interface.json`
|
|
176
178
|
|
|
177
179
|
### 4.3 通用字段纪律
|
|
178
180
|
|
package/payload/plugin/loom/skills/loom-handoff/.loom-runtime/shared/scripts/governance_surface.py
CHANGED
|
@@ -352,6 +352,7 @@ REPO_INTERFACE_V2_KEYS = REPO_INTERFACE_V1_KEYS | {
|
|
|
352
352
|
"policy_locators",
|
|
353
353
|
"hook_locators",
|
|
354
354
|
"release_targets",
|
|
355
|
+
"host_truth_locators",
|
|
355
356
|
}
|
|
356
357
|
DECLARED_LOCATOR_REQUIREMENTS = {"required", "optional", "advisory"}
|
|
357
358
|
DECLARED_LOCATOR_OWNERS = {"repo", "repo-companion", "host", "host-adapter", "platform", "external-tool"}
|
|
@@ -4336,6 +4336,28 @@ def check_deep_existing_repo_bootstrap(root: Path) -> list[Failure]:
|
|
|
4336
4336
|
if pr_template:
|
|
4337
4337
|
(target / ".github" / "PULL_REQUEST_TEMPLATE.md").write_text("## Summary\n", encoding="utf-8")
|
|
4338
4338
|
|
|
4339
|
+
attach_only_forbidden_patterns = (
|
|
4340
|
+
".loom/work-items/**",
|
|
4341
|
+
".loom/progress/**",
|
|
4342
|
+
".loom/status/current.md",
|
|
4343
|
+
".loom/reviews/**",
|
|
4344
|
+
".loom/specs/**",
|
|
4345
|
+
)
|
|
4346
|
+
|
|
4347
|
+
def matches_forbidden(path: str, pattern: str) -> bool:
|
|
4348
|
+
if pattern.endswith("/**"):
|
|
4349
|
+
prefix = pattern[:-3]
|
|
4350
|
+
return path == prefix or path.startswith(prefix + "/")
|
|
4351
|
+
return path == pattern
|
|
4352
|
+
|
|
4353
|
+
def forbidden_match(path: object) -> str | None:
|
|
4354
|
+
if not isinstance(path, str):
|
|
4355
|
+
return None
|
|
4356
|
+
for pattern in attach_only_forbidden_patterns:
|
|
4357
|
+
if matches_forbidden(path, pattern):
|
|
4358
|
+
return pattern
|
|
4359
|
+
return None
|
|
4360
|
+
|
|
4339
4361
|
deep_target = tmp_root / "deep-existing"
|
|
4340
4362
|
write_repo(deep_target, validation_entry=True, pr_template=True, workflow_doc=True)
|
|
4341
4363
|
deep_dry_payload, deep_dry_error = load_command_json(
|
|
@@ -4356,6 +4378,8 @@ def check_deep_existing_repo_bootstrap(root: Path) -> list[Failure]:
|
|
|
4356
4378
|
intent = deep_dry_payload.get("adoption_intent")
|
|
4357
4379
|
risk = deep_dry_payload.get("risk_summary")
|
|
4358
4380
|
planned = deep_dry_payload.get("planned_writes")
|
|
4381
|
+
required = deep_dry_payload.get("required_carriers")
|
|
4382
|
+
forbidden = deep_dry_payload.get("forbidden_authored_carriers")
|
|
4359
4383
|
detected = deep_dry_payload.get("detected_repository_mode")
|
|
4360
4384
|
write = deep_dry_payload.get("write")
|
|
4361
4385
|
if not isinstance(intent, dict) or intent.get("effective") != "attach-only":
|
|
@@ -4364,6 +4388,18 @@ def check_deep_existing_repo_bootstrap(root: Path) -> list[Failure]:
|
|
|
4364
4388
|
failures.append(Failure("deep-existing-bootstrap", "`deep-existing dry-run` must report preserved repo-owned truth risk"))
|
|
4365
4389
|
if not isinstance(planned, list) or not planned:
|
|
4366
4390
|
failures.append(Failure("deep-existing-bootstrap", "`deep-existing dry-run` must report planned write targets"))
|
|
4391
|
+
else:
|
|
4392
|
+
for item in planned:
|
|
4393
|
+
if isinstance(item, dict):
|
|
4394
|
+
pattern = forbidden_match(item.get("path"))
|
|
4395
|
+
if pattern:
|
|
4396
|
+
failures.append(Failure("deep-existing-bootstrap", f"`deep-existing dry-run` planned write must not match forbidden carrier `{pattern}`"))
|
|
4397
|
+
if not isinstance(required, list) or not required:
|
|
4398
|
+
failures.append(Failure("deep-existing-bootstrap", "`deep-existing dry-run` must report required carriers"))
|
|
4399
|
+
if not isinstance(forbidden, list) or {
|
|
4400
|
+
item.get("path") for item in forbidden if isinstance(item, dict)
|
|
4401
|
+
} != set(attach_only_forbidden_patterns):
|
|
4402
|
+
failures.append(Failure("deep-existing-bootstrap", "`deep-existing dry-run` must report the full attach-only forbidden carrier list"))
|
|
4367
4403
|
if not isinstance(detected, dict) or detected.get("scenario_key") != "complex-existing":
|
|
4368
4404
|
failures.append(Failure("deep-existing-bootstrap", "`deep-existing dry-run` must report detected repository mode"))
|
|
4369
4405
|
if not isinstance(write, dict) or write.get("enabled") is not False:
|
|
@@ -4391,6 +4427,7 @@ def check_deep_existing_repo_bootstrap(root: Path) -> list[Failure]:
|
|
|
4391
4427
|
recommended = deep_payload.get("recommended_adoption")
|
|
4392
4428
|
verification = deep_payload.get("verification")
|
|
4393
4429
|
governance_surface = deep_payload.get("governance_surface")
|
|
4430
|
+
repo_interface_path = deep_target / ".loom/companion/repo-interface.json"
|
|
4394
4431
|
if not isinstance(recommended, dict) or recommended.get("path") != "deep-existing-repo":
|
|
4395
4432
|
failures.append(Failure("deep-existing-bootstrap", "`deep-existing bootstrap` must select `recommended_adoption.path = deep-existing-repo`"))
|
|
4396
4433
|
run = deep_payload.get("run")
|
|
@@ -4413,12 +4450,79 @@ def check_deep_existing_repo_bootstrap(root: Path) -> list[Failure]:
|
|
|
4413
4450
|
".loom/work-items/INIT-0001.md",
|
|
4414
4451
|
".loom/progress/INIT-0001.md",
|
|
4415
4452
|
".loom/status/current.md",
|
|
4453
|
+
".loom/reviews/INIT-0001.json",
|
|
4454
|
+
".loom/specs/INIT-0001/spec.md",
|
|
4416
4455
|
):
|
|
4417
4456
|
if (deep_target / forbidden).exists():
|
|
4418
4457
|
failures.append(Failure("deep-existing-bootstrap", f"`deep-existing bootstrap` must not generate `{forbidden}`"))
|
|
4419
4458
|
fact_chain = deep_payload.get("fact_chain")
|
|
4420
4459
|
if not isinstance(fact_chain, dict) or fact_chain.get("mode") != "repo-native attach-only":
|
|
4421
4460
|
failures.append(Failure("deep-existing-bootstrap", "`deep-existing bootstrap` must keep `fact_chain.mode = repo-native attach-only`"))
|
|
4461
|
+
if repo_interface_path.exists():
|
|
4462
|
+
repo_interface = json.loads(repo_interface_path.read_text(encoding="utf-8"))
|
|
4463
|
+
host_truth = repo_interface.get("host_truth_locators")
|
|
4464
|
+
if not isinstance(host_truth, dict) or set(host_truth.keys()) != {"work_item", "project_status", "review", "closeout"}:
|
|
4465
|
+
failures.append(Failure("deep-existing-bootstrap", "`deep-existing bootstrap` repo-interface must declare attach-only host truth locators"))
|
|
4466
|
+
|
|
4467
|
+
poisoned_files_target = tmp_root / "deep-existing-poison-files"
|
|
4468
|
+
if deep_target.exists() and (deep_target / ".loom/bin/loom_init.py").exists():
|
|
4469
|
+
shutil.copytree(deep_target, poisoned_files_target)
|
|
4470
|
+
(poisoned_files_target / ".loom/reviews").mkdir(parents=True, exist_ok=True)
|
|
4471
|
+
(poisoned_files_target / ".loom/specs/EXISTING").mkdir(parents=True, exist_ok=True)
|
|
4472
|
+
(poisoned_files_target / ".loom/reviews/EXISTING.json").write_text("{}", encoding="utf-8")
|
|
4473
|
+
(poisoned_files_target / ".loom/specs/EXISTING/spec.md").write_text("# Existing Spec\n", encoding="utf-8")
|
|
4474
|
+
poisoned_payload, poisoned_error = load_command_json(
|
|
4475
|
+
root,
|
|
4476
|
+
[
|
|
4477
|
+
"python3",
|
|
4478
|
+
str(poisoned_files_target / ".loom/bin/loom_init.py"),
|
|
4479
|
+
"verify",
|
|
4480
|
+
"--target",
|
|
4481
|
+
str(poisoned_files_target),
|
|
4482
|
+
],
|
|
4483
|
+
)
|
|
4484
|
+
if poisoned_error:
|
|
4485
|
+
failures.append(Failure("deep-existing-bootstrap", f"`attach-only forbidden file verify` failed: {poisoned_error}"))
|
|
4486
|
+
else:
|
|
4487
|
+
errors_text = json.dumps(poisoned_payload.get("errors", []), ensure_ascii=False) if poisoned_payload else ""
|
|
4488
|
+
if poisoned_payload.get("ok") is not False:
|
|
4489
|
+
failures.append(Failure("deep-existing-bootstrap", "`attach-only forbidden file verify` must fail closed"))
|
|
4490
|
+
if "forbidden authored carrier" not in errors_text or "second truth chain" not in errors_text:
|
|
4491
|
+
failures.append(Failure("deep-existing-bootstrap", "`attach-only forbidden file verify` must explain the second truth-chain risk"))
|
|
4492
|
+
|
|
4493
|
+
poisoned_decl_target = tmp_root / "deep-existing-poison-declarations"
|
|
4494
|
+
if deep_target.exists() and (deep_target / ".loom/bin/loom_init.py").exists():
|
|
4495
|
+
shutil.copytree(deep_target, poisoned_decl_target)
|
|
4496
|
+
init_result_path = poisoned_decl_target / ".loom/bootstrap/init-result.json"
|
|
4497
|
+
manifest_path = poisoned_decl_target / ".loom/bootstrap/manifest.json"
|
|
4498
|
+
init_result = json.loads(init_result_path.read_text(encoding="utf-8"))
|
|
4499
|
+
init_result.setdefault("planned_writes", []).append(
|
|
4500
|
+
{"path": ".loom/work-items/POISON.md", "kind": "work-item", "owner": "loom"}
|
|
4501
|
+
)
|
|
4502
|
+
init_result_path.write_text(json.dumps(init_result, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
|
4503
|
+
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
|
|
4504
|
+
manifest.setdefault("artifacts", []).append(
|
|
4505
|
+
{"path": ".loom/progress/POISON.md", "kind": "progress", "source": "generated"}
|
|
4506
|
+
)
|
|
4507
|
+
manifest_path.write_text(json.dumps(manifest, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
|
4508
|
+
poisoned_payload, poisoned_error = load_command_json(
|
|
4509
|
+
root,
|
|
4510
|
+
[
|
|
4511
|
+
"python3",
|
|
4512
|
+
str(poisoned_decl_target / ".loom/bin/loom_init.py"),
|
|
4513
|
+
"verify",
|
|
4514
|
+
"--target",
|
|
4515
|
+
str(poisoned_decl_target),
|
|
4516
|
+
],
|
|
4517
|
+
)
|
|
4518
|
+
if poisoned_error:
|
|
4519
|
+
failures.append(Failure("deep-existing-bootstrap", f"`attach-only forbidden declaration verify` failed: {poisoned_error}"))
|
|
4520
|
+
else:
|
|
4521
|
+
errors_text = json.dumps(poisoned_payload.get("errors", []), ensure_ascii=False) if poisoned_payload else ""
|
|
4522
|
+
if poisoned_payload.get("ok") is not False:
|
|
4523
|
+
failures.append(Failure("deep-existing-bootstrap", "`attach-only forbidden declaration verify` must fail closed"))
|
|
4524
|
+
if "planned_writes" not in errors_text or "manifest.artifacts" not in errors_text:
|
|
4525
|
+
failures.append(Failure("deep-existing-bootstrap", "`attach-only forbidden declaration verify` must name poisoned declaration sources"))
|
|
4422
4526
|
|
|
4423
4527
|
full_target = tmp_root / "full-bootstrap"
|
|
4424
4528
|
write_repo(full_target, validation_entry=False, pr_template=False, workflow_doc=False)
|
|
@@ -4478,17 +4582,61 @@ def check_deep_existing_repo_bootstrap(root: Path) -> list[Failure]:
|
|
|
4478
4582
|
else:
|
|
4479
4583
|
intent = explicit_payload.get("adoption_intent")
|
|
4480
4584
|
recommended = explicit_payload.get("recommended_adoption")
|
|
4585
|
+
profile = explicit_payload.get("scaffold_profile")
|
|
4481
4586
|
if not isinstance(intent, dict) or intent.get("effective") != "execution-control":
|
|
4482
4587
|
failures.append(Failure("deep-existing-bootstrap", "explicit full-bootstrap sample must report `adoption_intent.effective = execution-control`"))
|
|
4483
4588
|
if not isinstance(recommended, dict) or recommended.get("path") != "full-bootstrap":
|
|
4484
4589
|
failures.append(Failure("deep-existing-bootstrap", "explicit execution-control sample must select `recommended_adoption.path = full-bootstrap`"))
|
|
4590
|
+
if not isinstance(profile, dict) or profile.get("name") != "execution-control":
|
|
4591
|
+
failures.append(Failure("deep-existing-bootstrap", "explicit execution-control sample must report `scaffold_profile.name = execution-control`"))
|
|
4485
4592
|
for required in (
|
|
4486
4593
|
".loom/work-items/INIT-0001.md",
|
|
4487
4594
|
".loom/progress/INIT-0001.md",
|
|
4488
4595
|
".loom/status/current.md",
|
|
4596
|
+
".loom/reviews/INIT-0001.json",
|
|
4597
|
+
".loom/specs/INIT-0001/spec.md",
|
|
4489
4598
|
):
|
|
4490
4599
|
if not (explicit_full_target / required).exists():
|
|
4491
4600
|
failures.append(Failure("deep-existing-bootstrap", f"`explicit execution-control bootstrap sample` must generate `{required}`"))
|
|
4601
|
+
|
|
4602
|
+
light_target = tmp_root / "light-governance"
|
|
4603
|
+
write_repo(light_target, validation_entry=True, pr_template=False, workflow_doc=False)
|
|
4604
|
+
light_payload, light_error = load_command_json(
|
|
4605
|
+
root,
|
|
4606
|
+
[
|
|
4607
|
+
"python3",
|
|
4608
|
+
"tools/loom_init.py",
|
|
4609
|
+
"bootstrap",
|
|
4610
|
+
"--target",
|
|
4611
|
+
str(light_target),
|
|
4612
|
+
"--intent",
|
|
4613
|
+
"light-governance",
|
|
4614
|
+
"--write",
|
|
4615
|
+
"--force",
|
|
4616
|
+
"--verify",
|
|
4617
|
+
"--install-pr-template",
|
|
4618
|
+
],
|
|
4619
|
+
)
|
|
4620
|
+
if light_error:
|
|
4621
|
+
failures.append(Failure("deep-existing-bootstrap", f"`light-governance bootstrap sample` failed: {light_error}"))
|
|
4622
|
+
else:
|
|
4623
|
+
profile = light_payload.get("scaffold_profile")
|
|
4624
|
+
if not isinstance(profile, dict) or profile.get("name") != "light-governance":
|
|
4625
|
+
failures.append(Failure("deep-existing-bootstrap", "light-governance sample must report `scaffold_profile.name = light-governance`"))
|
|
4626
|
+
if not isinstance(light_payload.get("upgrade_triggers"), list) or not light_payload["upgrade_triggers"]:
|
|
4627
|
+
failures.append(Failure("deep-existing-bootstrap", "light-governance sample must report top-level upgrade_triggers"))
|
|
4628
|
+
planned = light_payload.get("planned_writes")
|
|
4629
|
+
planned_paths = {item.get("path") for item in planned if isinstance(item, dict)} if isinstance(planned, list) else set()
|
|
4630
|
+
for required in (".loom/reviews/INIT-0001.json", ".loom/specs/INIT-0001/spec.md", ".github/PULL_REQUEST_TEMPLATE.md"):
|
|
4631
|
+
if required not in planned_paths or not (light_target / required).exists():
|
|
4632
|
+
failures.append(Failure("deep-existing-bootstrap", f"`light-governance bootstrap sample` must generate `{required}`"))
|
|
4633
|
+
for forbidden in (
|
|
4634
|
+
".loom/work-items/INIT-0001.md",
|
|
4635
|
+
".loom/progress/INIT-0001.md",
|
|
4636
|
+
".loom/status/current.md",
|
|
4637
|
+
):
|
|
4638
|
+
if forbidden in planned_paths or (light_target / forbidden).exists():
|
|
4639
|
+
failures.append(Failure("deep-existing-bootstrap", f"`light-governance bootstrap sample` must not generate `{forbidden}`"))
|
|
4492
4640
|
return failures
|
|
4493
4641
|
|
|
4494
4642
|
|