Phase 9 — Topic Splitting and Elevation#274
Open
leeovery wants to merge 10 commits into
Open
Conversation
leeovery
added a commit
that referenced
this pull request
May 11, 2026
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ence for active-map + dismissed-list checks New shared reference encapsulates the proposed-topic-name validation pattern. Takes work_unit + proposed_name + caller_context, returns one of: format-invalid, collision-active, matches-dismissed, ok. Caller branches on the result — pulls from dismissed before writing on matches-dismissed, re-prompts on the rejection branches, proceeds on ok. Will be loaded by topic-splitting, topic-elevation, refinement adds, and Phase 10's direct-entry adds. Read-only — never mutates the manifest. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…load shared topic-name-validation Replace the inline collision check in B. Validate with a Load directive to the new shared reference. Behaviour preserved: - collision-active → rejection, operation removed from group - matches-dismissed → allowed; Add pulls from dismissed (existing D. Add step 1), Rename proceeds without pulling - ok → proceed Adds kebab-case format enforcement via the shared reference. Refinement adds already kebab-case names through the inception conversation, so this is a defensive guard rather than a behavioural change for that flow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…plit; validate proposed name
Topic-splitting now writes a phases.inception.items.{new-topic} entry
alongside the new research file. Source: research-split:{parent_topic}.
Routing: research (the split fires inside a research session).
The flow gains a per-thread sub-flow:
1. Propose kebab-case name; user confirms.
2. Validate via shared topic-name-validation reference. On collision or
format-invalid, re-prompt and loop. On matches-dismissed, proceed
(user-explicit spawns bypass the dismissed list).
3. Extract content into the new research file (unchanged).
4. Capture a one-line summary for the inception item.
5. Write research init-phase + inception init-phase + routing + summary
+ source. Pull from dismissed first if applicable.
6. Single commit per batch.
Spawned topics now surface on the discovery map as `◐ in flight` with
`source: research-split:{parent}` provenance.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-elevation; validate proposed name
Section F (Topic Elevation) now writes a phases.inception.items.{new-topic}
entry alongside the seed discussion file. Source:
discussion-elevation:{parent_topic}. Routing: discussion (elevation
fires inside a discussion session).
The elevate sub-flow gains:
1. Propose kebab-case name; user confirms.
2. Validate via shared topic-name-validation reference. On collision or
format-invalid, re-prompt and loop. On matches-dismissed, proceed
(user-explicit spawns bypass dismissed list).
3. Capture a one-line summary for the inception item.
4. Write discussion init-phase + inception init-phase + routing +
summary + source. Pull from dismissed first if applicable.
5. Update parent's Discussion Map (unchanged).
6. Commit (unchanged).
Elevated topics now surface on the discovery map as ◐ in flight with
source: discussion-elevation:{parent} provenance.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ssion process skills The new topic-name-validation.md shared reference invokes workflow-inception-process/scripts/discovery.cjs to read the active discovery map and dismissed list. That CLI was not in either skill's allowed-tools, so every validation call from topic-splitting or topic-elevation would have triggered a permission prompt. Adding the permission is safe: discovery.cjs is read-only and is the canonical state source for these flows. Matches the precedent in workflow-inception-process (which already permits the same CLI). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…y loop boundary in topic-splitting Two cleanups from a self-review of Phase 9: 1. topic-name-validation.md declared `caller_context` as a parameter "used in the rejection display for clarity", but the rejection templates never actually rendered it. Dropped the param to remove the mismatch; Phase 10 can re-add it if direct-entry needs context-specific rejection text. Updated all three call sites (map-operations.md, topic-splitting.md, discussion-session.md) to stop passing it. 2. topic-splitting.md's per-thread sub-flow numbered "5. Commit" but the body said "after all accepted threads have been processed". Made the loop boundary explicit: steps 1-4 run per thread, then a "→ Loop back to step 1" sentinel routes back; step 5 is reached only once after the loop ends. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…stead of rejecting The format check in topic-name-validation.md was guarding against a Claude-side slip (callers always have Claude generate or extract the proposed name before invoking validation), but the original wording treated it like user input — rendered a rejection block and returned `format-invalid` to the caller. That escalated a model error into a user-visible interaction. Section A now normalises silently per casing-conventions.md and falls through to the collision check. `format-invalid` is dropped from the result enum. All three call sites (map-operations.md, topic-splitting.md, discussion-session.md) updated to remove the `format-invalid` branch from their result handling. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…read numbered flow Both topic-splitting.md and discussion-session.md F had introduced two non-conventional patterns: bold pseudo-headings on each numbered item (**1. Propose...**) and a manufactured "→ Loop back to step 1" arrow. Neither matches anything in the codebase. The convention — established by map-operations.md D. Add and matched by the original discussion elevation flow — is `For each X:` followed by a plain numbered list, then post-loop content in a paragraph after the list. The loop boundary is conveyed by "Once all accepted threads have been processed" rather than an invented routing arrow. Reverted both files to that pattern. Same content (validation, extraction, summary, manifest writes, commit), conventional structure. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…y, don't gate on user confirm Same reasoning as the topic-name self-correction: Claude is the one producing the summary text from extracted/elevated content, so a "propose, ask user to confirm or refine" round-trip is unnecessary friction. Generate it inline; the user sees it on the next map render and can edit-summary via refinement if they want a different framing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
f87f677 to
36531e0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
phases.inception.items.{new-topic}alongside the per-phase artefact they already create. Sources:research-split:{parent}anddiscussion-elevation:{parent}.skills/workflow-shared/references/topic-name-validation.mdencapsulates kebab-case + active-map + dismissed-list validation. Returnsformat-invalid/collision-active/matches-dismissed/ok— caller branches.map-operations.md(refinement adds + renames) refactored to load the shared validation instead of inlining the collision check. Behaviour preserved.After this PR, every map write goes through a known surface — splits, elevations, refinement, and self-healing all write properly-shaped inception items. Spawned topics surface on the next
/continue-epicrender as◐ in flightwithfrom {parent}provenance.Test plan
bash tests/scripts/test-workflow-manifest.sh— 214/214node --test tests/scripts/test-discovery-for-continue-epic.cjs— 71/71node --test tests/scripts/test-discovery-utils.cjs tests/scripts/test-discovery-for-refinement.cjs tests/scripts/test-refinement-session.cjs— 176/176node --testover the remaining discovery suites — all green◐ researchingwithfrom {parent}provenance.◐ discussingwithfrom {parent}provenance.Image Moderation→ format-invalid rejection + re-prompt.Base:
idea/inception-pr-7-self-healing(stacked).🤖 Generated with Claude Code