Browse Source

chore(trellis): 框架升级 0.5.19 → 0.6.5

- channel worker OOM guard 配置(idle_timeout / max_live_workers)
- 新增 check/implement agent 模板
- scripts 与 workflow.md 同步更新

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
lingfengQAQ 2 days ago
parent
commit
d964469c12

+ 147 - 17
.trellis/.template-hashes.json

@@ -1,10 +1,10 @@
 {
 {
   "__version": 2,
   "__version": 2,
   "hashes": {
   "hashes": {
-    ".trellis/config.yaml": "5c9207418cecc390e9d86d589b4183b831f76697d92fb42fefd5221cd8772e51",
-    ".trellis/scripts/add_session.py": "f26b66a539d160c739d4b88fd926b3d7f6745be326cd57131e5ef17a7b011fbe",
-    ".trellis/scripts/common/active_task.py": "6c88ed40ef7289bca0f6d2ecba0f8b8aef46cd58788080fbeeea88de138a431f",
-    ".trellis/scripts/common/cli_adapter.py": "cd844d1e84b1a09b373b3a7609e4d5606ee9d4825154c002cc9bb3f54c8e2fb9",
+    ".trellis/config.yaml": "3e295bf4310763240647f40b3aeee7a7c6d134142cdc826e02d850ca2407fc43",
+    ".trellis/scripts/add_session.py": "4cc762558532469b59ca43b9ed7fc1232ec6a84ca0c761030f70a693cf075bf6",
+    ".trellis/scripts/common/active_task.py": "8ac10263a88262aeaec2c600b33f3761f99d80c305718609a3bef97a2ff08938",
+    ".trellis/scripts/common/cli_adapter.py": "e7586505462c5449654a8fad70a50360a37a8aefa1efedfa06195bf80e9d1dae",
     ".trellis/scripts/common/config.py": "25c5a53ad20d6909be5209222e4208a84528805316a4d78350529459a364edb1",
     ".trellis/scripts/common/config.py": "25c5a53ad20d6909be5209222e4208a84528805316a4d78350529459a364edb1",
     ".trellis/scripts/common/developer.py": "b2141b0145a41f8cedb4f9a24c925796edb2f0f6fde7c86b559513ec30499368",
     ".trellis/scripts/common/developer.py": "b2141b0145a41f8cedb4f9a24c925796edb2f0f6fde7c86b559513ec30499368",
     ".trellis/scripts/common/git.py": "e14817be7de122d3a106f509c2825aeb9669d962ba73ba241642d2931cfdf1d6",
     ".trellis/scripts/common/git.py": "e14817be7de122d3a106f509c2825aeb9669d962ba73ba241642d2931cfdf1d6",
@@ -13,30 +13,160 @@
     ".trellis/scripts/common/log.py": "471df6895cfac80f995edebbf9974f6b7440634b7a688f28b8331c868bc0f3cf",
     ".trellis/scripts/common/log.py": "471df6895cfac80f995edebbf9974f6b7440634b7a688f28b8331c868bc0f3cf",
     ".trellis/scripts/common/packages_context.py": "efe158d7c99c2268851d0216fbb08de22836e418a8dbeb73575b8cc249eed7b7",
     ".trellis/scripts/common/packages_context.py": "efe158d7c99c2268851d0216fbb08de22836e418a8dbeb73575b8cc249eed7b7",
     ".trellis/scripts/common/paths.py": "05898ef136cc7c4d861b05fbf2b16d53ddd3e6f311a231d4fcfcb81bde7c45ee",
     ".trellis/scripts/common/paths.py": "05898ef136cc7c4d861b05fbf2b16d53ddd3e6f311a231d4fcfcb81bde7c45ee",
-    ".trellis/scripts/common/safe_commit.py": "8789bff4b30a9065469210f2efab3f59f03dddd77bef4e4b6a5bb641f93539f4",
-    ".trellis/scripts/common/session_context.py": "d669b96fd7a608808695b9e82e9bfd1693a9ae98ade03cc8dce6c24487696793",
+    ".trellis/scripts/common/safe_commit.py": "baa5c82324eb62154374ec63394ecdc8609bb37d93892e3bcb88f452bb7d6446",
+    ".trellis/scripts/common/session_context.py": "11e336b77a42e8ae080ebcea3fe45938eb8b0d1d279e968eededa57de6006db8",
     ".trellis/scripts/common/tasks.py": "4436a8b0b53c270a35989e26d9dbd92669408c6562d88c02083a404562da85fe",
     ".trellis/scripts/common/tasks.py": "4436a8b0b53c270a35989e26d9dbd92669408c6562d88c02083a404562da85fe",
-    ".trellis/scripts/common/task_context.py": "1c16a7fa82d363010d0d0ebdc038296ae1552bf6e90214787d707f49567bc159",
+    ".trellis/scripts/common/task_context.py": "d174684d417bbe2fafc26b6afcddb264c7dc519527bb24d2055cd27daaad9b55",
     ".trellis/scripts/common/task_queue.py": "0be61f713462b1fe4574927c82fc4704e678afe72dcb9813543aedf2f9e9e0c5",
     ".trellis/scripts/common/task_queue.py": "0be61f713462b1fe4574927c82fc4704e678afe72dcb9813543aedf2f9e9e0c5",
-    ".trellis/scripts/common/task_store.py": "4a6ad7f15fd6fdca0da174804ee2d750919d42e46066a891c7525aa8d8a2c592",
+    ".trellis/scripts/common/task_store.py": "47ee27ef2d840a9f4d40c49fd6656ee9e5fa0c333c9986ca33b7d754d66007c7",
     ".trellis/scripts/common/task_utils.py": "f5ef4af87ba3e11d8b19630c0c96d009de1811fc9be56c2027a9c96e21ed103e",
     ".trellis/scripts/common/task_utils.py": "f5ef4af87ba3e11d8b19630c0c96d009de1811fc9be56c2027a9c96e21ed103e",
     ".trellis/scripts/common/trellis_config.py": "0839dcf90ebbd77712c276930a89335b3313927051650c91d220fb51ca2a6a3c",
     ".trellis/scripts/common/trellis_config.py": "0839dcf90ebbd77712c276930a89335b3313927051650c91d220fb51ca2a6a3c",
     ".trellis/scripts/common/types.py": "9962081cc2608fb9d1deb32c6880e336f62cdca6b338e7ae813304701e155ee9",
     ".trellis/scripts/common/types.py": "9962081cc2608fb9d1deb32c6880e336f62cdca6b338e7ae813304701e155ee9",
-    ".trellis/scripts/common/workflow_phase.py": "2b260f4a7770e9c3223129836716bd8e2c0f0568acd682224a57415bc1dc726b",
+    ".trellis/scripts/common/workflow_phase.py": "f2b5fcf0c40cedcf3d7d0ad8023d141fa4095caf0302d73f2a73e1bc04b5692b",
     ".trellis/scripts/common/__init__.py": "3d5e9347141f0296319a5beb29d69ae714c5a474b9078caeb3edd7c5f6562e22",
     ".trellis/scripts/common/__init__.py": "3d5e9347141f0296319a5beb29d69ae714c5a474b9078caeb3edd7c5f6562e22",
     ".trellis/scripts/get_context.py": "af3ea7cd563a453227cf2cb4ab04d667390046b7febfac2217348d0892781f4b",
     ".trellis/scripts/get_context.py": "af3ea7cd563a453227cf2cb4ab04d667390046b7febfac2217348d0892781f4b",
     ".trellis/scripts/get_developer.py": "84c27076323c3e0f2c9c8ed16e8aa865e225d902a187c37e20ee1a46e7142d8f",
     ".trellis/scripts/get_developer.py": "84c27076323c3e0f2c9c8ed16e8aa865e225d902a187c37e20ee1a46e7142d8f",
     ".trellis/scripts/hooks/linear_sync.py": "cfc270b7ff775caa5b2434823c45414a3b37f9ba2aa1e293a26daef9fd2e577a",
     ".trellis/scripts/hooks/linear_sync.py": "cfc270b7ff775caa5b2434823c45414a3b37f9ba2aa1e293a26daef9fd2e577a",
     ".trellis/scripts/init_developer.py": "0943f1c240993649ab89b91a2c5b379e84daa8c53b35f0490774bff05a552873",
     ".trellis/scripts/init_developer.py": "0943f1c240993649ab89b91a2c5b379e84daa8c53b35f0490774bff05a552873",
-    ".trellis/scripts/task.py": "e2614fbfc1308c90c0708a11475ca6684ea0a1e2a845140300192229589a2f1f",
+    ".trellis/scripts/task.py": "b3a43f6ef149ec8f5a288be53fe7be0a94955b78872ad7f77d0db4a1aecfa87b",
     ".trellis/scripts/__init__.py": "1242be5b972094c2e141aecbe81a4efd478f6534e3d5e28306374e6a18fcf46c",
     ".trellis/scripts/__init__.py": "1242be5b972094c2e141aecbe81a4efd478f6534e3d5e28306374e6a18fcf46c",
-    ".trellis/workflow.md": "94810f640dcfe6fdaebcf6e9d0d6cec554610192c4f953b288029570ba8bc89d",
+    ".trellis/workflow.md": "ba0e5b715896d8b87c6fd1ba0583c352b09c866d0d07a5441c198d625a1b8f6d",
     "AGENTS.md": "6cacfe99748b435d0660c2463c697bc323d53798aecf3492283ca8eac1b29682",
     "AGENTS.md": "6cacfe99748b435d0660c2463c697bc323d53798aecf3492283ca8eac1b29682",
-    ".claude/skills/trellis-spec-bootstarp/references/mcp-setup.md": "df542fc8f279edd38046d26a7c8151804b708f57b24d4aa2733cea587a88c65e",
-    ".claude/skills/trellis-spec-bootstarp/references/repository-analysis.md": "0dae98d774f6e34559b9f3442888ac43e3a8af110c37cbefc49ce256986858b6",
-    ".claude/skills/trellis-spec-bootstarp/references/spec-task-planning.md": "ef493d028c3b0807a8a534bb71fb92a68129f273db763ad27ceb464a522e799d",
-    ".claude/skills/trellis-spec-bootstarp/references/spec-writing.md": "e9800fe9ed4a4cd87062ea1829cf2caa8d170ec15e141678a6a30e74c497f47d",
-    ".claude/skills/trellis-spec-bootstarp/SKILL.md": "81f400092b21392161e7d9dfa9111c9be36c81bc8641d252ed28e08373449ac0",
-    ".trellis/.gitignore": "3bc42434cbe61c937a1c26ea3c880b496bfad4e7d683750169e27ade509aa798"
+    ".trellis/.gitignore": "3bc42434cbe61c937a1c26ea3c880b496bfad4e7d683750169e27ade509aa798",
+    ".trellis/agents/implement.md": "66e25ad046c94869442834bc3cdfbd5a9a7412d3ff54561d64d2886552c27e87",
+    ".trellis/agents/check.md": "edb4f57361407249a53bf5998ebf91c40d2b969e826a2c5e1b4e813a08bcb175",
+    ".claude/skills/trellis-channel/references/command-reference.md": "c4df3d940d89814310bfdaded20e84dd1d6b96786f6772688de7a123338d3c8e",
+    ".claude/skills/trellis-channel/references/forum.md": "407db39e8ebde47cea8637e3069bdb3d76ba42b43ed1d08ba97a56f26dbcfcb4",
+    ".claude/skills/trellis-channel/references/progress-debugging.md": "fe59afd4c0a558cbefc49cc5ef8a7e0e3916d6718cb3255dc6da1b698c850ff7",
+    ".claude/skills/trellis-channel/references/workers.md": "d4481b2858bca82050cb8d131916da8a2ccc3857f199cdb9ced8bb41d592e2a7",
+    ".claude/skills/trellis-channel/references/workflows.md": "0782d602efde6e94a7d7d7950fd605eedc9a1f5a523908284e76b628fd618fd4",
+    ".claude/skills/trellis-channel/SKILL.md": "ff84801c511a736da018b4b1149348ebc9a16b7fc18d905ec10cfa7acbf269a3",
+    ".claude/skills/trellis-meta/references/local-architecture/bundled-skills.md": "bac739b042d7a12dae5d14d85cbc312e56ca03f571d2ba7a25b20641ddaefc3f",
+    ".claude/skills/trellis-meta/references/local-architecture/multi-agent-channel.md": "56e5070474aeca872e2d70c46feea5aaafecd3d3ec052c3f7b1877358dca62e9",
+    ".claude/skills/trellis-session-insight/references/cli-quick-reference.md": "c520353fe3fc00b9702ed4f780647c8fbd6d342e66527a03647f533a9fe09779",
+    ".claude/skills/trellis-session-insight/references/triggering-patterns.md": "121ecd23be83d1567e8ce15c366a81073d7a2b1d3ad616fce235c07ca1f1cc20",
+    ".claude/skills/trellis-session-insight/SKILL.md": "f6ad80eaca21b8fa63d31ae26b612bb2bb69dd04469603828509a8c5a0463ff1",
+    ".claude/skills/trellis-spec-bootstrap/references/mcp-setup.md": "df542fc8f279edd38046d26a7c8151804b708f57b24d4aa2733cea587a88c65e",
+    ".claude/skills/trellis-spec-bootstrap/references/repository-analysis.md": "0dae98d774f6e34559b9f3442888ac43e3a8af110c37cbefc49ce256986858b6",
+    ".claude/skills/trellis-spec-bootstrap/references/spec-task-planning.md": "ef493d028c3b0807a8a534bb71fb92a68129f273db763ad27ceb464a522e799d",
+    ".claude/skills/trellis-spec-bootstrap/references/spec-writing.md": "e9800fe9ed4a4cd87062ea1829cf2caa8d170ec15e141678a6a30e74c497f47d",
+    ".claude/skills/trellis-spec-bootstrap/SKILL.md": "97bfa68c06cebb558eb4464bc1b81f7d2d56040d75baa8de1ee5ad90cca0196a",
+    ".cursor/skills/trellis-channel/references/command-reference.md": "c4df3d940d89814310bfdaded20e84dd1d6b96786f6772688de7a123338d3c8e",
+    ".cursor/skills/trellis-channel/references/forum.md": "407db39e8ebde47cea8637e3069bdb3d76ba42b43ed1d08ba97a56f26dbcfcb4",
+    ".cursor/skills/trellis-channel/references/progress-debugging.md": "fe59afd4c0a558cbefc49cc5ef8a7e0e3916d6718cb3255dc6da1b698c850ff7",
+    ".cursor/skills/trellis-channel/references/workers.md": "d4481b2858bca82050cb8d131916da8a2ccc3857f199cdb9ced8bb41d592e2a7",
+    ".cursor/skills/trellis-channel/references/workflows.md": "0782d602efde6e94a7d7d7950fd605eedc9a1f5a523908284e76b628fd618fd4",
+    ".cursor/skills/trellis-channel/SKILL.md": "ff84801c511a736da018b4b1149348ebc9a16b7fc18d905ec10cfa7acbf269a3",
+    ".cursor/skills/trellis-meta/references/local-architecture/bundled-skills.md": "bac739b042d7a12dae5d14d85cbc312e56ca03f571d2ba7a25b20641ddaefc3f",
+    ".cursor/skills/trellis-meta/references/local-architecture/multi-agent-channel.md": "56e5070474aeca872e2d70c46feea5aaafecd3d3ec052c3f7b1877358dca62e9",
+    ".cursor/skills/trellis-session-insight/references/cli-quick-reference.md": "c520353fe3fc00b9702ed4f780647c8fbd6d342e66527a03647f533a9fe09779",
+    ".cursor/skills/trellis-session-insight/references/triggering-patterns.md": "121ecd23be83d1567e8ce15c366a81073d7a2b1d3ad616fce235c07ca1f1cc20",
+    ".cursor/skills/trellis-session-insight/SKILL.md": "f6ad80eaca21b8fa63d31ae26b612bb2bb69dd04469603828509a8c5a0463ff1",
+    ".cursor/skills/trellis-spec-bootstrap/references/mcp-setup.md": "df542fc8f279edd38046d26a7c8151804b708f57b24d4aa2733cea587a88c65e",
+    ".cursor/skills/trellis-spec-bootstrap/references/repository-analysis.md": "0dae98d774f6e34559b9f3442888ac43e3a8af110c37cbefc49ce256986858b6",
+    ".cursor/skills/trellis-spec-bootstrap/references/spec-task-planning.md": "ef493d028c3b0807a8a534bb71fb92a68129f273db763ad27ceb464a522e799d",
+    ".cursor/skills/trellis-spec-bootstrap/references/spec-writing.md": "e9800fe9ed4a4cd87062ea1829cf2caa8d170ec15e141678a6a30e74c497f47d",
+    ".cursor/skills/trellis-spec-bootstrap/SKILL.md": "97bfa68c06cebb558eb4464bc1b81f7d2d56040d75baa8de1ee5ad90cca0196a",
+    ".agents/skills/trellis-channel/references/command-reference.md": "c4df3d940d89814310bfdaded20e84dd1d6b96786f6772688de7a123338d3c8e",
+    ".agents/skills/trellis-channel/references/forum.md": "407db39e8ebde47cea8637e3069bdb3d76ba42b43ed1d08ba97a56f26dbcfcb4",
+    ".agents/skills/trellis-channel/references/progress-debugging.md": "fe59afd4c0a558cbefc49cc5ef8a7e0e3916d6718cb3255dc6da1b698c850ff7",
+    ".agents/skills/trellis-channel/references/workers.md": "d4481b2858bca82050cb8d131916da8a2ccc3857f199cdb9ced8bb41d592e2a7",
+    ".agents/skills/trellis-channel/references/workflows.md": "0782d602efde6e94a7d7d7950fd605eedc9a1f5a523908284e76b628fd618fd4",
+    ".agents/skills/trellis-channel/SKILL.md": "ff84801c511a736da018b4b1149348ebc9a16b7fc18d905ec10cfa7acbf269a3",
+    ".agents/skills/trellis-meta/references/local-architecture/bundled-skills.md": "bac739b042d7a12dae5d14d85cbc312e56ca03f571d2ba7a25b20641ddaefc3f",
+    ".agents/skills/trellis-meta/references/local-architecture/multi-agent-channel.md": "56e5070474aeca872e2d70c46feea5aaafecd3d3ec052c3f7b1877358dca62e9",
+    ".agents/skills/trellis-session-insight/references/cli-quick-reference.md": "c520353fe3fc00b9702ed4f780647c8fbd6d342e66527a03647f533a9fe09779",
+    ".agents/skills/trellis-session-insight/references/triggering-patterns.md": "121ecd23be83d1567e8ce15c366a81073d7a2b1d3ad616fce235c07ca1f1cc20",
+    ".agents/skills/trellis-session-insight/SKILL.md": "f6ad80eaca21b8fa63d31ae26b612bb2bb69dd04469603828509a8c5a0463ff1",
+    ".agents/skills/trellis-spec-bootstrap/references/mcp-setup.md": "df542fc8f279edd38046d26a7c8151804b708f57b24d4aa2733cea587a88c65e",
+    ".agents/skills/trellis-spec-bootstrap/references/repository-analysis.md": "0dae98d774f6e34559b9f3442888ac43e3a8af110c37cbefc49ce256986858b6",
+    ".agents/skills/trellis-spec-bootstrap/references/spec-task-planning.md": "ef493d028c3b0807a8a534bb71fb92a68129f273db763ad27ceb464a522e799d",
+    ".agents/skills/trellis-spec-bootstrap/references/spec-writing.md": "e9800fe9ed4a4cd87062ea1829cf2caa8d170ec15e141678a6a30e74c497f47d",
+    ".agents/skills/trellis-spec-bootstrap/SKILL.md": "97bfa68c06cebb558eb4464bc1b81f7d2d56040d75baa8de1ee5ad90cca0196a",
+    ".claude/commands/trellis/continue.md": "eade769e466179010d6a044b03fb57620b4f5eb142fa11a55afec781e2bfec05",
+    ".claude/skills/trellis-before-dev/SKILL.md": "8f897d8dd76c1eeb532cf15ba784360f45a93229f8dcd0acfc14282f014f92a0",
+    ".claude/skills/trellis-brainstorm/SKILL.md": "b3b33b61ec46c12293a021e7c6c746c9e4fba2844ee880e5e91370d35057ee6d",
+    ".claude/skills/trellis-break-loop/SKILL.md": "f5a93699832f29dee443b53c135a7459519b371f689af191d15c29e8ee5c7bde",
+    ".claude/skills/trellis-check/SKILL.md": "2be18b6665b4da497c554acd5d76ef038cc960d25f3d4216f03e047202f2eadc",
+    ".claude/skills/trellis-meta/references/customize-local/change-agents.md": "3eef0d9b9cf875f121c1a38afb8eee6d3cd3894127db601ae5a7760fa5b61575",
+    ".claude/skills/trellis-meta/references/customize-local/change-context-loading.md": "e6aa7d938741c08b864f54e9bda8e4e68e04bc60cb46682f6acabaf37f9b2da2",
+    ".claude/skills/trellis-meta/references/customize-local/change-hooks.md": "b3b1ed51cfa436a98fad8dda3ec75d997bd8f8cabbad04f101fd9e3d0e1a9e35",
+    ".claude/skills/trellis-meta/references/customize-local/change-skills-or-commands.md": "a6994e2418cdf5bcad10b4236b02741179ae794bc4fdd811a64f443293b69268",
+    ".claude/skills/trellis-meta/references/customize-local/change-spec-structure.md": "1a712408217ee9cc6a916d874e3d6ed1ba7a3bdc1b9dc4bb1c64393f0df1eb98",
+    ".claude/skills/trellis-meta/references/customize-local/change-workflow.md": "43fa780a2ca580de121b10893d49b99f978873deebbf45008c466e5ac6651519",
+    ".claude/skills/trellis-meta/references/customize-local/overview.md": "a0e4cbc3fcc521c0c0f481ade796d31d19c2a5ba697d93856c890fbcc6171d71",
+    ".claude/skills/trellis-meta/references/local-architecture/context-injection.md": "8497289bf333b3aa456f317039d1239b7ece79254aa0eb62cfc647714c866084",
+    ".claude/skills/trellis-meta/references/local-architecture/generated-files.md": "1128d45b2e8c011c247bcf3a3ca1184ca4951fb34a0802c50bf3fecbd7e4de55",
+    ".claude/skills/trellis-meta/references/local-architecture/overview.md": "50638fd9eaaba2e0edf2f2a84d920578d5b2fb7934031b174e417d3dc510b2a6",
+    ".claude/skills/trellis-meta/references/local-architecture/spec-system.md": "55f3c95033a3cbed6c06e225187071502d7dcf3f153f4becbec6aa79acc782f5",
+    ".claude/skills/trellis-meta/references/local-architecture/task-system.md": "25dbd2be6a2271591274b56616b853b16e6fd9f44f43073350688e89e87295a6",
+    ".claude/skills/trellis-meta/references/platform-files/agents.md": "dedea76cd3ff3221a0abd121093ddd32ed8815bb08ca63d20c32feb29ca76aa7",
+    ".claude/skills/trellis-meta/references/platform-files/hooks-and-settings.md": "acdeba5866ccbe0e68fffc847e77e726cf79f579898e61312f6a8d62b48380ff",
+    ".claude/skills/trellis-meta/references/platform-files/overview.md": "821a2718b38e17439c2bb487a6dd3a95c8138e83dbda60b142a00ff80178dc3c",
+    ".claude/skills/trellis-meta/references/platform-files/platform-map.md": "59e13cdaa2077149b5d82ad25fa5dd821195be30bdc43d853619c4702d334a6e",
+    ".claude/skills/trellis-meta/references/platform-files/skills-and-commands.md": "5732bb0a7d384a91abd0c103372f3865e0b186e75185f35e0e91b00a6b6bf5a3",
+    ".claude/skills/trellis-meta/SKILL.md": "a190ecbde70a658a5b5c3e2558783e99c9afc6f2e5cdecdac8f11c06dd42065e",
+    ".claude/agents/trellis-check.md": "9e48342243f311d55386f8fb42933945e87aba73d5ade547133aa98345a06128",
+    ".claude/agents/trellis-implement.md": "73b56b3047c0e852382c4630aa181fb847d1e5ea1f63459dac4bf728f43fd097",
+    ".claude/agents/trellis-research.md": "10aecdd3d0777746a516e23cd2a55c9e9c8a015dc98c63ffbac36be21b7a7bb0",
+    ".claude/hooks/inject-subagent-context.py": "4e7889074f93d668c6a312a7e9ddc65c8c619b17c2454bf72e5c563371c6bb98",
+    ".claude/hooks/inject-workflow-state.py": "552d4ee4ca059337856c587fde1aaf79364444d0465689faa88c43797969b7de",
+    ".claude/hooks/session-start.py": "03872a78cca107a932edde5ffffe52e4c7dd78e6b69ddc4408c9a0cd0e4fe9fc",
+    ".cursor/commands/trellis-continue.md": "a5486b17636b440bbb7d630479eb7fdb064acc07e8effd10b69dd9a2c9a86371",
+    ".cursor/skills/trellis-before-dev/SKILL.md": "8f897d8dd76c1eeb532cf15ba784360f45a93229f8dcd0acfc14282f014f92a0",
+    ".cursor/skills/trellis-brainstorm/SKILL.md": "b3b33b61ec46c12293a021e7c6c746c9e4fba2844ee880e5e91370d35057ee6d",
+    ".cursor/skills/trellis-break-loop/SKILL.md": "f5a93699832f29dee443b53c135a7459519b371f689af191d15c29e8ee5c7bde",
+    ".cursor/skills/trellis-check/SKILL.md": "2be18b6665b4da497c554acd5d76ef038cc960d25f3d4216f03e047202f2eadc",
+    ".cursor/skills/trellis-meta/references/customize-local/change-agents.md": "3eef0d9b9cf875f121c1a38afb8eee6d3cd3894127db601ae5a7760fa5b61575",
+    ".cursor/skills/trellis-meta/references/customize-local/change-context-loading.md": "e6aa7d938741c08b864f54e9bda8e4e68e04bc60cb46682f6acabaf37f9b2da2",
+    ".cursor/skills/trellis-meta/references/customize-local/change-hooks.md": "b3b1ed51cfa436a98fad8dda3ec75d997bd8f8cabbad04f101fd9e3d0e1a9e35",
+    ".cursor/skills/trellis-meta/references/customize-local/change-skills-or-commands.md": "a6994e2418cdf5bcad10b4236b02741179ae794bc4fdd811a64f443293b69268",
+    ".cursor/skills/trellis-meta/references/customize-local/change-spec-structure.md": "1a712408217ee9cc6a916d874e3d6ed1ba7a3bdc1b9dc4bb1c64393f0df1eb98",
+    ".cursor/skills/trellis-meta/references/customize-local/change-workflow.md": "43fa780a2ca580de121b10893d49b99f978873deebbf45008c466e5ac6651519",
+    ".cursor/skills/trellis-meta/references/customize-local/overview.md": "a0e4cbc3fcc521c0c0f481ade796d31d19c2a5ba697d93856c890fbcc6171d71",
+    ".cursor/skills/trellis-meta/references/local-architecture/context-injection.md": "8497289bf333b3aa456f317039d1239b7ece79254aa0eb62cfc647714c866084",
+    ".cursor/skills/trellis-meta/references/local-architecture/generated-files.md": "1128d45b2e8c011c247bcf3a3ca1184ca4951fb34a0802c50bf3fecbd7e4de55",
+    ".cursor/skills/trellis-meta/references/local-architecture/overview.md": "50638fd9eaaba2e0edf2f2a84d920578d5b2fb7934031b174e417d3dc510b2a6",
+    ".cursor/skills/trellis-meta/references/local-architecture/spec-system.md": "55f3c95033a3cbed6c06e225187071502d7dcf3f153f4becbec6aa79acc782f5",
+    ".cursor/skills/trellis-meta/references/local-architecture/task-system.md": "25dbd2be6a2271591274b56616b853b16e6fd9f44f43073350688e89e87295a6",
+    ".cursor/skills/trellis-meta/references/platform-files/agents.md": "dedea76cd3ff3221a0abd121093ddd32ed8815bb08ca63d20c32feb29ca76aa7",
+    ".cursor/skills/trellis-meta/references/platform-files/hooks-and-settings.md": "acdeba5866ccbe0e68fffc847e77e726cf79f579898e61312f6a8d62b48380ff",
+    ".cursor/skills/trellis-meta/references/platform-files/overview.md": "821a2718b38e17439c2bb487a6dd3a95c8138e83dbda60b142a00ff80178dc3c",
+    ".cursor/skills/trellis-meta/references/platform-files/platform-map.md": "59e13cdaa2077149b5d82ad25fa5dd821195be30bdc43d853619c4702d334a6e",
+    ".cursor/skills/trellis-meta/references/platform-files/skills-and-commands.md": "5732bb0a7d384a91abd0c103372f3865e0b186e75185f35e0e91b00a6b6bf5a3",
+    ".cursor/skills/trellis-meta/SKILL.md": "a190ecbde70a658a5b5c3e2558783e99c9afc6f2e5cdecdac8f11c06dd42065e",
+    ".cursor/agents/trellis-check.md": "e54d3de996bab4abd7653eef4d64c171638fbc2859e9b1fe4aae2483df72de99",
+    ".cursor/agents/trellis-implement.md": "636d55ebb56d9d3ea6ef9ec615c53bcaeab2b1afb3dc7e30ad51091efe5ab5ea",
+    ".cursor/agents/trellis-research.md": "e39b18734b4947ada2d1d6b2432f82daf58d16b6d98aa5b8b78e4a5364559617",
+    ".cursor/hooks/inject-subagent-context.py": "4e7889074f93d668c6a312a7e9ddc65c8c619b17c2454bf72e5c563371c6bb98",
+    ".cursor/hooks/session-start.py": "03872a78cca107a932edde5ffffe52e4c7dd78e6b69ddc4408c9a0cd0e4fe9fc",
+    ".agents/skills/trellis-continue/SKILL.md": "6ee22b56c363c4c3b4e6511d4d1b97d5d123bcb43bbcffa231265749631d4297",
+    ".agents/skills/trellis-start/SKILL.md": "ddcb643c43e967dc7e435cb815c9eb00ddab8913190d837d8b9504424f47a81a",
+    ".agents/skills/trellis-before-dev/SKILL.md": "8f897d8dd76c1eeb532cf15ba784360f45a93229f8dcd0acfc14282f014f92a0",
+    ".agents/skills/trellis-brainstorm/SKILL.md": "b3b33b61ec46c12293a021e7c6c746c9e4fba2844ee880e5e91370d35057ee6d",
+    ".agents/skills/trellis-break-loop/SKILL.md": "f5a93699832f29dee443b53c135a7459519b371f689af191d15c29e8ee5c7bde",
+    ".agents/skills/trellis-check/SKILL.md": "2be18b6665b4da497c554acd5d76ef038cc960d25f3d4216f03e047202f2eadc",
+    ".agents/skills/trellis-meta/references/customize-local/change-agents.md": "3eef0d9b9cf875f121c1a38afb8eee6d3cd3894127db601ae5a7760fa5b61575",
+    ".agents/skills/trellis-meta/references/customize-local/change-context-loading.md": "e6aa7d938741c08b864f54e9bda8e4e68e04bc60cb46682f6acabaf37f9b2da2",
+    ".agents/skills/trellis-meta/references/customize-local/change-hooks.md": "b3b1ed51cfa436a98fad8dda3ec75d997bd8f8cabbad04f101fd9e3d0e1a9e35",
+    ".agents/skills/trellis-meta/references/customize-local/change-skills-or-commands.md": "a6994e2418cdf5bcad10b4236b02741179ae794bc4fdd811a64f443293b69268",
+    ".agents/skills/trellis-meta/references/customize-local/change-spec-structure.md": "1a712408217ee9cc6a916d874e3d6ed1ba7a3bdc1b9dc4bb1c64393f0df1eb98",
+    ".agents/skills/trellis-meta/references/customize-local/change-workflow.md": "43fa780a2ca580de121b10893d49b99f978873deebbf45008c466e5ac6651519",
+    ".agents/skills/trellis-meta/references/customize-local/overview.md": "a0e4cbc3fcc521c0c0f481ade796d31d19c2a5ba697d93856c890fbcc6171d71",
+    ".agents/skills/trellis-meta/references/local-architecture/context-injection.md": "8497289bf333b3aa456f317039d1239b7ece79254aa0eb62cfc647714c866084",
+    ".agents/skills/trellis-meta/references/local-architecture/generated-files.md": "1128d45b2e8c011c247bcf3a3ca1184ca4951fb34a0802c50bf3fecbd7e4de55",
+    ".agents/skills/trellis-meta/references/local-architecture/overview.md": "50638fd9eaaba2e0edf2f2a84d920578d5b2fb7934031b174e417d3dc510b2a6",
+    ".agents/skills/trellis-meta/references/local-architecture/spec-system.md": "55f3c95033a3cbed6c06e225187071502d7dcf3f153f4becbec6aa79acc782f5",
+    ".agents/skills/trellis-meta/references/local-architecture/task-system.md": "25dbd2be6a2271591274b56616b853b16e6fd9f44f43073350688e89e87295a6",
+    ".agents/skills/trellis-meta/references/platform-files/agents.md": "dedea76cd3ff3221a0abd121093ddd32ed8815bb08ca63d20c32feb29ca76aa7",
+    ".agents/skills/trellis-meta/references/platform-files/hooks-and-settings.md": "acdeba5866ccbe0e68fffc847e77e726cf79f579898e61312f6a8d62b48380ff",
+    ".agents/skills/trellis-meta/references/platform-files/overview.md": "821a2718b38e17439c2bb487a6dd3a95c8138e83dbda60b142a00ff80178dc3c",
+    ".agents/skills/trellis-meta/references/platform-files/platform-map.md": "59e13cdaa2077149b5d82ad25fa5dd821195be30bdc43d853619c4702d334a6e",
+    ".agents/skills/trellis-meta/references/platform-files/skills-and-commands.md": "5732bb0a7d384a91abd0c103372f3865e0b186e75185f35e0e91b00a6b6bf5a3",
+    ".agents/skills/trellis-meta/SKILL.md": "a190ecbde70a658a5b5c3e2558783e99c9afc6f2e5cdecdac8f11c06dd42065e",
+    ".codex/agents/trellis-check.toml": "a64bf083a35146c9b0074b98d20efcdfa9dc448f1696677bab12ea390354c1b0",
+    ".codex/agents/trellis-implement.toml": "719b3c332d9bec179be5cbd2728994d1add7dbfc9585944df04e58a3f434fbc5",
+    ".codex/hooks/session-start.py": "a1f2de75eb17eb419ece4854d78f1d2255e0e732e672ec8fbfb439b71a09bf11",
+    ".codex/hooks/inject-workflow-state.py": "552d4ee4ca059337856c587fde1aaf79364444d0465689faa88c43797969b7de"
   }
   }
 }
 }

+ 1 - 1
.trellis/.version

@@ -1 +1 @@
-0.5.19
+0.6.5

+ 70 - 0
.trellis/agents/check.md

@@ -0,0 +1,70 @@
+---
+name: check
+description: |
+  Code quality auditor for the Trellis channel runtime. Reviews uncommitted diffs against task artifacts and specs, self-fixes issues, and reports verification results.
+provider: claude
+labels: [trellis, check]
+---
+
+# Check Agent (channel runtime)
+
+You are the Check Agent spawned by `trellis channel spawn --agent check` inside the Trellis channel runtime. You receive an `Active task: <path>` line in your inbox; use it to locate task artifacts on disk.
+
+## Context
+
+Before reviewing, read in this order:
+
+1. `<task-path>/check.jsonl` if present — spec manifest curated for this turn; read every listed file
+2. `<task-path>/prd.md` — requirements
+3. `<task-path>/design.md` if present — technical design
+4. `<task-path>/implement.md` if present — execution plan
+5. `.trellis/spec/` — project-wide guidelines (load only what is relevant to the diff under review)
+
+## Core Responsibilities
+
+1. **Get the diff** — `git diff` / `git diff --staged` for uncommitted changes
+2. **Review against task artifacts** — does the diff satisfy `prd.md` (and `design.md` / `implement.md` if present)?
+3. **Review against specs** — naming, structure, type safety, error handling, conventions in `.trellis/spec/`
+4. **Self-fix** — when an issue is mechanical and small, fix it directly with the editing tools you have
+5. **Run verification** — project lint and typecheck on the changed scope
+6. **Report** — concrete findings with `file:line` citations and what was fixed vs. what is open
+
+## Forbidden Operations
+
+- `git commit`
+- `git push`
+- `git merge`
+
+The supervising main session owns commits. Report the post-fix state; do not commit on its behalf.
+
+## Workflow
+
+1. Run `git diff --name-only` and `git diff` to scope the changes
+2. Read the task artifacts and relevant spec files
+3. For each issue:
+   - If mechanical (lint nit, missing type, wrong import, dead branch) → fix in-place
+   - If a design/judgment issue → record and report, do not silently rewrite
+4. Run the project's lint and typecheck on the changed scope after self-fixes
+5. Report
+
+## Report Format
+
+```
+## Self-Check Complete
+
+### Files Checked
+- <path>
+
+### Issues Found and Fixed
+1. `<file>:<line>` — <what was wrong> → <what you changed>
+
+### Issues Not Fixed
+- `<file>:<line>` — <issue> — <why deferred to the main session>
+
+### Verification Results
+- TypeCheck: <pass|fail|skipped + reason>
+- Lint: <pass|fail|skipped + reason>
+
+### Summary
+Checked <N> files, found <X> issues, fixed <Y>, <X-Y> open.
+```

+ 71 - 0
.trellis/agents/implement.md

@@ -0,0 +1,71 @@
+---
+name: implement
+description: |
+  Code implementation expert for the Trellis channel runtime. Understands specs and task artifacts, then implements features. No git commit allowed.
+provider: claude
+labels: [trellis, implement]
+---
+
+# Implement Agent (channel runtime)
+
+You are the Implement Agent spawned by `trellis channel spawn --agent implement` inside the Trellis channel runtime. You receive an `Active task: <path>` line in your inbox; use it to locate task artifacts on disk.
+
+## Context
+
+Before implementing, read in this order:
+
+1. `<task-path>/implement.jsonl` if present — spec manifest curated for this turn; read every listed file
+2. `<task-path>/prd.md` — requirements
+3. `<task-path>/design.md` if present — technical design
+4. `<task-path>/implement.md` if present — execution plan
+5. `.trellis/spec/` — project-wide guidelines (load only what is relevant to the diff you are about to write)
+
+## Core Responsibilities
+
+1. **Understand specs** — read relevant spec files in `.trellis/spec/`
+2. **Understand task artifacts** — read the artifacts listed above
+3. **Implement features** — write code that follows specs and existing patterns
+4. **Self-check** — run lint and typecheck on the changed scope before reporting
+
+## Forbidden Operations
+
+- `git commit`
+- `git push`
+- `git merge`
+
+The supervising main session owns commits. Report what changed; do not commit on its behalf.
+
+## Workflow
+
+1. Read relevant specs based on task type and the files in `implement.jsonl` if present
+2. Read the task's `prd.md`, `design.md` if present, and `implement.md` if present
+3. Implement features following specs and existing patterns
+4. Run the project's lint and typecheck commands on the changed scope
+5. Report files touched, key decisions, and verification results back to the channel
+
+## Code Standards
+
+- Follow existing code patterns
+- Don't add unnecessary abstractions
+- Only do what the PRD asks for; no speculative scope expansion
+- Surface uncertainty back to the channel rather than guessing
+
+## Report Format
+
+```
+## Implementation Complete
+
+### Files Modified
+- <path> — <one-line description>
+
+### Implementation Summary
+1. <step>
+2. <step>
+
+### Verification Results
+- Lint: <pass|fail|skipped + reason>
+- TypeCheck: <pass|fail|skipped + reason>
+
+### Open Questions
+- <if any, otherwise omit>
+```

+ 20 - 0
.trellis/config.yaml

@@ -76,6 +76,26 @@ max_journal_lines: 2000
 # Default package used when --package is not specified.
 # Default package used when --package is not specified.
 # default_package: frontend
 # default_package: frontend
 
 
+#-------------------------------------------------------------------------------
+# Channel worker OOM guard
+#-------------------------------------------------------------------------------
+# Default safeguards for `trellis channel spawn` workers. The guard runs
+# at spawn time (cleans expired idle workers, then enforces the live-worker
+# budget) and inside each supervisor (self-terminates a worker that stays
+# continuously idle past `idle_timeout`).
+#
+# Precedence: CLI flag > env var (TRELLIS_CHANNEL_WORKER_IDLE_TIMEOUT /
+# TRELLIS_CHANNEL_MAX_LIVE_WORKERS) > this config > built-in default.
+#
+# `idle_timeout: 0` disables idle cleanup (workers can sit idle forever
+# unless explicitly killed or given `--timeout`).
+# `max_live_workers: 0` disables the spawn-time budget check.
+#
+channel:
+  worker_guard:
+    idle_timeout: 5m
+    max_live_workers: 6
+
 #-------------------------------------------------------------------------------
 #-------------------------------------------------------------------------------
 # Codex (dispatch behavior)
 # Codex (dispatch behavior)
 #-------------------------------------------------------------------------------
 #-------------------------------------------------------------------------------

+ 26 - 6
.trellis/scripts/add_session.py

@@ -28,6 +28,8 @@ from datetime import datetime
 from pathlib import Path
 from pathlib import Path
 
 
 from common.paths import (
 from common.paths import (
+    DIR_TASKS,
+    DIR_WORKFLOW,
     FILE_JOURNAL_PREFIX,
     FILE_JOURNAL_PREFIX,
     get_repo_root,
     get_repo_root,
     get_current_task,
     get_current_task,
@@ -319,12 +321,14 @@ def update_index(
 # =============================================================================
 # =============================================================================
 
 
 def _auto_commit_workspace(repo_root: Path) -> None:
 def _auto_commit_workspace(repo_root: Path) -> None:
-    """Stage Trellis-owned workspace + task paths and commit.
+    """Stage Trellis-owned workspace + current-task paths and commit.
 
 
-    Path scope is restricted to specific products (journal files, index.md,
-    active task dirs, the archive subtree). We never `git add` the whole
-    `.trellis/` tree, and if `.gitignore` blocks the specific paths we
-    warn + skip — never retry with ``-f``.
+    Path scope is restricted to specific products: the current developer's
+    journal files + index.md, and ONLY the current task directory (resolved
+    via ``get_current_task``). We never `git add` the whole `.trellis/` tree
+    or iterate over all active task dirs (#303: parallel-window dirty task
+    dirs must not be bundled into the session auto-commit). If `.gitignore`
+    blocks the specific paths we warn + skip — never retry with ``-f``.
 
 
     Honors ``session_auto_commit`` in ``.trellis/config.yaml``: when set to
     Honors ``session_auto_commit`` in ``.trellis/config.yaml``: when set to
     ``false``, this function returns immediately without touching git
     ``false``, this function returns immediately without touching git
@@ -338,7 +342,23 @@ def _auto_commit_workspace(repo_root: Path) -> None:
         return
         return
 
 
     commit_msg = get_session_commit_message(repo_root)
     commit_msg = get_session_commit_message(repo_root)
-    paths = safe_trellis_paths_to_add(repo_root)
+    # Resolve the current task so staging is scoped to its dir only. The ref
+    # is ``.trellis/tasks/<name>`` (or under archive/) — pass the bare name.
+    current = get_current_task(repo_root)
+    if current:
+        task_name = Path(current).name
+        paths = safe_trellis_paths_to_add(repo_root, task_name=task_name)
+    else:
+        # Current task unknown (0 or >=2 parallel sessions — exactly the
+        # parallel-window case #303 is about). Do NOT fall back to the wide
+        # `tasks_dir.iterdir()` scan; that would re-leak other tasks' dirty
+        # dirs into the session commit. Stage only the developer's journal/
+        # index and skip every task dir.
+        paths = [
+            p
+            for p in safe_trellis_paths_to_add(repo_root, task_name=None)
+            if not p.startswith(f"{DIR_WORKFLOW}/{DIR_TASKS}/")
+        ]
     if not paths:
     if not paths:
         print("[OK] No workspace changes to commit.", file=sys.stderr)
         print("[OK] No workspace changes to commit.", file=sys.stderr)
         return
         return

+ 2 - 0
.trellis/scripts/common/active_task.py

@@ -43,6 +43,7 @@ _KNOWN_PLATFORMS = {
     "kiro",
     "kiro",
     "copilot",
     "copilot",
     "pi",
     "pi",
+    "trae",
 }
 }
 
 
 _ENV_SESSION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
 _ENV_SESSION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
@@ -57,6 +58,7 @@ _ENV_SESSION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
     ("kiro", ("KIRO_SESSION_ID",)),
     ("kiro", ("KIRO_SESSION_ID",)),
     ("copilot", ("COPILOT_SESSION_ID", "COPILOT_SESSIONID")),
     ("copilot", ("COPILOT_SESSION_ID", "COPILOT_SESSIONID")),
     ("pi", ("PI_SESSION_ID", "PI_SESSIONID")),
     ("pi", ("PI_SESSION_ID", "PI_SESSIONID")),
+    ("trae", ("TRAE_SESSION_ID",)),
 )
 )
 _ENV_CONVERSATION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
 _ENV_CONVERSATION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
     ("cursor", ("CURSOR_CONVERSATION_ID", "CURSOR_CONVERSATIONID")),
     ("cursor", ("CURSOR_CONVERSATION_ID", "CURSOR_CONVERSATIONID")),

+ 78 - 38
.trellis/scripts/common/cli_adapter.py

@@ -1,7 +1,7 @@
 """
 """
 CLI Adapter for Multi-Platform Support.
 CLI Adapter for Multi-Platform Support.
 
 
-Abstracts differences between Claude Code, OpenCode, Cursor, iFlow, Codex, Kilo, Kiro Code, Gemini CLI, Antigravity, Windsurf, Qoder, CodeBuddy, GitHub Copilot, Factory Droid, and Pi Agent interfaces.
+Abstracts differences between Claude Code, OpenCode, Cursor, iFlow, Codex, Kilo, Kiro Code, Gemini CLI, Antigravity, Devin, Qoder, CodeBuddy, GitHub Copilot, Factory Droid, and Pi Agent interfaces.
 
 
 Supported platforms:
 Supported platforms:
 - claude: Claude Code (default)
 - claude: Claude Code (default)
@@ -13,12 +13,13 @@ Supported platforms:
 - kiro: Kiro Code (skills-based)
 - kiro: Kiro Code (skills-based)
 - gemini: Gemini CLI
 - gemini: Gemini CLI
 - antigravity: Antigravity (workflow-based)
 - antigravity: Antigravity (workflow-based)
-- windsurf: Windsurf (workflow-based)
+- devin: Devin (formerly Windsurf; workflow-based)
 - qoder: Qoder
 - qoder: Qoder
 - codebuddy: CodeBuddy
 - codebuddy: CodeBuddy
 - copilot: GitHub Copilot (VS Code)
 - copilot: GitHub Copilot (VS Code)
 - droid: Factory Droid (commands-based)
 - droid: Factory Droid (commands-based)
 - pi: Pi Agent (extension-backed)
 - pi: Pi Agent (extension-backed)
+- trae: Trae IDE (IDE-only, hooks-based)
 
 
 Usage:
 Usage:
     from common.cli_adapter import CLIAdapter
     from common.cli_adapter import CLIAdapter
@@ -47,12 +48,13 @@ Platform = Literal[
     "kiro",
     "kiro",
     "gemini",
     "gemini",
     "antigravity",
     "antigravity",
-    "windsurf",
+    "devin",
     "qoder",
     "qoder",
     "codebuddy",
     "codebuddy",
     "copilot",
     "copilot",
     "droid",
     "droid",
     "pi",
     "pi",
+    "trae",
 ]
 ]
 
 
 
 
@@ -97,7 +99,7 @@ class CLIAdapter:
         """Get platform-specific config directory name.
         """Get platform-specific config directory name.
 
 
         Returns:
         Returns:
-            Directory name ('.claude', '.opencode', '.cursor', '.iflow', '.codex', '.kilocode', '.kiro', '.gemini', '.agent', '.windsurf', '.qoder', '.codebuddy', '.github/copilot', '.factory', or '.pi')
+            Directory name ('.claude', '.opencode', '.cursor', '.iflow', '.codex', '.kilocode', '.kiro', '.gemini', '.agent', '.devin', '.qoder', '.codebuddy', '.github/copilot', '.factory', '.pi', or '.trae')
         """
         """
         if self.platform == "opencode":
         if self.platform == "opencode":
             return ".opencode"
             return ".opencode"
@@ -115,8 +117,8 @@ class CLIAdapter:
             return ".gemini"
             return ".gemini"
         elif self.platform == "antigravity":
         elif self.platform == "antigravity":
             return ".agent"
             return ".agent"
-        elif self.platform == "windsurf":
-            return ".windsurf"
+        elif self.platform == "devin":
+            return ".devin"
         elif self.platform == "qoder":
         elif self.platform == "qoder":
             return ".qoder"
             return ".qoder"
         elif self.platform == "codebuddy":
         elif self.platform == "codebuddy":
@@ -127,6 +129,8 @@ class CLIAdapter:
             return ".factory"
             return ".factory"
         elif self.platform == "pi":
         elif self.platform == "pi":
             return ".pi"
             return ".pi"
+        elif self.platform == "trae":
+            return ".trae"
         else:
         else:
             return ".claude"
             return ".claude"
 
 
@@ -137,7 +141,7 @@ class CLIAdapter:
             project_root: Project root directory
             project_root: Project root directory
 
 
         Returns:
         Returns:
-            Path to config directory (.claude, .opencode, .cursor, .iflow, .codex, .kilocode, .kiro, .gemini, .agent, .windsurf, .qoder, .codebuddy, .github/copilot, .factory, or .pi)
+            Path to config directory (.claude, .opencode, .cursor, .iflow, .codex, .kilocode, .kiro, .gemini, .agent, .devin, .qoder, .codebuddy, .github/copilot, .factory, .pi, or .trae)
         """
         """
         return project_root / self.config_dir_name
         return project_root / self.config_dir_name
 
 
@@ -169,7 +173,7 @@ class CLIAdapter:
         Note:
         Note:
             Cursor uses prefix naming: .cursor/commands/trellis-<name>.md
             Cursor uses prefix naming: .cursor/commands/trellis-<name>.md
             Antigravity uses workflow directory: .agent/workflows/<name>.md
             Antigravity uses workflow directory: .agent/workflows/<name>.md
-            Windsurf uses workflow directory: .windsurf/workflows/trellis-<name>.md
+            Devin uses workflow directory: .devin/workflows/trellis-<name>.md
             Copilot uses prompt files: .github/prompts/<name>.prompt.md
             Copilot uses prompt files: .github/prompts/<name>.prompt.md
             Pi uses prompt templates: .pi/prompts/trellis-<name>.md
             Pi uses prompt templates: .pi/prompts/trellis-<name>.md
             Claude/OpenCode use subdirectory: .claude/commands/trellis/<name>.md
             Claude/OpenCode use subdirectory: .claude/commands/trellis/<name>.md
@@ -185,7 +189,7 @@ class CLIAdapter:
                 return prompts_dir / f"trellis-{filename}.md"
                 return prompts_dir / f"trellis-{filename}.md"
             return prompts_dir / Path(*parts)
             return prompts_dir / Path(*parts)
 
 
-        if self.platform == "windsurf":
+        if self.platform == "devin":
             workflow_dir = self.get_config_dir(project_root) / "workflows"
             workflow_dir = self.get_config_dir(project_root) / "workflows"
             if not parts:
             if not parts:
                 return workflow_dir
                 return workflow_dir
@@ -242,7 +246,7 @@ class CLIAdapter:
             Kiro: .kiro/skills/trellis-<name>/SKILL.md
             Kiro: .kiro/skills/trellis-<name>/SKILL.md
             Gemini: .gemini/commands/trellis/<name>.toml
             Gemini: .gemini/commands/trellis/<name>.toml
             Antigravity: .agent/workflows/<name>.md
             Antigravity: .agent/workflows/<name>.md
-            Windsurf: .windsurf/workflows/trellis-<name>.md
+            Devin: .devin/workflows/trellis-<name>.md
             Pi: .pi/prompts/trellis-<name>.md
             Pi: .pi/prompts/trellis-<name>.md
             Others: .{platform}/commands/trellis/<name>.md
             Others: .{platform}/commands/trellis/<name>.md
         """
         """
@@ -258,8 +262,8 @@ class CLIAdapter:
             return f".gemini/commands/trellis/{name}.toml"
             return f".gemini/commands/trellis/{name}.toml"
         elif self.platform == "antigravity":
         elif self.platform == "antigravity":
             return f".agent/workflows/{name}.md"
             return f".agent/workflows/{name}.md"
-        elif self.platform == "windsurf":
-            return f".windsurf/workflows/trellis-{name}.md"
+        elif self.platform == "devin":
+            return f".devin/workflows/trellis-{name}.md"
         elif self.platform == "kilo":
         elif self.platform == "kilo":
             return f".kilocode/workflows/{name}.md"
             return f".kilocode/workflows/{name}.md"
         elif self.platform == "copilot":
         elif self.platform == "copilot":
@@ -293,7 +297,7 @@ class CLIAdapter:
             return {}  # Gemini CLI doesn't have a non-interactive env var
             return {}  # Gemini CLI doesn't have a non-interactive env var
         elif self.platform == "antigravity":
         elif self.platform == "antigravity":
             return {}
             return {}
-        elif self.platform == "windsurf":
+        elif self.platform == "devin":
             return {}
             return {}
         elif self.platform == "qoder":
         elif self.platform == "qoder":
             return {}
             return {}
@@ -305,6 +309,8 @@ class CLIAdapter:
             return {}
             return {}
         elif self.platform == "pi":
         elif self.platform == "pi":
             return {}
             return {}
+        elif self.platform == "trae":
+            return {}
         else:
         else:
             return {"CLAUDE_NON_INTERACTIVE": "1"}
             return {"CLAUDE_NON_INTERACTIVE": "1"}
 
 
@@ -370,9 +376,9 @@ class CLIAdapter:
             raise ValueError(
             raise ValueError(
                 "Antigravity workflows are UI slash commands; CLI agent run is not supported."
                 "Antigravity workflows are UI slash commands; CLI agent run is not supported."
             )
             )
-        elif self.platform == "windsurf":
+        elif self.platform == "devin":
             raise ValueError(
             raise ValueError(
-                "Windsurf workflows are UI slash commands; CLI agent run is not supported."
+                "Devin workflows are UI slash commands; CLI agent run is not supported."
             )
             )
         elif self.platform == "qoder":
         elif self.platform == "qoder":
             cmd = ["qodercli", "-p", prompt]
             cmd = ["qodercli", "-p", prompt]
@@ -390,6 +396,10 @@ class CLIAdapter:
             )
             )
         elif self.platform == "pi":
         elif self.platform == "pi":
             cmd = ["pi", "-p", prompt]
             cmd = ["pi", "-p", prompt]
+        elif self.platform == "trae":
+            raise ValueError(
+                "Trae is IDE-only; CLI agent run is not supported."
+            )
 
 
         else:  # claude
         else:  # claude
             cmd = ["claude", "-p"]
             cmd = ["claude", "-p"]
@@ -436,9 +446,9 @@ class CLIAdapter:
             raise ValueError(
             raise ValueError(
                 "Antigravity workflows are UI slash commands; CLI resume is not supported."
                 "Antigravity workflows are UI slash commands; CLI resume is not supported."
             )
             )
-        elif self.platform == "windsurf":
+        elif self.platform == "devin":
             raise ValueError(
             raise ValueError(
-                "Windsurf workflows are UI slash commands; CLI resume is not supported."
+                "Devin workflows are UI slash commands; CLI resume is not supported."
             )
             )
         elif self.platform == "qoder":
         elif self.platform == "qoder":
             return ["qodercli", "--resume", session_id]
             return ["qodercli", "--resume", session_id]
@@ -456,6 +466,10 @@ class CLIAdapter:
             )
             )
         elif self.platform == "pi":
         elif self.platform == "pi":
             return ["pi", "-c", session_id]
             return ["pi", "-c", session_id]
+        elif self.platform == "trae":
+            raise ValueError(
+                "Trae is IDE-only; CLI resume is not supported."
+            )
         else:
         else:
             return ["claude", "--resume", session_id]
             return ["claude", "--resume", session_id]
 
 
@@ -518,8 +532,8 @@ class CLIAdapter:
             return "gemini"
             return "gemini"
         elif self.platform == "antigravity":
         elif self.platform == "antigravity":
             return "agy"
             return "agy"
-        elif self.platform == "windsurf":
-            return "windsurf"
+        elif self.platform == "devin":
+            return "devin"
         elif self.platform == "qoder":
         elif self.platform == "qoder":
             return "qodercli"
             return "qodercli"
         elif self.platform == "codebuddy":
         elif self.platform == "codebuddy":
@@ -530,6 +544,8 @@ class CLIAdapter:
             return "droid"
             return "droid"
         elif self.platform == "pi":
         elif self.platform == "pi":
             return "pi"
             return "pi"
+        elif self.platform == "trae":
+            return "trae"
         else:
         else:
             return "claude"
             return "claude"
 
 
@@ -594,14 +610,21 @@ def get_cli_adapter(platform: str = "claude") -> CLIAdapter:
     """Get CLI adapter for the specified platform.
     """Get CLI adapter for the specified platform.
 
 
     Args:
     Args:
-        platform: Platform name ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'windsurf', 'qoder', 'codebuddy', 'copilot', 'droid', or 'pi')
+        platform: Platform name ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'devin', 'qoder', 'codebuddy', 'copilot', 'droid', 'pi', or 'trae')
 
 
     Returns:
     Returns:
         CLIAdapter instance
         CLIAdapter instance
 
 
     Raises:
     Raises:
         ValueError: If platform is not supported
         ValueError: If platform is not supported
+
+    Note:
+        'windsurf' is accepted as a deprecated alias for 'devin' (Windsurf was
+        renamed to Devin) and normalized before validation.
     """
     """
+    # Deprecated alias: Windsurf was renamed to Devin.
+    if platform == "windsurf":
+        platform = "devin"
     if platform not in (
     if platform not in (
         "claude",
         "claude",
         "opencode",
         "opencode",
@@ -612,15 +635,16 @@ def get_cli_adapter(platform: str = "claude") -> CLIAdapter:
         "kiro",
         "kiro",
         "gemini",
         "gemini",
         "antigravity",
         "antigravity",
-        "windsurf",
+        "devin",
         "qoder",
         "qoder",
         "codebuddy",
         "codebuddy",
         "copilot",
         "copilot",
         "droid",
         "droid",
         "pi",
         "pi",
+        "trae",
     ):
     ):
         raise ValueError(
         raise ValueError(
-            f"Unsupported platform: {platform} (must be 'claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'windsurf', 'qoder', 'codebuddy', 'copilot', 'droid', or 'pi')"
+            f"Unsupported platform: {platform} (must be 'claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'devin', 'qoder', 'codebuddy', 'copilot', 'droid', 'pi', or 'trae')"
         )
         )
 
 
     return CLIAdapter(platform=platform)  # type: ignore
     return CLIAdapter(platform=platform)  # type: ignore
@@ -636,18 +660,20 @@ _ALL_PLATFORM_CONFIG_DIRS = (
     ".kiro",
     ".kiro",
     ".gemini",
     ".gemini",
     ".agent",
     ".agent",
-    ".windsurf",
+    ".devin",
+    ".windsurf",  # deprecated: pre-rename Devin config dir (still a platform signal)
     ".qoder",
     ".qoder",
     ".codebuddy",
     ".codebuddy",
     ".github/copilot",
     ".github/copilot",
     ".factory",
     ".factory",
     ".pi",
     ".pi",
+    ".trae",
 )
 )
 """Platform-specific config directory names used by detect_platform exclusion
 """Platform-specific config directory names used by detect_platform exclusion
 checks. `.agents/skills/` is NOT listed here: it is a shared cross-platform
 checks. `.agents/skills/` is NOT listed here: it is a shared cross-platform
 layer (written by Codex, also consumed by Amp/Cline/Warp/etc. via the
 layer (written by Codex, also consumed by Amp/Cline/Warp/etc. via the
 agentskills.io standard), not a single-platform signal. Its presence must not
 agentskills.io standard), not a single-platform signal. Its presence must not
-block detection of Kiro, Antigravity, Windsurf, or other platforms."""
+block detection of Kiro, Antigravity, Devin, or other platforms."""
 
 
 
 
 def _has_other_platform_dir(project_root: Path, exclude: set[str]) -> bool:
 def _has_other_platform_dir(project_root: Path, exclude: set[str]) -> bool:
@@ -667,27 +693,33 @@ def detect_platform(project_root: Path) -> Platform:
     2. .opencode directory exists → opencode
     2. .opencode directory exists → opencode
     3. .iflow directory exists → iflow
     3. .iflow directory exists → iflow
     4. .cursor directory exists (without .claude) → cursor
     4. .cursor directory exists (without .claude) → cursor
-    5. .codex exists and no other platform dirs → codex
-    6. .kilocode directory exists → kilo
-    7. .kiro/skills exists and no other platform dirs → kiro
-    8. .gemini directory exists → gemini
+    5. .gemini directory exists → gemini
+    6. .codex exists and no other platform dirs → codex
+    7. .kilocode directory exists → kilo
+    8. .kiro/skills exists and no other platform dirs → kiro
     9. .agent/workflows exists and no other platform dirs → antigravity
     9. .agent/workflows exists and no other platform dirs → antigravity
-    10. .windsurf/workflows exists and no other platform dirs → windsurf
+    10. .devin/workflows (or legacy .windsurf/workflows) exists and no other platform dirs → devin
     11. .codebuddy directory exists → codebuddy
     11. .codebuddy directory exists → codebuddy
     12. .qoder directory exists → qoder
     12. .qoder directory exists → qoder
-    13. .pi directory exists → pi
-    14. Default → claude
+    13. .github/copilot directory exists → copilot
+    14. .factory directory exists → droid
+    15. .pi directory exists → pi
+    16. .trae directory exists → trae
+    17. Default → claude
 
 
     Args:
     Args:
         project_root: Project root directory
         project_root: Project root directory
 
 
     Returns:
     Returns:
-        Detected platform ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'windsurf', 'qoder', 'codebuddy', 'copilot', 'droid', 'pi', or default 'claude')
+        Detected platform ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'devin', 'qoder', 'codebuddy', 'copilot', 'droid', 'pi', 'trae', or default 'claude')
     """
     """
     import os
     import os
 
 
     # Check environment variable first
     # Check environment variable first
     env_platform = os.environ.get("TRELLIS_PLATFORM", "").lower()
     env_platform = os.environ.get("TRELLIS_PLATFORM", "").lower()
+    # Deprecated alias: Windsurf was renamed to Devin.
+    if env_platform == "windsurf":
+        env_platform = "devin"
     if env_platform in (
     if env_platform in (
         "claude",
         "claude",
         "opencode",
         "opencode",
@@ -698,12 +730,13 @@ def detect_platform(project_root: Path) -> Platform:
         "kiro",
         "kiro",
         "gemini",
         "gemini",
         "antigravity",
         "antigravity",
-        "windsurf",
+        "devin",
         "qoder",
         "qoder",
         "codebuddy",
         "codebuddy",
         "copilot",
         "copilot",
         "droid",
         "droid",
         "pi",
         "pi",
+        "trae",
     ):
     ):
         return env_platform  # type: ignore
         return env_platform  # type: ignore
 
 
@@ -749,13 +782,16 @@ def detect_platform(project_root: Path) -> Platform:
     ):
     ):
         return "antigravity"
         return "antigravity"
 
 
-    # Check for Windsurf workflow directory only when no other platform config exists
+    # Check for Devin workflow directory only when no other platform config
+    # exists. `.windsurf/workflows` is the legacy pre-rename path (still detected
+    # as devin for back-compat until users migrate via `trellis update --migrate`).
     if (
     if (
-        project_root / ".windsurf" / "workflows"
-    ).is_dir() and not _has_other_platform_dir(
-        project_root, {".windsurf"}
+        (project_root / ".devin" / "workflows").is_dir()
+        or (project_root / ".windsurf" / "workflows").is_dir()
+    ) and not _has_other_platform_dir(
+        project_root, {".devin", ".windsurf"}
     ):
     ):
-        return "windsurf"
+        return "devin"
 
 
     # Check for .codebuddy directory (CodeBuddy-specific)
     # Check for .codebuddy directory (CodeBuddy-specific)
     if (project_root / ".codebuddy").is_dir():
     if (project_root / ".codebuddy").is_dir():
@@ -777,6 +813,10 @@ def detect_platform(project_root: Path) -> Platform:
     if (project_root / ".pi").is_dir():
     if (project_root / ".pi").is_dir():
         return "pi"
         return "pi"
 
 
+    # Check for .trae directory (Trae IDE-specific)
+    if (project_root / ".trae").is_dir():
+        return "trae"
+
     # Fallback: checkout only has the Codex shared-skills layer
     # Fallback: checkout only has the Codex shared-skills layer
     # (.agents/skills/trellis-* dirs) and no explicit platform config dir.
     # (.agents/skills/trellis-* dirs) and no explicit platform config dir.
     # Happens on fresh clones where .codex/ is gitignored/absent but the
     # Happens on fresh clones where .codex/ is gitignored/absent but the

+ 46 - 16
.trellis/scripts/common/safe_commit.py

@@ -58,7 +58,10 @@ TRELLIS_IGNORED_SUBPATHS = (
 )
 )
 
 
 
 
-def safe_trellis_paths_to_add(repo_root: Path) -> list[str]:
+def safe_trellis_paths_to_add(
+    repo_root: Path,
+    task_name: str | None = None,
+) -> list[str]:
     """Return the list of repo-relative paths the auto-commit should stage.
     """Return the list of repo-relative paths the auto-commit should stage.
 
 
     Only includes paths that exist on disk so callers don't pass non-existent
     Only includes paths that exist on disk so callers don't pass non-existent
@@ -68,12 +71,23 @@ def safe_trellis_paths_to_add(repo_root: Path) -> list[str]:
     Included:
     Included:
       - .trellis/workspace/<developer>/journal-*.md
       - .trellis/workspace/<developer>/journal-*.md
       - .trellis/workspace/<developer>/index.md
       - .trellis/workspace/<developer>/index.md
-      - .trellis/tasks/<task-dir>/   (every active task directory)
-      - .trellis/tasks/archive/      (whole archive subtree, if present)
+      - .trellis/tasks/<task_name>/   (ONLY the current task dir when
+        ``task_name`` is passed; plus its archive location if the task
+        already lives under archive/)
 
 
     Excluded (intentionally — these must not be staged):
     Excluded (intentionally — these must not be staged):
       - .trellis/.backup-*, .trellis/worktrees/,
       - .trellis/.backup-*, .trellis/worktrees/,
         .trellis/.template-hashes.json, .trellis/.runtime/, .trellis/.cache/
         .trellis/.template-hashes.json, .trellis/.runtime/, .trellis/.cache/
+
+    Scope contract (see #303 / break-loop analysis): when ``task_name`` is
+    passed, the task segment stages ONLY that task directory — it never walks
+    ``tasks_dir.iterdir()`` over all active tasks. This mirrors
+    :func:`safe_archive_paths_to_add` and prevents dirty changes in OTHER
+    parallel-window task dirs from being bundled into the session auto-commit.
+
+    Backwards-compat: with no ``task_name``, the function walks every active
+    task directory (+ the archive subtree) the old wide way. New callers
+    should always pass ``task_name``.
     """
     """
     paths: list[str] = []
     paths: list[str] = []
 
 
@@ -93,20 +107,36 @@ def safe_trellis_paths_to_add(repo_root: Path) -> list[str]:
                     f"{DIR_WORKFLOW}/{DIR_WORKSPACE}/{developer}/index.md"
                     f"{DIR_WORKFLOW}/{DIR_WORKSPACE}/{developer}/index.md"
                 )
                 )
 
 
-    # Active tasks: each direct child of tasks/ that is a directory and not
-    # the archive root. The archive subtree is added as a single path below.
     tasks_dir = repo_root / DIR_WORKFLOW / DIR_TASKS
     tasks_dir = repo_root / DIR_WORKFLOW / DIR_TASKS
-    if tasks_dir.is_dir():
-        for child in sorted(tasks_dir.iterdir()):
-            if not child.is_dir():
-                continue
-            if child.name == DIR_ARCHIVE:
-                continue
-            paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{child.name}")
-
-        archive_dir = tasks_dir / DIR_ARCHIVE
-        if archive_dir.is_dir():
-            paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}")
+    if not tasks_dir.is_dir():
+        return paths
+
+    if task_name is not None:
+        # Narrow scope — ONLY the current task directory (active or archived).
+        # Never iterdir() all tasks: parallel-window dirty task dirs must not
+        # leak into the session auto-commit.
+        active_task = tasks_dir / task_name
+        if active_task.is_dir():
+            paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{task_name}")
+        archived_task = tasks_dir / DIR_ARCHIVE / task_name
+        if archived_task.is_dir():
+            paths.append(
+                f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}/{task_name}"
+            )
+        return paths
+
+    # Legacy wide scope (no task_name): each direct child of tasks/ that is a
+    # directory and not the archive root, plus the whole archive subtree.
+    for child in sorted(tasks_dir.iterdir()):
+        if not child.is_dir():
+            continue
+        if child.name == DIR_ARCHIVE:
+            continue
+        paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{child.name}")
+
+    archive_dir = tasks_dir / DIR_ARCHIVE
+    if archive_dir.is_dir():
+        paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}")
 
 
     return paths
     return paths
 
 

+ 1 - 1
.trellis/scripts/common/session_context.py

@@ -412,7 +412,7 @@ def _get_update_hint(repo_root: Path) -> str | None:
 
 
     return (
     return (
         f"Trellis update available: {current_version} -> {latest_version}, "
         f"Trellis update available: {current_version} -> {latest_version}, "
-        f"run npm install -g {_PACKAGE_NAME}@latest"
+        "run trellis upgrade"
     )
     )
 
 
 
 

+ 3 - 3
.trellis/scripts/common/task_context.py

@@ -10,9 +10,9 @@ Provides:
 Note:
 Note:
     ``cmd_init_context`` was removed in v0.5.0-beta.12. JSONL context files
     ``cmd_init_context`` was removed in v0.5.0-beta.12. JSONL context files
     are now seeded at ``task.py create`` time with a self-describing
     are now seeded at ``task.py create`` time with a self-describing
-    ``_example`` line; the AI agent curates real entries during Phase 1.3 of
-    the workflow. See ``.trellis/workflow.md`` Phase 1.3 for the current
-    instructions.
+    ``_example`` line; the AI agent curates real entries during planning when
+    the task needs sub-agent/spec context. See ``.trellis/workflow.md`` for the
+    current planning artifact contract.
 """
 """
 
 
 from __future__ import annotations
 from __future__ import annotations

+ 66 - 16
.trellis/scripts/common/task_store.py

@@ -115,7 +115,7 @@ def _repo_relative_path(path: Path, repo_root: Path) -> str:
 # Keep in sync with src/types/ai-tools.ts AI_TOOLS entries — these are the
 # Keep in sync with src/types/ai-tools.ts AI_TOOLS entries — these are the
 # platforms listed in workflow.md's "agent-capable" Skill Routing block
 # platforms listed in workflow.md's "agent-capable" Skill Routing block
 # (Class-1 hook-inject + Class-2 pull-based preludes). Kilo / Antigravity /
 # (Class-1 hook-inject + Class-2 pull-based preludes). Kilo / Antigravity /
-# Windsurf are NOT in this list: they do not consume JSONL.
+# Devin are NOT in this list: they do not consume JSONL.
 _SUBAGENT_CONFIG_DIRS: tuple[str, ...] = (
 _SUBAGENT_CONFIG_DIRS: tuple[str, ...] = (
     ".claude",
     ".claude",
     ".cursor",
     ".cursor",
@@ -128,6 +128,7 @@ _SUBAGENT_CONFIG_DIRS: tuple[str, ...] = (
     ".factory",   # Factory Droid
     ".factory",   # Factory Droid
     ".github/copilot",
     ".github/copilot",
     ".pi",        # Pi Agent
     ".pi",        # Pi Agent
+    ".trae",      # Trae IDE
 )
 )
 
 
 _SEED_EXAMPLE = (
 _SEED_EXAMPLE = (
@@ -162,6 +163,32 @@ def _write_seed_jsonl(path: Path) -> None:
     path.write_text(json.dumps(seed, ensure_ascii=False) + "\n", encoding="utf-8")
     path.write_text(json.dumps(seed, ensure_ascii=False) + "\n", encoding="utf-8")
 
 
 
 
+def _default_prd_content(title: str, description: str | None = None) -> str:
+    """Return the default PRD skeleton created with every task."""
+    goal = (description or "").strip() or "TBD."
+    heading = title.strip() or "Untitled task"
+    return f"""# {heading}
+
+## Goal
+
+{goal}
+
+## Requirements
+
+- TBD
+
+## Acceptance Criteria
+
+- [ ] TBD
+
+## Notes
+
+- Keep `prd.md` focused on requirements, constraints, and acceptance criteria.
+- Lightweight tasks can remain PRD-only.
+- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`.
+"""
+
+
 # =============================================================================
 # =============================================================================
 # Command: create
 # Command: create
 # =============================================================================
 # =============================================================================
@@ -264,9 +291,16 @@ def cmd_create(args: argparse.Namespace) -> int:
 
 
     write_json(task_json_path, task_data)
     write_json(task_json_path, task_data)
 
 
+    prd_path = task_dir / "prd.md"
+    if not prd_path.exists():
+        prd_path.write_text(
+            _default_prd_content(args.title, args.description),
+            encoding="utf-8",
+        )
+
     # Seed implement.jsonl / check.jsonl for sub-agent-capable platforms.
     # Seed implement.jsonl / check.jsonl for sub-agent-capable platforms.
-    # Agent curates real entries in Phase 1.3 (see .trellis/workflow.md).
-    # Agent-less platforms (Kilo / Antigravity / Windsurf) skip this — they
+    # Agent curates real entries during planning when the task needs them.
+    # Agent-less platforms (Kilo / Antigravity / Devin) skip this — they
     # load specs via the trellis-before-dev skill instead of JSONL.
     # load specs via the trellis-before-dev skill instead of JSONL.
     seeded_jsonl = False
     seeded_jsonl = False
     if _has_subagent_platform(repo_root):
     if _has_subagent_platform(repo_root):
@@ -317,16 +351,15 @@ def cmd_create(args: argparse.Namespace) -> int:
     print(colored(f"Created task: {dir_name}", Colors.GREEN), file=sys.stderr)
     print(colored(f"Created task: {dir_name}", Colors.GREEN), file=sys.stderr)
     print("", file=sys.stderr)
     print("", file=sys.stderr)
     print(colored("Next steps:", Colors.BLUE), file=sys.stderr)
     print(colored("Next steps:", Colors.BLUE), file=sys.stderr)
-    print("  1. Create prd.md with requirements", file=sys.stderr)
+    print("  - Fill prd.md with requirements and acceptance criteria", file=sys.stderr)
+    print("  - Lightweight task: PRD-only is valid", file=sys.stderr)
+    print("  - Complex task: add design.md and implement.md before task.py start", file=sys.stderr)
     if seeded_jsonl:
     if seeded_jsonl:
         print(
         print(
-            "  2. Curate implement.jsonl / check.jsonl (spec + research files only — "
-            "see .trellis/workflow.md Phase 1.3)",
+            "  - Curate implement.jsonl / check.jsonl as spec/research manifests when sub-agents need context",
             file=sys.stderr,
             file=sys.stderr,
         )
         )
-        print("  3. Run: python task.py start <dir>", file=sys.stderr)
-    else:
-        print("  2. Run: python task.py start <dir>", file=sys.stderr)
+    print("  - Use /trellis:continue or phase context to decide the next step", file=sys.stderr)
     print("", file=sys.stderr)
     print("", file=sys.stderr)
 
 
     # Output relative path for script chaining
     # Output relative path for script chaining
@@ -410,7 +443,16 @@ def cmd_archive(args: argparse.Namespace) -> int:
 
 
         # Auto-commit unless --no-commit
         # Auto-commit unless --no-commit
         if not getattr(args, "no_commit", False):
         if not getattr(args, "no_commit", False):
-            _auto_commit_archive(dir_name, repo_root, modified_children)
+            if not _auto_commit_archive(dir_name, repo_root, modified_children):
+                print(
+                    colored(
+                        "Archive moved on disk, but git auto-commit did not complete. "
+                        "Resolve `git status` before continuing.",
+                        Colors.RED,
+                    ),
+                    file=sys.stderr,
+                )
+                return 1
 
 
         # Return the archive path
         # Return the archive path
         print(f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}/{year_month}/{dir_name}")
         print(f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}/{year_month}/{dir_name}")
@@ -427,7 +469,7 @@ def _auto_commit_archive(
     task_name: str,
     task_name: str,
     repo_root: Path,
     repo_root: Path,
     modified_children: list[str] | None = None,
     modified_children: list[str] | None = None,
-) -> None:
+) -> bool:
     """Stage Trellis-owned task paths and commit after archive.
     """Stage Trellis-owned task paths and commit after archive.
 
 
     Scoped narrowly to the archived task's source + destination paths
     Scoped narrowly to the archived task's source + destination paths
@@ -449,14 +491,21 @@ def _auto_commit_archive(
             "[OK] session_auto_commit: false — skipping git stage/commit.",
             "[OK] session_auto_commit: false — skipping git stage/commit.",
             file=sys.stderr,
             file=sys.stderr,
         )
         )
-        return
+        return True
+
+    source_rel = f"{DIR_WORKFLOW}/{DIR_TASKS}/{task_name}"
+    rc, tracked_out, _ = run_git(
+        ["ls-files", "--", source_rel],
+        cwd=repo_root,
+    )
+    source_was_tracked = rc == 0 and bool(tracked_out.strip())
 
 
     paths = safe_archive_paths_to_add(
     paths = safe_archive_paths_to_add(
         repo_root, task_name=task_name, modified_children=modified_children
         repo_root, task_name=task_name, modified_children=modified_children
     )
     )
     if not paths:
     if not paths:
         print("[OK] No task changes to commit.", file=sys.stderr)
         print("[OK] No task changes to commit.", file=sys.stderr)
-        return
+        return True
 
 
     success, _, err = safe_git_add(paths, repo_root)
     success, _, err = safe_git_add(paths, repo_root)
     if not success:
     if not success:
@@ -467,7 +516,7 @@ def _auto_commit_archive(
                 f"[WARN] git add failed: {err.strip() if err else 'unknown error'}",
                 f"[WARN] git add failed: {err.strip() if err else 'unknown error'}",
                 file=sys.stderr,
                 file=sys.stderr,
             )
             )
-        return
+        return not source_was_tracked
 
 
     # Belt-and-suspenders for the phantom-delete bug: `safe_git_add` uses
     # Belt-and-suspenders for the phantom-delete bug: `safe_git_add` uses
     # `git add` (no -A) which only stages additions/modifications. The
     # `git add` (no -A) which only stages additions/modifications. The
@@ -478,7 +527,6 @@ def _auto_commit_archive(
     #
     #
     # `--ignore-unmatch` makes this a no-op when the task was never tracked
     # `--ignore-unmatch` makes this a no-op when the task was never tracked
     # (e.g. archiving a task that lived only in working tree).
     # (e.g. archiving a task that lived only in working tree).
-    source_rel = f"{DIR_WORKFLOW}/{DIR_TASKS}/{task_name}"
     run_git(
     run_git(
         ["rm", "-r", "--cached", "--ignore-unmatch", "--", source_rel],
         ["rm", "-r", "--cached", "--ignore-unmatch", "--", source_rel],
         cwd=repo_root,
         cwd=repo_root,
@@ -490,14 +538,16 @@ def _auto_commit_archive(
     )
     )
     if rc == 0:
     if rc == 0:
         print("[OK] No task changes to commit.", file=sys.stderr)
         print("[OK] No task changes to commit.", file=sys.stderr)
-        return
+        return True
 
 
     commit_msg = f"chore(task): archive {task_name}"
     commit_msg = f"chore(task): archive {task_name}"
     rc, _, err = run_git(["commit", "-m", commit_msg], cwd=repo_root)
     rc, _, err = run_git(["commit", "-m", commit_msg], cwd=repo_root)
     if rc == 0:
     if rc == 0:
         print(f"[OK] Auto-committed: {commit_msg}", file=sys.stderr)
         print(f"[OK] Auto-committed: {commit_msg}", file=sys.stderr)
+        return True
     else:
     else:
         print(f"[WARN] Auto-commit failed: {err.strip()}", file=sys.stderr)
         print(f"[WARN] Auto-commit failed: {err.strip()}", file=sys.stderr)
+        return not source_was_tracked
 
 
 
 
 # =============================================================================
 # =============================================================================

+ 8 - 11
.trellis/scripts/common/workflow_phase.py

@@ -60,15 +60,12 @@ def _parse_marker(line: str) -> tuple[bool, list[str]] | None:
 
 
 
 
 def get_phase_index() -> str:
 def get_phase_index() -> str:
-    """Return Phase Index + Phase 1/2/3 step bodies from workflow.md.
-
-    Matches what the SessionStart hook injects into the `<workflow>` block:
-    starts at `## Phase Index`, continues through `## Phase 1: Plan`,
-    `## Phase 2: Execute`, `## Phase 3: Finish`, stops at
-    `## Customizing Trellis (for forks)` (the docs-for-forks footer).
-    `[workflow-state:STATUS]` tag blocks (now embedded in Phase Index since
-    v0.5.0-rc.0) are consumed by the UserPromptSubmit hook so they're
-    stripped from this output.
+    """Return the compact Phase Index summary from workflow.md.
+
+    SessionStart and no-step phase context use this small summary as their
+    orientation payload. Detailed Phase 1/2/3 instructions are loaded with
+    ``get_step`` on demand. ``[workflow-state:STATUS]`` tag blocks are
+    consumed by the per-turn hook, so they're stripped from this output.
     """
     """
     text = _read_workflow()
     text = _read_workflow()
     lines = text.splitlines()
     lines = text.splitlines()
@@ -80,7 +77,7 @@ def get_phase_index() -> str:
         if start is None and stripped == _PHASE_INDEX_HEADING:
         if start is None and stripped == _PHASE_INDEX_HEADING:
             start = i
             start = i
             continue
             continue
-        if start is not None and stripped == "## Customizing Trellis (for forks)":
+        if start is not None and stripped == "## Phase 1: Plan":
             end = i
             end = i
             break
             break
 
 
@@ -151,7 +148,7 @@ def resolve_effective_platform(platform: str, config: dict) -> str:
     or ``"codex-sub-agent"`` based on ``.trellis/config.yaml`` ``codex.dispatch_mode``.
     or ``"codex-sub-agent"`` based on ``.trellis/config.yaml`` ``codex.dispatch_mode``.
     ``filter_platform`` then surfaces blocks whose marker lists include the
     ``filter_platform`` then surfaces blocks whose marker lists include the
     namespaced name (e.g. ``[codex-sub-agent, ...]`` or ``[codex-inline, Kilo,
     namespaced name (e.g. ``[codex-sub-agent, ...]`` or ``[codex-inline, Kilo,
-    Antigravity, Windsurf]``).
+    Antigravity, Devin]``).
 
 
     Default is ``inline`` because Codex sub-agents run with ``fork_turns="none"``
     Default is ``inline`` because Codex sub-agents run with ``fork_turns="none"``
     isolation and can't inherit the parent session's task context — inline
     isolation and can't inherit the parent session's task context — inline

+ 3 - 3
.trellis/scripts/task.py

@@ -369,12 +369,12 @@ def main() -> int:
             file=sys.stderr,
             file=sys.stderr,
         )
         )
         print(
         print(
-            "sub-agent-capable platforms and curated by the AI during Phase 1.3.",
+            "sub-agent-capable platforms and curated by the AI during planning when needed.",
             file=sys.stderr,
             file=sys.stderr,
         )
         )
-        print("See .trellis/workflow.md Phase 1.3 or run:", file=sys.stderr)
+        print("See .trellis/workflow.md planning artifact guidance or run:", file=sys.stderr)
         print(
         print(
-            "  python ./.trellis/scripts/get_context.py --mode phase --step 1.3",
+            "  python ./.trellis/scripts/get_context.py --mode phase --step 1",
             file=sys.stderr,
             file=sys.stderr,
         )
         )
         print(
         print(

+ 155 - 137
.trellis/workflow.md

@@ -39,7 +39,7 @@ python ./.trellis/scripts/get_context.py --mode packages   # list packages / lay
 
 
 ### Task System
 ### Task System
 
 
-Every task has its own directory under `.trellis/tasks/{MM-DD-name}/` holding `prd.md`, `implement.jsonl`, `check.jsonl`, `task.json`, optional `research/`, `info.md`.
+Every task has its own directory under `.trellis/tasks/{MM-DD-name}/` holding `task.json`, `prd.md`, optional `design.md`, optional `implement.md`, optional `research/`, and context manifests (`implement.jsonl`, `check.jsonl`) for sub-agent-capable platforms.
 
 
 ```bash
 ```bash
 # Task lifecycle
 # Task lifecycle
@@ -53,7 +53,7 @@ python ./.trellis/scripts/task.py list-archive
 
 
 # Code-spec context (injected into implement/check agents via JSONL).
 # Code-spec context (injected into implement/check agents via JSONL).
 # `implement.jsonl` / `check.jsonl` are seeded on `task create` for sub-agent-capable
 # `implement.jsonl` / `check.jsonl` are seeded on `task create` for sub-agent-capable
-# platforms; the AI curates real spec + research entries during Phase 1.3.
+# platforms; the AI curates real spec + research entries during planning when needed.
 python ./.trellis/scripts/task.py add-context <name> <action> <file> <reason>
 python ./.trellis/scripts/task.py add-context <name> <action> <file> <reason>
 python ./.trellis/scripts/task.py list-context <name> [action]
 python ./.trellis/scripts/task.py list-context <name> [action]
 python ./.trellis/scripts/task.py validate <name>
 python ./.trellis/scripts/task.py validate <name>
@@ -99,7 +99,7 @@ python ./.trellis/scripts/get_context.py --mode phase --step <X.Y>  # detailed g
 <!--
 <!--
   WORKFLOW-STATE BREADCRUMB CONTRACT (read this before editing the tag blocks below)
   WORKFLOW-STATE BREADCRUMB CONTRACT (read this before editing the tag blocks below)
 
 
-  The 4 [workflow-state:STATUS] blocks embedded in the ## Phase Index section
+  The [workflow-state:STATUS] blocks embedded in the ## Phase Index section
   below are the SINGLE source of truth for the per-turn `<workflow-state>`
   below are the SINGLE source of truth for the per-turn `<workflow-state>`
   breadcrumb that every supported AI platform's UserPromptSubmit hook
   breadcrumb that every supported AI platform's UserPromptSubmit hook
   reads. inject-workflow-state.py (Python platforms) and
   reads. inject-workflow-state.py (Python platforms) and
@@ -114,15 +114,17 @@ python ./.trellis/scripts/get_context.py --mode phase --step <X.Y>  # detailed g
     Every workflow-walkthrough step marked `[required · once]` must have a
     Every workflow-walkthrough step marked `[required · once]` must have a
     matching enforcement line in its phase's [workflow-state:*] block. The
     matching enforcement line in its phase's [workflow-state:*] block. The
     breadcrumb is the only per-turn channel; if a mandatory step isn't
     breadcrumb is the only per-turn channel; if a mandatory step isn't
-    mentioned there, the AI silently skips it (Phase 1.3 jsonl curation
+    mentioned there, the AI silently skips it (Phase 1 planning gate
     skip and Phase 3.4 commit skip both manifested via this gap).
     skip and Phase 3.4 commit skip both manifested via this gap).
 
 
   TAG ↔ PHASE scoping:
   TAG ↔ PHASE scoping:
     [workflow-state:no_task]      → no active task; before Phase 1
     [workflow-state:no_task]      → no active task; before Phase 1
     [workflow-state:planning]     → all of Phase 1 (status='planning')
     [workflow-state:planning]     → all of Phase 1 (status='planning')
-    [workflow-state:in_progress]  → Phase 2 + Phase 3.1-3.4
+    [workflow-state:planning-inline] → Codex inline variant of Phase 1
+    [workflow-state:in_progress]  → Phase 2 + Phase 3.2-3.4
                                     (status stays 'in_progress' from
                                     (status stays 'in_progress' from
                                     task.py start until task.py archive)
                                     task.py start until task.py archive)
+    [workflow-state:in_progress-inline] → Codex inline variant of Phase 2/3
     [workflow-state:completed]    → currently DEAD: cmd_archive flips
     [workflow-state:completed]    → currently DEAD: cmd_archive flips
                                     status and moves the dir in the same
                                     status and moves the dir in the same
                                     call, so the resolver loses the
                                     call, so the resolver loses the
@@ -142,45 +144,69 @@ python ./.trellis/scripts/get_context.py --mode phase --step <X.Y>  # detailed g
 ## Phase Index
 ## Phase Index
 
 
 ```
 ```
-Phase 1: Plan    → figure out what to do (brainstorm + research → prd.md)
-Phase 2: Execute → write code and pass quality checks
-Phase 3: Finish  → distill lessons + wrap-up
+Phase 1: Plan    → classify, get task-creation consent, then write planning artifacts
+Phase 2: Execute → implement only after task status is in_progress
+Phase 3: Finish  → verify, update spec, commit, and wrap up
 ```
 ```
 
 
+### Request Triage
+
+- Simple conversation or small task: ask only whether this turn should create a Trellis task. If the user says no, skip Trellis for this session.
+- Complex task: ask whether you may create a Trellis task and enter planning. If the user says no, do not do broad inline implementation; explain, clarify scope, or suggest a smaller split.
+- User approval to create a task is not approval to start implementation. Planning still happens first.
+
+### Planning Artifacts
+
+- `prd.md` — requirements, constraints, and acceptance criteria. Do not put technical design or execution checklists here.
+- `design.md` — technical design for complex tasks: boundaries, contracts, data flow, tradeoffs, compatibility, rollout / rollback shape.
+- `implement.md` — execution plan for complex tasks: ordered checklist, validation commands, review gates, and rollback points.
+- `implement.jsonl` / `check.jsonl` — spec and research manifests for sub-agent context. They do not replace `implement.md`.
+- Lightweight tasks may be PRD-only. Complex tasks must have `prd.md`, `design.md`, and `implement.md` before `task.py start`.
+
+### Parent / Child Task Trees
+
+Use a parent task when one user request contains several independently verifiable deliverables. The parent task owns the source requirement set, the task map, cross-child acceptance criteria, and final integration review; it normally should not be the implementation target unless it also has direct work.
+
+Use child tasks for deliverables that can be planned, implemented, checked, and archived independently. Parent/child structure is not a dependency system: if one child must wait for another, write that ordering in the child `prd.md` / `implement.md` and keep each child's acceptance criteria testable.
+
+Create new children with `task.py create "<title>" --slug <name> --parent <parent-dir>`. Link existing tasks with `task.py add-subtask <parent> <child>`, and unlink mistakes with `task.py remove-subtask <parent> <child>`.
+
 <!-- Per-turn breadcrumb: shown when there is no active task (before Phase 1) -->
 <!-- Per-turn breadcrumb: shown when there is no active task (before Phase 1) -->
 
 
 [workflow-state:no_task]
 [workflow-state:no_task]
-No active task. **A Direct answer** — pure Q&A / explanation / lookup / chat; no file writes + one-line answer + repo reads ≤ 2 files → AI judges, no override needed.
-**B Create a task** — any implementation / code change / build / refactor work. Entry sequence: (1) `python ./.trellis/scripts/task.py create "<title>"` to create the task (status=planning, breadcrumb switches to [workflow-state:planning] for brainstorm + jsonl phase guidance) → (2) load `trellis-brainstorm` skill to discuss requirements with the user and iterate on prd.md → (3) once prd is done and jsonl is curated, run `task.py start <task-dir>` to enter [workflow-state:in_progress] for the implementation skeleton. **"It looks small" is NOT grounds for downgrading B to A or C**.
-**C Inline change** (per-turn only, escape hatch for B) — the user's CURRENT message MUST contain one of: "skip trellis" / "no task" / "just do it" / "don't create a task" / "跳过 trellis" / "别走流程" / "小修一下" / "直接改" / "先别建任务" → briefly acknowledge ("ok, skipping trellis flow this turn"), then inline. **Without seeing one of these phrases you must NOT inline on your own**; do not invent an override the user never said.
+No active task. First classify the current turn and ask for task-creation consent before creating any Trellis task.
+Simple conversation / small task: ask only whether this turn should create a Trellis task. If the user says no, skip Trellis for this session.
+Complex task: ask the user if you can create a Trellis task and enter the planning phase. If the user says no, explain, clarify scope, or suggest a smaller split.
 [/workflow-state:no_task]
 [/workflow-state:no_task]
 
 
 ### Phase 1: Plan
 ### Phase 1: Plan
-- 1.0 Create task `[required · once]` (just `task.py create`; status enters planning)
-- 1.1 Requirement exploration `[required · repeatable]`
+- 1.0 Create task `[required · once]` (only after task-creation consent)
+- 1.1 Requirement exploration `[required · repeatable]` (`prd.md`; complex tasks also need `design.md` + `implement.md`)
 - 1.2 Research `[optional · repeatable]`
 - 1.2 Research `[optional · repeatable]`
-- 1.3 Configure context `[required · once]` — Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi
-- 1.4 Activate task `[required · once]` (run `task.py start`; status → in_progress)
+- 1.3 Configure context `[required · once]` — Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, ZCode, Reasonix (sub-agent-dispatch platforms only; inline platforms skip)
+- 1.4 Activate task `[required · once]` (review gate, then `task.py start`; status → in_progress)
 - 1.5 Completion criteria
 - 1.5 Completion criteria
 
 
 <!-- Per-turn breadcrumb: shown throughout Phase 1 (status='planning') -->
 <!-- Per-turn breadcrumb: shown throughout Phase 1 (status='planning') -->
 
 
 [workflow-state:planning]
 [workflow-state:planning]
-Load the `trellis-brainstorm` skill and iterate on prd.md with the user.
-Phase 1.3 (required, once): before `task.py start`, you MUST curate `implement.jsonl` and `check.jsonl` — list the spec / research files sub-agents need so they get the right context injected. You may skip only if the jsonl already has agent-curated entries (the seed `_example` row alone doesn't count).
-Then run `task.py start <task-dir>` to flip status to in_progress.
+Load `trellis-brainstorm`; stay in planning.
+Lightweight: `prd.md` can be enough. Complex: finish `prd.md`, `design.md`, and `implement.md`; ask for review before `task.py start`.
+Multi-deliverable scope: consider a parent task plus independently verifiable child tasks; dependencies must be written in child artifacts, not implied by tree position.
+Sub-agent mode: curate `implement.jsonl` and `check.jsonl` as spec/research manifests before start.
 [/workflow-state:planning]
 [/workflow-state:planning]
 
 
 <!-- Per-turn breadcrumb: shown throughout Phase 1 when codex.dispatch_mode=inline.
 <!-- Per-turn breadcrumb: shown throughout Phase 1 when codex.dispatch_mode=inline.
      Codex-only opt-in alternate to [workflow-state:planning]. The main agent
      Codex-only opt-in alternate to [workflow-state:planning]. The main agent
-     edits code directly in Phase 2, so Phase 1.3 jsonl curation is skipped —
+     edits code directly in Phase 2, so jsonl curation is skipped —
      the inline workflow loads `trellis-before-dev` instead of injecting JSONL
      the inline workflow loads `trellis-before-dev` instead of injecting JSONL
      into a sub-agent. -->
      into a sub-agent. -->
 
 
 [workflow-state:planning-inline]
 [workflow-state:planning-inline]
-Load the `trellis-brainstorm` skill and iterate on prd.md with the user.
-Phase 1.3 jsonl curation is **skipped** in inline dispatch mode — the main session loads `trellis-before-dev` directly in Phase 2 and reads spec context itself, so there is no sub-agent to inject jsonl into.
-Then run `task.py start <task-dir>` to flip status to in_progress.
+Load `trellis-brainstorm`; stay in planning.
+Lightweight: `prd.md` can be enough. Complex: finish `prd.md`, `design.md`, and `implement.md`; ask for review before `task.py start`.
+Multi-deliverable scope: consider a parent task plus independently verifiable child tasks; dependencies must be written in child artifacts, not implied by tree position.
+Inline mode: skip jsonl curation; Phase 2 reads artifacts/specs via `trellis-before-dev`.
 [/workflow-state:planning-inline]
 [/workflow-state:planning-inline]
 
 
 ### Phase 2: Execute
 ### Phase 2: Execute
@@ -189,18 +215,18 @@ Then run `task.py start <task-dir>` to flip status to in_progress.
 - 2.3 Rollback `[on demand]`
 - 2.3 Rollback `[on demand]`
 
 
 <!-- Per-turn breadcrumb: shown while status='in_progress'.
 <!-- Per-turn breadcrumb: shown while status='in_progress'.
-     Scope: all of Phase 2 + Phase 3.1-3.4 (status stays 'in_progress' from
+     Scope: all of Phase 2 + Phase 3.2-3.4 (status stays 'in_progress' from
      task.py start until task.py archive; only archive flips it). The body
      task.py start until task.py archive; only archive flips it). The body
      therefore must cover every required step from implementation through
      therefore must cover every required step from implementation through
      commit, including Phase 3.3 spec update and Phase 3.4 commit. -->
      commit, including Phase 3.3 spec update and Phase 3.4 commit. -->
 
 
+Sub-agent dispatch protocol applies to all platforms and all sub-agents, including class-2 Codex/Gemini/Qoder/Copilot/ZCode/Reasonix/Trae and `trellis-research`: every dispatch prompt starts with `Active task: <task path from task.py current>` before role-specific instructions.
+
 [workflow-state:in_progress]
 [workflow-state:in_progress]
-**Tools**: `trellis-implement` / `trellis-research` are sub-agent types only (Task/Agent tool, NOT Skill — there is no skill by these names). `trellis-update-spec` is a skill. `trellis-check` exists as both; prefer the Agent form when verifying after code changes.
-**Flow**: trellis-implement → trellis-check → trellis-update-spec → commit (Phase 3.4) → `/trellis:finish-work`.
-**Main-session default (no override)**: dispatch the `trellis-implement` / `trellis-check` sub-agents — the main agent does NOT edit code by default. Phase 3.4 commit (required, once): after trellis-update-spec, or whenever implementation is verifiably complete, the main agent **drives the commit** — state the commit plan in user-facing text, then run `git commit` — BEFORE suggesting `/trellis:finish-work`. `/finish-work` refuses to run on a dirty working tree (paths outside `.trellis/workspace/` and `.trellis/tasks/`).
-**Sub-agent self-exemption**: if you are already running as `trellis-implement`, implement directly from the loaded task context and do NOT spawn another `trellis-implement`; if you are already running as `trellis-check`, review/fix directly and do NOT spawn another `trellis-check`. The default dispatch rule applies to the main session only.
-**Sub-agent dispatch protocol (all platforms, all sub-agents)**: When you spawn `trellis-implement` / `trellis-check` / `trellis-research`, your dispatch prompt **MUST** start with one line: `Active task: <task path from \`task.py current\`>`. No exceptions. On class-2 platforms (codex / copilot / gemini / qoder) the sub-agent depends on this line because there is no hook to inject task context. On class-1 platforms (claude / cursor / opencode / kiro / codebuddy / droid) the line is normally redundant — the hook injects context directly — but it serves as a critical fallback when the hook fails (Windows + Claude Code PreToolUse silent skip, `--continue` resume, fork distribution, hooks disabled, etc.). For `trellis-research`, the line tells the sub-agent which `{task_dir}/research/` to write into.
-**Inline override** (per-turn only, escape hatch for sub-agent dispatch): the user's CURRENT message MUST explicitly contain one of: "do it inline" / "no sub-agent" / "你直接改" / "别派 sub-agent" / "main session 写就行" / "不用 sub-agent". **Without seeing one of these phrases you must NOT inline on your own**; do not invent an override the user never said.
+Tools: `trellis-implement` / `trellis-research` are sub-agent types only (Task/Agent tool, NOT Skill; there is no skill by these names). `trellis-update-spec` is a skill. `trellis-check` exists as both; prefer the Agent form when verifying after code changes.
+Flow: `trellis-implement` -> `trellis-check` -> `trellis-update-spec` -> commit (Phase 3.4) -> `/trellis:finish-work`.
+Main-session default: dispatch implement/check sub-agents. Sub-agent self-exemption: if already running as `trellis-implement`, do NOT spawn another `trellis-implement` or `trellis-check`; if already running as `trellis-check`, do NOT spawn another `trellis-check` or `trellis-implement`. Dispatch is main session only.
+Dispatch prompt starts with `Active task: <task path from task.py current>`. Read context: jsonl entries -> `prd.md` -> `design.md if present` -> `implement.md if present`.
 [/workflow-state:in_progress]
 [/workflow-state:in_progress]
 
 
 <!-- Per-turn breadcrumb: shown while status='in_progress' when
 <!-- Per-turn breadcrumb: shown while status='in_progress' when
@@ -209,18 +235,19 @@ Then run `task.py start <task-dir>` to flip status to in_progress.
      instead of dispatching sub-agents. -->
      instead of dispatching sub-agents. -->
 
 
 [workflow-state:in_progress-inline]
 [workflow-state:in_progress-inline]
-**Flow** (inline mode): main session loads `trellis-before-dev` → main session edits code → main session loads `trellis-check` → run lint / type-check / tests → fix → `trellis-update-spec` → commit (Phase 3.4) → `/trellis:finish-work`.
-**Main-session default (inline dispatch_mode)**: the main agent edits code directly. Do NOT dispatch `trellis-implement` / `trellis-check` sub-agents. Load the `trellis-before-dev` skill before writing code; load the `trellis-check` skill before reporting completion.
-Phase 3.4 commit (required, once): after `trellis-update-spec`, or whenever implementation is verifiably complete, the main agent **drives the commit** — state the commit plan in user-facing text, then run `git commit` — BEFORE suggesting `/trellis:finish-work`. `/finish-work` refuses to run on a dirty working tree (paths outside `.trellis/workspace/` and `.trellis/tasks/`).
+Flow: `trellis-before-dev` -> edit -> `trellis-check` -> validation -> `trellis-update-spec` -> commit (Phase 3.4) -> `/trellis:finish-work`.
+Do not dispatch implement/check sub-agents in inline mode.
+Read context: `prd.md` -> `design.md if present` -> `implement.md if present`, plus relevant spec/research loaded by skills.
 [/workflow-state:in_progress-inline]
 [/workflow-state:in_progress-inline]
 
 
 ### Phase 3: Finish
 ### Phase 3: Finish
-- 3.1 Quality verification `[required · repeatable]`
 - 3.2 Debug retrospective `[on demand]`
 - 3.2 Debug retrospective `[on demand]`
 - 3.3 Spec update `[required · once]`
 - 3.3 Spec update `[required · once]`
 - 3.4 Commit changes `[required · once]`
 - 3.4 Commit changes `[required · once]`
 - 3.5 Wrap-up reminder
 - 3.5 Wrap-up reminder
 
 
+> Note: step 3.1 was folded into 2.2 (last-iteration full-scope check) and 3.4 (commit preamble). Numbering kept stable to avoid breaking external references.
+
 <!-- Per-turn breadcrumb: shown while status='completed'.
 <!-- Per-turn breadcrumb: shown while status='completed'.
      Currently DEAD in normal flow: cmd_archive writes status='completed' in
      Currently DEAD in normal flow: cmd_archive writes status='completed' in
      the same call that moves the task dir to archive/, so the active-task
      the same call that moves the task dir to archive/, so the active-task
@@ -230,9 +257,7 @@ Phase 3.4 commit (required, once): after `trellis-update-spec`, or whenever impl
      channel as the live blocks. -->
      channel as the live blocks. -->
 
 
 [workflow-state:completed]
 [workflow-state:completed]
-Code committed via Phase 3.4; run `/trellis:finish-work` to wrap up (archive the task + record session).
-If you reach this state with uncommitted code, return to Phase 3.4 first — `/finish-work` refuses to run on a dirty working tree.
-`task.py archive` deletes any runtime session files that still point at the archived task.
+Code committed. Run `/trellis:finish-work`; if dirty, return to Phase 3.4 first.
 [/workflow-state:completed]
 [/workflow-state:completed]
 
 
 ### Rules
 ### Rules
@@ -241,60 +266,33 @@ If you reach this state with uncommitted code, return to Phase 3.4 first — `/f
 2. Run steps in order inside each Phase; `[required]` steps can't be skipped
 2. Run steps in order inside each Phase; `[required]` steps can't be skipped
 3. Phases can roll back (e.g., Execute reveals a prd defect → return to Plan to fix, then re-enter Execute)
 3. Phases can roll back (e.g., Execute reveals a prd defect → return to Plan to fix, then re-enter Execute)
 4. Steps tagged `[once]` are skipped if the output already exists; don't re-run
 4. Steps tagged `[once]` are skipped if the output already exists; don't re-run
+5. Artifact presence informs the next step; missing `design.md` / `implement.md` is valid for lightweight tasks and incomplete planning for complex tasks.
 
 
-### Skill Routing
-
-When a user request matches one of these intents, load the corresponding skill (or dispatch the corresponding sub-agent) first — do not skip skills.
-
-[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
-
-| User intent | Route |
-|---|---|
-| Wants a new feature / requirement unclear | `trellis-brainstorm` |
-| About to write code / start implementing | Dispatch the `trellis-implement` sub-agent per Phase 2.1 |
-| Finished writing / want to verify | Dispatch the `trellis-check` sub-agent per Phase 2.2 |
-| Stuck / fixed same bug several times | `trellis-break-loop` |
-| Spec needs update | `trellis-update-spec` |
-
-**Why `trellis-before-dev` is NOT in this table:** you are not the one writing code — the `trellis-implement` sub-agent is. Sub-agent platforms get spec context via `implement.jsonl` injection / prelude, not via the main thread loading `trellis-before-dev`.
-
-[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
-
-[codex-inline, Kilo, Antigravity, Windsurf]
+### Active Task Routing
 
 
-| User intent | Skill |
-|---|---|
-| Wants a new feature / requirement unclear | `trellis-brainstorm` |
-| About to write code / start implementing | `trellis-before-dev` (then implement directly in the main session) |
-| Finished writing / want to verify | `trellis-check` |
-| Stuck / fixed same bug several times | `trellis-break-loop` |
-| Spec needs update | `trellis-update-spec` |
+When a user request matches one of these intents inside an active task, route first, then load the detailed phase step if needed.
 
 
-[/codex-inline, Kilo, Antigravity, Windsurf]
+[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, ZCode, Reasonix, Trae]
 
 
-### DO NOT skip skills
+- Planning or unclear requirements -> `trellis-brainstorm`.
+- `in_progress` implementation/check -> dispatch `trellis-implement` / `trellis-check`.
+- Repeated debugging -> `trellis-break-loop`; spec updates -> `trellis-update-spec`.
 
 
-[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
+[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, ZCode, Reasonix, Trae]
 
 
-| What you're thinking | Why it's wrong |
-|---|---|
-| "This is simple, I'll just code it in the main thread" | Dispatching `trellis-implement` is the cheap path; skipping it tempts you to write code in the main thread and lose spec context — sub-agents get `implement.jsonl` injected, you don't |
-| "I already thought it through in plan mode" | Plan-mode output lives in memory — sub-agents can't see it; must be persisted to prd.md |
-| "I already know the spec" | The spec may have been updated since you last read it; the sub-agent gets the fresh copy, you may not |
-| "Code first, check later" | `trellis-check` surfaces issues you won't notice yourself; earlier is cheaper |
+[codex-inline, Kilo, Antigravity, Devin]
 
 
-[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
+- Planning or unclear requirements -> `trellis-brainstorm`.
+- Before editing -> `trellis-before-dev`; after editing -> `trellis-check`.
+- Repeated debugging -> `trellis-break-loop`; spec updates -> `trellis-update-spec`.
 
 
-[codex-inline, Kilo, Antigravity, Windsurf]
+[/codex-inline, Kilo, Antigravity, Devin]
 
 
-| What you're thinking | Why it's wrong |
-|---|---|
-| "This is simple, just code it" | Simple tasks often grow complex; `trellis-before-dev` takes under a minute and loads the spec context you'll need |
-| "I already thought it through in plan mode" | Plan-mode output lives in memory — must be persisted to prd.md before code |
-| "I already know the spec" | The spec may have been updated since you last read it; read again |
-| "Code first, check later" | `trellis-check` surfaces issues you won't notice yourself; earlier is cheaper |
+### Guardrails
 
 
-[/codex-inline, Kilo, Antigravity, Windsurf]
+- Task creation approval is not implementation approval; implementation waits for `task.py start` after artifact review.
+- PRD-only is valid for lightweight tasks; complex tasks need `design.md` + `implement.md`.
+- Planning must be persisted to task artifacts; checks must run before reporting completion.
 
 
 ### Loading Step Detail
 ### Loading Step Detail
 
 
@@ -309,11 +307,11 @@ python ./.trellis/scripts/get_context.py --mode phase --step <step>
 
 
 ## Phase 1: Plan
 ## Phase 1: Plan
 
 
-Goal: figure out what to build, produce a clear requirements doc and the context needed to implement it.
+Goal: classify the request, get task-creation consent when a task is needed, and produce the planning artifacts required before implementation.
 
 
 #### 1.0 Create task `[required · once]`
 #### 1.0 Create task `[required · once]`
 
 
-Create the task directory (status enters `planning`, the session active-task pointer auto-targets the new task when session identity is available):
+Create the task directory only after task-creation consent. The command sets status to `planning`, writes `task.json`, creates a default `prd.md`, and auto-targets the new task when session identity is available:
 
 
 ```bash
 ```bash
 python ./.trellis/scripts/task.py create "<task title>" --slug <name>
 python ./.trellis/scripts/task.py create "<task title>" --slug <name>
@@ -321,9 +319,11 @@ python ./.trellis/scripts/task.py create "<task title>" --slug <name>
 
 
 `--slug` is the human-readable name only. Do **not** include the `MM-DD-` date prefix; `task.py create` adds that prefix automatically.
 `--slug` is the human-readable name only. Do **not** include the `MM-DD-` date prefix; `task.py create` adds that prefix automatically.
 
 
-After this command succeeds, the per-turn breadcrumb auto-switches to `[workflow-state:planning]`, telling the AI to enter the brainstorm + jsonl curation phase.
+For task trees, create the parent task first and then create each child with `--parent <parent-dir>`. Do not start the parent just because children exist; start the child that owns the next independently verifiable deliverable.
 
 
-⚠️ **Run only `create` here — do not also run `start`**. `start` flips status to `in_progress`, which switches the breadcrumb to the implementation phase before brainstorm + jsonl are done — the AI will silently skip them. Save `start` for step 1.4, after jsonl curation is complete.
+After this command succeeds, the per-turn breadcrumb auto-switches to `[workflow-state:planning]`, telling the AI to stay in planning.
+
+Run only `create` here — do not also run `start`. `start` flips status to `in_progress`, which switches the breadcrumb to the implementation phase before planning artifacts are reviewed. Save `start` for step 1.4.
 
 
 Skip when `python ./.trellis/scripts/task.py current --source` already points to a task.
 Skip when `python ./.trellis/scripts/task.py current --source` already points to a task.
 
 
@@ -336,14 +336,24 @@ The brainstorm skill will guide you to:
 - Prefer researching over asking the user
 - Prefer researching over asking the user
 - Prefer offering options over open-ended questions
 - Prefer offering options over open-ended questions
 - Update `prd.md` immediately after each user answer
 - Update `prd.md` immediately after each user answer
+- Split large scopes into a parent task plus child tasks when the deliverables can be verified independently
+- Keep `prd.md` focused on requirements and acceptance criteria
+- For complex tasks, produce `design.md` and `implement.md` before implementation starts
+
+When considering a parent/child split:
+- Use a parent task when one request contains several independently verifiable deliverables.
+- Parent tasks own source requirements, child-task mapping, cross-child acceptance criteria, and final integration review.
+- Child tasks own actual deliverables that can be planned, implemented, checked, and archived independently.
+- Parent/child structure is not a dependency system. If child B depends on child A, write that ordering in child B's `prd.md` / `implement.md`.
+- Start the child task that owns the next deliverable. Do not start the parent unless the parent itself has direct implementation work.
 
 
-Return to this step whenever requirements change and revise `prd.md`.
+Return to this step whenever requirements change and revise the relevant artifact.
 
 
 #### 1.2 Research `[optional · repeatable]`
 #### 1.2 Research `[optional · repeatable]`
 
 
 Research can happen at any time during requirement exploration. It isn't limited to local code — you can use any available tool (MCP servers, skills, web search, etc.) to look up external information, including third-party library docs, industry practices, API references, etc.
 Research can happen at any time during requirement exploration. It isn't limited to local code — you can use any available tool (MCP servers, skills, web search, etc.) to look up external information, including third-party library docs, industry practices, API references, etc.
 
 
-[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
+[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, ZCode, Reasonix, Trae]
 
 
 Spawn the research sub-agent:
 Spawn the research sub-agent:
 
 
@@ -351,13 +361,13 @@ Spawn the research sub-agent:
 - **Task description**: Research <specific question>
 - **Task description**: Research <specific question>
 - **Key requirement**: Research output MUST be persisted to `{TASK_DIR}/research/`
 - **Key requirement**: Research output MUST be persisted to `{TASK_DIR}/research/`
 
 
-[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
+[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, ZCode, Reasonix, Trae]
 
 
-[codex-inline, Kilo, Antigravity, Windsurf]
+[codex-inline, Kilo, Antigravity, Devin]
 
 
 Do the research in the main session directly and write findings into `{TASK_DIR}/research/`. (For `codex-inline` this avoids the `fork_turns="none"` isolation that prevents `trellis-research` sub-agents from resolving the active task path.)
 Do the research in the main session directly and write findings into `{TASK_DIR}/research/`. (For `codex-inline` this avoids the `fork_turns="none"` isolation that prevents `trellis-research` sub-agents from resolving the active task path.)
 
 
-[/codex-inline, Kilo, Antigravity, Windsurf]
+[/codex-inline, Kilo, Antigravity, Devin]
 
 
 **Research artifact conventions**:
 **Research artifact conventions**:
 - One file per research topic (e.g. `research/auth-library-comparison.md`)
 - One file per research topic (e.g. `research/auth-library-comparison.md`)
@@ -370,9 +380,9 @@ Brainstorm and research can interleave freely — pause to research a technical
 
 
 #### 1.3 Configure context `[required · once]`
 #### 1.3 Configure context `[required · once]`
 
 
-[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
+[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, ZCode, Reasonix, Trae]
 
 
-Curate `implement.jsonl` and `check.jsonl` so the Phase 2 sub-agents get the right spec context. These files were seeded on `task create` with a single self-describing `_example` line; your job here is to fill in real entries.
+Curate `implement.jsonl` and `check.jsonl` so the Phase 2 sub-agents get the right spec/research context. These files were seeded on `task create` with a single self-describing `_example` line; your job here is to fill in real entries.
 
 
 **Location**: `{TASK_DIR}/implement.jsonl` and `{TASK_DIR}/check.jsonl` (already exist).
 **Location**: `{TASK_DIR}/implement.jsonl` and `{TASK_DIR}/check.jsonl` (already exist).
 
 
@@ -390,6 +400,8 @@ Curate `implement.jsonl` and `check.jsonl` so the Phase 2 sub-agents get the rig
 - `implement.jsonl` → specs + research the implement sub-agent needs to write code correctly
 - `implement.jsonl` → specs + research the implement sub-agent needs to write code correctly
 - `check.jsonl` → specs for the check sub-agent (quality guidelines, check conventions, same research if needed)
 - `check.jsonl` → specs for the check sub-agent (quality guidelines, check conventions, same research if needed)
 
 
+These manifests do not replace `implement.md`. `implement.md` is the human-readable execution plan for a complex task; jsonl files only list context files to inject or load.
+
 **How to discover relevant specs**:
 **How to discover relevant specs**:
 
 
 ```bash
 ```bash
@@ -409,24 +421,28 @@ python ./.trellis/scripts/task.py add-context "$TASK_DIR" check "<path>" "<reaso
 
 
 Delete the seed `_example` line once real entries exist (optional — it's skipped automatically by consumers).
 Delete the seed `_example` line once real entries exist (optional — it's skipped automatically by consumers).
 
 
-Skip when: `implement.jsonl` has agent-curated entries (the seed row alone doesn't count).
+Ready gate: both `implement.jsonl` and `check.jsonl` must contain at least one real `{"file": "...", "reason": "..."}` entry before `task.py start`. The seed `_example` row alone is not ready.
+
+Skip this step only when both files already have real curated entries.
 
 
-[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
+[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, ZCode, Reasonix, Trae]
 
 
-[codex-inline, Kilo, Antigravity, Windsurf]
+[codex-inline, Kilo, Antigravity, Devin]
 
 
 Skip this step. Context is loaded directly by the `trellis-before-dev` skill in Phase 2.
 Skip this step. Context is loaded directly by the `trellis-before-dev` skill in Phase 2.
 
 
-[/codex-inline, Kilo, Antigravity, Windsurf]
+[/codex-inline, Kilo, Antigravity, Devin]
 
 
 #### 1.4 Activate task `[required · once]`
 #### 1.4 Activate task `[required · once]`
 
 
-Once prd.md is complete and 1.3 jsonl curation is done, flip the task status to `in_progress`:
+After artifact review, flip the task status to `in_progress`:
 
 
 ```bash
 ```bash
 python ./.trellis/scripts/task.py start <task-dir>
 python ./.trellis/scripts/task.py start <task-dir>
 ```
 ```
 
 
+For lightweight tasks, `prd.md` can be enough. For complex tasks, `prd.md`, `design.md`, and `implement.md` must exist and be reviewed before start. On sub-agent-dispatch platforms, `implement.jsonl` and `check.jsonl` must both have real curated entries before start. Runtime consumers tolerate missing or seed-only manifests for compatibility, but that tolerance is not a planning-ready state.
+
 After this command succeeds, the breadcrumb auto-switches to `[workflow-state:in_progress]`, and the rest of Phase 2 / 3 follows.
 After this command succeeds, the breadcrumb auto-switches to `[workflow-state:in_progress]`, and the rest of Phase 2 / 3 follows.
 
 
 If `task.py start` errors with a session-identity message (no context key from hook input, `TRELLIS_CONTEXT_ID`, or platform-native session env), follow the hint in the error to set up session identity, then retry.
 If `task.py start` errors with a session-identity message (no context key from hook input, `TRELLIS_CONTEXT_ID`, or platform-native session env), follow the hint in the error to set up session identity, then retry.
@@ -436,95 +452,97 @@ If `task.py start` errors with a session-identity message (no context key from h
 | Condition | Required |
 | Condition | Required |
 |------|:---:|
 |------|:---:|
 | `prd.md` exists | ✅ |
 | `prd.md` exists | ✅ |
-| User confirms requirements | ✅ |
+| User confirms task should enter implementation | ✅ |
 | `task.py start` has been run (status = in_progress) | ✅ |
 | `task.py start` has been run (status = in_progress) | ✅ |
 | `research/` has artifacts (complex tasks) | recommended |
 | `research/` has artifacts (complex tasks) | recommended |
-| `info.md` technical design (complex tasks) | optional |
+| `design.md` exists (complex tasks) | ✅ |
+| `implement.md` exists (complex tasks) | ✅ |
 
 
-[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
+[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, ZCode, Reasonix, Trae]
 
 
-| `implement.jsonl` has agent-curated entries (not just the seed row) | ✅ |
+| `implement.jsonl` and `check.jsonl` each contain at least one real curated entry (seed row does not count) | ✅ |
 
 
-[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
+[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, ZCode, Reasonix, Trae]
 
 
 ---
 ---
 
 
 ## Phase 2: Execute
 ## Phase 2: Execute
 
 
-Goal: turn the prd into code that passes quality checks.
+Goal: turn reviewed planning artifacts into code that passes quality checks.
 
 
 #### 2.1 Implement `[required · repeatable]`
 #### 2.1 Implement `[required · repeatable]`
 
 
-[Claude Code, Cursor, OpenCode, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
+[Claude Code, Cursor, OpenCode, CodeBuddy, Droid, Pi]
 
 
 Spawn the implement sub-agent:
 Spawn the implement sub-agent:
 
 
 - **Agent type**: `trellis-implement`
 - **Agent type**: `trellis-implement`
-- **Task description**: Implement the requirements per prd.md, consulting materials under `{TASK_DIR}/research/`; finish by running project lint and type-check
+- **Task description**: Implement the reviewed task artifacts, consulting materials under `{TASK_DIR}/research/`; finish by running project lint and type-check
 - **Dispatch prompt guard**: Tell the spawned agent it is already the `trellis-implement` sub-agent and must implement directly, not spawn another `trellis-implement` / `trellis-check`.
 - **Dispatch prompt guard**: Tell the spawned agent it is already the `trellis-implement` sub-agent and must implement directly, not spawn another `trellis-implement` / `trellis-check`.
 
 
 The platform hook/plugin auto-handles:
 The platform hook/plugin auto-handles:
-- Reads `implement.jsonl` and injects the referenced spec files into the agent prompt
-- Injects prd.md content
+- Reads `implement.jsonl` and injects referenced spec/research files into the agent prompt
+- Injects `prd.md`, `design.md` if present, and `implement.md` if present
 
 
-[/Claude Code, Cursor, OpenCode, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
+[/Claude Code, Cursor, OpenCode, CodeBuddy, Droid, Pi]
 
 
-[codex-sub-agent]
+[codex-sub-agent, Gemini, Qoder, Copilot, ZCode, Reasonix, Trae]
 
 
 Spawn the implement sub-agent:
 Spawn the implement sub-agent:
 
 
 - **Agent type**: `trellis-implement`
 - **Agent type**: `trellis-implement`
-- **Task description**: Implement the requirements per prd.md, consulting materials under `{TASK_DIR}/research/`; finish by running project lint and type-check
+- **Task description**: Implement the reviewed task artifacts, consulting materials under `{TASK_DIR}/research/`; finish by running project lint and type-check
 - **Dispatch prompt guard**: The prompt MUST start with `Active task: <task path>`, then explicitly say the spawned agent is already `trellis-implement` and must implement directly without spawning another `trellis-implement` / `trellis-check`.
 - **Dispatch prompt guard**: The prompt MUST start with `Active task: <task path>`, then explicitly say the spawned agent is already `trellis-implement` and must implement directly without spawning another `trellis-implement` / `trellis-check`.
 
 
-The Codex sub-agent definition auto-handles the context load requirement:
-- Resolves the active task with `task.py current --source`, then reads `prd.md` and `info.md` if present
-- Reads `implement.jsonl` and requires the agent to load each referenced spec file before coding
+The pull-based sub-agent definition auto-handles the context load requirement:
+- Resolves the active task with `task.py current --source`, then reads `prd.md`, `design.md` if present, and `implement.md` if present
+- Reads `implement.jsonl` and requires the agent to load each referenced spec/research file before coding
 
 
-[/codex-sub-agent]
+[/codex-sub-agent, Gemini, Qoder, Copilot, ZCode, Reasonix, Trae]
 
 
 [Kiro]
 [Kiro]
 
 
 Spawn the implement sub-agent:
 Spawn the implement sub-agent:
 
 
 - **Agent type**: `trellis-implement`
 - **Agent type**: `trellis-implement`
-- **Task description**: Implement the requirements per prd.md, consulting materials under `{TASK_DIR}/research/`; finish by running project lint and type-check
+- **Task description**: Implement the reviewed task artifacts, consulting materials under `{TASK_DIR}/research/`; finish by running project lint and type-check
 - **Dispatch prompt guard**: Tell the spawned agent it is already the `trellis-implement` sub-agent and must implement directly, not spawn another `trellis-implement` / `trellis-check`.
 - **Dispatch prompt guard**: Tell the spawned agent it is already the `trellis-implement` sub-agent and must implement directly, not spawn another `trellis-implement` / `trellis-check`.
 
 
 The platform prelude auto-handles the context load requirement:
 The platform prelude auto-handles the context load requirement:
-- Reads `implement.jsonl` and injects the referenced spec files into the agent prompt
-- Injects prd.md content
+- Reads `implement.jsonl` and injects referenced spec/research files into the agent prompt
+- Injects `prd.md`, `design.md` if present, and `implement.md` if present
 
 
 [/Kiro]
 [/Kiro]
 
 
-[codex-inline, Kilo, Antigravity, Windsurf]
+[codex-inline, Kilo, Antigravity, Devin]
 
 
 1. Load the `trellis-before-dev` skill to read project guidelines
 1. Load the `trellis-before-dev` skill to read project guidelines
-2. Read `{TASK_DIR}/prd.md` for requirements
+2. Read `{TASK_DIR}/prd.md`, then `design.md` if present, then `implement.md` if present
 3. Consult materials under `{TASK_DIR}/research/`
 3. Consult materials under `{TASK_DIR}/research/`
-4. Implement the code per requirements
+4. Implement the code per reviewed artifacts
 5. Run project lint and type-check
 5. Run project lint and type-check
 
 
-[/codex-inline, Kilo, Antigravity, Windsurf]
+[/codex-inline, Kilo, Antigravity, Devin]
 
 
 #### 2.2 Quality check `[required · repeatable]`
 #### 2.2 Quality check `[required · repeatable]`
 
 
-[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
+[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, ZCode, Reasonix, Trae]
 
 
 Spawn the check sub-agent:
 Spawn the check sub-agent:
 
 
 - **Agent type**: `trellis-check`
 - **Agent type**: `trellis-check`
-- **Task description**: Review all code changes against spec and prd; fix any findings directly; ensure lint and type-check pass
+- **Task description**: Review all code changes against specs and task artifacts; fix any findings directly; ensure lint and type-check pass
 - **Dispatch prompt guard**: Tell the spawned agent it is already the `trellis-check` sub-agent and must review/fix directly, not spawn another `trellis-check` / `trellis-implement`.
 - **Dispatch prompt guard**: Tell the spawned agent it is already the `trellis-check` sub-agent and must review/fix directly, not spawn another `trellis-check` / `trellis-implement`.
 
 
 The check agent's job:
 The check agent's job:
 - Review code changes against specs
 - Review code changes against specs
+- Review code changes against `prd.md`, `design.md` if present, and `implement.md` if present
 - Auto-fix issues it finds
 - Auto-fix issues it finds
 - Run lint and typecheck to verify
 - Run lint and typecheck to verify
 
 
-[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
+[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, ZCode, Reasonix, Trae]
 
 
-[codex-inline, Kilo, Antigravity, Windsurf]
+[codex-inline, Kilo, Antigravity, Devin]
 
 
 Load the `trellis-check` skill and verify the code per its guidance:
 Load the `trellis-check` skill and verify the code per its guidance:
 - Spec compliance
 - Spec compliance
@@ -533,7 +551,9 @@ Load the `trellis-check` skill and verify the code per its guidance:
 
 
 If issues are found → fix → re-check, until green.
 If issues are found → fix → re-check, until green.
 
 
-[/codex-inline, Kilo, Antigravity, Windsurf]
+[/codex-inline, Kilo, Antigravity, Devin]
+
+**Final pass (before Phase 3.4 commit)**: the last 2.2 of a task must run full-scope, not just on the latest implement chunk. List all affected packages with `python ./.trellis/scripts/get_context.py --mode packages`, then load each package's spec index Quality Check section. This catches cross-layer / multi-package issues a mid-iteration local 2.2 cannot.
 
 
 #### 2.3 Rollback `[on demand]`
 #### 2.3 Rollback `[on demand]`
 
 
@@ -547,15 +567,6 @@ If issues are found → fix → re-check, until green.
 
 
 Goal: ensure code quality, capture lessons, record the work.
 Goal: ensure code quality, capture lessons, record the work.
 
 
-#### 3.1 Quality verification `[required · repeatable]`
-
-Load the `trellis-check` skill and do a final verification:
-- Spec compliance
-- lint / type-check / tests
-- Cross-layer consistency (when changes span layers)
-
-If issues are found → fix → re-check, until green.
-
 #### 3.2 Debug retrospective `[on demand]`
 #### 3.2 Debug retrospective `[on demand]`
 
 
 If this task involved repeated debugging (the same issue was fixed multiple times), load the `trellis-break-loop` skill to:
 If this task involved repeated debugging (the same issue was fixed multiple times), load the `trellis-break-loop` skill to:
@@ -576,6 +587,8 @@ Update the docs under `.trellis/spec/` accordingly. Even if the conclusion is "n
 
 
 #### 3.4 Commit changes `[required · once]`
 #### 3.4 Commit changes `[required · once]`
 
 
+**Spec-sync preamble**: before drafting commits, ask: did this task fix a bug or surface non-obvious knowledge that should land in `.trellis/spec/` so future-you (or future-AI) doesn't repeat the mistake? If yes, return to Phase 3.3 first — spec writes belong in the same task's commit batch, not as a forgotten follow-up.
+
 The AI drives a batched commit of this task's code changes so `/finish-work` can run cleanly afterwards. Goal: produce work commits FIRST, then bookkeeping (archive + journal) commits land after — never interleaved.
 The AI drives a batched commit of this task's code changes so `/finish-work` can run cleanly afterwards. Goal: produce work commits FIRST, then bookkeeping (archive + journal) commits land after — never interleaved.
 
 
 **Step-by-step**:
 **Step-by-step**:
@@ -636,15 +649,20 @@ This section is for developers who want to modify the Trellis workflow itself. A
 
 
 ### Changing what a step means
 ### Changing what a step means
 
 
-Edit the corresponding step's walkthrough body in the Phase 1 / 2 / 3 sections above. **Critical constraint**: if you change a step's `[required · once]` marker or add a new `[required · once]` step, you MUST also add a matching enforcement line to that phase's `[workflow-state:STATUS]` tag block — otherwise the per-turn breadcrumb omits the reinforcement, and the AI silently skips the step. The regression tests assert this.
+Edit the corresponding step's walkthrough body in the Phase 1 / 2 / 3 sections above. Critical invariants:
+- No active task must triage first and ask for task-creation consent before creating a Trellis task.
+- Planning must distinguish lightweight PRD-only tasks from complex tasks that require `prd.md`, `design.md`, and `implement.md` before start.
+- Every required execution path must keep the Phase 3.4 commit reminder reachable before `/trellis:finish-work`.
 
 
-All 4 tag blocks live in the `## Phase Index` section above, immediately after each phase summary:
+All tag blocks live in the `## Phase Index` section above, immediately after each phase summary:
 
 
 | Scope | Corresponding tag |
 | Scope | Corresponding tag |
 |---|---|
 |---|---|
 | No active task (before Phase 1) | `[workflow-state:no_task]` (after the Phase Index ASCII art) |
 | No active task (before Phase 1) | `[workflow-state:no_task]` (after the Phase Index ASCII art) |
 | All of Phase 1 (task created → ready for implementation) | `[workflow-state:planning]` (after Phase 1 summary) |
 | All of Phase 1 (task created → ready for implementation) | `[workflow-state:planning]` (after Phase 1 summary) |
-| Phase 2 + Phase 3.1–3.4 (implementation + check + wrap-up) | `[workflow-state:in_progress]` (after Phase 2 summary) |
+| Codex inline Phase 1 | `[workflow-state:planning-inline]` |
+| Phase 2 + Phase 3.2–3.4 (implementation + check + wrap-up) | `[workflow-state:in_progress]` (after Phase 2 summary) |
+| Codex inline Phase 2 + Phase 3.2–3.4 | `[workflow-state:in_progress-inline]` |
 | After Phase 3.5 (archived) | `[workflow-state:completed]` (after Phase 3 summary; **currently DEAD**) |
 | After Phase 3.5 (archived) | `[workflow-state:completed]` (after Phase 3 summary; **currently DEAD**) |
 
 
 ### Changing the per-turn prompt text
 ### Changing the per-turn prompt text