feat(engine): outstanding research is a wait the discussion cannot conclude over - #1091
Open
leeovery wants to merge 1 commit into
Open
feat(engine): outstanding research is a wait the discussion cannot conclude over#1091leeovery wants to merge 1 commit into
leeovery wants to merge 1 commit into
Conversation
…nclude over Research feeds discussion. A topic's in-progress or parked research is now a wait on its same-named discussion — derived from the research item's status, never stored — generalising the experiment wait with a `kind`: - derivations: `waits(manifest, phase, topic)` / `topicWaits` return kind-aware descriptors; the map row carries `waits` instead of `awaiting_experiments` - transitions: `topic complete` refuses over every wait, naming each kind; the hop out of research flags an in-progress discussion as well as a completed one (every other hop stays completed-only) - render: `wait-gate` renders the blocked-conclusion gate over all waits and is empty when nothing blocks; `experiment-wait-gate` stays as its alias (still refusing an unblocked item); `direct-entry-gate` refuses every mapped name — the parked-stub pass-through is gone - epic menu: a research row (`continue_research` / `start_research · triage waiting`) sits directly above the topic's own row whenever research is outstanding; the map row cues `awaiting research` / `awaiting E1` / both - docs: commands.md, the usage banner, CLAUDE.md, research-entry step 1 Tests: derivations, transactions (a new completion-wait suite), render surfaces (wait-gate + alias + the flipped door), epic projections (the research row, cue text, recommendation, presence), the epic gateway dump, and the pipeline simulation, whose epic recipe now lands research beneath a live discussion and walks the wait to release. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
What
Research outstanding on a topic — in flight, or parked as a triage stub — now holds that topic's discussion shut, is reachable from the epic menu, and flags the discussion whatever its live state. The
rdoor's pass-through for a parked stub goes with it. Engine slice; the prose that consumes it (advisory hold, conclude flow on the generic gate, cases) stacks on top.Why
A research-side triage landing on topic B creates a
triagedresearch stub or reopens B's completed research. Until now a live discussion on B was never told (the hop flagged only completed items) and could conclude over it; the epic menu derived one row per topic and a live discussion outranked live research, so B's research had no row at all — therfree-text door was its only drain, and #1089 had to carve an exception into the collision rule to keep it. Research feeds discussion, discussion feeds specification: none of that should have been possible.Design
No new stored state. A wait is derived:
waits(manifest, phase, topic)returns kind-tagged descriptors —{kind: 'research', status}when a discussion's same-named research isin-progressortriaged,{kind: 'experiment', id}per awaited id. The experiment wait's four sites generalise over it: thetopic completerefusal names every wait; onewait-gatesurface renders the blocked-conclusion gate for whatever kinds are present (empty when nothing is owed, so the prose can branch on one fetch); the map row cue readsawaiting research,awaiting E1, or both; the release side already carried a kind inreconcile_needed.in-progressdiscussion as well as a completed one — the one hop that reaches a live neighbour. Every other hop keeps completed-only.direct-entry-gaterefuses every mapped name;topic startkeeps letting a parked research stub start — now what the menu row offers.experiment-wait-gatestays as an alias (refusing with no wait, as before) until the prose slice moves its two call sites.Tests
Derivations (
waits,topicWaits), transactions (every refusal arm, both hops, release by completion and cancel), render surfaces (each kind, both, empty vs alias, door refusal), epic projections (the row for each lifecycle, presence hand-off, settled-map recommendation, cue text), gateway dump parity, and the pipeline simulation — whose epic recipe was completing a discussion over a parked stub and now walks the whole path: landing flags the live discussion → complete refuses → gate (parked) → research row above the discussion row → stub starts → gate (in flight) → research lands → gate empty → discussion completes.npm test2780 pass ·npm run typecheckclean ·npm run test:cligreen.🤖 Generated with Claude Code