githubnext/chopinPublic

Let's compose rich plans together

Give a decision one place in the plan, not two

A question carried what it was about and what its answer produced as separate
anchor sets, on the theory that they move independently. The agent, asked to
tell them apart, anchored the first block of the result and called it the
subject — in every record it has ever written:

    q1  subject 72e814   result 72e814, 5b5cb2, d8f0c6
    q2  subject 0fe395   result 0fe395, 5b5cb2
    q3  subject 72e814   result 72e814, d8f0c6

So a resolved card offered two adjacent, full-width, identically labelled
"Show in plan" buttons that led to the same block.

The split cost more than the duplicate. A subject was never derived when a
question was asked and never invalidated when the plan moved, so it sat
permanently unreviewed: `counts()` reported nowhere, which rendered it inert,
and `anchors_pending` carried an entry per question that no amount of anchoring
could clear and that every `edit_plan` served back to the agent. It was also
untested at every layer, and `answer_changed` — the one reason that would have
justified separate lifecycles — was never emitted.

There is one `AnchorSet` per question now. `anchor_plan` takes `{widget,
question, blocks}` beside the `{thread, blocks}` it already took, which is the
shape a comment thread has always used. A thread keeps its two, because there
the halves have different authors and different shapes and neither can stand
for the other. On a resolved card the question and what was chosen are one
button, since they are one decision.

An unanswered question owes nothing, rather than owing a review from the moment
it exists.

Records written before the fold are read through `folded`, which keeps both
halves. Without it the rebase on open meets a set with no `anchors` array — and
that does not fail the open, it is caught and logged, so every decision in the
plan silently loses its place and the shared guard takes the comment threads'
anchors with it.

Adds the coverage this never had: the bookkeeping, resolution against a real
editor, and the fold end to end through `Service.open`.
KCKrzysztof Cieslak authored
615854fPatch
Parent19cfa2d
15 files changed+866-257
StackedSplit
agents.md+21 −0
apps/server/src/agent/planner.ts+7 −6
apps/server/src/agent/tools.ts+11 −23
apps/server/src/questions.anchors.test.ts+189 −0
apps/server/src/questions/anchors.test.ts+174 −0
apps/server/src/questions/anchors.ts+78 −43
apps/server/src/questions/service.ts+6 −10
packages/editor/src/anchors.test.ts+216 −0
packages/editor/src/anchors.ts+14 −24
packages/editor/src/decisions.tsx+4 −4
packages/editor/src/questionnaires.ts+18 −24
packages/editor/src/widgets/questionnaire.tsx+14 −16
packages/protocol/plan.d.ts+20 −14
packages/question/src/react/question-view.tsx+90 −89
readme.md+4 −4