Skip to content

feat(#377): /plan-initiative — initiative → milestones → tasks (DAG + topo-sort + two-pass filing)#379

Merged
atlas-apex merged 3 commits into
devfrom
feature/GH-377-plan-initiative-skill
May 22, 2026
Merged

feat(#377): /plan-initiative — initiative → milestones → tasks (DAG + topo-sort + two-pass filing)#379
atlas-apex merged 3 commits into
devfrom
feature/GH-377-plan-initiative-skill

Conversation

@atlas-apex

Copy link
Copy Markdown
Collaborator

Summary

  • New /plan-initiative skill — quarter-shape planning surface above /write-spec and /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**: #Y cross-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 TBD as 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**: #Y lines 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 the Filed 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-initiative slots BEFORE the existing ticket-level skills:

/idea            (capture a raw idea)
/validate-idea   (5-question pre-spec gate)
/plan-initiative (NEW — initiative → milestones → tasks, dependency-aware)
/write-spec      (PRD for one feature)
/feature / /task / /bug / /spike (one ticket at a time)

After the interview, each filed milestone naturally becomes a /write-spec invocation, which decomposes into multiple /feature invocations. 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, Mermaid flowchart LR DAG section, open-uncertainties roll-up, anti-scope, and re-run history
  • docs/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-batch batch, (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 → 54

Testing

This is a prose / interactive skill that dispatches to other skills (/feature for 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.

  • Markdownlint clean on all 4 changed/new files (npx markdownlint-cli2@0.13.0 ... — verified locally, 0 errors)
  • AgDR-0051 references valid links (sibling AgDR-0023, /handover step 7.5)
  • No collision with existing skill names (verified — /plan-initiative is new)
  • Template at templates/initiative.md resolvable via portfolio_resolve_template initiative.md (default path, no custom-templates mirror yet)
  • Manual smoke test will follow once merged — invoke /plan-initiative q3-test against a small initiative to validate the interview shape

Glossary

Term Definition
Initiative The strategic unit above features — 1-3 per quarter, multi-feature, multi-week. The thing /plan-initiative plans.
Milestone A 1-4-week chunk of work that contributes to an initiative. Each milestone has a success criterion, blocks-list, blocked-by-list, and optional kill criterion / value / risk / confidence.
DAG Directed Acyclic Graph — the dependency graph computed from milestones' blocks/blocked-by relationships. Rendered as Mermaid flowchart LR.
Topological sort Algorithm (Kahn's) that produces a linear ordering of the milestones such that every milestone appears after the milestones it depends on. v1 uses value × risk-inverse as the tie-break within a topo layer.
Socratic interview Question-bank-driven shape where the operator answers one question at a time, with optional "TBD" deferral on uncertainty-surfacing questions. Contrast with LLM auto-decompose where a single prompt produces an N-milestone list.
Two-pass filing Pass 1 files each accepted milestone (no cross-refs — issue numbers not yet known). Pass 2 iterates filed set, computes per-milestone DAG edges restricted to the also-filed subset, rewrites each ticket's body via gh issue edit to add **Blocks**: #X / **Blocked by**: #Y lines.
Filed-marker presence Idempotence rule: re-runs partition milestones by whether they carry a Filed as [#N](url) marker from a prior run. Same rule as /handover Rule 18.
Anti-scope Section in the initiative doc listing things the operator considered and explicitly rejected — distinct from things nobody thought of. Mirrors templates/architecture/vision.md § Anti-scope.

Closes #377.

🤖 Generated with Claude Code

…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 atlas-apex left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 resolve

cycle_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:

  1. First run: operator names a milestone "Token endpoint" → filed as #100, doc carries Filed as [#100](url)
  2. Re-run with reworded name: operator types "Auth token endpoint"
  3. Skill matches by name only → "Auth token endpoint" ≠ "Token endpoint" → treated as NEW
  4. 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-idea is the 5-question pre-spec gate, /write-spec is the per-feature PRD, /plan-initiative sits between as the quarter-shape orchestrator. Each filed milestone naturally becomes a /write-spec invocation downstream.
  • AgDR-0023 reference (item 1): confirmed — AgDR-0023 establishes the custom-templates/<path> path-mirroring override convention via portfolio_resolve_template. The skill's plug-in to portfolio_resolve_template initiative.md is consistent.
  • Feature ticket body shape (item 2): confirmed — step 8 pass 1 body has both ## User Story and ## Acceptance Criteria non-empty, which satisfies validate-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 .md files (exempt from require-active-ticket.sh per the *.md glob at hook line 109), and gh issue create is gated by require-skill-for-issue-create.sh which accepts any non-empty active-issue-skill marker. No path in the skill writes a non-.md file.
  • 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 atlas-apex left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 appexyardapexyard) — RESOLVED

  • Repo-wide search for appexyard / appex yard / appex-yard at HEAD f70fbf5 returns zero matches.
  • All 3 surviving me2resh/apexyard references in docs/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 / standalone 0376 returns zero matches at HEAD.
  • Lines 3 and 64 of AgDR-0051 are clean: the #377 and #376 references that survive are plain GitHub-issue references (no AgDR- prefix).
  • #377 is verified OPEN and is this PR's tracker ticket. #376 is verified OPEN (state: OPEN, closedAt: null on the issue itself) — note that the user's brief said #376 "was merged via PR #378", but gh pr view 378 shows 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.sh locally 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 atlas-apex left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  1. Drift test PASS at HEAD. Ran bash .claude/hooks/tests/test_site_counts.sh against the cloned PR branch at 8597f7e:

    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).

  2. 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 HEAD 8597f7e.

  3. 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 --statsite/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 (e1a7d53f70fbf58597f7e) 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

@atlas-apex atlas-apex merged commit c180eb3 into dev May 22, 2026
4 checks passed
@atlas-apex atlas-apex deleted the feature/GH-377-plan-initiative-skill branch May 22, 2026 17:37
me2resh added a commit that referenced this pull request Jun 5, 2026
… 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants