Skip to content

feat(engine): outstanding research is a wait the discussion cannot conclude over - #1091

Open
leeovery wants to merge 1 commit into
mainfrom
feat/research-wait-engine
Open

feat(engine): outstanding research is a wait the discussion cannot conclude over#1091
leeovery wants to merge 1 commit into
mainfrom
feat/research-wait-engine

Conversation

@leeovery

@leeovery leeovery commented Sep 2, 2026

Copy link
Copy Markdown
Owner

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 r door'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 triaged research 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 — the r free-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 is in-progress or triaged, {kind: 'experiment', id} per awaited id. The experiment wait's four sites generalise over it: the topic complete refusal names every wait; one wait-gate surface 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 reads awaiting research, awaiting E1, or both; the release side already carried a kind in reconcile_needed.

  • Hop: the landing/reopen out of research flags an in-progress discussion as well as a completed one — the one hop that reaches a live neighbour. Every other hop keeps completed-only.
  • Menu: a research row directly above the topic's own whenever research is outstanding beneath a discussing, decided, or discussion-routed fresh topic. On a settled map it leads the recommendation ahead of a build start (the first step of a reconcile; a build start elsewhere would propagate stale input one hop removed).
  • Doors: direct-entry-gate refuses every mapped name; topic start keeps letting a parked research stub start — now what the menu row offers.
  • experiment-wait-gate stays 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 test 2780 pass · npm run typecheck clean · npm run test:cli green.

🤖 Generated with Claude Code

…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant