feat(#377): /plan-initiative — initiative → milestones → tasks (DAG + topo-sort + two-pass filing)#379
Conversation
…topo-sort, two-pass filing)
New skill that sits between /validate-idea and /write-spec in the planning
stack: quarter-shape initiative planning that decomposes deterministically
into the existing ticket primitives.
What the skill does:
1. Initiative-level interview (goal, quarter, success criterion, scope —
per-project vs framework-wide)
2. Per-milestone Socratic interview, one milestone at a time:
- Mandatory: name + success criterion + blocks + blocked-by
- Optional (operator can defer with TBD): kill criterion, value,
risk, confidence in time estimate
3. Cycle detection on the resulting DAG via Kahn-style topo sort;
operator-driven cycle resolution (v1 doesn't auto-break)
4. Topo-sorted recommended sequence with value × risk-inverse tie-breaks
5. Mermaid `flowchart LR` DAG rendered into the doc
6. Optional per-item filing of milestones as Feature-shape tickets,
mirroring /handover step 7.5's UX (per-item y/n, bulk shapes, source
link in the ticket body pointing back at the initiative doc)
7. Two-pass filing: pass 1 files each milestone, pass 2 iterates over
the filed set and adds `**Blocks**: #X` / `**Blocked by**: #Y` lines
to each ticket's body so the tracker reflects the DAG. Partial
filings are supported (cross-refs only span the filed subset).
8. Idempotent on re-runs: preserves prior `Filed as [#N](url)` markers,
prompts only on unfiled milestones. Same filed-marker-presence pattern
as /handover step 7.5 (NOT byte-equivalence, which composes badly
with the post-filing rewrite — same lesson learned in #376).
Files:
- .claude/skills/plan-initiative/SKILL.md (~250 lines, 15 rules + notes)
- templates/initiative.md (master initiative doc with inline milestone
blocks + DAG Mermaid + open-uncertainties roll-up + re-run history)
- docs/agdr/AgDR-0051-plan-initiative-skill.md (4-axis decision record:
Socratic vs LLM-decompose, single template vs separate, two-pass
filing vs single-pass, filed-marker idempotence vs byte-equivalence)
- CLAUDE.md: skill table row + count bumped to 54
What's out of scope (v1, documented in the AgDR + skill notes):
- Cross-initiative DAGs (initiative A blocks initiative B)
- Time/effort estimation (only confidence is captured)
- Resource allocation / role assignment (framework's role-trigger
machinery handles that downstream)
- Auto-decomposition without operator input — Socratic interview IS
the forcing function
- Gantt / PM-tool sync — Mermaid for the DAG is the v1 surface
Closes #377.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
atlas-apex
left a comment
There was a problem hiding this comment.
Code Review: PR #379
Commit: e1a7d53e0767dc5c66fc59ca1287698a1db61296
VERDICT: CHANGES REQUESTED (submitted as comment because self-PR can't take --request-changes).
Summary
New /plan-initiative skill (~250 lines), templates/initiative.md (~125 lines), AgDR-0051 (~115 lines), and the CLAUDE.md skill-table row. Slot is correct (between /validate-idea and /write-spec), the Socratic-vs-LLM-decompose decision is well-defended in the AgDR, and the two-pass filing + filed-marker-presence idempotence mirror the /handover step 7.5 pattern from #376/#378 cleanly. Three CI-blocking issues need to land before this merges, plus advisories worth fixing now.
Checklist Results
- Architecture & Design: Pass
- Code Quality: Pass
- Testing: N/A (interactive prose skill — pseudocode only; acceptable per PR description)
- Security: Pass (no auth/crypto/secrets touched)
- Performance: Pass
- PR Description & Glossary: Pass (8 terms, narrative summary bullets)
- Summary Bullet Narrative: Pass (all 4 bullets are verb-led, > 6 words, why-it-matters present)
- Technical Decisions (AgDR): Pass (AgDR-0051 walks 4 axes with option matrices)
- Adopter Handbooks: N/A (markdown-only diff; no architecture/migration/language code touched substantively)
Issues Found
Blocker 1 — Broken link in AgDR-0051 causes lychee CI failure
docs/agdr/AgDR-0051-plan-initiative-skill.md:112 reads:
- GitHub Issue [#377](https://github.com/me2resh/appexyard/issues/377) — the feature ticket this AgDR implements
Note appexyard (double-p) — should be apexyard. Line 113 has the correct spelling for #376. lychee is currently red on the PR for this 404. One-character fix.
Blocker 2 — Site-counts drift detection is RED (27 places need updating)
The PR bumped the skill count in CLAUDE.md from 53 → 54 at the "Available skills (53)" header (line 222), but missed the count surface elsewhere. The site-counts drift detection CI job lists 27 places that still say 53:
CLAUDE.md:191—| Skills | .claude/skills/ | 53 slash commands — see the full list below |CLAUDE.md:290—| Skills (53 slash commands) | .claude/skills/ |- 25 places across
site/index.html,site/skills.html,site/architecture.html,site/llms.txt,site/llms-full.txt,site/index.md.gen,site/skills.md.gen,site/architecture.md.gen,site/skill.md
All need to be bumped from 53 → 54. AgDR-0046 (site-counts drift prevention) is the framework's existing rule that catches exactly this class of regression; the CI is doing its job.
Blocker 3 — AgDR-0051 references a non-existent AgDR-0376
Two places in docs/agdr/AgDR-0051-plan-initiative-skill.md reference AgDR-0376:
- Line 3 (the H1 italic summary):
... mirrors the /handover step-7.5 per-item filing UX from AgDR-0376 / #376 - Line 64 (Axis 4 option matrix):
Matches /handover step 7.5's pattern (AgDR-0376 / #376).
The highest AgDR ID in the framework is AgDR-0051 (this one). 0376 is presumably issue-number-confused-for-AgDR-number — #376 is the issue, but no AgDR-0376 exists. Fix: drop the AgDR-0376 / prefix in both places, leaving just #376 (the issue reference is correct), OR cite the actual AgDR that records the /handover step 7.5 design if one exists.
Handbook Findings
(None — diff is markdown-only with no code, no migrations, no architecture changes. Always-load handbooks clean-architecture-layers.md, migration-safety.md, commit-message-quality.md have no triggers in this diff. Commit message itself is conventional + well-structured.)
Suggestions
Advisory 1 — Topo-sort tie-break formula has a counter-intuitive property
SKILL.md step 5 + Rule 6:
score = value_num - (risk_num - 2)
With L=1, M=2, H=3, TBD=2. Walk through:
| Milestone | Value | Risk | score |
|---|---|---|---|
| M1 | H (3) | L (1) | 3 − (1−2) = 4 |
| M2 | H (3) | H (3) | 3 − (3−2) = 2 |
| M3 | L (1) | L (1) | 1 − (1−2) = 2 |
| M4 | H (3) | H (3) | 2 |
M1 (4) > M2 (2): correct, M1 sorts first. ✓
But M3 (value=L, risk=L, score 2) ties with M2/M4 (value=H, risk=H, score 2). The skill's prose says "high-value, low-risk milestones first" — but the additive formula treats "worst-value-best-risk" identically to "best-value-worst-risk". Operators reading the rationale ("value × risk-inverse") expect high-value to dominate; the formula doesn't honour that intent.
A multiplicative formula closer to the stated semantics:
score = value_num * (4 - risk_num)
# M1: 3*3=9, M2: 3*1=3, M3: 1*3=3, M4: 3*1=3
Still ties M2/M3/M4 — resolved by the secondary insertion-order tie-break — but M1 (best-value-best-risk) wouldn't tie with worst-everything milestones. Worth re-thinking before v1 lands, or acknowledge the additive-property tie in the rationale.
Advisory 2 — Cycle detection doesn't disambiguate multiple independent cycles
SKILL.md step 4 pseudocode (lines ~233-249):
if len(sorted_order) < len(milestones):
cycle_nodes = [m for m in milestones if in_degree[m] > 0]
# FAIL — print cycle, ask operator to resolvecycle_nodes is the union of all nodes participating in cycles AND downstream nodes — Kahn's failure set, not a single named cycle. The error message template (lines 254-264) prints exactly one cycle path:
Milestone "M2" → "M3" → "M2"
If there are two independent cycles M2↔M3 and M5↔M6, the pseudocode's cycle_nodes would be [M2, M3, M5, M6] but the operator-facing message only shows one. v1 doesn't actually trace SCC components. Edge case — most 5-milestone initiatives won't hit it — but worth surfacing in the prose or the AgDR § Risks.
Advisory 3 — Idempotence matching is name-only; reworded milestones become duplicates
Rule 8: match milestones across runs by name (case-insensitive, normalised whitespace). Walk this scenario:
- First run: operator names a milestone "Token endpoint" → filed as #100, doc carries
Filed as [#100](url) - Re-run with reworded name: operator types "Auth token endpoint"
- Skill matches by name only → "Auth token endpoint" ≠ "Token endpoint" → treated as NEW
- Result: doc now has both milestones — old one with
Filed as [#100], new one offered for filing
Same soft failure mode /handover faces with verb+noun matching ("Fix 5 tests" → "Fix tests"). v1-acceptable per AgDR-0051 § Risks, but worth telling the operator in the SKILL.md or Rule 8: "subtle renames create duplicate entries — delete the stale one manually if rewording".
Advisory 4 — Two-pass race condition not surfaced to operator
AgDR-0051 § Risks acknowledges the race window between pass 1 fetch and pass 2 write. The skill body (step 8 pass 2) just says "Fetch the current body to handle the teammate-edit race" without surfacing the risk to the operator at pass-2 start. For high-traffic repos / shared-tracker workflows, a one-line "about to rewrite N ticket bodies — pause if any are being actively edited" would close the loop. Low-priority for single-operator workflows.
Advisory 5 — Table-style MD060 (markdownlint-cli2 v0.22+) flags 71 column-style nits
The repo's CI passes markdownlint (using markdownlint-cli2-action@v16, which doesn't enforce MD060). Newer cli versions do. The PR-author claim of "0 errors" is true against the CI version but not against the latest local-tooling default. Not a blocker; just calibrate the claim if the CI ever bumps the action version.
Things that DO work cleanly (per the focus checklist)
- Slot diagram (item 9): confirmed —
/validate-ideais the 5-question pre-spec gate,/write-specis the per-feature PRD,/plan-initiativesits between as the quarter-shape orchestrator. Each filed milestone naturally becomes a/write-specinvocation downstream. - AgDR-0023 reference (item 1): confirmed — AgDR-0023 establishes the
custom-templates/<path>path-mirroring override convention viaportfolio_resolve_template. The skill's plug-in toportfolio_resolve_template initiative.mdis consistent. - Feature ticket body shape (item 2): confirmed — step 8 pass 1 body has both
## User Storyand## Acceptance Criterianon-empty, which satisfiesvalidate-issue-structure.sh's required sections for[Feature]prefix. - Topo-sort tie-break basic check (item 4): confirmed — M1 (H, L) sorts before M2 (H, H). Counter-intuitive tie under additive formula flagged as Advisory 1.
- No bootstrap exemption needed (item 8): confirmed — the skill writes only
.mdfiles (exempt fromrequire-active-ticket.shper the*.mdglob at hook line 109), andgh issue createis gated byrequire-skill-for-issue-create.shwhich accepts any non-emptyactive-issue-skillmarker. No path in the skill writes a non-.mdfile. - Active-issue-skill marker handling (item 7): the skill body says "Always remove on every exit path (success, abort, error)" with the SessionStart sweeper as safety net. Acceptable for an interactive prose skill where Claude is the runtime — interruption-safety is the sweeper's job.
- No tests claim (item 11): agree — the testable logic (Kahn's topo-sort, cycle detection) is described as pseudocode for Claude to implement inline at runtime. There's no shell function to unit-test. Acceptable for v1.
Verdict
CHANGES REQUESTED
The skill design itself is sound — Socratic-vs-LLM-decompose is well-defended, two-pass filing correctly handles partial-fillings, filed-marker-presence is the right idempotence rule (same lesson as #376/#378). Slot positioning is accurate, AgDR walks 4 honest axes, summary bullets are narrative, glossary covers the skill surface.
The three blockers are all mechanical and easy to fix (one typo, one count refresh across 27 lines, one AgDR-reference correction in two places). Once those land and CI is green, this is a clean approval.
Operator: per the sandbox workaround memory, do NOT write the rex.approved marker for this PR — verdict is CHANGES REQUESTED, not APPROVED.
🤖 Reviewed by Rex (Code Reviewer Agent)
📌 Reviewed commit: e1a7d53e0767dc5c66fc59ca1287698a1db61296
…drift Three CI-blocking issues from Rex's review of e1a7d53: 1. Typo `appexyard` (double-p) → `apexyard` in the GitHub Issue link at docs/agdr/AgDR-0051-plan-initiative-skill.md:112. One-character fix. 2. Bogus `AgDR-0376` references in AgDR-0051 (lines 3 + 64) — issue-number confusion. AgDR IDs only go up to 0051. Removed the `AgDR-0376 /` prefix and kept the `#376` issue reference (which IS real). 3. Site-counts drift — bumping the skill count 53 → 54 in CLAUDE.md (lines 191 + 290) and across all 10 site/ files that surface the count: index.html, index.md.gen, architecture.html, architecture.md.gen, llms.txt, llms-full.txt, skill.md, skills.html, skills.md.gen. Covers meta descriptions, OG/Twitter cards, hero metrics block, JSON-LD description, and llms.txt summary text. The "Available skills (53)" header was already bumped in e1a7d53; this commit catches the long tail. Markdownlint: 0 errors on the 2 markdown files touched in this round (CLAUDE.md + AgDR-0051). Site HTML/txt files are pre-existing format — no lint rule applies. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
atlas-apex
left a comment
There was a problem hiding this comment.
Code Review (Round 2): PR #379
Commit: f70fbf511554dc707145f5a71f6c9a849d23cb70
Summary
Re-review of round-2 fix-up commit f70fbf5 ("fix(#377): address Rex blockers") against the 3 CHANGES-REQUESTED blockers from round-1 review at e1a7d53. The earlier-PASS'd structural items (Socratic design, template shape, cycle detection, topo-sort, two-pass filing, idempotence, slot diagram, no-tests decision, glossary, summary bullets, markdownlint, handbook violations) carry over and are not re-litigated.
Round-1 blockers — verification
Blocker 1 (typo appexyard → apexyard) — RESOLVED
- Repo-wide search for
appexyard/appex yard/appex-yardat HEADf70fbf5returns zero matches. - All 3 surviving
me2resh/apexyardreferences indocs/agdr/AgDR-0051-plan-initiative-skill.md(lines 7, 112, 113) spell the org correctly.
Blocker 3 (bogus AgDR-0376 / prefix on lines 3 + 64) — RESOLVED
- Repo-wide grep for
AgDR-0376/ standalone0376returns zero matches at HEAD. - Lines 3 and 64 of
AgDR-0051are clean: the#377and#376references that survive are plain GitHub-issue references (noAgDR-prefix). #377is verified OPEN and is this PR's tracker ticket.#376is verified OPEN (state: OPEN, closedAt: null on the issue itself) — note that the user's brief said #376 "was merged via PR #378", butgh pr view 378shows PR #378 merged today without auto-closing #376 (closingIssuesReferences: []). This is a sibling housekeeping concern, not a blocker on this PR — the AgDR's narrative reference to #376 as the UX-pattern sibling is still factually correct.
Blocker 2 (site-counts drift 53 → 54) — NOT FULLY RESOLVED
The fix-up bumped 53 → 54 across 11 files (CLAUDE.md + 10 site/* files), and the same-line 53 skills / 53 slash commands / Skills (53 / >53</strong> patterns are now zero across the working tree (git grep -nE "\b53 (skills|slash|slash-command)|Skills \(53|>53</strong" pr-379-head -- CLAUDE.md site/ returns no matches).
However, the site-counts-check.yml CI job at HEAD f70fbf5 is RED:
DRIFT: site/llms-full.txt:multiline — claims 53 slash commands (across newline), actual is 54
FAIL: 1 count-drift mismatch(es) detected in site/ marketing copy.
Root cause: site/llms-full.txt lines 131-132 carry a wrapped phrasing that the simple grep approach in the fix-up commit could not catch:
2. **Capability layer** — the runnable spec: `.claude/skills/` (53
slash commands), `.claude/agents/` (23 sub-agents incl. Rex), and
The drift-detection test runs both a same-line pass AND a multiline-flatten pass (per .claude/hooks/tests/test_site_counts.sh ≈ line 140, check_multiline_count) — the multiline pass joins consecutive whitespace including newlines and re-greps. That's how 53\n slash commands got caught. The grep-based bump in f70fbf5 only inspected per-line context.
Required fix: change site/llms-full.txt:131 from (53 to (54. One-character edit, same shape as the other 10 bumps. Re-run bash .claude/hooks/tests/test_site_counts.sh locally to verify.
Tangential observation (not blocking): the test_site_counts.sh self-test fixture at the bottom uses a 52→54 synthetic, which proves the multiline detector works — but the round-1 review missed the multiline phrasing because I only listed the same-line site/* counts in the original blocker description. Apologies — that single phrase was on me to enumerate.
Sanity checks per the user's specific re-check questions
| Question | Result |
|---|---|
Q1 Any other appexyard in diff / adjacent files? |
None. Repo-wide grep is clean. |
Q2 AgDR-0376 cleanup + surviving #376 validity? |
AgDR-0376 gone everywhere. #376 exists (OPEN), PR #378 merged today but didn't auto-close it — sibling housekeeping, not this PR's blocker. |
| Q3 User's grep returns nothing? | Confirmed zero matches on CLAUDE.md site/. |
| Q3 New baseline of 54 accurate? | Confirmed: .claude/skills/ has exactly 54 dirs with SKILL.md after this PR (excluding the 2 _lib- test helpers). Baseline of 53 on origin/dev is also confirmed. |
| Q4 Any non-skill 53s got accidentally bumped? | No. Pre-PR scan of origin/dev -- CLAUDE.md site/ shows every existing 53 was a skill-count reference. Zero confounders. |
| Q5 Markdownlint clean? | markdownlint-cli2 CI step PASSES at f70fbf5. Local run flags only pre-existing MD060 table-pipe-spacing nits that exist identically on origin/dev (36 violations on both branches, untouched by this PR). |
Issues Found
Blocker (CI-gating): site/llms-full.txt:131 — the wrapped (53\n slash commands) phrasing was not bumped to (54. The site-counts-check.yml job fails on this. One-character fix.
Handbook Findings
No new handbook findings introduced by f70fbf5. Round-1 handbook findings (none flagged) carry over.
Suggestions
- Round-1 advisory items (slot diagram, summary bullet narrative, etc.) all hold from the prior pass.
- For future grep-based site-counts bumps, consider running
bash .claude/hooks/tests/test_site_counts.shlocally before committing — the multiline-flatten pass catches wrap-shaped misses that visual grep cannot.
Verdict
CHANGES REQUESTED — at HEAD f70fbf5, one of three blockers (Blocker 2: site-counts) is partially resolved. The same-line patterns are fixed but a multiline 53\n slash commands reference in site/llms-full.txt:131 survives and trips the site-counts-check.yml CI gate. The merge-gate hook will refuse the merge until this is green.
Fix: edit site/llms-full.txt:131 from (53 to (54. Re-run bash .claude/hooks/tests/test_site_counts.sh to verify drift is zero before pushing.
Blockers 1 and 3 are fully resolved. Once the trailing 53 is bumped, this PR should be approvable.
Reviewed by Rex (Code Reviewer Agent)
Reviewed commit: f70fbf511554dc707145f5a71f6c9a849d23cb70
Rex's round-2 review found the round-2 fix-up missed one occurrence — `site/llms-full.txt:131` wraps the phrase `.claude/skills/` (53\n slash commands) across a newline, so the per-line grep in the prior substitution pass missed it. The drift-detection test (.claude/hooks/tests/test_site_counts.sh) flattens before matching, so it caught what the grep didn't. One character: `(53` → `(54` on line 131. Local re-run of test_site_counts.sh: PASS (all framework counts match actuals across all scanned files). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
atlas-apex
left a comment
There was a problem hiding this comment.
Code Review: PR #379 (re-review at HEAD 8597f7e)
Commit: 8597f7e668eec0021ff62949433724b70d63c70d
Prior reviews: e1a7d53 (CHANGES REQUESTED — 3 CI blockers) → f70fbf5 (CHANGES REQUESTED — multiline drift on site/llms-full.txt:131) → this review.
Summary
Single-character fix on top of f70fbf5: (53 → (54 on site/llms-full.txt:131. The prior round-2 substitution pass used per-line grep, which missed this occurrence because the phrase `.claude/skills/` (54 slash commands) wraps the (54 and slash commands) across a newline boundary. The drift-detection test (test_site_counts.sh) flattens before matching, so it caught what the grep didn't.
Verification — all three checks PASS at 8597f7e
-
Drift test PASS at HEAD. Ran
bash .claude/hooks/tests/test_site_counts.shagainst the cloned PR branch at8597f7e:Actual framework counts: skills: 54, hooks: 31, roles: 19 PASS: site framework counts match actuals across all scanned files.All three meta-tag payload-size assertions also pass (within 5% on index.html, architecture.html, skills.html).
-
No other multiline wraps in
site/. Ran a hand-rolled flatten-then-search across all 9 files in the drift test's scan list, hunting for stale skill counts (50/51/52/53+skill|slash command), hook counts (29/30/32/33+hook|shell script), and role counts (17/18/20/21+role|persona) — including across newline boundaries. Zero hits. The site/ tree is fully drift-free across all three count classes at HEAD8597f7e. -
Line 131 reads correctly. Verified locally:
131 2. **Capability layer** — the runnable spec: `.claude/skills/` (54 132 slash commands), `.claude/agents/` (23 sub-agents incl. Rex), and 133 `.claude/hooks/` (31 mechanical enforcement scripts).The wrap renders correctly when joined.
Diff scope confirmed
git show 8597f7e --stat → site/llms-full.txt | 2 +- (1 insertion, 1 deletion). Exactly the single character substitution claimed. No other files touched in this commit.
CI
All four required checks pass on 8597f7e: Verify Ticket ID, lychee, markdownlint-cli2, site-counts drift detection (the gate that caught the prior misses).
Checklist Results
- Architecture & Design: Pass (no change since prior approval)
- Code Quality: Pass (no change)
- Testing: Pass — the drift test exists, fires in CI, and catches multiline wraps the previous grep missed
- Security: Pass (no change)
- Performance: Pass (no change)
- PR Description & Glossary: Pass (no change since prior approval)
- Summary Bullet Narrative: Pass (no change)
- Technical Decisions (AgDR):Pass (AgDR-0051 unchanged, still correctly linked)
- Adopter Handbooks: N/A
Issues Found
None at this HEAD. All blockers from the prior two reviews are resolved.
Side observation (not a blocker on #379, surfacing for the operator)
Issue #376 (Stage 1: handover offers to file Next Steps) still shows OPEN in upstream despite PR #378 having merged. Operator likely needs a manual gh issue close 376 with a comment naming PR #378 — the auto-close fired but didn't propagate, or the Closes #376 reference wasn't picked up by GitHub's auto-close (possibly because the PR was cross-repo or the closing keyword landed in a fork → upstream PR body which doesn't auto-close upstream issues from forks). Not in scope for this PR.
Verdict
APPROVED
The multiline drift is fully resolved, no other count drifts remain in the site/ tree, CI is green, and the load-bearing change is one well-targeted character. The series of three commits (e1a7d53 → f70fbf5 → 8597f7e) demonstrates the exact convergence shape the drift-detection test is meant to enable: each iteration narrowed the gap until the test went green.
Per the operator's sandbox workaround, the approval marker will be written on my behalf with this SHA: 8597f7e668eec0021ff62949433724b70d63c70d.
🤖 Reviewed by Rex (Code Reviewer Agent)
📌 Reviewed commit: 8597f7e668eec0021ff62949433724b70d63c70d
… topo-sort + two-pass filing) (#379) * feat(#377): /plan-initiative — initiative → milestones → tasks (DAG, topo-sort, two-pass filing) New skill that sits between /validate-idea and /write-spec in the planning stack: quarter-shape initiative planning that decomposes deterministically into the existing ticket primitives. What the skill does: 1. Initiative-level interview (goal, quarter, success criterion, scope — per-project vs framework-wide) 2. Per-milestone Socratic interview, one milestone at a time: - Mandatory: name + success criterion + blocks + blocked-by - Optional (operator can defer with TBD): kill criterion, value, risk, confidence in time estimate 3. Cycle detection on the resulting DAG via Kahn-style topo sort; operator-driven cycle resolution (v1 doesn't auto-break) 4. Topo-sorted recommended sequence with value × risk-inverse tie-breaks 5. Mermaid `flowchart LR` DAG rendered into the doc 6. Optional per-item filing of milestones as Feature-shape tickets, mirroring /handover step 7.5's UX (per-item y/n, bulk shapes, source link in the ticket body pointing back at the initiative doc) 7. Two-pass filing: pass 1 files each milestone, pass 2 iterates over the filed set and adds `**Blocks**: #X` / `**Blocked by**: #Y` lines to each ticket's body so the tracker reflects the DAG. Partial filings are supported (cross-refs only span the filed subset). 8. Idempotent on re-runs: preserves prior `Filed as [#N](url)` markers, prompts only on unfiled milestones. Same filed-marker-presence pattern as /handover step 7.5 (NOT byte-equivalence, which composes badly with the post-filing rewrite — same lesson learned in #376). Files: - .claude/skills/plan-initiative/SKILL.md (~250 lines, 15 rules + notes) - templates/initiative.md (master initiative doc with inline milestone blocks + DAG Mermaid + open-uncertainties roll-up + re-run history) - docs/agdr/AgDR-0051-plan-initiative-skill.md (4-axis decision record: Socratic vs LLM-decompose, single template vs separate, two-pass filing vs single-pass, filed-marker idempotence vs byte-equivalence) - CLAUDE.md: skill table row + count bumped to 54 What's out of scope (v1, documented in the AgDR + skill notes): - Cross-initiative DAGs (initiative A blocks initiative B) - Time/effort estimation (only confidence is captured) - Resource allocation / role assignment (framework's role-trigger machinery handles that downstream) - Auto-decomposition without operator input — Socratic interview IS the forcing function - Gantt / PM-tool sync — Mermaid for the DAG is the v1 surface Closes #377. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(#377): address Rex blockers — typo, bogus AgDR refs, site-counts drift Three CI-blocking issues from Rex's review of d543e77: 1. Typo `appexyard` (double-p) → `apexyard` in the GitHub Issue link at docs/agdr/AgDR-0051-plan-initiative-skill.md:112. One-character fix. 2. Bogus `AgDR-0376` references in AgDR-0051 (lines 3 + 64) — issue-number confusion. AgDR IDs only go up to 0051. Removed the `AgDR-0376 /` prefix and kept the `#376` issue reference (which IS real). 3. Site-counts drift — bumping the skill count 53 → 54 in CLAUDE.md (lines 191 + 290) and across all 10 site/ files that surface the count: index.html, index.md.gen, architecture.html, architecture.md.gen, llms.txt, llms-full.txt, skill.md, skills.html, skills.md.gen. Covers meta descriptions, OG/Twitter cards, hero metrics block, JSON-LD description, and llms.txt summary text. The "Available skills (53)" header was already bumped in d543e77; this commit catches the long tail. Markdownlint: 0 errors on the 2 markdown files touched in this round (CLAUDE.md + AgDR-0051). Site HTML/txt files are pre-existing format — no lint rule applies. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(#377): site/llms-full.txt:131 multiline 53→54 drift Rex's round-2 review found the round-2 fix-up missed one occurrence — `site/llms-full.txt:131` wraps the phrase `.claude/skills/` (53\n slash commands) across a newline, so the per-line grep in the prior substitution pass missed it. The drift-detection test (.claude/hooks/tests/test_site_counts.sh) flattens before matching, so it caught what the grep didn't. One character: `(53` → `(54` on line 131. Local re-run of test_site_counts.sh: PASS (all framework counts match actuals across all scanned files). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: me2resh <ahmed.abdelaliem@gmail.com> Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Summary
New
/plan-initiativeskill — quarter-shape planning surface above/write-specand/feature. Walks the operator from initiative-level goal through per-milestone Socratic interview, computes a topo-sorted recommended sequence over the dependency DAG, and optionally files each accepted milestone as a Feature-shape ticket with**Blocks**: #X/**Blocked by**: #Ycross-refs. Why it matters: today's planning bottoms out at the ticket primitive — operators end up doing quarter-shape planning in prose-in-a-notes-file that drifts from the tracker, loses the dependency graph, and rots the moment a milestone slips. This skill makes initiative-level planning a first-class surface that decomposes deterministically into the existing ticket primitives.Socratic interview shape, not LLM auto-decompose — mandatory questions per milestone (success criterion, blocks, blocked-by) MUST be answered; optional questions (kill criterion, value, risk, confidence) ACCEPT
TBDas a defer-to-later marker. Why it matters: operators commit deeper to plans they articulate themselves. An LLM "give me 10 milestones" doesn't surface kill criteria or value, so the plan is fiction; the Socratic shape forces the operator to commit to what completing milestone N actually unblocks. The cost in interview time IS the value.Two-pass filing with cross-refs — pass 1 dispatches a Feature ticket per accepted milestone in topo order; pass 2 iterates the filed set, computes per-milestone DAG edges restricted to the also-filed subset, and rewrites each ticket's body to insert
**Blocks**: #X/**Blocked by**: #Ylines below the user story. Why it matters: cross-refs need the issue numbers, which aren't known until after filing — single-pass with placeholders breaks on partial filings (operator says "file only 3 of 5", cross-refs point at milestones that were never filed). Two-pass with read-then-write on the body also handles the teammate-edit race.Idempotent on re-runs (filed-marker presence, NOT byte-equivalence) —
/plan-initiative <slug>on an existing initiative doc reads the prior state, partitions milestones into already-filed (silently skipped) vs unfiled (offered), preserves theFiled as [#N](url)markers across regeneration. Same lesson from [Feature] /handover — offer to file 'Next Steps' as tracker tickets after the assessment #376: byte-equivalence composes badly with the skill's own post-filing rewrite (which mutates the section to strikethrough+link forms, guaranteeing non-byte-equivalence on every subsequent run). Marker-presence as the source of truth is the only shape that survives re-runs.Why this matters (operator-facing)
The planning surface today bottoms out at the ticket primitive (
/feature,/task,/bug,/spike). The closest "zoom out" surfaces are/write-spec(PRD for ONE feature) and/validate-idea(5-question pre-spec gate for ONE idea). Operators who want to plan at the initiative level — the strategic unit above features, usually 1-3 per quarter, multi-feature, multi-week — end up doing it in prose that drifts from the tracker, loses the dependency graph, and rots the moment one milestone slips./plan-initiativeslots BEFORE the existing ticket-level skills:After the interview, each filed milestone naturally becomes a
/write-specinvocation, which decomposes into multiple/featureinvocations. This skill does not replace those — it sits above them.Files changed
.claude/skills/plan-initiative/SKILL.md(NEW, ~250 lines + 15 rules + notes) — the skill itself: 10-step process (resolve slug, initiative-level interview, per-milestone Socratic interview, cycle detection, topo-sort, render doc, surface unfiled milestones, two-pass filing, update doc, return summary)templates/initiative.md(NEW) — master initiative-doc template with inline milestone blocks, Mermaidflowchart LRDAG section, open-uncertainties roll-up, anti-scope, and re-run historydocs/agdr/AgDR-0051-plan-initiative-skill.md(NEW) — design record covering 4 axes: (1) Socratic interview vs LLM auto-decompose vs hybrid, (2) single template vs separate initiative + milestone vs extend PRD, (3) two-pass dispatch vs single-pass vs/tickets-batchbatch, (4) filed-marker presence vs byte-equivalence vs full-regen prompt. Consequences + risks accepted (question-bank length, DAG-cycle detection, cross-ref rewrite race).CLAUDE.md— skill-table row for/plan-initiative; skill count bumped 53 → 54Testing
This is a prose / interactive skill that dispatches to other skills (
/featurefor filing) which have their own validation gates (validate-issue-structure.sh,require-skill-for-issue-create.sh). No new hooks introduced; no new tests added.npx markdownlint-cli2@0.13.0 ...— verified locally, 0 errors)/plan-initiativeis new)templates/initiative.mdresolvable viaportfolio_resolve_template initiative.md(default path, nocustom-templatesmirror yet)/plan-initiative q3-testagainst a small initiative to validate the interview shapeGlossary
/plan-initiativeplans.flowchart LR.gh issue editto add**Blocks**: #X/**Blocked by**: #Ylines.Filed as [#N](url)marker from a prior run. Same rule as/handoverRule 18.templates/architecture/vision.md§ Anti-scope.Closes #377.
🤖 Generated with Claude Code