@namewta/speculo 0.7.3 → 0.7.4

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.
Files changed (43) hide show
  1. package/dist/src/migrations.js +190 -39
  2. package/dist/src/migrations.js.map +1 -1
  3. package/package.json +1 -1
  4. package/template/canonical/canonical-specdev-engineering-cognitive-mentor.md +51 -15
  5. package/template/canonical/canonical-specdev-goal-plan.md +183 -116
  6. package/template/canonical/canonical-specdev-grill-with-docs.md +51 -15
  7. package/template/canonical/canonical-specdev-spec.md +61 -21
  8. package/template/canonical/canonical-specdev-tickets.md +83 -43
  9. package/template/canonical/canonical-specdev-wayfinder.md +51 -15
  10. package/template/skills/migrate-runtime-state/references/migration-contract.md +3 -3
  11. package/template/skills/migrate-runtime-state/scripts/migrate-runtime-state.mjs +94 -12
  12. package/template/workflows/specdev/I-implement/I-implement.md +27 -26
  13. package/template/workflows/specdev/I-implement/evidence-template.md +18 -12
  14. package/template/workflows/specdev/I-implement/execution-preflight.md +11 -9
  15. package/template/workflows/specdev/I-init-setup/I-init-setup.md +2 -2
  16. package/template/workflows/specdev/I-init-setup/change-status-template.json +3 -3
  17. package/template/workflows/specdev/I-init-setup/config-template.json +5 -2
  18. package/template/workflows/specdev/INDEX.md +6 -6
  19. package/template/workflows/specdev/P-goal-plan/P-goal-plan.md +16 -16
  20. package/template/workflows/specdev/P-goal-plan/completion-control.md +8 -8
  21. package/template/workflows/specdev/P-goal-plan/goal-plan-template.md +20 -14
  22. package/template/workflows/specdev/P-goal-plan/lead-orchestration.md +5 -5
  23. package/template/workflows/specdev/P-goal-plan/orchestration-protocol.md +13 -13
  24. package/template/workflows/specdev/P-goal-plan/planning-modes.md +27 -15
  25. package/template/workflows/specdev/P-prototype/ui-prototype.md +1 -1
  26. package/template/workflows/specdev/T-tickets/T-tickets.md +4 -4
  27. package/template/workflows/specdev/T-tickets/ticket-readiness.md +3 -3
  28. package/template/workflows/specdev/T-tickets/ticket-template.md +6 -6
  29. package/template/workflows/specdev/T-tickets/tickets-map-template.md +2 -2
  30. package/template/workflows/specdev/common/README.md +1 -1
  31. package/template/workflows/specdev/common/rules/change-completion.md +2 -2
  32. package/template/workflows/specdev/common/rules/evidence-and-verification.md +10 -6
  33. package/template/workflows/specdev/common/rules/path-ownership.md +4 -4
  34. package/template/workflows/specdev/common/schemas/change-status.schema.json +31 -4
  35. package/template/workflows/specdev/common/schemas/config.schema.json +12 -6
  36. package/template/workflows/specdev/common/schemas/goal-plan.schema.json +15 -6
  37. package/template/workflows/specdev/common/skills/dev-worktree/SKILL.md +3 -3
  38. package/template/workflows/specdev/common/skills/dev-worktree/references/finalize.md +1 -1
  39. package/template/workflows/specdev/common/skills/subagent-delivery/SKILL.md +4 -4
  40. package/template/workflows/specdev/common/skills/subagent-delivery/references/external-web-subagent.md +1 -1
  41. package/template/workflows/specdev/common/skills/subagent-delivery/references/native-subagent.md +4 -4
  42. package/template/workflows/specdev/common/tools/README.md +2 -1
  43. package/template/workflows/specdev/common/tools/validate-specdev.mjs +261 -66
@@ -656,7 +656,7 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
656
656
 
657
657
  ```json
658
658
  {
659
- "schema_version": 4,
659
+ "schema_version": 5,
660
660
  "interaction_language": "zh-CN",
661
661
  "artifact_language": "zh-CN",
662
662
  "git": {
@@ -664,6 +664,7 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
664
664
  },
665
665
  "execution": {
666
666
  "max_implementation_agents": 3,
667
+ "max_integration_attempts": 3,
667
668
  "deep_ticket_human_approval": true,
668
669
  "shared_path_owner": "explicit"
669
670
  },
@@ -676,7 +677,9 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
676
677
  "planning": {
677
678
  "default_depth": "standard",
678
679
  "require_ready_gate": true,
679
- "require_evidence": true
680
+ "require_evidence": true,
681
+ "ui_prototype_default_variants": 3,
682
+ "ui_prototype_max_variants": 5
680
683
  }
681
684
  }
682
685
  ```
@@ -688,12 +691,12 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
688
691
  ```json
689
692
  {
690
693
  "$schema": "https://json-schema.org/draft/2020-12/schema",
691
- "$id": "urn:speculo:specdev:config:v4",
694
+ "$id": "urn:speculo:specdev:config:v5",
692
695
  "title": "SpecDev Configuration",
693
696
  "type": "object",
694
697
  "required": ["schema_version", "interaction_language", "artifact_language", "git", "execution", "verification", "planning"],
695
698
  "properties": {
696
- "schema_version": {"const": 4},
699
+ "schema_version": {"const": 5},
697
700
  "interaction_language": {"type": "string", "minLength": 1},
698
701
  "artifact_language": {"type": "string", "minLength": 1},
699
702
  "git": {
@@ -706,9 +709,10 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
706
709
  },
707
710
  "execution": {
708
711
  "type": "object",
709
- "required": ["max_implementation_agents", "deep_ticket_human_approval", "shared_path_owner"],
712
+ "required": ["max_implementation_agents", "max_integration_attempts", "deep_ticket_human_approval", "shared_path_owner"],
710
713
  "properties": {
711
- "max_implementation_agents": {"type": "integer", "minimum": 1, "maximum": 3},
714
+ "max_implementation_agents": {"type": "integer", "minimum": 1},
715
+ "max_integration_attempts": {"type": "integer", "minimum": 1},
712
716
  "deep_ticket_human_approval": {"type": "boolean"},
713
717
  "shared_path_owner": {"type": "string", "minLength": 1}
714
718
  },
@@ -727,15 +731,20 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
727
731
  },
728
732
  "planning": {
729
733
  "type": "object",
730
- "required": ["default_depth", "require_ready_gate", "require_evidence"],
734
+ "required": ["default_depth", "require_ready_gate", "require_evidence", "ui_prototype_default_variants", "ui_prototype_max_variants"],
731
735
  "properties": {
732
736
  "default_depth": {"enum": ["lite", "standard", "deep"]},
733
737
  "require_ready_gate": {"type": "boolean"},
734
- "require_evidence": {"type": "boolean"}
738
+ "require_evidence": {"type": "boolean"},
739
+ "ui_prototype_default_variants": {"type": "integer", "minimum": 1},
740
+ "ui_prototype_max_variants": {"type": "integer", "minimum": 1}
735
741
  },
736
742
  "additionalProperties": true
737
743
  }
738
744
  },
745
+ "allOf": [{
746
+ "$comment": "ui_prototype_default_variants <= ui_prototype_max_variants is enforced by validate-specdev.mjs because JSON Schema cannot compare sibling numeric values."
747
+ }],
739
748
  "additionalProperties": false
740
749
  }
741
750
  ```
@@ -801,7 +810,7 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
801
810
 
802
811
  ```json
803
812
  {
804
- "schema_version": 5,
813
+ "schema_version": 6,
805
814
  "artifact": "change-status",
806
815
  "change": "<YYYY-MM-DD-topic>",
807
816
  "change_status": "active",
@@ -809,8 +818,8 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
809
818
  "works_run": [],
810
819
  "claimed_investigations": [],
811
820
  "execution_authorization": {
812
- "implementation_commit": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Ticket source commits"},
813
- "local_candidate_integration": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Lead-owned local parent candidate integration and parent update"},
821
+ "implementation_commit": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Ticket implementation commits"},
822
+ "local_candidate_integration": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Lead-owned local direct-parent or candidate integration and parent update"},
814
823
  "source_cleanup": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Source worktree and branch cleanup"}
815
824
  },
816
825
  "leadership": {
@@ -837,7 +846,7 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
837
846
  ```json
838
847
  {
839
848
  "$schema": "https://json-schema.org/draft/2020-12/schema",
840
- "$id": "urn:speculo:specdev:change-status:v5",
849
+ "$id": "urn:speculo:specdev:change-status:v6",
841
850
  "title": "SpecDev Change Status",
842
851
  "type": "object",
843
852
  "required": [
@@ -846,7 +855,7 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
846
855
  "completed_at", "archived", "archive_path", "blockers", "deviations", "worktrees"
847
856
  ],
848
857
  "properties": {
849
- "schema_version": {"const": 5},
858
+ "schema_version": {"const": 6},
850
859
  "artifact": {"const": "change-status"},
851
860
  "change": {"type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*$"},
852
861
  "change_status": {"enum": ["active", "blocked", "completed", "archived"]},
@@ -950,12 +959,39 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
950
959
  "base_sha": {"type": "string", "minLength": 1},
951
960
  "parent_branch": {"type": "string", "minLength": 1},
952
961
  "branch": {"type": "string", "minLength": 1},
953
- "workspace_ref": {"type": "string", "pattern": "^specdev-worktree/[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*/T-[0-9]{2,}$"},
962
+ "workspace_ref": {"type": "string", "pattern": "^(?:current|specdev-worktree/[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*/T-[0-9]{2,})$"},
954
963
  "source_checkpoint": {"type": ["string", "null"]},
955
964
  "integration": {"$ref": "#/$defs/integration"},
956
965
  "status": {"enum": ["planned", "active", "review", "integrating", "integrated", "removed", "blocked"]},
957
966
  "updated_at": {"type": "string", "minLength": 1}
958
967
  },
968
+ "allOf": [
969
+ {
970
+ "if": {"properties": {"workspace_ref": {"const": "current"}}, "required": ["workspace_ref"]},
971
+ "then": {
972
+ "properties": {
973
+ "integration": {
974
+ "allOf": [{
975
+ "properties": {
976
+ "candidate_sha": {"const": null},
977
+ "candidate_tree_sha": {"const": null},
978
+ "candidate_branch": {"const": null},
979
+ "candidate_workspace_ref": {"const": null},
980
+ "method": {"enum": [null, "direct-parent"]}
981
+ }
982
+ }]
983
+ }
984
+ }
985
+ },
986
+ "else": {
987
+ "properties": {
988
+ "integration": {
989
+ "allOf": [{"properties": {"method": {"enum": [null, "fast-forward", "merge-commit"]}}}]
990
+ }
991
+ }
992
+ }
993
+ }
994
+ ],
959
995
  "additionalProperties": false
960
996
  },
961
997
  "integration": {
@@ -971,7 +1007,7 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
971
1007
  "candidate_branch": {"type": ["string", "null"]},
972
1008
  "candidate_workspace_ref": {"anyOf": [{"type": "null"}, {"type": "string", "pattern": "^specdev-worktree/\\.integration/[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*/T-[0-9]{2,}$"}]},
973
1009
  "result_sha": {"type": ["string", "null"]},
974
- "method": {"enum": [null, "fast-forward", "merge-commit"]},
1010
+ "method": {"enum": [null, "direct-parent", "fast-forward", "merge-commit"]},
975
1011
  "conflict_paths": {"type": "array", "items": {"type": "string"}},
976
1012
  "verification": {"enum": ["pending", "passed", "failed"]},
977
1013
  "full_suite": {"$ref": "#/$defs/full-suite"},
@@ -490,19 +490,23 @@ Ticket 只有同时满足以下适用条件才可设置 `ready: true`:
490
490
 
491
491
  | 行为或风险 | 接缝 | 命令/方法 | 环境 | 预期 | Evidence |
492
492
  |---|---|---|---|---|---|
493
- | 正常/失败路径 | 公共接口或稳定接缝 | 定向测试 | source-worktree | 合同成立 | Ticket Evidence |
494
- | 跨模块回归 | 集成接缝 | 回归命令 | parent-candidate | 组合状态成立 | Ticket Evidence |
495
- | E2E required | 真实端到端边界 | 场景步骤 | parent-candidate | 外部行为成立 | Ticket Evidence |
493
+ | 正常/失败路径 | 公共接口或稳定接缝 | 定向测试 | current-workspace 或 source-worktree | 合同成立 | Ticket Evidence |
494
+ | 跨模块回归 | 集成接缝 | 回归命令 | current-workspace 或 parent-candidate | 组合状态成立 | Ticket Evidence |
495
+ | E2E required | 真实端到端边界 | 场景步骤 | current-workspace 或 parent-candidate | 外部行为成立 | Ticket Evidence |
496
496
 
497
497
  ## 2. 两层验证
498
498
 
499
+ ### Current workspace
500
+
501
+ current 模式的 implementation owner 在当前父分支和当前 workspace 工作。Ticket 必须严格串行,workspace clean 后形成非空 implementation commit;Lead 在同一 workspace 执行适用集成/回归和 E2E,并在父 HEAD 未漂移时将 Ticket commit 记录为 result SHA。
502
+
499
503
  ### Source-worktree
500
504
 
501
505
  implementation owner 运行最接近目标行为的单元/组件测试、静态分析、类型、lint/build 等适用非 E2E 检查。来源实现必须在 clean worktree 形成 commit。任何 source-worktree E2E pass 声明无效。
502
506
 
503
507
  ### Parent-candidate
504
508
 
505
- Lead 在最新父分支与 source commit 的 candidate 状态运行受影响集成/回归、项目父状态检查和适用 E2E。E2E 由实际跨边界风险决定,不限于 UI;not-required 必须写理由。required E2E 未运行或失败时不得推进父分支。
509
+ required 模式下,Lead 在最新父分支与 source commit 的 candidate 状态运行受影响集成/回归、项目父状态检查和适用 E2E。E2E 由实际跨边界风险决定,不限于 UI;not-required 必须写理由。required E2E 未运行或失败时不得推进父分支。
506
510
 
507
511
  ### Direct Spec
508
512
 
@@ -522,9 +526,9 @@ subagent 只返回候选命令与结果,不写 Evidence。Lead 重读 workspac
522
526
 
523
527
  ## 5. Evidence 最低内容
524
528
 
525
- 每个 Ticket Evidence 至少包含:Lead、Dispatch/返回(若有)、base/source/candidate/result SHA、来源 worktree、实际路径、每条命令/环境/退出状态、合同映射、双轴审查、E2E disposition、未运行项、失败分类、偏差、残余风险和父分支重读结果。
529
+ 每个 Ticket Evidence 至少包含:Lead、Dispatch/返回(若有)、workspace 策略、base/source/result SHA、candidate 字段(required 模式适用,current 模式明确不适用)、实际路径、每条命令/环境/退出状态、合同映射、双轴审查、E2E disposition、未运行项、失败分类、偏差、残余风险和父分支重读结果。
526
530
 
527
- Ticket Done 必须有 source commit、通过 candidate、父分支 result 与 Lead Evidence。无法运行 required 验证、存在未批准偏差、父分支未包含 source commit 或 Evidence 不完整时不得 Done。
531
+ required Ticket Done 必须有 source commit、通过 candidate、父分支 result 与 Lead Evidence;current Ticket Done 必须有 implementation commit、通过 direct-parent 验证、父分支 result 与 Lead Evidence。无法运行 required 验证、存在未批准偏差、父分支未包含 Ticket commit 或 Evidence 不完整时不得 Done。
528
532
 
529
533
  Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施前/最终 checkpoint、实际路径、定向/回归/E2E 命令及环境、验收映射、未运行项、偏差、残余风险和提交授权状态。
530
534
 
@@ -637,7 +641,7 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
637
641
 
638
642
  ```json
639
643
  {
640
- "schema_version": 4,
644
+ "schema_version": 5,
641
645
  "interaction_language": "zh-CN",
642
646
  "artifact_language": "zh-CN",
643
647
  "git": {
@@ -645,6 +649,7 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
645
649
  },
646
650
  "execution": {
647
651
  "max_implementation_agents": 3,
652
+ "max_integration_attempts": 3,
648
653
  "deep_ticket_human_approval": true,
649
654
  "shared_path_owner": "explicit"
650
655
  },
@@ -657,7 +662,9 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
657
662
  "planning": {
658
663
  "default_depth": "standard",
659
664
  "require_ready_gate": true,
660
- "require_evidence": true
665
+ "require_evidence": true,
666
+ "ui_prototype_default_variants": 3,
667
+ "ui_prototype_max_variants": 5
661
668
  }
662
669
  }
663
670
  ```
@@ -669,12 +676,12 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
669
676
  ```json
670
677
  {
671
678
  "$schema": "https://json-schema.org/draft/2020-12/schema",
672
- "$id": "urn:speculo:specdev:config:v4",
679
+ "$id": "urn:speculo:specdev:config:v5",
673
680
  "title": "SpecDev Configuration",
674
681
  "type": "object",
675
682
  "required": ["schema_version", "interaction_language", "artifact_language", "git", "execution", "verification", "planning"],
676
683
  "properties": {
677
- "schema_version": {"const": 4},
684
+ "schema_version": {"const": 5},
678
685
  "interaction_language": {"type": "string", "minLength": 1},
679
686
  "artifact_language": {"type": "string", "minLength": 1},
680
687
  "git": {
@@ -687,9 +694,10 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
687
694
  },
688
695
  "execution": {
689
696
  "type": "object",
690
- "required": ["max_implementation_agents", "deep_ticket_human_approval", "shared_path_owner"],
697
+ "required": ["max_implementation_agents", "max_integration_attempts", "deep_ticket_human_approval", "shared_path_owner"],
691
698
  "properties": {
692
- "max_implementation_agents": {"type": "integer", "minimum": 1, "maximum": 3},
699
+ "max_implementation_agents": {"type": "integer", "minimum": 1},
700
+ "max_integration_attempts": {"type": "integer", "minimum": 1},
693
701
  "deep_ticket_human_approval": {"type": "boolean"},
694
702
  "shared_path_owner": {"type": "string", "minLength": 1}
695
703
  },
@@ -708,15 +716,20 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
708
716
  },
709
717
  "planning": {
710
718
  "type": "object",
711
- "required": ["default_depth", "require_ready_gate", "require_evidence"],
719
+ "required": ["default_depth", "require_ready_gate", "require_evidence", "ui_prototype_default_variants", "ui_prototype_max_variants"],
712
720
  "properties": {
713
721
  "default_depth": {"enum": ["lite", "standard", "deep"]},
714
722
  "require_ready_gate": {"type": "boolean"},
715
- "require_evidence": {"type": "boolean"}
723
+ "require_evidence": {"type": "boolean"},
724
+ "ui_prototype_default_variants": {"type": "integer", "minimum": 1},
725
+ "ui_prototype_max_variants": {"type": "integer", "minimum": 1}
716
726
  },
717
727
  "additionalProperties": true
718
728
  }
719
729
  },
730
+ "allOf": [{
731
+ "$comment": "ui_prototype_default_variants <= ui_prototype_max_variants is enforced by validate-specdev.mjs because JSON Schema cannot compare sibling numeric values."
732
+ }],
720
733
  "additionalProperties": false
721
734
  }
722
735
  ```
@@ -782,7 +795,7 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
782
795
 
783
796
  ```json
784
797
  {
785
- "schema_version": 5,
798
+ "schema_version": 6,
786
799
  "artifact": "change-status",
787
800
  "change": "<YYYY-MM-DD-topic>",
788
801
  "change_status": "active",
@@ -790,8 +803,8 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
790
803
  "works_run": [],
791
804
  "claimed_investigations": [],
792
805
  "execution_authorization": {
793
- "implementation_commit": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Ticket source commits"},
794
- "local_candidate_integration": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Lead-owned local parent candidate integration and parent update"},
806
+ "implementation_commit": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Ticket implementation commits"},
807
+ "local_candidate_integration": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Lead-owned local direct-parent or candidate integration and parent update"},
795
808
  "source_cleanup": {"status": "not-authorized", "source": null, "granted_at": null, "scope": "Source worktree and branch cleanup"}
796
809
  },
797
810
  "leadership": {
@@ -818,7 +831,7 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
818
831
  ```json
819
832
  {
820
833
  "$schema": "https://json-schema.org/draft/2020-12/schema",
821
- "$id": "urn:speculo:specdev:change-status:v5",
834
+ "$id": "urn:speculo:specdev:change-status:v6",
822
835
  "title": "SpecDev Change Status",
823
836
  "type": "object",
824
837
  "required": [
@@ -827,7 +840,7 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
827
840
  "completed_at", "archived", "archive_path", "blockers", "deviations", "worktrees"
828
841
  ],
829
842
  "properties": {
830
- "schema_version": {"const": 5},
843
+ "schema_version": {"const": 6},
831
844
  "artifact": {"const": "change-status"},
832
845
  "change": {"type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*$"},
833
846
  "change_status": {"enum": ["active", "blocked", "completed", "archived"]},
@@ -931,12 +944,39 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
931
944
  "base_sha": {"type": "string", "minLength": 1},
932
945
  "parent_branch": {"type": "string", "minLength": 1},
933
946
  "branch": {"type": "string", "minLength": 1},
934
- "workspace_ref": {"type": "string", "pattern": "^specdev-worktree/[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*/T-[0-9]{2,}$"},
947
+ "workspace_ref": {"type": "string", "pattern": "^(?:current|specdev-worktree/[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*/T-[0-9]{2,})$"},
935
948
  "source_checkpoint": {"type": ["string", "null"]},
936
949
  "integration": {"$ref": "#/$defs/integration"},
937
950
  "status": {"enum": ["planned", "active", "review", "integrating", "integrated", "removed", "blocked"]},
938
951
  "updated_at": {"type": "string", "minLength": 1}
939
952
  },
953
+ "allOf": [
954
+ {
955
+ "if": {"properties": {"workspace_ref": {"const": "current"}}, "required": ["workspace_ref"]},
956
+ "then": {
957
+ "properties": {
958
+ "integration": {
959
+ "allOf": [{
960
+ "properties": {
961
+ "candidate_sha": {"const": null},
962
+ "candidate_tree_sha": {"const": null},
963
+ "candidate_branch": {"const": null},
964
+ "candidate_workspace_ref": {"const": null},
965
+ "method": {"enum": [null, "direct-parent"]}
966
+ }
967
+ }]
968
+ }
969
+ }
970
+ },
971
+ "else": {
972
+ "properties": {
973
+ "integration": {
974
+ "allOf": [{"properties": {"method": {"enum": [null, "fast-forward", "merge-commit"]}}}]
975
+ }
976
+ }
977
+ }
978
+ }
979
+ ],
940
980
  "additionalProperties": false
941
981
  },
942
982
  "integration": {
@@ -952,7 +992,7 @@ Direct Spec Evidence 至少包含:用户批准与轻量合同、Lead、实施
952
992
  "candidate_branch": {"type": ["string", "null"]},
953
993
  "candidate_workspace_ref": {"anyOf": [{"type": "null"}, {"type": "string", "pattern": "^specdev-worktree/\\.integration/[0-9]{4}-[0-9]{2}-[0-9]{2}-[a-z0-9]+(?:-[a-z0-9]+)*/T-[0-9]{2,}$"}]},
954
994
  "result_sha": {"type": ["string", "null"]},
955
- "method": {"enum": [null, "fast-forward", "merge-commit"]},
995
+ "method": {"enum": [null, "direct-parent", "fast-forward", "merge-commit"]},
956
996
  "conflict_paths": {"type": "array", "items": {"type": "string"}},
957
997
  "verification": {"enum": ["pending", "passed", "failed"]},
958
998
  "full_suite": {"$ref": "#/$defs/full-suite"},