Skip to content

fix(desktop,ui): restage a selected message's quotes and attachments on edit - #5274

Draft
ggbdpq wants to merge 6 commits into
apache:mainfrom
ggbdpq:fix/desktop-revision-structured-context
Draft

ggbdpq wants to merge 6 commits into
apache:mainfrom
ggbdpq:fix/desktop-revision-structured-context

Conversation

@ggbdpq

@ggbdpq ggbdpq commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Edit & resend refused a selected message that itself carried quotes or attachments: the replacement submit only carried the human-facing text, silently dropping the context the original answer was grounded in (#5109, reproduction cases A and B — case C, the TUI rewind side, landed in #5265).

The desktop edit now stages the selected message's quotes into the quote plate and its attachments into the attachment plate as retained refs, recording both on the revision draft:

  • the plates make the carried context visible and explicitly removable, satisfying the issue's "removing is an explicit edit" expectation;
  • after the revision commit, the staged attachment refs are swapped for the copied message's target-owned refs read back from the branch child transcript — the Host's copier already rewrote them, so the replacement submit only claims files the new Session owns (no protocol change);
  • a no-op send (text and staged context both unchanged vs the draft) stays refused, cancel restores the pre-edit plates, and mid-edit staging of new context is refused so user additions cannot silently mix with the restored set.

The chat-turn edit gate drops quotes and attachments from its disabled list; directory references keep the gate, since they have no client-side restage path, and their two dead copy keys are removed together with the branches that rendered them.

Part of #5109 — with this, both clients restore the selected turn's quotes and attachments; directory references remain fail-closed on both.

Verification

Check Result
New ui tests (attachment- and quote-carrying messages keep the edit action) red on the old gate (2/2 fail via stash rebuild), 2/2 green after
Desktop revision-actions tests (source attachments/quotes stage and are recorded on the draft) 3/3 green; the replaced upstream test asserted the exact negation (rejection) and was green pre-change
@maka/ui full suite 446/450 — 3 failures (session-todo-panel, prompt-rail-observer-identity, transcript-history-notice) fail identically on pristine upstream/main via stash rebuild; composer-plus-menu fails only under full-suite concurrency and passes 11/11 in isolation
npm --workspace @maka/desktop run build:main (typecheck incl. renderer sources) clean
check-locale-hygiene passed
biome check on all 7 changed files clean
check:asf-headers passed locally

AI use

Select exactly one:

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Tool(s) and scope: GLM-5.3-Flash (ZCode) implemented the desktop/ui changes and tests under human direction and review.

Checklist

  • Tests cover the change and fail without it
  • Lint, format, typecheck and the affected suites pass locally

Does this PR entail a change in behavior?

  • Yes — a selected message carrying quotes or attachments is now editable; the replacement submit restages that context (attachments rewritten to target-owned refs after the revision commit).
  • No

…on edit

Edit & resend refused a selected message that itself carried quotes or
attachments: the replacement submit only carried the human-facing text,
silently dropping the context the original answer was grounded in
(apache#5109, reproduction cases A and B).

The desktop edit now stages the selected message's quotes into the quote
plate and its attachments into the attachment plate as retained refs,
recording both on the revision draft. After the revision commit the
staged attachment refs are swapped for the copied message's
target-owned refs read back from the branch child transcript, so the
replacement submit only claims files the new Session owns. A no-op send
(text and staged context both unchanged) stays refused, and cancel
restores the pre-edit plates.

The chat-turn edit gate drops quotes and attachments from its disabled
list; directory references keep the gate since they have no
client-side restage path, and their two dead copy keys are removed.

Part of apache#5109

Generated-by: GLM-5.3-Flash (ZCode)
@github-actions github-actions Bot added the effort/M Under 500 readable lines label Sep 13, 2026
The revision-actions restage work grows app-shell-revision-actions and
app-shell token counts; the ledger follows the sources.

Part of apache#5109

Generated-by: GLM-5.3-Flash (ZCode)
The renderer architecture ratchet freezes app-shell-revision-actions and
app-shell at their base token counts. The staged-context gate, plate
restage/restore helpers, and the draft shape move into the @maka/ui
revision-staged-context module; the shell keeps thin orchestrators.

Part of apache#5109

Generated-by: GLM-5.3-Flash (ZCode)
@ggbdpq

ggbdpq commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Marking draft while the renderer debt ratchet question is settled — see the gate comment below.

The renderer architecture strict-base check freezes app-shell-revision-actions.ts at 2155 non-trivia tokens; the feature needs ~160 more than the slimmest extraction I could land (88dc60e, 2318). Two honest paths forward:

  1. I extract the beginEditUserMessage orchestration into @maka/ui/revision-staged-context as well (fits the budget, but moves shell orchestration into the package), or
  2. a one-time sanctioned budget bump for app-shell-revision-actions.ts in renderer-architecture.json.

Happy to do either — flagging before burning another CI round.

@ggbdpq
ggbdpq marked this pull request as draft September 13, 2026 22:34
Structural gate/stage signatures and a one-line restage call shave
further renderer tokens (2305 against the frozen 2155 budget); the
ledger follows. Remaining gap is tracked for the beginEdit extraction.

Part of apache#5109

Generated-by: GLM-5.3-Flash (ZCode)
@github-actions github-actions Bot added effort/L Under 1000 readable lines and removed effort/M Under 500 readable lines labels Sep 14, 2026
The renderer architecture ratchet freezes app-shell-revision-actions and
app-shell at their base token counts, and the apache#5109 restage feature could
not fit under them. The whole revision lifecycle — beginEdit, prepare,
cancel, rollback, and the copy-attempt bookkeeping — now lives in
@maka/ui/revision-staged-context; the desktop file is a thin assembler
injecting the bridge, the locale catalog, and the attempt tracker. The
duplicate pre-send gate in app-shell goes away with it: prepare owns the
unchanged and mixed-context refusals, and one stale guard referencing
removed draft fields goes with the duplication.

Ledger: app-shell-revision-actions 2305->506/9->6, app-shell 13482->13344
/105->104, against a frozen 2155/8 and 13386/104.

Part of apache#5109

Generated-by: GLM-5.3-Flash (ZCode)
Empty commit: the push event for c4d7065 did not start a workflow run.

Part of apache#5109

Generated-by: GLM-5.3-Flash (ZCode)
@ggbdpq ggbdpq closed this Sep 15, 2026
@ggbdpq ggbdpq reopened this Sep 15, 2026
@github-actions

Copy link
Copy Markdown

No description provided.

@github-actions github-actions Bot added effort/XL Under 2500 readable lines and removed effort/L Under 1000 readable lines labels Sep 15, 2026
@ggbdpq

ggbdpq commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

The ratchet conflict is resolved without touching the frozen budgets: the whole revision lifecycle (beginEdit / prepare / cancel / rollback + copy-attempt bookkeeping) moved into @maka/ui/revision-staged-context, and app-shell-revision-actions.ts is now a thin assembler injecting the bridge, the locale catalog, and the attempt tracker.

Measured against the frozen base budgets: app-shell-revision-actions.ts 2305 -> 506 tokens / 6 specifiers (base 2155/8); app-shell.tsx 13482 -> 13344 tokens / 104 specifiers (base 13386/104). The duplicate pre-send gate in the shell goes away with the move — prepareRevisionSend owns the unchanged and mixed-context refusals — and one stale guard referencing removed draft fields is gone with it.

Heads 0a5af05 / 0a5af05 have not started a CI run for a few hours (the pull_request workflow never fired on the pushes or the reopen — likely the external-contributor workflow approval); pull_request_target checks ran. Once a run is approved: local verification passed — desktop revision-actions 3/3, ui chat-turn 26/26, biome clean, ASF clean, and the refreshed ledger confirms both files under budget.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/XL Under 2500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant