@ecc-hgy/ae 0.4.0 → 0.6.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 (49) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +168 -138
  3. package/bin/ae.js +2 -2
  4. package/package.json +43 -43
  5. package/skills/brainstorming/SKILL.md +133 -133
  6. package/skills/diagnose/SKILL.md +146 -146
  7. package/skills/diagnose/assets/issue-7-sections.md +35 -35
  8. package/skills/diagnose/scripts/hitl-loop.template.sh +41 -41
  9. package/skills/grill-me/SKILL.md +10 -10
  10. package/skills/handoff/SKILL.md +19 -19
  11. package/skills/improve-codebase-architecture/DEEPENING.md +37 -37
  12. package/skills/improve-codebase-architecture/HTML-REPORT.md +123 -123
  13. package/skills/improve-codebase-architecture/INTERFACE-DESIGN.md +44 -44
  14. package/skills/improve-codebase-architecture/LANGUAGE.md +53 -53
  15. package/skills/improve-codebase-architecture/SKILL.md +101 -101
  16. package/skills/karpathy-guidelines/SKILL.md +63 -63
  17. package/skills/powerautomate-email-to-sharepoint-excel/powerautomate-email-to-sharepoint-excel-skill.md +496 -0
  18. package/skills/review/SKILL.md +119 -119
  19. package/skills/tdd/SKILL.md +157 -157
  20. package/skills/tdd/deep-modules.md +33 -33
  21. package/skills/tdd/interface-design.md +31 -31
  22. package/skills/tdd/mocking.md +59 -59
  23. package/skills/tdd/refactoring.md +10 -10
  24. package/skills/tdd/tests.md +61 -61
  25. package/skills/to-issues/SKILL.md +79 -79
  26. package/skills/to-issues/todo-template.md +25 -25
  27. package/skills/to-prd/SKILL.md +108 -108
  28. package/skills/using-agentic-engineering/SKILL.md +62 -62
  29. package/skills/verification-before-completion/SKILL.md +153 -153
  30. package/skills/writing-plans/SKILL.md +115 -115
  31. package/skills/zoom-out/SKILL.md +7 -7
  32. package/src/cli.js +61 -61
  33. package/src/commands/init.js +137 -134
  34. package/src/commands/setup.js +162 -103
  35. package/src/platforms.js +132 -0
  36. package/src/skeleton.js +134 -99
  37. package/src/utils/copy.js +100 -100
  38. package/src/utils/paths.js +60 -60
  39. package/src/utils/report.js +30 -30
  40. package/templates/entries/AGENTS.md +2 -0
  41. package/templates/entries/CLAUDE.md +5 -5
  42. package/templates/entries/README.md +33 -31
  43. package/templates/entries/handoff.md +1 -1
  44. package/templates/entries/spec/ADR/AGENTS.md +30 -30
  45. package/templates/entries/spec/ADR/CLAUDE.md +5 -5
  46. package/templates/entries/spec/AGENTS.md +34 -34
  47. package/templates/entries/spec/CLAUDE.md +5 -5
  48. package/templates/entries/spec/INDEX.md +28 -28
  49. package/templates/entries/spec/README.md +23 -23
@@ -1,31 +1,31 @@
1
- # Interface Design for Testability
2
-
3
- Good interfaces make testing natural:
4
-
5
- 1. **Accept dependencies, don't create them**
6
-
7
- ```typescript
8
- // Testable
9
- function processOrder(order, paymentGateway) {}
10
-
11
- // Hard to test
12
- function processOrder(order) {
13
- const gateway = new StripeGateway();
14
- }
15
- ```
16
-
17
- 2. **Return results, don't produce side effects**
18
-
19
- ```typescript
20
- // Testable
21
- function calculateDiscount(cart): Discount {}
22
-
23
- // Hard to test
24
- function applyDiscount(cart): void {
25
- cart.total -= discount;
26
- }
27
- ```
28
-
29
- 3. **Small surface area**
30
- - Fewer methods = fewer tests needed
31
- - Fewer params = simpler test setup
1
+ # Interface Design for Testability
2
+
3
+ Good interfaces make testing natural:
4
+
5
+ 1. **Accept dependencies, don't create them**
6
+
7
+ ```typescript
8
+ // Testable
9
+ function processOrder(order, paymentGateway) {}
10
+
11
+ // Hard to test
12
+ function processOrder(order) {
13
+ const gateway = new StripeGateway();
14
+ }
15
+ ```
16
+
17
+ 2. **Return results, don't produce side effects**
18
+
19
+ ```typescript
20
+ // Testable
21
+ function calculateDiscount(cart): Discount {}
22
+
23
+ // Hard to test
24
+ function applyDiscount(cart): void {
25
+ cart.total -= discount;
26
+ }
27
+ ```
28
+
29
+ 3. **Small surface area**
30
+ - Fewer methods = fewer tests needed
31
+ - Fewer params = simpler test setup
@@ -1,59 +1,59 @@
1
- # When to Mock
2
-
3
- Mock at **system boundaries** only:
4
-
5
- - External APIs (payment, email, etc.)
6
- - Databases (sometimes - prefer test DB)
7
- - Time/randomness
8
- - File system (sometimes)
9
-
10
- Don't mock:
11
-
12
- - Your own classes/modules
13
- - Internal collaborators
14
- - Anything you control
15
-
16
- ## Designing for Mockability
17
-
18
- At system boundaries, design interfaces that are easy to mock:
19
-
20
- **1. Use dependency injection**
21
-
22
- Pass external dependencies in rather than creating them internally:
23
-
24
- ```typescript
25
- // Easy to mock
26
- function processPayment(order, paymentClient) {
27
- return paymentClient.charge(order.total);
28
- }
29
-
30
- // Hard to mock
31
- function processPayment(order) {
32
- const client = new StripeClient(process.env.STRIPE_KEY);
33
- return client.charge(order.total);
34
- }
35
- ```
36
-
37
- **2. Prefer SDK-style interfaces over generic fetchers**
38
-
39
- Create specific functions for each external operation instead of one generic function with conditional logic:
40
-
41
- ```typescript
42
- // GOOD: Each function is independently mockable
43
- const api = {
44
- getUser: (id) => fetch(`/users/${id}`),
45
- getOrders: (userId) => fetch(`/users/${userId}/orders`),
46
- createOrder: (data) => fetch('/orders', { method: 'POST', body: data }),
47
- };
48
-
49
- // BAD: Mocking requires conditional logic inside the mock
50
- const api = {
51
- fetch: (endpoint, options) => fetch(endpoint, options),
52
- };
53
- ```
54
-
55
- The SDK approach means:
56
- - Each mock returns one specific shape
57
- - No conditional logic in test setup
58
- - Easier to see which endpoints a test exercises
59
- - Type safety per endpoint
1
+ # When to Mock
2
+
3
+ Mock at **system boundaries** only:
4
+
5
+ - External APIs (payment, email, etc.)
6
+ - Databases (sometimes - prefer test DB)
7
+ - Time/randomness
8
+ - File system (sometimes)
9
+
10
+ Don't mock:
11
+
12
+ - Your own classes/modules
13
+ - Internal collaborators
14
+ - Anything you control
15
+
16
+ ## Designing for Mockability
17
+
18
+ At system boundaries, design interfaces that are easy to mock:
19
+
20
+ **1. Use dependency injection**
21
+
22
+ Pass external dependencies in rather than creating them internally:
23
+
24
+ ```typescript
25
+ // Easy to mock
26
+ function processPayment(order, paymentClient) {
27
+ return paymentClient.charge(order.total);
28
+ }
29
+
30
+ // Hard to mock
31
+ function processPayment(order) {
32
+ const client = new StripeClient(process.env.STRIPE_KEY);
33
+ return client.charge(order.total);
34
+ }
35
+ ```
36
+
37
+ **2. Prefer SDK-style interfaces over generic fetchers**
38
+
39
+ Create specific functions for each external operation instead of one generic function with conditional logic:
40
+
41
+ ```typescript
42
+ // GOOD: Each function is independently mockable
43
+ const api = {
44
+ getUser: (id) => fetch(`/users/${id}`),
45
+ getOrders: (userId) => fetch(`/users/${userId}/orders`),
46
+ createOrder: (data) => fetch('/orders', { method: 'POST', body: data }),
47
+ };
48
+
49
+ // BAD: Mocking requires conditional logic inside the mock
50
+ const api = {
51
+ fetch: (endpoint, options) => fetch(endpoint, options),
52
+ };
53
+ ```
54
+
55
+ The SDK approach means:
56
+ - Each mock returns one specific shape
57
+ - No conditional logic in test setup
58
+ - Easier to see which endpoints a test exercises
59
+ - Type safety per endpoint
@@ -1,10 +1,10 @@
1
- # Refactor Candidates
2
-
3
- After TDD cycle, look for:
4
-
5
- - **Duplication** → Extract function/class
6
- - **Long methods** → Break into private helpers (keep tests on public interface)
7
- - **Shallow modules** → Combine or deepen
8
- - **Feature envy** → Move logic to where data lives
9
- - **Primitive obsession** → Introduce value objects
10
- - **Existing code** the new code reveals as problematic
1
+ # Refactor Candidates
2
+
3
+ After TDD cycle, look for:
4
+
5
+ - **Duplication** → Extract function/class
6
+ - **Long methods** → Break into private helpers (keep tests on public interface)
7
+ - **Shallow modules** → Combine or deepen
8
+ - **Feature envy** → Move logic to where data lives
9
+ - **Primitive obsession** → Introduce value objects
10
+ - **Existing code** the new code reveals as problematic
@@ -1,61 +1,61 @@
1
- # Good and Bad Tests
2
-
3
- ## Good Tests
4
-
5
- **Integration-style**: Test through real interfaces, not mocks of internal parts.
6
-
7
- ```typescript
8
- // GOOD: Tests observable behavior
9
- test("user can checkout with valid cart", async () => {
10
- const cart = createCart();
11
- cart.add(product);
12
- const result = await checkout(cart, paymentMethod);
13
- expect(result.status).toBe("confirmed");
14
- });
15
- ```
16
-
17
- Characteristics:
18
-
19
- - Tests behavior users/callers care about
20
- - Uses public API only
21
- - Survives internal refactors
22
- - Describes WHAT, not HOW
23
- - One logical assertion per test
24
-
25
- ## Bad Tests
26
-
27
- **Implementation-detail tests**: Coupled to internal structure.
28
-
29
- ```typescript
30
- // BAD: Tests implementation details
31
- test("checkout calls paymentService.process", async () => {
32
- const mockPayment = jest.mock(paymentService);
33
- await checkout(cart, payment);
34
- expect(mockPayment.process).toHaveBeenCalledWith(cart.total);
35
- });
36
- ```
37
-
38
- Red flags:
39
-
40
- - Mocking internal collaborators
41
- - Testing private methods
42
- - Asserting on call counts/order
43
- - Test breaks when refactoring without behavior change
44
- - Test name describes HOW not WHAT
45
- - Verifying through external means instead of interface
46
-
47
- ```typescript
48
- // BAD: Bypasses interface to verify
49
- test("createUser saves to database", async () => {
50
- await createUser({ name: "Alice" });
51
- const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]);
52
- expect(row).toBeDefined();
53
- });
54
-
55
- // GOOD: Verifies through interface
56
- test("createUser makes user retrievable", async () => {
57
- const user = await createUser({ name: "Alice" });
58
- const retrieved = await getUser(user.id);
59
- expect(retrieved.name).toBe("Alice");
60
- });
61
- ```
1
+ # Good and Bad Tests
2
+
3
+ ## Good Tests
4
+
5
+ **Integration-style**: Test through real interfaces, not mocks of internal parts.
6
+
7
+ ```typescript
8
+ // GOOD: Tests observable behavior
9
+ test("user can checkout with valid cart", async () => {
10
+ const cart = createCart();
11
+ cart.add(product);
12
+ const result = await checkout(cart, paymentMethod);
13
+ expect(result.status).toBe("confirmed");
14
+ });
15
+ ```
16
+
17
+ Characteristics:
18
+
19
+ - Tests behavior users/callers care about
20
+ - Uses public API only
21
+ - Survives internal refactors
22
+ - Describes WHAT, not HOW
23
+ - One logical assertion per test
24
+
25
+ ## Bad Tests
26
+
27
+ **Implementation-detail tests**: Coupled to internal structure.
28
+
29
+ ```typescript
30
+ // BAD: Tests implementation details
31
+ test("checkout calls paymentService.process", async () => {
32
+ const mockPayment = jest.mock(paymentService);
33
+ await checkout(cart, payment);
34
+ expect(mockPayment.process).toHaveBeenCalledWith(cart.total);
35
+ });
36
+ ```
37
+
38
+ Red flags:
39
+
40
+ - Mocking internal collaborators
41
+ - Testing private methods
42
+ - Asserting on call counts/order
43
+ - Test breaks when refactoring without behavior change
44
+ - Test name describes HOW not WHAT
45
+ - Verifying through external means instead of interface
46
+
47
+ ```typescript
48
+ // BAD: Bypasses interface to verify
49
+ test("createUser saves to database", async () => {
50
+ await createUser({ name: "Alice" });
51
+ const row = await db.query("SELECT * FROM users WHERE name = ?", ["Alice"]);
52
+ expect(row).toBeDefined();
53
+ });
54
+
55
+ // GOOD: Verifies through interface
56
+ test("createUser makes user retrievable", async () => {
57
+ const user = await createUser({ name: "Alice" });
58
+ const retrieved = await getUser(user.id);
59
+ expect(retrieved.name).toBe("Alice");
60
+ });
61
+ ```
@@ -1,79 +1,79 @@
1
- ---
2
- name: to-issues
3
- description: Break a design (and supporting spec context) into vertical-slice tasks and save them as `spec/needs/<need-name>/todo.md`. Use when user wants to convert a design into actionable tasks (S1 node A4).
4
- ---
5
-
6
- # To Issues
7
-
8
- Break a plan into independently-grabbable issues using vertical slices (tracer bullets).
9
-
10
- ## Process
11
-
12
- ### 1. Gather context
13
-
14
- **Primary input:** `spec/needs/<need-name>/design.md` (produced by A3 `writing-plans`).
15
-
16
- If the design is insufficient on its own (acceptance criteria not concrete enough, scope boundaries unclear, or a slice references behavior that's defined elsewhere), supplement with:
17
-
18
- - The sibling `spec/needs/<need-name>/prd.md` — for user-facing acceptance criteria, out-of-scope notes
19
- - The `related-needs` field in `design.md` frontmatter — read those needs' `design.md` for shared module decisions
20
- - `spec/INDEX.md` and `spec/ADR/` — for vocabulary and accepted cross-need decisions
21
-
22
- If a design gap is severe enough that you can't draft a slice, STOP and surface it as a finding — go back to A3 (`writing-plans`) to patch `design.md` first, rather than guessing.
23
-
24
- ### 2. Explore the codebase (optional)
25
-
26
- If you have not already explored the codebase, do so to understand the current state of the code. Task titles and descriptions should use vocabulary from `spec/INDEX.md` and existing `spec/needs/*/`, and respect ADRs under `spec/ADR/`.
27
-
28
- ### 3. Draft vertical slices
29
-
30
- Break the plan into **tracer bullet** issues. Each issue is a thin vertical slice that cuts through ALL integration layers end-to-end, NOT a horizontal slice of one layer.
31
-
32
- <vertical-slice-rules>
33
- - Each slice delivers a narrow but COMPLETE path through every layer (schema, API, UI, tests)
34
- - A completed slice is demoable or verifiable on its own
35
- - Prefer many thin slices over few thick ones
36
- </vertical-slice-rules>
37
-
38
- ### 4. Quiz the user
39
-
40
- Present the proposed breakdown as a numbered list. For each slice, show:
41
-
42
- - **Title**: short descriptive name
43
- - **Acceptance**: one-line acceptance criterion (the observable behavior that proves it's done)
44
- - **Blocked by**: which other slices (if any) must complete first; reference by slice number (e.g. "T2")
45
-
46
- Ask the user:
47
-
48
- - Does the granularity feel right? (too coarse / too fine)
49
- - Are the dependency relationships correct?
50
- - Should any slices be merged or split further?
51
-
52
- Iterate until the user approves the breakdown.
53
-
54
- ### 5. Save the task list to `todo.md`
55
-
56
- Save the approved breakdown to `spec/needs/<need-name>/todo.md`, using [`todo-template.md`](todo-template.md) as the starting structure. The template encodes the format and the maintenance rules; copy it, fill in the slices, then save.
57
-
58
- `todo.md` has NO frontmatter — it is a rolling working artifact, not a stateful spec document.
59
-
60
- Format summary (full rules live in [`todo-template.md`](todo-template.md)):
61
-
62
- - Two sections: `## 实施` (executable slices) and `## 阻塞 / 待澄清` (open blockers)
63
- - Slice IDs: `T<n>` for tasks, `B<n>` for blockers; stable across the life of the need
64
- - Each `## 实施` line: `- [ ] T<n> <title> — <one-line acceptance>[; blocked by T<m>]`
65
- - Each slice MUST trace back to a section in `design.md`; if it can't, that's a signal to patch `design.md`, not to smuggle scope into `todo.md`
66
-
67
- ## After Saving
68
-
69
- 1. Update `spec/INDEX.md`:
70
- - Set the `todo` column to `0/N` (where N = total tasks in `## 实施`)
71
- - Recompute the `当前节点` column per the rules in `spec/AGENTS.md` §INDEX 推导规则 (likely now `A5 执行`)
72
- - If unsure, run `ae index-rebuild` for an idempotent rescan
73
- 2. Hand off to the next S1 node: A5 `tdd` will read this `todo.md` (plus `design.md`) and drive the red-green-refactor loop. Tell the user the task list is ready and recommend invoking `tdd` next.
74
-
75
- ## Boundaries
76
-
77
- - This skill writes ONLY `spec/needs/<need-name>/todo.md` (plus the INDEX row). It does NOT modify `prd.md` or `design.md`.
78
- - A task in `todo.md` MUST trace back to a section in `design.md`. New scope discovered here is a signal to patch `design.md` first.
79
- - This skill does NOT execute tasks — that is A5 `tdd`.
1
+ ---
2
+ name: to-issues
3
+ description: Break a design (and supporting spec context) into vertical-slice tasks and save them as `spec/needs/<need-name>/todo.md`. Use when user wants to convert a design into actionable tasks (S1 node A4).
4
+ ---
5
+
6
+ # To Issues
7
+
8
+ Break a plan into independently-grabbable issues using vertical slices (tracer bullets).
9
+
10
+ ## Process
11
+
12
+ ### 1. Gather context
13
+
14
+ **Primary input:** `spec/needs/<need-name>/design.md` (produced by A3 `writing-plans`).
15
+
16
+ If the design is insufficient on its own (acceptance criteria not concrete enough, scope boundaries unclear, or a slice references behavior that's defined elsewhere), supplement with:
17
+
18
+ - The sibling `spec/needs/<need-name>/prd.md` — for user-facing acceptance criteria, out-of-scope notes
19
+ - The `related-needs` field in `design.md` frontmatter — read those needs' `design.md` for shared module decisions
20
+ - `spec/INDEX.md` and `spec/ADR/` — for vocabulary and accepted cross-need decisions
21
+
22
+ If a design gap is severe enough that you can't draft a slice, STOP and surface it as a finding — go back to A3 (`writing-plans`) to patch `design.md` first, rather than guessing.
23
+
24
+ ### 2. Explore the codebase (optional)
25
+
26
+ If you have not already explored the codebase, do so to understand the current state of the code. Task titles and descriptions should use vocabulary from `spec/INDEX.md` and existing `spec/needs/*/`, and respect ADRs under `spec/ADR/`.
27
+
28
+ ### 3. Draft vertical slices
29
+
30
+ Break the plan into **tracer bullet** issues. Each issue is a thin vertical slice that cuts through ALL integration layers end-to-end, NOT a horizontal slice of one layer.
31
+
32
+ <vertical-slice-rules>
33
+ - Each slice delivers a narrow but COMPLETE path through every layer (schema, API, UI, tests)
34
+ - A completed slice is demoable or verifiable on its own
35
+ - Prefer many thin slices over few thick ones
36
+ </vertical-slice-rules>
37
+
38
+ ### 4. Quiz the user
39
+
40
+ Present the proposed breakdown as a numbered list. For each slice, show:
41
+
42
+ - **Title**: short descriptive name
43
+ - **Acceptance**: one-line acceptance criterion (the observable behavior that proves it's done)
44
+ - **Blocked by**: which other slices (if any) must complete first; reference by slice number (e.g. "T2")
45
+
46
+ Ask the user:
47
+
48
+ - Does the granularity feel right? (too coarse / too fine)
49
+ - Are the dependency relationships correct?
50
+ - Should any slices be merged or split further?
51
+
52
+ Iterate until the user approves the breakdown.
53
+
54
+ ### 5. Save the task list to `todo.md`
55
+
56
+ Save the approved breakdown to `spec/needs/<need-name>/todo.md`, using [`todo-template.md`](todo-template.md) as the starting structure. The template encodes the format and the maintenance rules; copy it, fill in the slices, then save.
57
+
58
+ `todo.md` has NO frontmatter — it is a rolling working artifact, not a stateful spec document.
59
+
60
+ Format summary (full rules live in [`todo-template.md`](todo-template.md)):
61
+
62
+ - Two sections: `## 实施` (executable slices) and `## 阻塞 / 待澄清` (open blockers)
63
+ - Slice IDs: `T<n>` for tasks, `B<n>` for blockers; stable across the life of the need
64
+ - Each `## 实施` line: `- [ ] T<n> <title> — <one-line acceptance>[; blocked by T<m>]`
65
+ - Each slice MUST trace back to a section in `design.md`; if it can't, that's a signal to patch `design.md`, not to smuggle scope into `todo.md`
66
+
67
+ ## After Saving
68
+
69
+ 1. Update `spec/INDEX.md`:
70
+ - Set the `todo` column to `0/N` (where N = total tasks in `## 实施`)
71
+ - Recompute the `当前节点` column per the rules in `spec/AGENTS.md` §INDEX 推导规则 (likely now `A5 执行`)
72
+ - If unsure, run `ae index-rebuild` for an idempotent rescan
73
+ 2. Hand off to the next S1 node: A5 `tdd` will read this `todo.md` (plus `design.md`) and drive the red-green-refactor loop. Tell the user the task list is ready and recommend invoking `tdd` next.
74
+
75
+ ## Boundaries
76
+
77
+ - This skill writes ONLY `spec/needs/<need-name>/todo.md` (plus the INDEX row). It does NOT modify `prd.md` or `design.md`.
78
+ - A task in `todo.md` MUST trace back to a section in `design.md`. New scope discovered here is a signal to patch `design.md` first.
79
+ - This skill does NOT execute tasks — that is A5 `tdd`.
@@ -1,25 +1,25 @@
1
- # Todo - <need-name>
2
-
3
- > Derived from: prd.md + design.md
4
-
5
- ## 实施
6
-
7
- - [ ] T1 <title> — <one-line acceptance>
8
- - [ ] T2 <title> — <one-line acceptance>; blocked by T1
9
- - [ ] T3 <title> — <one-line acceptance>
10
-
11
- ## 阻塞 / 待澄清
12
-
13
- - B1 <blocker description, link back to the design section that needs sharpening>
14
-
15
- <!--
16
- Rules for maintaining this file:
17
-
18
- - NO frontmatter — this is a rolling working artifact, not a stateful spec document.
19
- - Use `- [ ]` for unfinished, `- [x]` for finished. Never delete completed items — they are visible history.
20
- - Sort by dependency order (blockers first); within the same level, sort by suggested execution order.
21
- - If a slice depends on a design decision that is still open, put it in `## 阻塞 / 待澄清` instead of `## 实施`.
22
- - Each slice MUST be traceable to a section in `design.md`. If a new slice has no traceable design section, that itself is a finding — go back and patch `design.md` rather than smuggling new scope into `todo.md`.
23
- - Slice identifiers: `T<n>` for execution tasks, `B<n>` for blockers. Stable across the life of the need; do not renumber.
24
- - Acceptance criteria: a single observable behavior that proves the slice is done. If it needs multiple lines, the slice is probably too coarse — split it.
25
- -->
1
+ # Todo - <need-name>
2
+
3
+ > Derived from: prd.md + design.md
4
+
5
+ ## 实施
6
+
7
+ - [ ] T1 <title> — <one-line acceptance>
8
+ - [ ] T2 <title> — <one-line acceptance>; blocked by T1
9
+ - [ ] T3 <title> — <one-line acceptance>
10
+
11
+ ## 阻塞 / 待澄清
12
+
13
+ - B1 <blocker description, link back to the design section that needs sharpening>
14
+
15
+ <!--
16
+ Rules for maintaining this file:
17
+
18
+ - NO frontmatter — this is a rolling working artifact, not a stateful spec document.
19
+ - Use `- [ ]` for unfinished, `- [x]` for finished. Never delete completed items — they are visible history.
20
+ - Sort by dependency order (blockers first); within the same level, sort by suggested execution order.
21
+ - If a slice depends on a design decision that is still open, put it in `## 阻塞 / 待澄清` instead of `## 实施`.
22
+ - Each slice MUST be traceable to a section in `design.md`. If a new slice has no traceable design section, that itself is a finding — go back and patch `design.md` rather than smuggling new scope into `todo.md`.
23
+ - Slice identifiers: `T<n>` for execution tasks, `B<n>` for blockers. Stable across the life of the need; do not renumber.
24
+ - Acceptance criteria: a single observable behavior that proves the slice is done. If it needs multiple lines, the slice is probably too coarse — split it.
25
+ -->