@blxzer/cursor-trellis 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +23 -14
  3. package/README.zh-CN.md +14 -10
  4. package/bin/smart-search.js +10 -2
  5. package/dist/cli/index.d.ts.map +1 -1
  6. package/dist/cli/index.js +36 -15
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/commands/init.d.ts +1 -1
  9. package/dist/commands/init.d.ts.map +1 -1
  10. package/dist/commands/init.js +42 -153
  11. package/dist/commands/init.js.map +1 -1
  12. package/dist/commands/migrate.d.ts +10 -0
  13. package/dist/commands/migrate.d.ts.map +1 -0
  14. package/dist/commands/migrate.js +38 -0
  15. package/dist/commands/migrate.js.map +1 -0
  16. package/dist/commands/update.d.ts +5 -0
  17. package/dist/commands/update.d.ts.map +1 -1
  18. package/dist/commands/update.js +137 -40
  19. package/dist/commands/update.js.map +1 -1
  20. package/dist/configurators/cursor.d.ts +2 -1
  21. package/dist/configurators/cursor.d.ts.map +1 -1
  22. package/dist/configurators/cursor.js +4 -2
  23. package/dist/configurators/cursor.js.map +1 -1
  24. package/dist/configurators/index.js +4 -4
  25. package/dist/configurators/index.js.map +1 -1
  26. package/dist/configurators/shared.d.ts +8 -0
  27. package/dist/configurators/shared.d.ts.map +1 -1
  28. package/dist/configurators/shared.js +27 -1
  29. package/dist/configurators/shared.js.map +1 -1
  30. package/dist/configurators/workflow.d.ts +0 -9
  31. package/dist/configurators/workflow.d.ts.map +1 -1
  32. package/dist/configurators/workflow.js +2 -4
  33. package/dist/configurators/workflow.js.map +1 -1
  34. package/dist/constants/paths.d.ts +9 -0
  35. package/dist/constants/paths.d.ts.map +1 -1
  36. package/dist/constants/paths.js +13 -0
  37. package/dist/constants/paths.js.map +1 -1
  38. package/dist/migrations/manifests/0.3.0.json +1 -1
  39. package/dist/templates/common/bundled-skills/cstl-meta/references/platform-files/skills-and-commands.md +2 -4
  40. package/dist/templates/common/bundled-skills/cstl-skill-creator/SKILL.md +10 -7
  41. package/dist/templates/common/bundled-skills/cstl-skill-creator/references/authoring-rules.md +93 -19
  42. package/dist/templates/common/bundled-skills/cstl-skill-creator/references/general-authoring.md +189 -0
  43. package/dist/templates/common/bundled-skills/cstl-skill-creator/references/review-checklist.md +10 -5
  44. package/dist/templates/common/commands/continue.md +5 -4
  45. package/dist/templates/common/index.d.ts +20 -0
  46. package/dist/templates/common/index.d.ts.map +1 -1
  47. package/dist/templates/common/index.js +21 -2
  48. package/dist/templates/common/index.js.map +1 -1
  49. package/dist/templates/common/optional-skills/chrome-cdp/SKILL.md +179 -0
  50. package/dist/templates/common/optional-skills/chrome-cdp/examples/fetch-hook-api-capture.md +149 -0
  51. package/dist/templates/common/optional-skills/chrome-cdp/scripts/cdp.mjs +903 -0
  52. package/dist/templates/cursor/agents/cstl-research.md +1 -1
  53. package/dist/templates/cursor/fixtures/expected-rules.d.ts +1 -1
  54. package/dist/templates/cursor/fixtures/expected-rules.d.ts.map +1 -1
  55. package/dist/templates/cursor/fixtures/expected-rules.js +7 -24
  56. package/dist/templates/cursor/fixtures/expected-rules.js.map +1 -1
  57. package/dist/templates/cursor/hooks.json +4 -0
  58. package/dist/templates/cursor/index.d.ts +1 -1
  59. package/dist/templates/cursor/index.js +1 -1
  60. package/dist/templates/cursor/rules/cstl-bootstrap.mdc +17 -0
  61. package/dist/templates/markdown/agents.md +15 -10
  62. package/dist/templates/markdown/framework/cursor-native-modes-guide.md.txt +12 -9
  63. package/dist/templates/markdown/framework/cursor-subagent-policy.md.txt +62 -126
  64. package/dist/templates/markdown/framework/dogfood-only-surfaces.md.txt +4 -6
  65. package/dist/templates/markdown/framework/execution-strategy.md.txt +2 -0
  66. package/dist/templates/markdown/framework/index.md.txt +4 -0
  67. package/dist/templates/markdown/framework/internal-skills-cursor-reachability.md.txt +4 -3
  68. package/dist/templates/markdown/framework/middleware-protocol.md.txt +83 -0
  69. package/dist/templates/markdown/framework/parallel-first-execution.md.txt +78 -0
  70. package/dist/templates/markdown/framework/release-boundary.md.txt +30 -0
  71. package/dist/templates/markdown/framework/retrieval-daily-guide.md.txt +1 -1
  72. package/dist/templates/markdown/framework/upgrade.md.txt +15 -0
  73. package/dist/templates/markdown/index.d.ts +4 -0
  74. package/dist/templates/markdown/index.d.ts.map +1 -1
  75. package/dist/templates/markdown/index.js +17 -0
  76. package/dist/templates/markdown/index.js.map +1 -1
  77. package/dist/templates/markdown/spec/guides/index.md.txt +0 -6
  78. package/dist/templates/shared-hooks/event-bridge.py +60 -0
  79. package/dist/templates/shared-hooks/index.d.ts +1 -1
  80. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  81. package/dist/templates/shared-hooks/index.js +1 -0
  82. package/dist/templates/shared-hooks/index.js.map +1 -1
  83. package/dist/templates/shared-hooks/session-start.py +18 -1
  84. package/dist/templates/trellis/CONTEXT.md +63 -3
  85. package/dist/templates/trellis/gitignore.txt +39 -39
  86. package/dist/templates/trellis/index.d.ts +12 -0
  87. package/dist/templates/trellis/index.d.ts.map +1 -1
  88. package/dist/templates/trellis/index.js +73 -15
  89. package/dist/templates/trellis/index.js.map +1 -1
  90. package/dist/templates/trellis/pool/README.md +12 -3
  91. package/dist/templates/trellis/pool/plan.md +24 -5
  92. package/dist/templates/trellis/scripts/common/adapter_middleware.py +158 -0
  93. package/dist/templates/trellis/scripts/common/artifact_locale.py +12 -3
  94. package/dist/templates/trellis/scripts/common/cursor_retrieval_env.py +5 -2
  95. package/dist/templates/trellis/scripts/common/full_quality.py +237 -0
  96. package/dist/templates/trellis/scripts/common/git.py +6 -0
  97. package/dist/templates/trellis/scripts/common/git_context.py +17 -5
  98. package/dist/templates/trellis/scripts/common/kernel_command.py +367 -0
  99. package/dist/templates/trellis/scripts/common/lite_context.py +280 -0
  100. package/dist/templates/trellis/scripts/common/ondemand_topology.py +225 -0
  101. package/dist/templates/trellis/scripts/common/parent_orchestration.py +1 -1
  102. package/dist/templates/trellis/scripts/common/pool_store.py +16 -4
  103. package/dist/templates/trellis/scripts/common/retrieval_agent_instructions.py +2 -2
  104. package/dist/templates/trellis/scripts/common/session_context.py +28 -2
  105. package/dist/templates/trellis/scripts/common/task_gates.py +73 -12
  106. package/dist/templates/trellis/scripts/common/task_map.py +42 -9
  107. package/dist/templates/trellis/scripts/common/task_store.py +286 -56
  108. package/dist/templates/trellis/scripts/common/test_adapter_middleware.py +56 -0
  109. package/dist/templates/trellis/scripts/common/test_depends_mode_block.py +9 -0
  110. package/dist/templates/trellis/scripts/common/test_full_quality.py +197 -0
  111. package/dist/templates/trellis/scripts/common/test_kernel_command.py +326 -0
  112. package/dist/templates/trellis/scripts/common/test_lite_path.py +190 -0
  113. package/dist/templates/trellis/scripts/common/test_ondemand_topology.py +122 -0
  114. package/dist/templates/trellis/scripts/common/test_pool_store.py +17 -0
  115. package/dist/templates/trellis/scripts/common/test_task_store_kernel_patch.py +163 -0
  116. package/dist/templates/trellis/scripts/common/workflow_phase.py +3 -0
  117. package/dist/templates/trellis/scripts/get_context.py +1 -0
  118. package/dist/templates/trellis/scripts/pool.py +5 -0
  119. package/dist/templates/trellis/scripts/task.py +83 -7
  120. package/dist/templates/trellis/workflow.md +100 -18
  121. package/dist/utils/cursor-retrieval-env.d.ts +2 -1
  122. package/dist/utils/cursor-retrieval-env.d.ts.map +1 -1
  123. package/dist/utils/cursor-retrieval-env.js +3 -2
  124. package/dist/utils/cursor-retrieval-env.js.map +1 -1
  125. package/dist/utils/cursor2plus-residue-cleanup.d.ts +38 -0
  126. package/dist/utils/cursor2plus-residue-cleanup.d.ts.map +1 -0
  127. package/dist/utils/cursor2plus-residue-cleanup.js +145 -0
  128. package/dist/utils/cursor2plus-residue-cleanup.js.map +1 -0
  129. package/dist/utils/manifest-prune.d.ts.map +1 -1
  130. package/dist/utils/manifest-prune.js +7 -2
  131. package/dist/utils/manifest-prune.js.map +1 -1
  132. package/dist/utils/p36-upgrade.d.ts +62 -0
  133. package/dist/utils/p36-upgrade.d.ts.map +1 -0
  134. package/dist/utils/p36-upgrade.js +160 -0
  135. package/dist/utils/p36-upgrade.js.map +1 -0
  136. package/dist/utils/project-capabilities.d.ts +1 -12
  137. package/dist/utils/project-capabilities.d.ts.map +1 -1
  138. package/dist/utils/project-capabilities.js +3 -100
  139. package/dist/utils/project-capabilities.js.map +1 -1
  140. package/dist/utils/readiness.d.ts +10 -0
  141. package/dist/utils/readiness.d.ts.map +1 -1
  142. package/dist/utils/readiness.js +58 -26
  143. package/dist/utils/readiness.js.map +1 -1
  144. package/dist/utils/retrieval-agent-instructions.js +1 -1
  145. package/dist/utils/retrieval-agent-instructions.js.map +1 -1
  146. package/dist/utils/template-hash.d.ts.map +1 -1
  147. package/dist/utils/template-hash.js +11 -1
  148. package/dist/utils/template-hash.js.map +1 -1
  149. package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
  150. package/dist/utils/uninstall-scrubbers.js +52 -14
  151. package/dist/utils/uninstall-scrubbers.js.map +1 -1
  152. package/dist/utils/update-rollout-report.d.ts +14 -0
  153. package/dist/utils/update-rollout-report.d.ts.map +1 -1
  154. package/dist/utils/update-rollout-report.js +1 -0
  155. package/dist/utils/update-rollout-report.js.map +1 -1
  156. package/dist/utils/workflow-ownership.d.ts +1 -1
  157. package/dist/utils/workflow-ownership.js +4 -4
  158. package/dist/utils/workflow-ownership.js.map +1 -1
  159. package/package.json +5 -4
  160. package/scripts/postinstall.js +6 -7
  161. package/dist/commands/campaign/canvas-render.d.ts +0 -68
  162. package/dist/commands/campaign/canvas-render.d.ts.map +0 -1
  163. package/dist/commands/campaign/canvas-render.js +0 -414
  164. package/dist/commands/campaign/canvas-render.js.map +0 -1
  165. package/dist/commands/campaign/compose.d.ts +0 -15
  166. package/dist/commands/campaign/compose.d.ts.map +0 -1
  167. package/dist/commands/campaign/compose.js +0 -110
  168. package/dist/commands/campaign/compose.js.map +0 -1
  169. package/dist/commands/campaign/index.d.ts +0 -13
  170. package/dist/commands/campaign/index.d.ts.map +0 -1
  171. package/dist/commands/campaign/index.js +0 -134
  172. package/dist/commands/campaign/index.js.map +0 -1
  173. package/dist/commands/campaign/kind-map.d.ts +0 -6
  174. package/dist/commands/campaign/kind-map.d.ts.map +0 -1
  175. package/dist/commands/campaign/kind-map.js +0 -21
  176. package/dist/commands/campaign/kind-map.js.map +0 -1
  177. package/dist/commands/campaign/mcp-server.d.ts +0 -6
  178. package/dist/commands/campaign/mcp-server.d.ts.map +0 -1
  179. package/dist/commands/campaign/mcp-server.js +0 -167
  180. package/dist/commands/campaign/mcp-server.js.map +0 -1
  181. package/dist/commands/campaign/render.d.ts +0 -5
  182. package/dist/commands/campaign/render.d.ts.map +0 -1
  183. package/dist/commands/campaign/render.js +0 -103
  184. package/dist/commands/campaign/render.js.map +0 -1
  185. package/dist/commands/campaign/trellis-load.d.ts +0 -13
  186. package/dist/commands/campaign/trellis-load.d.ts.map +0 -1
  187. package/dist/commands/campaign/trellis-load.js +0 -122
  188. package/dist/commands/campaign/trellis-load.js.map +0 -1
  189. package/dist/commands/campaign/types.d.ts +0 -61
  190. package/dist/commands/campaign/types.d.ts.map +0 -1
  191. package/dist/commands/campaign/types.js +0 -3
  192. package/dist/commands/campaign/types.js.map +0 -1
  193. package/dist/commands/goal/index.d.ts +0 -3
  194. package/dist/commands/goal/index.d.ts.map +0 -1
  195. package/dist/commands/goal/index.js +0 -159
  196. package/dist/commands/goal/index.js.map +0 -1
  197. package/dist/commands/goal/review.d.ts +0 -6
  198. package/dist/commands/goal/review.d.ts.map +0 -1
  199. package/dist/commands/goal/review.js +0 -28
  200. package/dist/commands/goal/review.js.map +0 -1
  201. package/dist/commands/rpc/client.d.ts +0 -51
  202. package/dist/commands/rpc/client.d.ts.map +0 -1
  203. package/dist/commands/rpc/client.js +0 -147
  204. package/dist/commands/rpc/client.js.map +0 -1
  205. package/dist/commands/rpc/index.d.ts +0 -10
  206. package/dist/commands/rpc/index.d.ts.map +0 -1
  207. package/dist/commands/rpc/index.js +0 -157
  208. package/dist/commands/rpc/index.js.map +0 -1
  209. package/dist/commands/rpc/serve.d.ts +0 -23
  210. package/dist/commands/rpc/serve.d.ts.map +0 -1
  211. package/dist/commands/rpc/serve.js +0 -60
  212. package/dist/commands/rpc/serve.js.map +0 -1
  213. package/dist/commands/rpc/smoke.d.ts +0 -16
  214. package/dist/commands/rpc/smoke.d.ts.map +0 -1
  215. package/dist/commands/rpc/smoke.js +0 -92
  216. package/dist/commands/rpc/smoke.js.map +0 -1
  217. package/dist/commands/sdk/index.d.ts +0 -9
  218. package/dist/commands/sdk/index.d.ts.map +0 -1
  219. package/dist/commands/sdk/index.js +0 -58
  220. package/dist/commands/sdk/index.js.map +0 -1
  221. package/dist/commands/sdk/run.d.ts +0 -42
  222. package/dist/commands/sdk/run.d.ts.map +0 -1
  223. package/dist/commands/sdk/run.js +0 -220
  224. package/dist/commands/sdk/run.js.map +0 -1
  225. package/dist/commands/sdk/status.d.ts +0 -14
  226. package/dist/commands/sdk/status.d.ts.map +0 -1
  227. package/dist/commands/sdk/status.js +0 -69
  228. package/dist/commands/sdk/status.js.map +0 -1
  229. package/dist/configurators/cursor2plus-local.d.ts +0 -6
  230. package/dist/configurators/cursor2plus-local.d.ts.map +0 -1
  231. package/dist/configurators/cursor2plus-local.js +0 -21
  232. package/dist/configurators/cursor2plus-local.js.map +0 -1
  233. package/dist/goal/action-packet.d.ts +0 -89
  234. package/dist/goal/action-packet.d.ts.map +0 -1
  235. package/dist/goal/action-packet.js +0 -113
  236. package/dist/goal/action-packet.js.map +0 -1
  237. package/dist/goal/audit.d.ts +0 -14
  238. package/dist/goal/audit.d.ts.map +0 -1
  239. package/dist/goal/audit.js +0 -12
  240. package/dist/goal/audit.js.map +0 -1
  241. package/dist/goal/constants.d.ts +0 -26
  242. package/dist/goal/constants.d.ts.map +0 -1
  243. package/dist/goal/constants.js +0 -24
  244. package/dist/goal/constants.js.map +0 -1
  245. package/dist/goal/paths.d.ts +0 -8
  246. package/dist/goal/paths.d.ts.map +0 -1
  247. package/dist/goal/paths.js +0 -36
  248. package/dist/goal/paths.js.map +0 -1
  249. package/dist/goal/preflight.d.ts +0 -21
  250. package/dist/goal/preflight.d.ts.map +0 -1
  251. package/dist/goal/preflight.js +0 -97
  252. package/dist/goal/preflight.js.map +0 -1
  253. package/dist/goal/review-seam.d.ts +0 -44
  254. package/dist/goal/review-seam.d.ts.map +0 -1
  255. package/dist/goal/review-seam.js +0 -153
  256. package/dist/goal/review-seam.js.map +0 -1
  257. package/dist/goal/reviewer-rules.d.ts +0 -13
  258. package/dist/goal/reviewer-rules.d.ts.map +0 -1
  259. package/dist/goal/reviewer-rules.js +0 -153
  260. package/dist/goal/reviewer-rules.js.map +0 -1
  261. package/dist/goal/reviewer.d.ts +0 -9
  262. package/dist/goal/reviewer.d.ts.map +0 -1
  263. package/dist/goal/reviewer.js +0 -54
  264. package/dist/goal/reviewer.js.map +0 -1
  265. package/dist/goal/runtime.d.ts +0 -32
  266. package/dist/goal/runtime.d.ts.map +0 -1
  267. package/dist/goal/runtime.js +0 -242
  268. package/dist/goal/runtime.js.map +0 -1
  269. package/dist/goal/sdk-client.d.ts +0 -10
  270. package/dist/goal/sdk-client.d.ts.map +0 -1
  271. package/dist/goal/sdk-client.js +0 -34
  272. package/dist/goal/sdk-client.js.map +0 -1
  273. package/dist/goal/state.d.ts +0 -40
  274. package/dist/goal/state.d.ts.map +0 -1
  275. package/dist/goal/state.js +0 -37
  276. package/dist/goal/state.js.map +0 -1
  277. package/dist/goal/task-triggers.d.ts +0 -15
  278. package/dist/goal/task-triggers.d.ts.map +0 -1
  279. package/dist/goal/task-triggers.js +0 -23
  280. package/dist/goal/task-triggers.js.map +0 -1
  281. package/dist/goal/walls.d.ts +0 -12
  282. package/dist/goal/walls.d.ts.map +0 -1
  283. package/dist/goal/walls.js +0 -65
  284. package/dist/goal/walls.js.map +0 -1
  285. package/dist/goal/worker-prompt.d.ts +0 -13
  286. package/dist/goal/worker-prompt.d.ts.map +0 -1
  287. package/dist/goal/worker-prompt.js +0 -41
  288. package/dist/goal/worker-prompt.js.map +0 -1
  289. package/dist/goal/worker.d.ts +0 -42
  290. package/dist/goal/worker.d.ts.map +0 -1
  291. package/dist/goal/worker.js +0 -180
  292. package/dist/goal/worker.js.map +0 -1
  293. package/dist/templates/common/bundled-skills/cstl-cursor2plus-setup/SKILL.md +0 -63
  294. package/dist/templates/cursor/commands/cursor2plus-setup.md +0 -82
  295. package/dist/templates/cursor/rules/cstl-cursor-modes.mdc +0 -32
  296. package/dist/templates/cursor/rules/cstl-session-rename.mdc +0 -31
  297. package/dist/templates/cursor/rules/cstl-subagent-dispatch.mdc +0 -34
  298. package/dist/templates/cursor/rules/cstl-triage.mdc +0 -36
  299. package/dist/templates/cursor/rules/retrieval-routing.mdc +0 -78
  300. package/dist/templates/trellis/local/README.md +0 -85
  301. package/dist/templates/trellis/local/config.local.json.example +0 -6
  302. package/dist/templates/trellis/local/index.d.ts +0 -8
  303. package/dist/templates/trellis/local/index.d.ts.map +0 -1
  304. package/dist/templates/trellis/local/index.js +0 -15
  305. package/dist/templates/trellis/local/index.js.map +0 -1
  306. package/dist/templates/trellis/local/patch_wpelc8.py +0 -421
  307. package/dist/templates/trellis/local/smoke.py +0 -94
  308. package/dist/templates/trellis/local/subagent-models.json.example +0 -4
  309. package/dist/templates/trellis/local/trellis-task-models.json.example +0 -10
  310. package/dist/templates/trellis/local/trellis-task-models.json5.example +0 -45
  311. package/dist/templates/trellis/local/trellis_task_models_config.py +0 -200
  312. package/dist/utils/cursor-sdk-gate.d.ts +0 -10
  313. package/dist/utils/cursor-sdk-gate.d.ts.map +0 -1
  314. package/dist/utils/cursor-sdk-gate.js +0 -32
  315. package/dist/utils/cursor-sdk-gate.js.map +0 -1
@@ -26,6 +26,7 @@ from .task_map import (
26
26
  validate_child_archive_state,
27
27
  validate_parent_children_complete,
28
28
  )
29
+ from .full_quality import full_quality_archive_errors, rigor_from_required_controls
29
30
 
30
31
  SCHEMA_VERSION = 1
31
32
  BASELINE_GATE = "baseline-check"
@@ -182,13 +183,45 @@ def normalize_result(result: str) -> str:
182
183
  return result.strip().upper()
183
184
 
184
185
 
186
+ def wave_c_stop_read_confirmed(start: Path | None = None) -> bool:
187
+ """Return True after ``cstl update`` wrote the Wave C confirm flag.
188
+
189
+ Unconfirmed projects keep leftover dual-read. Missing ``.cstl`` is
190
+ unconfirmed (unit fixtures without a repo root stay dual-read).
191
+ """
192
+ from .paths import DIR_WORKFLOW, get_repo_root
193
+
194
+ root = get_repo_root(start)
195
+ path = root / DIR_WORKFLOW / ".p36-wave-c.json"
196
+ if not path.is_file():
197
+ return False
198
+ try:
199
+ parsed = json.loads(path.read_text(encoding="utf-8"))
200
+ except (OSError, json.JSONDecodeError):
201
+ return False
202
+ return isinstance(parsed, dict) and parsed.get("confirmed") is True
203
+
204
+
185
205
  def task_closeout_profile(task_dir: Path, task_data: dict | None = None) -> str:
186
- """Return lite, full, or parent closeout profile."""
206
+ """Return lite, full, or parent closeout profile.
207
+
208
+ New Tasks use persisted ``required_controls`` / Topology only. Missing
209
+ contract is explicit Lite. File existence and ``children[]`` are not
210
+ used to infer Rigor or Parent. Leftover kind/mode/classification are
211
+ dual-read only until Wave C is confirmed.
212
+ """
187
213
  data = task_data or {}
188
- child_names = data.get("children")
189
- if isinstance(child_names, list) and any(isinstance(name, str) for name in child_names):
214
+ topology = data.get("topology") if isinstance(data.get("topology"), dict) else {}
215
+ if topology.get("kind") == "parent-child":
190
216
  return "parent"
191
217
 
218
+ persisted = rigor_from_required_controls(data)
219
+ if persisted in ("lite", "full"):
220
+ return persisted
221
+
222
+ if wave_c_stop_read_confirmed(task_dir):
223
+ return "lite"
224
+
192
225
  meta = data.get("meta") if isinstance(data.get("meta"), dict) else {}
193
226
  candidates = [
194
227
  data.get("task_kind"),
@@ -200,8 +233,6 @@ def task_closeout_profile(task_dir: Path, task_data: dict | None = None) -> str:
200
233
  meta.get("classification"),
201
234
  meta.get("mode"),
202
235
  ]
203
-
204
- explicit_lite = False
205
236
  for value in candidates:
206
237
  if not isinstance(value, str):
207
238
  continue
@@ -211,13 +242,8 @@ def task_closeout_profile(task_dir: Path, task_data: dict | None = None) -> str:
211
242
  if "full" in normalized:
212
243
  return "full"
213
244
  if "lite" in normalized:
214
- explicit_lite = True
215
-
216
- if explicit_lite:
217
- return "lite"
245
+ return "lite"
218
246
 
219
- if (task_dir / "design.md").is_file() and (task_dir / "implement.md").is_file():
220
- return "full"
221
247
  return "lite"
222
248
 
223
249
 
@@ -478,7 +504,12 @@ def make_baseline_record(
478
504
 
479
505
 
480
506
  def write_gate_record(task_data: dict, transition: str, gate: str, record: dict) -> None:
481
- """Write a gate record into task_data in-place."""
507
+ """Write a gate record into task_data in-place.
508
+
509
+ This mutates memory only. Stage 2 persists `quality_gate_results` as a
510
+ Kernel Command projection (same command as `record-gate` / start / archive).
511
+ Do not treat this helper as an independent `task.json` writer.
512
+ """
482
513
  qgr = task_data.get("quality_gate_results")
483
514
  if not isinstance(qgr, dict):
484
515
  qgr = {}
@@ -499,6 +530,35 @@ def write_gate_record(task_data: dict, transition: str, gate: str, record: dict)
499
530
  transition_records[gate] = record
500
531
 
501
532
 
533
+ KERNEL_PROJECTION_EXTRA_KEYS = (
534
+ "quality_gate_results",
535
+ "execution_approval",
536
+ "required_controls",
537
+ "ac_evidence_ledger",
538
+ "independent_check",
539
+ "topology",
540
+ "dependency_graph",
541
+ "ondemand_modules",
542
+ "depends_on",
543
+ "dependency_satisfied",
544
+ "decompose_proposal",
545
+ "profile_health",
546
+ "event_bridge",
547
+ "middleware_providers",
548
+ "capability_router",
549
+ "required_capabilities",
550
+ )
551
+
552
+
553
+ def collect_kernel_projection_extras(task_data: dict) -> dict:
554
+ """Non-canonical task.json fields owned by the same Kernel Command."""
555
+ extras: dict = {}
556
+ for key in KERNEL_PROJECTION_EXTRA_KEYS:
557
+ if key in task_data:
558
+ extras[key] = task_data[key]
559
+ return extras
560
+
561
+
502
562
  def build_reviewer_gate_record(
503
563
  task_dir: Path,
504
564
  task_data: dict,
@@ -998,6 +1058,7 @@ def validate_archive(
998
1058
 
999
1059
  errors.extend(_required_file_errors(task_dir, ["verify.md"]))
1000
1060
  errors.extend(_verify_evidence_errors(task_dir, task_data))
1061
+ errors.extend(full_quality_archive_errors(task_dir, task_data))
1001
1062
 
1002
1063
  parent_name = task_data.get("parent")
1003
1064
  if isinstance(parent_name, str) and parent_name:
@@ -2,8 +2,10 @@
2
2
  """
3
3
  Parent/Child task-map helpers.
4
4
 
5
- task-map.md is the Parent Supervisor's orchestration authority. This module
6
- parses and writes only the small YAML frontmatter subset generated here.
5
+ task-map.md is a projection of the Kernel Topology / Dependency Graph plus
6
+ Parent orchestration fields (child worker state, event log). Graph authority
7
+ is Kernel extras (`topology`, `dependency_graph`); this module may render,
8
+ not invent, typed edges.
7
9
  """
8
10
 
9
11
  from __future__ import annotations
@@ -75,7 +77,7 @@ def ensure_task_map(
75
77
  data = {
76
78
  "parent_id": parent_data.get("id") or parent_dir.name,
77
79
  "contract_epoch": 1,
78
- "execution_topology": "serial",
80
+ "execution_topology": "parallel",
79
81
  "merge_limit": 1,
80
82
  "children": [],
81
83
  "stages": [],
@@ -85,7 +87,7 @@ def ensure_task_map(
85
87
 
86
88
  data.setdefault("parent_id", parent_data.get("id") or parent_dir.name)
87
89
  data.setdefault("contract_epoch", 1)
88
- data.setdefault("execution_topology", "serial")
90
+ data.setdefault("execution_topology", "parallel")
89
91
  data.setdefault("merge_limit", 1)
90
92
  data.setdefault("children", [])
91
93
  data.setdefault("stages", [])
@@ -102,6 +104,16 @@ def ensure_task_map(
102
104
  data["children"].append(child)
103
105
  existing[child_name] = child
104
106
 
107
+ extras = {
108
+ key: parent_data[key]
109
+ for key in ("topology", "dependency_graph")
110
+ if key in parent_data
111
+ }
112
+ if extras:
113
+ from .ondemand_topology import apply_kernel_graph_projection
114
+
115
+ apply_kernel_graph_projection(data, extras)
116
+
105
117
  write_task_map(parent_dir, data, body, event)
106
118
  return data
107
119
 
@@ -492,12 +504,21 @@ def _default_body() -> str:
492
504
  return (
493
505
  "# Task Map\n\n"
494
506
  "## Orchestration notes\n\n"
495
- "- `execution_topology: parallel` children with empty `depends_on` may run concurrently; "
496
- "Parent integrates serially up to `merge_limit`.\n"
507
+ "- **parallel-first:** Prefer Cursor Multitask / Build in Parallel / Agent `Task` / native "
508
+ "worktree. Trellis does not schedule workers or replace Multitask.\n"
509
+ "- `execution_topology: parallel` — default when ≥2 children have empty `depends_on`. "
510
+ "Parent `integrate-child`, HITL, `start-execution --approved`, and reviewer gates stay "
511
+ "serial (`merge_limit`).\n"
512
+ "- `serial_reason` — required when topology is `serial`. One of: shared write-set / "
513
+ "HITL or reviewer gate / `depends_on` unmet / user asked serial / conflict surface "
514
+ "cannot isolate.\n"
515
+ "- `stages:` (or `parallel_groups`) — concurrently runnable child id groups.\n"
516
+ "- `merge_points` — where serial join happens (usually `integrate-child` + gates). "
517
+ "Default `merge_limit: 1`.\n"
518
+ "- `touches` (or `conflict_surface`) — write-sets that can collide; declare before dispatch.\n"
497
519
  "- Child-reported states: `open` → `working` → `blocked` | `review`.\n"
498
520
  "- Parent-controlled states: `review` → `changes` | `accepted` → `integrating` → "
499
521
  "`integrated` | `cancelled`.\n"
500
- "- Declare `touches` per child before dispatch to reduce merge conflicts.\n"
501
522
  "- `isolation: git-worktree` — run `prepare-child-worktree` from the **git package root** "
502
523
  "(not a non-git harness root).\n\n"
503
524
  "## Event Log\n\n"
@@ -594,10 +615,22 @@ def _format_frontmatter(data: dict) -> str:
594
615
  lines = [
595
616
  f"parent_id: {_format_value(data.get('parent_id'))}",
596
617
  f"contract_epoch: {_format_value(data.get('contract_epoch', 1))}",
597
- f"execution_topology: {_format_value(data.get('execution_topology', 'serial'))}",
618
+ f"execution_topology: {_format_value(data.get('execution_topology', 'parallel'))}",
598
619
  f"merge_limit: {_format_value(data.get('merge_limit', 1))}",
599
- "children:",
600
620
  ]
621
+ if data.get("serial_reason"):
622
+ lines.append(f"serial_reason: {_format_value(data.get('serial_reason'))}")
623
+ if data.get("parallel_groups"):
624
+ lines.append(f"parallel_groups: {_format_value(data.get('parallel_groups'))}")
625
+ if data.get("merge_points"):
626
+ lines.append(f"merge_points: {_format_value(data.get('merge_points'))}")
627
+ if data.get("conflict_surface"):
628
+ lines.append(f"conflict_surface: {_format_value(data.get('conflict_surface'))}")
629
+ if data.get("graph_authority"):
630
+ lines.append(f"graph_authority: {_format_value(data.get('graph_authority'))}")
631
+ if data.get("topology_kind"):
632
+ lines.append(f"topology_kind: {_format_value(data.get('topology_kind'))}")
633
+ lines.append("children:")
601
634
  children = data.get("children", [])
602
635
  if isinstance(children, list):
603
636
  for child in children: