@chinhae/atw-cli 0.2.9 → 0.3.0

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 (99) hide show
  1. package/README.md +29 -5
  2. package/dist/commands/init.d.ts.map +1 -1
  3. package/dist/commands/init.js +243 -123
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/commands/uninstall.d.ts.map +1 -1
  6. package/dist/commands/uninstall.js +18 -3
  7. package/dist/commands/uninstall.js.map +1 -1
  8. package/dist/commands/update.d.ts +0 -3
  9. package/dist/commands/update.d.ts.map +1 -1
  10. package/dist/commands/update.js +45 -0
  11. package/dist/commands/update.js.map +1 -1
  12. package/dist/configurators/index.d.ts +8 -0
  13. package/dist/configurators/index.d.ts.map +1 -1
  14. package/dist/configurators/index.js +19 -0
  15. package/dist/configurators/index.js.map +1 -1
  16. package/dist/migrations/manifests/0.2.10.json +9 -0
  17. package/dist/migrations/manifests/0.3.0.json +3410 -0
  18. package/dist/templates/atw/config.yaml +4 -3
  19. package/dist/templates/atw/index.d.ts +2 -0
  20. package/dist/templates/atw/index.d.ts.map +1 -1
  21. package/dist/templates/atw/index.js +4 -0
  22. package/dist/templates/atw/index.js.map +1 -1
  23. package/dist/templates/atw/scripts/common/noob_mode.py +102 -0
  24. package/dist/templates/atw/scripts/common/session_context.py +7 -0
  25. package/dist/templates/atw/scripts/noob_mode.py +41 -0
  26. package/dist/templates/atw/scripts/tickets.py +66 -10
  27. package/dist/templates/atw/workflow.md +81 -17
  28. package/dist/templates/common/bundled-skills/atw-code-review/SKILL.md +4 -2
  29. package/dist/templates/common/bundled-skills/atw-codebase-design/DESIGN-IT-TWICE.md +1 -1
  30. package/dist/templates/common/bundled-skills/atw-diagnosing-bugs/SKILL.md +2 -2
  31. package/dist/templates/common/bundled-skills/atw-domain-modeling/{CONTEXT-FORMAT.md → GLOSSARY-FORMAT.md} +10 -10
  32. package/dist/templates/common/bundled-skills/atw-domain-modeling/SKILL.md +12 -12
  33. package/dist/templates/common/bundled-skills/atw-handoff/SKILL.md +1 -1
  34. package/dist/templates/common/bundled-skills/atw-implement/SKILL.md +6 -4
  35. package/dist/templates/common/bundled-skills/atw-implement-spec/SKILL.md +79 -0
  36. package/dist/templates/common/bundled-skills/atw-implement-spec/agents/openai.yaml +5 -0
  37. package/dist/templates/common/bundled-skills/atw-improve-codebase-architecture/SKILL.md +5 -5
  38. package/dist/templates/common/bundled-skills/atw-init-repo/SKILL.md +6 -4
  39. package/dist/templates/common/bundled-skills/atw-init-repo/references/domain.md +8 -8
  40. package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-atw-local.md +5 -2
  41. package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-atw.md +5 -2
  42. package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-github.md +5 -4
  43. package/dist/templates/common/bundled-skills/atw-init-repo/references/issue-tracker-gitlab.md +2 -2
  44. package/dist/templates/common/bundled-skills/atw-init-repo/references/triage-labels.md +1 -1
  45. package/dist/templates/common/bundled-skills/atw-interview/SKILL.md +9 -1
  46. package/dist/templates/common/bundled-skills/atw-map/SKILL.md +5 -5
  47. package/dist/templates/common/bundled-skills/atw-noob-mode/SKILL.md +101 -0
  48. package/dist/templates/common/bundled-skills/atw-noob-mode/agents/openai.yaml +3 -0
  49. package/dist/templates/common/bundled-skills/atw-prototype/scripts/build_explorer.py +15 -9
  50. package/dist/templates/common/bundled-skills/atw-spec/SKILL.md +1 -1
  51. package/dist/templates/common/bundled-skills/atw-tdd/SKILL.md +2 -2
  52. package/dist/templates/common/bundled-skills/atw-tickets/SKILL.md +4 -4
  53. package/dist/templates/common/bundled-skills/atw-triage/SKILL.md +2 -2
  54. package/dist/templates/common/commands/continue.md +1 -1
  55. package/dist/templates/opencode/plugins/inject-workflow-state.js +29 -1
  56. package/dist/templates/shared-hooks/inject-subagent-context.py +29 -3
  57. package/dist/templates/shared-hooks/inject-workflow-state.py +27 -3
  58. package/dist/templates/shared-hooks/session-start.py +23 -0
  59. package/dist/templates/snow/SNOW.md +1 -1
  60. package/dist/utils/file-writer.d.ts.map +1 -1
  61. package/dist/utils/file-writer.js +29 -16
  62. package/dist/utils/file-writer.js.map +1 -1
  63. package/dist/utils/interactive-guard.d.ts +2 -2
  64. package/dist/utils/interactive-guard.js +2 -2
  65. package/dist/utils/lang.d.ts +14 -0
  66. package/dist/utils/lang.d.ts.map +1 -0
  67. package/dist/utils/lang.js +20 -0
  68. package/dist/utils/lang.js.map +1 -0
  69. package/dist/utils/optional-skills.d.ts +90 -0
  70. package/dist/utils/optional-skills.d.ts.map +1 -0
  71. package/dist/utils/optional-skills.js +266 -0
  72. package/dist/utils/optional-skills.js.map +1 -0
  73. package/dist/utils/template-fetcher.d.ts +6 -0
  74. package/dist/utils/template-fetcher.d.ts.map +1 -1
  75. package/dist/utils/template-fetcher.js +1 -1
  76. package/dist/utils/template-fetcher.js.map +1 -1
  77. package/package.json +2 -2
  78. package/dist/templates/common/bundled-skills/atw-merge/SKILL.md +0 -14
  79. package/dist/templates/common/bundled-skills/atw-merge/agents/openai.yaml +0 -3
  80. package/dist/templates/common/bundled-skills/dejargonizer/SKILL.md +0 -133
  81. package/dist/templates/common/bundled-skills/noob-mode/SKILL.md +0 -175
  82. package/dist/templates/common/bundled-skills/noob-mode/references/examples.md +0 -418
  83. package/dist/templates/common/bundled-skills/noob-mode/references/glossary.md +0 -368
  84. package/dist/templates/common/bundled-skills/oxy-explanation/SKILL.md +0 -80
  85. package/dist/templates/common/bundled-skills/oxy-learning-hub/SKILL.md +0 -179
  86. package/dist/templates/common/bundled-skills/oxy-learning-hub/assets/course.css +0 -1044
  87. package/dist/templates/common/bundled-skills/oxy-learning-hub/assets/course.js +0 -184
  88. package/dist/templates/common/bundled-skills/oxy-learning-hub/assets/lesson-template.html +0 -125
  89. package/dist/templates/common/bundled-skills/oxy-learning-hub/assets/summary-template.html +0 -659
  90. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/publishing.md +0 -64
  91. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/summary-mode.md +0 -96
  92. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching/GLOSSARY-FORMAT.md +0 -30
  93. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching/LEARNING-RECORD-FORMAT.md +0 -42
  94. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching/MISSION-FORMAT.md +0 -50
  95. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching/RESOURCES-FORMAT.md +0 -40
  96. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/teaching-mode.md +0 -251
  97. package/dist/templates/common/bundled-skills/oxy-learning-hub/references/workspace.md +0 -112
  98. package/dist/templates/common/bundled-skills/oxy-learning-hub/scripts/validate_html.py +0 -198
  99. package/dist/templates/common/bundled-skills/show-me/SKILL.md +0 -127
@@ -111,9 +111,10 @@ channel:
111
111
  # Codex (dispatch behavior)
112
112
  #-------------------------------------------------------------------------------
113
113
  # Codex-only knob; other platforms ignore it. Default ("auto") dispatches
114
- # atw-review sub-agents for the two review axes. Implementation is never
115
- # dispatched on any platform: it runs inside `/atw-implement` in the main
116
- # session (`atw-implement-agent` ships only as a reserved role). This does
114
+ # atw-review sub-agents for the two review axes. On the per-ticket path
115
+ # implementation is never dispatched on any platform: it runs inside
116
+ # `/atw-implement` in the main session (`atw-implement-agent` ships only as a
117
+ # reserved role). Only a `/atw-implement-spec` run dispatches implementers. This does
117
118
  # not rely on inherited parent transcripts: `fork_turns` remains
118
119
  # caller-controlled, while Codex's native SubagentStart hook injects task
119
120
  # context when trusted and child-side loading remains the fallback when it is
@@ -40,8 +40,10 @@ export declare const commonPackagesContext: string;
40
40
  export declare const commonWorkflowPhase: string;
41
41
  export declare const commonAtwConfig: string;
42
42
  export declare const commonSafeCommit: string;
43
+ export declare const commonNoobMode: string;
43
44
  export declare const getDeveloperScript: string;
44
45
  export declare const initDeveloperScript: string;
46
+ export declare const noobModeScript: string;
45
47
  export declare const taskScript: string;
46
48
  export declare const getContextScript: string;
47
49
  export declare const addSessionScript: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/atw/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAG9E,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,aAAa,QAAqC,CAAC;AAChE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AAGF,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAC/D,eAAO,MAAM,qBAAqB,QAAoC,CAAC;AAMvE,eAAO,MAAM,sBAAsB,QAA4C,CAAC;AAChF,eAAO,MAAM,mBAAmB,QAAmC,CAAC;AAEpE;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAkDnD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAKlD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/atw/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,cAAc,QAA8C,CAAC;AAG1E,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,cAAc,QAAuC,CAAC;AACnE,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,aAAa,QAAqC,CAAC;AAChE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AAGF,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAC/D,eAAO,MAAM,qBAAqB,QAAoC,CAAC;AAMvE,eAAO,MAAM,sBAAsB,QAA4C,CAAC;AAChF,eAAO,MAAM,mBAAmB,QAAmC,CAAC;AAEpE;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAoDnD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAKlD"}
@@ -50,9 +50,11 @@ export const commonPackagesContext = readTemplate("scripts/common/packages_conte
50
50
  export const commonWorkflowPhase = readTemplate("scripts/common/workflow_phase.py");
51
51
  export const commonAtwConfig = readTemplate("scripts/common/atw_config.py");
52
52
  export const commonSafeCommit = readTemplate("scripts/common/safe_commit.py");
53
+ export const commonNoobMode = readTemplate("scripts/common/noob_mode.py");
53
54
  // Python scripts - main
54
55
  export const getDeveloperScript = readTemplate("scripts/get_developer.py");
55
56
  export const initDeveloperScript = readTemplate("scripts/init_developer.py");
57
+ export const noobModeScript = readTemplate("scripts/noob_mode.py");
56
58
  export const taskScript = readTemplate("scripts/task.py");
57
59
  export const getContextScript = readTemplate("scripts/get_context.py");
58
60
  export const addSessionScript = readTemplate("scripts/add_session.py");
@@ -99,9 +101,11 @@ export function getAllScripts() {
99
101
  scripts.set("common/workflow_phase.py", commonWorkflowPhase);
100
102
  scripts.set("common/atw_config.py", commonAtwConfig);
101
103
  scripts.set("common/safe_commit.py", commonSafeCommit);
104
+ scripts.set("common/noob_mode.py", commonNoobMode);
102
105
  // Main
103
106
  scripts.set("get_developer.py", getDeveloperScript);
104
107
  scripts.set("init_developer.py", initDeveloperScript);
108
+ scripts.set("noob_mode.py", noobModeScript);
105
109
  scripts.set("task.py", taskScript);
106
110
  scripts.set("get_context.py", getContextScript);
107
111
  scripts.set("add_session.py", addSessionScript);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/atw/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/atw/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ """Noob mode — a per-developer switch for plain-language replies.
2
+
3
+ A non-technical user turns it on once (the `atw-noob-mode` skill runs
4
+ `noob_mode.py on`). From then on the hooks that already speak to the AI at
5
+ session start and on every turn append a short reminder, so the mode holds
6
+ across long conversations, compaction and new sessions instead of fading the
7
+ way a skill loaded once does.
8
+
9
+ The switch is a `noob_mode=on` line in `.atw/.developer`. That file is
10
+ gitignored and personal by design, so one developer's choice never reaches a
11
+ teammate, and no new ignore rule is needed in existing projects.
12
+
13
+ The reminder text itself lives in workflow.md, in a
14
+ `[workflow-state:noob_mode]` block next to the per-status breadcrumbs — the
15
+ JS/TS hook ports already parse those blocks, so every platform reads one copy.
16
+ """
17
+
18
+ from __future__ import annotations
19
+
20
+ import re
21
+ from pathlib import Path
22
+
23
+ from .git import main_worktree_root
24
+ from .paths import DIR_WORKFLOW, FILE_DEVELOPER
25
+
26
+ FIELD = "noob_mode"
27
+ BREADCRUMB_TAG = "noob_mode"
28
+
29
+ # Used when workflow.md has no noob_mode block (a custom workflow template, or
30
+ # a workflow.md older than this feature): the mode still has to take effect.
31
+ FALLBACK_REMINDER = (
32
+ "Noob mode is ON — this user is not an engineer. Hold to the "
33
+ "`/atw-noob-mode` rules in every reply: plain words in the user's "
34
+ "language, and every term, command or path explained where it appears."
35
+ )
36
+
37
+ _FIELD_RE = re.compile(rf"^{FIELD}=(.*)$", re.MULTILINE)
38
+ _TAG_RE = re.compile(
39
+ rf"\[workflow-state:{BREADCRUMB_TAG}\]\s*\n(.*?)\n\s*\[/workflow-state:{BREADCRUMB_TAG}\]",
40
+ re.DOTALL,
41
+ )
42
+
43
+
44
+ def _developer_file(repo_root: Path) -> Path | None:
45
+ """The identity file this checkout uses, following get_developer():
46
+ its own, else the main checkout's when this is a linked worktree."""
47
+ local = repo_root / DIR_WORKFLOW / FILE_DEVELOPER
48
+ if local.is_file():
49
+ return local
50
+ main_root = main_worktree_root(repo_root)
51
+ if main_root is None:
52
+ return None
53
+ inherited = main_root / DIR_WORKFLOW / FILE_DEVELOPER
54
+ return inherited if inherited.is_file() else None
55
+
56
+
57
+ def is_noob_mode_on(repo_root: Path) -> bool:
58
+ dev_file = _developer_file(repo_root)
59
+ if dev_file is None:
60
+ return False
61
+ try:
62
+ match = _FIELD_RE.search(dev_file.read_text(encoding="utf-8"))
63
+ except OSError:
64
+ return False
65
+ return match is not None and match.group(1).strip() == "on"
66
+
67
+
68
+ def set_noob_mode(repo_root: Path, on: bool) -> bool:
69
+ """Switch noob mode for this developer.
70
+
71
+ Returns False when there is no identity file to record it in (run
72
+ init_developer.py first); the file's other lines are left as they are.
73
+ """
74
+ dev_file = _developer_file(repo_root)
75
+ if dev_file is None:
76
+ return False
77
+ lines = [
78
+ line
79
+ for line in dev_file.read_text(encoding="utf-8").splitlines()
80
+ if not line.startswith(f"{FIELD}=")
81
+ ]
82
+ if on:
83
+ lines.append(f"{FIELD}=on")
84
+ dev_file.write_text("\n".join(lines) + "\n", encoding="utf-8")
85
+ return True
86
+
87
+
88
+ def noob_mode_reminder(repo_root: Path) -> str:
89
+ """The `<noob-mode>` block to hand the AI, or "" while the mode is off."""
90
+ if not is_noob_mode_on(repo_root):
91
+ return ""
92
+ body = ""
93
+ try:
94
+ content = (repo_root / DIR_WORKFLOW / "workflow.md").read_text(
95
+ encoding="utf-8"
96
+ )
97
+ match = _TAG_RE.search(content)
98
+ if match:
99
+ body = match.group(1).strip()
100
+ except OSError:
101
+ pass
102
+ return f"<noob-mode>\n{body or FALLBACK_REMINDER}\n</noob-mode>"
@@ -24,6 +24,7 @@ from pathlib import Path
24
24
  from .active_task import resolve_context_key
25
25
  from .config import get_git_packages
26
26
  from .git import run_git
27
+ from .noob_mode import noob_mode_reminder
27
28
  from .packages_context import get_packages_section
28
29
  from .tasks import iter_active_tasks, load_task, get_all_statuses, children_progress
29
30
  from .paths import (
@@ -606,6 +607,12 @@ def get_context_text(repo_root: Path | None = None) -> str:
606
607
  lines.append(f"Name: {developer}")
607
608
  lines.append("")
608
609
 
610
+ # Platforms without a hook learn about noob mode from this output alone.
611
+ noob_mode = noob_mode_reminder(repo_root)
612
+ if noob_mode:
613
+ lines.append(noob_mode)
614
+ lines.append("")
615
+
609
616
  root_git_info = _collect_root_git_info(repo_root)
610
617
  _append_root_git_context(lines, root_git_info)
611
618
 
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Switch noob mode (plain-language replies) for the current developer.
4
+
5
+ Usage:
6
+ python3 noob_mode.py on Turn it on
7
+ python3 noob_mode.py off Turn it off
8
+ python3 noob_mode.py status Show whether it is on
9
+
10
+ The switch is personal — see common/noob_mode.py.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import sys
16
+
17
+ from common.noob_mode import is_noob_mode_on, set_noob_mode
18
+ from common.paths import DIR_SCRIPTS, DIR_WORKFLOW, FILE_DEVELOPER, get_repo_root
19
+
20
+
21
+ def main() -> None:
22
+ """CLI entry point."""
23
+ action = sys.argv[1] if len(sys.argv) > 1 else "status"
24
+ if action not in ("on", "off", "status"):
25
+ print(f"Usage: {sys.argv[0]} on|off|status", file=sys.stderr)
26
+ sys.exit(1)
27
+
28
+ repo_root = get_repo_root()
29
+ if action != "status" and not set_noob_mode(repo_root, action == "on"):
30
+ print(
31
+ f"Error: no {DIR_WORKFLOW}/{FILE_DEVELOPER} to record noob mode in. "
32
+ f"Run: python3 ./{DIR_WORKFLOW}/{DIR_SCRIPTS}/init_developer.py <name>",
33
+ file=sys.stderr,
34
+ )
35
+ sys.exit(1)
36
+
37
+ print(f"Noob mode: {'on' if is_noob_mode_on(repo_root) else 'off'}")
38
+
39
+
40
+ if __name__ == "__main__":
41
+ main()
@@ -6,6 +6,8 @@
6
6
  claim <NN> 校验在 frontier 里 → Impl: doing
7
7
  → 记 implementation_base_sha
8
8
  → 把该票路径写进 <task>/check.jsonl
9
+ claim <NN> --parallel 并行批次认领(/atw-implement-spec 用):允许多张票同时
10
+ doing,不写 check.jsonl 的当前票行,meta.ticket_mode = parallel
9
11
  done <NN> 标记 Impl: done,并撤掉 check.jsonl 里的那行
10
12
  summary 汇总一行,给 workflow-state 用
11
13
  selfcheck 跑内置断言,不依赖仓库状态
@@ -14,7 +16,7 @@
14
16
  Blocker 引用不存在 → 失败
15
17
  Blocker 形成环 → 失败
16
18
  claim 不在 frontier 里的票 → 失败
17
- 已有别的票在 doing → 失败(票默认串行)
19
+ 已有别的票在 doing → 失败(票默认串行;--parallel 除外)
18
20
 
19
21
  不要把这些函数塞进 task_utils.py / task.py:票是任务目录里的一层,任务目录和
20
22
  meta 的读写一律走 task.py,本脚本不直接写 task.json。
@@ -44,6 +46,12 @@ RE_BLOCKER = re.compile(r"#?(\d+)")
44
46
  MANAGED_REASON = "ATW current ticket"
45
47
  MANIFEST_NAME = "check.jsonl"
46
48
 
49
+ # 并行批次的标记写在 task.json 的 meta 里 —— 子代理注入 hook 靠它区分
50
+ # 「并行跑着多张票」和「票状态自相矛盾」。
51
+ META_TICKET_MODE = "ticket_mode"
52
+ MODE_PARALLEL = "parallel"
53
+ MODE_SERIAL = "serial"
54
+
47
55
 
48
56
  def field_pattern(name: str) -> re.Pattern[str]:
49
57
  """匹配 `**Impl:** doing` 这类字段行。"""
@@ -199,6 +207,17 @@ def task_dir(root: Path, override: str | None) -> Path:
199
207
  return (root / rel).resolve()
200
208
 
201
209
 
210
+ def ticket_mode(task: Path) -> str:
211
+ """只读 meta.ticket_mode;写一律走 task.py set-meta。"""
212
+ try:
213
+ data = json.loads((task / "task.json").read_text(encoding="utf-8"))
214
+ except (OSError, json.JSONDecodeError):
215
+ return MODE_SERIAL
216
+ meta = data.get("meta") if isinstance(data, dict) else None
217
+ mode = meta.get(META_TICKET_MODE) if isinstance(meta, dict) else None
218
+ return MODE_PARALLEL if mode == MODE_PARALLEL else MODE_SERIAL
219
+
220
+
202
221
  def set_meta(root: Path, task: Path, key: str, value: str) -> None:
203
222
  run(
204
223
  [
@@ -289,14 +308,10 @@ def cmd_frontier(tickets: list[Ticket], **_) -> int:
289
308
  return 0
290
309
 
291
310
 
292
- def cmd_claim(tickets: list[Ticket], root: Path, task: Path, num: str, **_) -> int:
293
- target = pick(tickets, num)
294
- if target.impl == "doing":
295
- print(f"{target.label} 已经在 doing,无需重复 claim")
296
- return 0
297
- # 票默认串行:同一任务一次只推进一张
311
+ def ensure_claimable(tickets: list[Ticket], target: Ticket, parallel: bool) -> None:
312
+ # 票默认串行:同一任务一次只推进一张。并行批次是唯一的例外
298
313
  busy = [t for t in tickets if t.impl == "doing"]
299
- if busy:
314
+ if busy and not parallel:
300
315
  raise TicketError(
301
316
  f"{busy[0].label} 还在 doing。票默认串行,先 done 它再 claim 下一张"
302
317
  )
@@ -307,9 +322,32 @@ def cmd_claim(tickets: list[Ticket], root: Path, task: Path, num: str, **_) -> i
307
322
  else f"Impl 是 {target.impl},不是 ready"
308
323
  raise TicketError(f"{target.label} 不在 frontier 里({reason})")
309
324
 
325
+
326
+ def cmd_claim(tickets: list[Ticket], root: Path, task: Path, num: str,
327
+ parallel: bool = False, **_) -> int:
328
+ target = pick(tickets, num)
329
+ if target.impl == "doing":
330
+ print(f"{target.label} 已经在 doing,无需重复 claim")
331
+ return 0
332
+ first_of_batch = not any(t.impl == "doing" for t in tickets)
333
+ ensure_claimable(tickets, target, parallel)
334
+
310
335
  set_impl(target, "doing")
336
+ if parallel:
337
+ # 基线只在批次的第一张票上记:之后 HEAD 随合并前移,再记就把已合并的
338
+ # 票排除在整批审查的 diff 之外了
339
+ if first_of_batch:
340
+ record_base_sha(root, task)
341
+ # 并行批次没有「唯一的当前票」,check.jsonl 里不留当前票行
342
+ rewrite_manifest(root, task, None)
343
+ if ticket_mode(task) != MODE_PARALLEL:
344
+ set_meta(root, task, META_TICKET_MODE, MODE_PARALLEL)
345
+ print(f"claimed {target.label} → Impl: doing(并行批次)")
346
+ return 0
311
347
  record_base_sha(root, task)
312
348
  rewrite_manifest(root, task, target)
349
+ if ticket_mode(task) == MODE_PARALLEL:
350
+ set_meta(root, task, META_TICKET_MODE, MODE_SERIAL)
313
351
  print(f"claimed {target.label} → Impl: doing")
314
352
  return 0
315
353
 
@@ -347,7 +385,7 @@ def cmd_summary(tickets: list[Ticket], **_) -> int:
347
385
  doing = [t for t in tickets if t.impl == "doing"]
348
386
  done = [t for t in tickets if t.impl == "done"]
349
387
  parts = [f"票 {len(tickets)} 张", f"done {len(done)}"]
350
- parts.append(f"doing {doing[0].label}" if doing else "doing -")
388
+ parts.append("doing " + ("、".join(t.label for t in doing) or "-"))
351
389
  parts.append("frontier " + ("、".join(f"{t.num:02d}" for t in frontier(tickets)) or "-"))
352
390
  print(" | ".join(parts))
353
391
  return 0
@@ -414,6 +452,21 @@ def cmd_selfcheck(**_) -> int:
414
452
  # 重复 done 幂等,不报错
415
453
  assert cmd_done(load_tickets(tmp), tmp, tmp, "02") == 0
416
454
 
455
+ with tempfile.TemporaryDirectory() as d:
456
+ tmp = Path(d)
457
+ ts = build(tmp, [(1, "doing", "none"), (2, "ready", "none"), (3, "ready", "02")])
458
+ fails(lambda: ensure_claimable(ts, ts[1], parallel=False), "票默认串行")
459
+ ensure_claimable(ts, ts[1], parallel=True) # 并行批次放行第二张 doing
460
+ # 并行不绕过阻塞:Blocker 没 done 的票照样认领不了
461
+ fails(lambda: ensure_claimable(ts, ts[2], parallel=True), "不在 frontier 里")
462
+
463
+ with tempfile.TemporaryDirectory() as d:
464
+ tmp = Path(d)
465
+ assert ticket_mode(tmp) == MODE_SERIAL # 没有 task.json 按串行算
466
+ (tmp / "task.json").write_text(
467
+ json.dumps({"meta": {META_TICKET_MODE: MODE_PARALLEL}}), encoding="utf-8")
468
+ assert ticket_mode(tmp) == MODE_PARALLEL
469
+
417
470
  with tempfile.TemporaryDirectory() as d:
418
471
  tmp = Path(d)
419
472
  fails(lambda: build(tmp, [(1, "ready", "09")]), "不存在的票")
@@ -473,6 +526,8 @@ def main(argv: list[str] | None = None) -> int:
473
526
  p.add_argument("command", choices=sorted(COMMANDS))
474
527
  p.add_argument("num", nargs="?", help="票号,claim / done 用")
475
528
  p.add_argument("--task-dir", help="仓库相对的任务目录,缺省问 task.py current")
529
+ p.add_argument("--parallel", action="store_true",
530
+ help="claim 用:并行批次认领,允许多张票同时 doing")
476
531
  args = p.parse_args(argv)
477
532
 
478
533
  try:
@@ -484,7 +539,8 @@ def main(argv: list[str] | None = None) -> int:
484
539
  task = task_dir(root, args.task_dir)
485
540
  tickets = load_tickets(task / "issues")
486
541
  return COMMANDS[args.command](
487
- tickets=tickets, root=root, task=task, num=args.num
542
+ tickets=tickets, root=root, task=task, num=args.num,
543
+ parallel=args.parallel,
488
544
  )
489
545
  except TicketError as e:
490
546
  print(f"错误:{e}", file=sys.stderr)
@@ -7,7 +7,7 @@
7
7
  1. **Plan before code** — figure out what to do before you start
8
8
  2. **Specs injected, not remembered** — guidelines are injected via hook/skill, not recalled from memory
9
9
  3. **Persist everything** — research, decisions, and lessons all go to files; conversations get compacted, files don't
10
- 4. **One ticket at a time** — serial execution; claim, finish, close, then take the next
10
+ 4. **One ticket at a time, unless the user asks for the whole spec at once** — serial by default: claim, finish, close, then take the next. `/atw-implement-spec` is the one parallel path, and only the user starts it
11
11
  5. **Capture learnings** — after each ticket, review and write new knowledge back to spec
12
12
 
13
13
  ---
@@ -24,6 +24,16 @@ python3 ./.atw/scripts/init_developer.py <your-name>
24
24
 
25
25
  Creates `.atw/.developer` (gitignored) + `.atw/workspace/<your-name>/`.
26
26
 
27
+ ### Noob Mode
28
+
29
+ For a user who is not an engineer. While it is on, every reply in every stage is in plain language: terms explained where they appear, each action explained before it happens (what, why, how risky, what approving or declining leads to), errors and results retold with what they affect and what comes next. The full rules are `/atw-noob-mode`.
30
+
31
+ ```bash
32
+ python3 ./.atw/scripts/noob_mode.py on|off|status
33
+ ```
34
+
35
+ The user switches it by saying "开启小白模式" / "关闭小白模式" or running `/atw-noob-mode`; the skill runs the script. The switch is one line in that user's own `.atw/.developer`, so it is personal and never committed. It changes how the AI talks to the user — not the stages, the stops, or what goes into task files.
36
+
27
37
  ### Spec System
28
38
 
29
39
  `.atw/spec/` holds coding guidelines organized by package and layer.
@@ -109,6 +119,7 @@ Implementation tickets live in `{TASK_DIR}/issues/NN-slug.md` and carry two fiel
109
119
  python3 ./.atw/scripts/tickets.py list [--task-dir <dir>] # every ticket + state
110
120
  python3 ./.atw/scripts/tickets.py frontier [--task-dir <dir>] # ready tickets with dependencies cleared
111
121
  python3 ./.atw/scripts/tickets.py claim NN [--task-dir <dir>] # ready → doing
122
+ python3 ./.atw/scripts/tickets.py claim NN --parallel # ready → doing alongside others (`/atw-implement-spec` only)
112
123
  python3 ./.atw/scripts/tickets.py done NN [--task-dir <dir>] # doing → done
113
124
  python3 ./.atw/scripts/tickets.py summary [--task-dir <dir>]
114
125
  python3 ./.atw/scripts/tickets.py selfcheck
@@ -116,6 +127,8 @@ python3 ./.atw/scripts/tickets.py selfcheck
116
127
 
117
128
  **The current ticket is the single `issues/` ticket marked `**Impl:** doing`.** The per-turn hook reads that directly from the ticket files. Two tickets marked `doing` at once is a broken state, not a choice — clear it before continuing.
118
129
 
130
+ The one exception is a `/atw-implement-spec` run. Its orchestrator claims with `--parallel`, which records `meta.ticket_mode = parallel` in `task.json`; with that set, the hook reads several `doing` tickets as the run in progress rather than a contradiction, and no single ticket is the current one. The next plain `claim` puts the task back in serial mode.
131
+
119
132
  Decision tickets from the map live in `{TASK_DIR}/map-issues/` and use a different vocabulary (`Type` / `Status` / `Blocked by`). **Never mix the two directories**: `tickets.py` only reads `issues/`, and a decision ticket filed there corrupts the frontier in both directions.
120
133
 
121
134
  ### Workspace System
@@ -192,7 +205,7 @@ python3 ./.atw/scripts/get_context.py --mode phase --step <X.Y> # detailed guid
192
205
 
193
206
  ```
194
207
  Phase 1: Plan → discover, specify, and (when needed) slice into tickets
195
- Phase 2: Execute → one ticket at a time, each through the full implement chain
208
+ Phase 2: Execute → one ticket at a time through the full implement chain, or the whole spec in one parallel run
196
209
  Phase 3: Finish → read-only acceptance check, then archive
197
210
  ```
198
211
 
@@ -230,7 +243,7 @@ Outside these four, the AI advances stages on its own. It does not stop to ask "
230
243
  |---|---|---|
231
244
  | ① | Before creating a task | Does this work deserve a record — the user's |
232
245
  | ② | After the spec is written | Is the spec right — the user's |
233
- | ③ | Before each ticket starts | The user runs `/atw-implement`; the AI cannot invoke it |
246
+ | ③ | Before implementation starts | The user runs `/atw-implement` per ticket, or `/atw-implement-spec` once for the whole spec; the AI cannot invoke either |
234
247
  | ④ | Before archiving | "This is done" — the user's acceptance |
235
248
 
236
249
  ### Planning Artifacts
@@ -266,6 +279,17 @@ Inspect the task directory named above and repair its task.json. It must be a va
266
279
  Preserve existing task fields and artifacts. If the correct status cannot be determined safely, ask the user before reconstructing the record.
267
280
  [/workflow-state:task_error]
268
281
 
282
+ <!-- Appended to every per-turn breadcrumb, whatever the status, while this developer has noob mode on. Not a task status. -->
283
+
284
+ [workflow-state:noob_mode]
285
+ Noob mode is ON — this user is not an engineer. Hold to these rules in every reply, in every stage (the full set is `/atw-noob-mode`):
286
+ - Plain words in the user's language. Explain any unavoidable term, command, path or flag in the same sentence it appears in.
287
+ - Before anything they must approve or that is hard to undo: what will happen, why, how risky it is, and what approving or declining leads to.
288
+ - Say who did what, what you actually ran versus what you only expect, and every decision you made for them.
289
+ - Retell sub-agent reports, command output and errors the same way: what happened, what it affects, what comes next.
290
+ Only the user turns it off ("关闭小白模式" / "turn off noob mode"): run `python3 ./.atw/scripts/noob_mode.py off`.
291
+ [/workflow-state:noob_mode]
292
+
269
293
  ### Phase 1: Plan
270
294
 
271
295
  - 1.0 Create task `[required · once]` (only after stop ①)
@@ -309,18 +333,20 @@ When the tickets are written, run `task.py start <task>` (step 1.5) to enter imp
309
333
  - 2.3 Relay the review reports `[required · repeatable]`
310
334
  - 2.4 Close the ticket `[required · repeatable]`
311
335
  - 2.5 Roll back `[on demand]`
336
+ - 2.7 Whole-spec run `[alternative to 2.1–2.4 · once]` (stop ③; the user picks it)
312
337
 
313
338
  <!-- Per-turn breadcrumb: stage 'implement' — set by task.py start, held for all of Phase 2 -->
314
339
 
315
340
  [workflow-state:implement]
316
- One ticket at a time. Run `tickets.py frontier`, pick one, `tickets.py claim NN` — never hold two tickets at `doing`.
317
- Stop ③: tell the user to run `/atw-implement` for the claimed ticket. You may not invoke it yourself, and you may not do the implementation inline instead. One user invocation per ticket.
318
- That one run is a closed chain and must not be broken up from the outside: implement (test-first where it fits) → run tests, full suite on the last pass → review → handle findings → write spec updates back → commit. Never instruct it to skip the review or the commit.
341
+ Stop ③: implementation is the user's to start. You may not invoke either skill below yourself, and you may not do the implementation inline instead. When the task has tickets, name both ways and let the user pick; a task with no tickets has only the first.
342
+ Per-ticket path (the default): one ticket at a time. Run `tickets.py frontier`, pick one, `tickets.py claim NN` — never hold two tickets at `doing` — then tell the user to run `/atw-implement` for the claimed ticket. One user invocation per ticket.
343
+ Whole-spec path: the user runs `/atw-implement-spec` once. It owns the run from the first claim to the closing commit: it claims with `tickets.py claim NN --parallel`, dispatches implementer sub-agents across the frontier, each in its own worktree, lands everything on one integration branch, marks each ticket `done` as its work merges, reviews that branch once at the end, and writes spec updates back before its closing commit. Do not claim, review or commit around it. It needs a platform that dispatches sub-agents.
344
+ On the per-ticket path, that one `/atw-implement` run is a closed chain and must not be broken up from the outside: implement (test-first where it fits) → run tests, full suite on the last pass → review → handle findings → write spec updates back → commit. Never instruct it to skip the review or the commit.
319
345
  Findings triage: spec-axis findings and anything the standards axis calls a hard violation get fixed first, then a full re-review, then the commit. Judgement calls ship and get reported.
320
346
  Relay every review report to the user verbatim — Standards and Spec, plus Visual when the ticket changed UI — even when the verdict is "nothing found". No report reaching you is not a passing review.
321
347
  Any sub-agent dispatched from here starts its prompt with `Active task: <task path from task.py current>` — the role files read that line to find the task, and it is the context hooks' fallback when session resolution misses.
322
- Main-session default: run the process; the implementation itself is written inside `/atw-implement`, never by a dispatched `atw-implement-agent` — that role file is reserved and is not a step in this flow. The only sub-agent this phase raises is `atw-review` (twice, from inside `/atw-implement` — three times when the ticket changes UI and a Visual review runs). Sub-agent self-exemption: this breadcrumb reaches sub-agent turns on some hosts, so if you are already running as `atw-review`, do NOT spawn another `atw-review` — do the review you were dispatched for. Dispatch is main session only.
323
- Then `tickets.py done NN` and back to the frontier. When the frontier is empty, run `task.py set-status <task> accept`.
348
+ Main-session default: run the process; on the per-ticket path the implementation itself is written inside `/atw-implement`, never by a dispatched `atw-implement-agent` — that role file is reserved and is not a step in this flow. The only sub-agent that path raises is `atw-review` (twice, from inside `/atw-implement` — three times when the ticket changes UI and a Visual review runs). Implementer sub-agents exist only inside a `/atw-implement-spec` run, dispatched by that skill and by nothing else. Sub-agent self-exemption: this breadcrumb reaches sub-agent turns on some hosts. If you are already running as `atw-review`, do NOT spawn another `atw-review` — do the review you were dispatched for. If you were dispatched by `/atw-implement-spec` as an implementer or merger, stop ③ is already satisfied — do the work you were dispatched for and dispatch nothing. Dispatch is main session only.
349
+ Per-ticket path: then `tickets.py done NN` and back to the frontier. Either path: when the frontier is empty and every ticket is `done`, run `task.py set-status <task> accept`.
324
350
  [/workflow-state:implement]
325
351
 
326
352
  ### Phase 3: Finish
@@ -363,12 +389,15 @@ When a user request matches one of these intents inside an active task, route fi
363
389
  - Writing or revising the spec → `/atw-spec`
364
390
  - Slicing a confirmed spec into tickets → `/atw-tickets`
365
391
  - Starting a claimed ticket → `/atw-implement` (the user runs it; stop ③)
392
+ - Implementing every ticket of a sliced spec in one parallel run → `/atw-implement-spec` (the user runs it; stop ③)
366
393
  - Building or polishing a screen for a claimed ticket → `/atw-ui`, used from inside `/atw-implement`
367
394
  - Same bug fixed more than once → `/atw-diagnosing-bugs`
368
395
  - Knowledge worth keeping outside a ticket → `/atw-update-spec`
396
+ - The user cannot follow the terms, an approval prompt or an error, or says "开启小白模式" / "关闭小白模式" → `/atw-noob-mode` (in any stage, with or without a task)
369
397
 
370
- Six of these are user-triggered and the AI cannot invoke them: `/atw-askme`,
371
- `/atw-askme-with-docs`, `/atw-map`, `/atw-spec`, `/atw-tickets`, `/atw-implement`.
398
+ Seven of these are user-triggered and the AI cannot invoke them: `/atw-askme`,
399
+ `/atw-askme-with-docs`, `/atw-map`, `/atw-spec`, `/atw-tickets`, `/atw-implement`,
400
+ `/atw-implement-spec`.
372
401
  Name the one that fits and let the user run it — calling the Skill tool on one
373
402
  returns an error and nothing else.
374
403
 
@@ -377,7 +406,7 @@ returns an error and nothing else.
377
406
  - Consent to create a task is not consent to implement. Implementation starts at `task.py start`, after the user confirms `prd.md`.
378
407
  - Stops ①–④ are the user's calls. Never advance through one by inferring the answer.
379
408
  - Planning must be persisted to task artifacts; the review chain must run before reporting a ticket complete.
380
- - Never mark two tickets `**Impl:** doing` at the same time.
409
+ - Never mark two tickets `**Impl:** doing` at the same time. The only thing that may is a `/atw-implement-spec` run, through `tickets.py claim NN --parallel`.
381
410
 
382
411
  ### Loading Step Detail
383
412
 
@@ -558,9 +587,18 @@ Ready to leave Phase 1:
558
587
 
559
588
  ## Phase 2: Execute
560
589
 
561
- Goal: turn the confirmed spec into committed code, one ticket at a time, each one reviewed before it is closed.
590
+ Goal: turn the confirmed spec into committed, reviewed code.
591
+
592
+ There are two ways through this phase, and the user picks at stop ③:
593
+
594
+ | Path | What the user runs | How the tickets move |
595
+ |---|---|---|
596
+ | Per ticket (the default) | `/atw-implement`, once per ticket | Steps 2.1–2.4: one ticket at a time, each reviewed before it is closed |
597
+ | Whole spec | `/atw-implement-spec`, once | Step 2.7: implementer sub-agents work the frontier in parallel on one integration branch, reviewed once at the end |
598
+
599
+ A task with no tickets has only the per-ticket path. The whole-spec path also needs a platform that dispatches sub-agents; on one that does not, name only the per-ticket path.
562
600
 
563
- The main session runs the process. It does not write the implementation itself and it does not dispatch an implementation sub-agent — the work happens inside `/atw-implement`, which the user starts.
601
+ The main session runs the process. On the per-ticket path it does not write the implementation itself and it does not dispatch an implementation sub-agent — the work happens inside `/atw-implement`, which the user starts. On the whole-spec path the main session is the orchestrator `/atw-implement-spec` describes, and the implementers it dispatches are that skill's, not a step of this file.
564
602
 
565
603
  **Sub-agent dispatch protocol** — applies to every platform and every sub-agent
566
604
  dispatched anywhere in this workflow (the review sub-agents raised inside the
@@ -582,9 +620,12 @@ not spawn another `atw-review`.
582
620
  Without this the guidance a sub-agent inherits reads as an instruction to
583
621
  dispatch, and it dispatches itself.
584
622
 
585
- Implementation is never dispatched. `atw-implement-agent` ships as a reserved
586
- role file so the injection path stays wired (D23), but no step in this
587
- workflow spawns it — the code is written inside `/atw-implement`.
623
+ Implementation is never dispatched on the per-ticket path. `atw-implement-agent`
624
+ ships as a reserved role file so the injection path stays wired (D23), but no
625
+ step in this workflow spawns it — the code is written inside `/atw-implement`.
626
+ A `/atw-implement-spec` run does dispatch implementers, as general-purpose
627
+ sub-agents carrying that skill's own brief — not `atw-implement-agent`, which
628
+ may not commit.
588
629
 
589
630
  On Grok Build, use `spawn_subagent` with `subagent_type` set to the ATW agent
590
631
  name (e.g. `atw-review`). On Kimi Code, dispatch the built-in `coder` /
@@ -666,6 +707,26 @@ python3 ./.atw/scripts/task.py set-status <task-dir> accept
666
707
 
667
708
  If the same issue has now been fixed more than once, stop patching and tell the user to run `/atw-diagnosing-bugs` — it classifies the root cause, explains why the earlier fixes did not hold, and proposes prevention worth writing into `.atw/spec/`.
668
709
 
710
+ #### 2.7 Whole-spec run `[alternative to 2.1–2.4 · once]`
711
+
712
+ **Stop ③**, the other way through it: the user runs `/atw-implement-spec` instead of `/atw-implement`. You cannot invoke it, and you do not start it because it looks faster — the user is trading a per-ticket look at the work for one review at the end, and that trade is theirs.
713
+
714
+ It replaces steps 2.1–2.4 for the whole task. The skill carries the procedure; what this file needs you to know is what changes around it:
715
+
716
+ - **Tickets run in parallel.** The orchestrator claims with `tickets.py claim NN --parallel`, so several tickets sit at `**Impl:** doing` at once and none of them is "the current ticket". Do not claim by hand during the run.
717
+ - **Work lands on an integration branch**, not the branch the task started on. Each implementer sub-agent works in its own worktree and its own branch; a merger sub-agent lands each one. `task.json.branch` records the integration branch.
718
+ - **One review, at the end.** The review compares the code against the whole spec, so it only makes sense once every ticket has landed. Its findings are fixed once and re-checked once; whatever is still open after that comes back to the user rather than starting another round.
719
+ - **Spec updates still land before the closing commit**, once for the run instead of once per ticket.
720
+ - **Review reports are relayed as written** (step 2.3 applies unchanged).
721
+
722
+ The run stops and reports when a ticket cannot be finished as written, a merge cannot be resolved, or the tests cannot be made to pass. Everything already merged stays. Roll back as in 2.5; a ticket left at `doing` by a stopped run is finished with `/atw-implement` or by running `/atw-implement-spec` again.
723
+
724
+ When every ticket is `done`:
725
+
726
+ ```bash
727
+ python3 ./.atw/scripts/task.py set-status <task-dir> accept
728
+ ```
729
+
669
730
  ---
670
731
 
671
732
  ## Phase 3: Finish
@@ -683,6 +744,8 @@ python3 ./.atw/scripts/tickets.py summary # every ticket done
683
744
  git status --porcelain # clean tree; the chain commits as it goes
684
745
  ```
685
746
 
747
+ After a whole-spec run the work sits on the integration branch named in `task.json.branch`. Say so in the report: merging it is the user's call, made after acceptance.
748
+
686
749
  **Stop ④**: present that and wait. Whether the work is done is the user's judgement, not yours — you can report that every criterion is met, but you cannot accept on their behalf.
687
750
 
688
751
  #### 3.2 Archive `[required · once]`
@@ -709,7 +772,7 @@ Edit the corresponding step's walkthrough body in the Phase 1 / 2 / 3 sections a
709
772
 
710
773
  - No active task must triage first and ask for task-creation consent before creating an ATW task.
711
774
  - Each of the four stops must stay reachable and must stay the user's call.
712
- - Every execution path must keep the implement chain intact: review and spec update before the commit, never after.
775
+ - Every execution path must keep review and spec update inside the run, never after it: before each ticket's commit on the per-ticket path, before the closing commit on the integration branch on the whole-spec path.
713
776
 
714
777
  Structure is guarded by `packages/cli/test/scripts/workflow-structure.test.ts`, which runs with `pnpm test` — there is no separate step to remember.
715
778
 
@@ -727,6 +790,7 @@ All tag blocks live in the `## Phase Index` section above, immediately after eac
727
790
  | All of Phase 2 | `[workflow-state:implement]` |
728
791
  | All of Phase 3 up to archive | `[workflow-state:accept]` |
729
792
  | Archive interrupted; task still under `.atw/tasks/` | `[workflow-state:completed]` |
793
+ | Any of the above, while the developer has noob mode on (appended, not a status) | `[workflow-state:noob_mode]` |
730
794
 
731
795
  Directly edit the body of the corresponding `[workflow-state:STATUS]` block. After editing, run `atw update` (if you're a template maintainer) or restart your AI session (if you're customizing your own project) — no script changes required.
732
796