Skip to content

Let the Planner re-link an answered decision's lost written prose - #742

Open
MaggieAppleton wants to merge 1 commit into
mainfrom
maggieappleton-prose-anchor-repair
Open

MaggieAppleton wants to merge 1 commit into
mainfrom
maggieappleton-prose-anchor-repair

Conversation

@MaggieAppleton

Copy link
Copy Markdown
Collaborator

What people saw

When the paragraph holding a decision's write-up could no longer be found, the decision card said Prose removed. If the Planner then re-anchored the decision to the paragraph that now holds that prose, the call reported success, but the card still said Prose removed, even after a restart. The re-anchor updated the decision's related blocks and left its written prose orphaned.

Fix

anchor_plan placements now also repair an answered single-question conversation or Planner decision's written prose, but only when that prose is lost: it has anchors and every one is orphaned (Prose.orphaned). Prose that still resolves is never touched, so routine reviews (every answered decision is marked for review after an invalidating edit) with multi-block or empty placements behave exactly as before.

For lost prose:

  • A write-up must name one paragraph whose digest still matches, or no blocks to record that it has none.
  • A Planner decision whose dropped follow-up left multi-block prose may name a bounded passage, by the same rules as a follow-up target (a paragraph, then contiguous paragraphs, tables or diagrams, at most eight).
  • Anything else fails with an error and leaves the orphaned state, the document and the durable record untouched. The repair is staged with the rest of the re-anchor and committed before publication.

decision-followup-reanchor.ts / reanchorScopes is renamed decision-reanchor.ts / reanchorDecisionRelationships, since it now does more than follow-up scopes; the follow-up passage check is shared.

Server-only change; no UI changed, so no screenshot.

Tests

New apps/server/src/questions/conversation-prose-reanchor.test.ts (24 tests, both origins where relevant): lost prose re-linked and survives restart, persistence before publication, empty review, stale/digest/non-paragraph/multiple rejections, rejected commit, live prose kept when reviewed with two blocks or with [], and dropped-follow-up paragraph-plus-table prose (live and lost) not rejected. On main 8 of the original tests fail; the 8 live-prose and passage tests fail against the first version of this fix.

  • bun test apps/server/src/questions apps/server/src/agent apps/server/src/plan: 1001 pass, 0 fail
  • bun run types: pass
  • bun run ci: pass

Review

Two adversarial reviews ran on the first version. Both asked for the same change: it rewrote prose whenever a placement named the decision, even if the prose was healthy, which would have failed routine multi-block anchor_plan batches, let blocks: [] erase live prose (and the next write-up duplicate the paragraph), let one paragraph steal the prose link, and rejected dropped-follow-up prose spanning a table. The repair is now gated on the prose being lost, dropped-follow-up prose may name a bounded passage, tests cover each of those cases, and the module was renamed.

When every paragraph a conversation or Planner decision's write-up was
anchored to could no longer be found, the decision card showed "Prose
removed". The Planner could re-anchor the decision to the paragraph that
now holds that prose and the call succeeded, but it only changed the
decision's related blocks: the written prose kept its orphaned anchors, so
the card kept saying the prose was removed, even after a restart.

An explicit reviewed placement now also replaces the written prose of an
answered single-question decision that is not a follow-up, but only when
that prose is lost (it has anchors and every one is orphaned). Prose that
still resolves is never touched, so routine anchor_plan reviews with
multi-block placements or no blocks keep working and keep the write-up.
A write-up must be re-linked to one paragraph whose digest still matches,
or to no blocks to record it has none. A Planner decision whose dropped
follow-up left multi-block prose may name a bounded passage, by the same
rules as a follow-up target (a paragraph, then contiguous paragraphs,
tables or diagrams, at most eight). Anything else is rejected and leaves
the orphaned state untouched. The change is staged with the rest of the
re-anchor and committed before it is published.

The module is renamed decision-reanchor.ts and its function
reanchorDecisionRelationships, since it now handles more than follow-up
scopes; the follow-up passage check is shared between the two.

Co-authored-by: Copilot App <[email protected]>

This branch has not been deployed

No deployments
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