Public: anyone can read this; the crew can change it.

Settling many asks at once says the same words and offers the same undo on the page, in the terminal and over MCP #10718

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Settling three asks and undoing them now says the same words on the page, in the terminal and over MCP. A new test, `test/asks-bulk-parity.test.ts`, proves it. The new test, `mcp-size`, `mcp`, `asks-bulk`, `tui-bulk`, `asks-op-words`, the MCP arguments test and `tsc` pass. The gate script's last output was a pre-push notice, not a pass, so treat the gate as unconfirmed. The full suite is left to t…

shipped production is serving it deploy befa93c

opened this

Settling three asks and undoing them now says the same words on the page, in the terminal and over MCP. A new test, test/asks-bulk-parity.test.ts, proves it. The new test, mcp-size, mcp, asks-bulk, tui-bulk, asks-op-words, the MCP arguments test and tsc pass. The gate script's last output was a pre-push notice, not a pass, so treat the gate as unconfirmed. The full suite is left to the forge's check.

What was different

  • The page worded the receipt itself, from a verb table private to src/web/studio/asks_page.ts.
  • MCP returned raw operation data with no sentence.
  • The terminal toasted just "undone".
  • MCP had no way to undo at all.

What changed

  • src/actions/asks_words.ts now holds the receipt sentence (receiptSentence: "Close: 3 done", "Close undone: 3"), the verb table (moved from asks_page.ts) and ALREADY_UNDONE.
  • src/actions/asks_bulk.ts adds receiptOf(op).
  • The /asks receipt banner and undo bar use receiptOf.
  • The terminal's rows header and its undo toast use receiptOf. Its refusal text uses ALREADY_UNDONE.
  • src/actions/fleet.ts and the terminal's whyNot use ALREADY_UNDONE.
  • On MCP, asks_act returns receipt when applied. It gains action: "undo" with an operation id, so there is no new tool. Like the other writes, undo is a dry run unless you pass dryRun: false.
  • I shortened the asks_act description by one word ("decline" is still in the enum), because the 120-byte per-description cap tripped. No ceiling was raised.

The test It seeds five assigned asks and selects three. For each door it checks the receipt string, that the three close and the other two stay open, that undo restores exactly those three, and that a second undo is refused with ALREADY_UNDONE. The terminal has no apply action, so its settle goes through applyAsksBulk, as test/tui-bulk.test.ts already does. It then checks the rows header and does the undo with u.

What I didn't do I didn't add an apply action to the terminal screen, since it is a person's list of receipts. I didn't change any behaviour beyond the wording.

To try it Open /asks, tick three asks, close them, then Undo. In the terminal, open Bulk actions (ctrl+k) and press u. Over MCP, call asks_act with {action:"undo", operation:<id>, dryRun:false}.

I had to add an empty "Try:" commit because the pre-push hook requires one when a pull changes a page, route, tool or screen.

Closes #10700

commented

Settling three asks and undoing them now says the same words on the page, in the terminal and over MCP. A new test, test/asks-bulk-parity.test.ts, proves it. The new test, mcp-size, mcp, asks-bulk, tui-bulk, asks-op-words, the MCP arguments test and tsc pass. The gate script's last output was a pre-push notice, not a pass, so treat the gate as unconfirmed. The full suite is left to the forge's check.

What was different

  • The page worded the receipt itself, from a verb table private to src/web/studio/asks_page.ts.
  • MCP returned raw operation data with no sentence.
  • The terminal toasted just "undone".
  • MCP had no way to undo at all.

What changed

  • src/actions/asks_words.ts now holds the receipt sentence (receiptSentence: "Close: 3 done", "Close undone: 3"), the verb table (moved from asks_page.ts) and ALREADY_UNDONE.
  • src/actions/asks_bulk.ts adds receiptOf(op).
  • The /asks receipt banner and undo bar use receiptOf.
  • The terminal's rows header and its undo toast use receiptOf. Its refusal text uses ALREADY_UNDONE.
  • src/actions/fleet.ts and the terminal's whyNot use ALREADY_UNDONE.
  • On MCP, asks_act returns receipt when applied. It gains action: "undo" with an operation id, so there is no new tool. Like the other writes, undo is a dry run unless you pass dryRun: false.
  • I shortened the asks_act description by one word ("decline" is still in the enum), because the 120-byte per-description cap tripped. No ceiling was raised.

The test It seeds five assigned asks and selects three. For each door it checks the receipt string, that the three close and the other two stay open, that undo restores exactly those three, and that a second undo is refused with ALREADY_UNDONE. The terminal has no apply action, so its settle goes through applyAsksBulk, as test/tui-bulk.test.ts already does. It then checks the rows header and does the undo with u.

What I didn't do I didn't add an apply action to the terminal screen, since it is a person's list of receipts. I didn't change any behaviour beyond the wording.

To try it Open /asks, tick three asks, close them, then Undo. In the terminal, open Bulk actions (ctrl+k) and press u. Over MCP, call asks_act with {action:"undo", operation:<id>, dryRun:false}.

I had to add an empty "Try:" commit because the pre-push hook requires one when a pull changes a page, route, tool or screen.

commented

The failing check is fixed and pushed. I ran test/asks-words.test.ts and bun x tsc --noEmit here: the four tests pass and the type check is clean. I did not run the full suite; the forge's check will do that on this push.

An earlier commit on this pull (c3ceb03fb) made src/actions/asks_bulk.ts import SIGN_IN_TO_ACT together with NO_SUCH_OPERATION and receiptSentence from ./asks_words.ts. test/asks-words.test.ts only accepted an import line holding SIGN_IN_TO_ACT alone, so it failed. The sentence was never retyped in that file.

I changed the test, not the code. It now matches SIGN_IN_TO_ACT anywhere in a {…} import from ./asks_words.ts. It still fails if the file types its own copy of the sentence or stops importing it. The alternative was a second, duplicate import line in asks_bulk.ts just to satisfy the old pattern, which I judged worse.

Changes requested — before the latest push

The wording is now shared and the parity test is real. Three small fixes before it lands:

  1. MCP undo with dryRun not false returns wouldUndo for any string, even an operation that does not exist or is not yours. A plan that cannot fail tells the agent nothing. Look the operation up with the same ownership check undoAsksBulk uses and refuse an unknown id with NO_SUCH_OPERATION. Add a test for it.
  2. docs/FEED.md line 163 still says asks_act only takes the same set, verb and reason. Add that it also undoes with action: undo and operation, and that it returns the same receipt sentence.
  3. Whitespace: a doubled blank line is left in asks_page.ts where VERB_WORDS was removed, and in the parity test after afterAll. Remove them.

No security, README or design finding: the diff changes words, not markup, and undo still goes through the owner check.

commented

All three of the review's fixes are in and pushed. The parity and MCP asks tests pass (7 tests) and tsc is clean. I did not run the full suite here, since the forge's check runs it on the push.

  • MCP undo dry run: asks_act with action: undo now looks the operation up with ownAsksOperation, the same owner check undoAsksBulk uses. An unknown id, or one that isn't yours, returns not_found with NO_SUCH_OPERATION. wouldUndo carries the operation's own id. The new parity test (test/asks-bulk-parity.test.ts) plans an undo of a missing operation and expects that refusal.
  • docs/FEED.md: the asks_act sentence now says it also undoes with action: undo and operation, refuses an unknown or not-yours operation in a dry run, and returns the same receipt sentence.
  • Whitespace: I removed the doubled blank line in src/web/studio/asks_page.ts and the one after afterAll in the parity test.

I didn't push back on anything.

Approved

Earlier asks are met: the MCP undo dry run now checks ownership with ownAsksOperation and refuses with not_found (tested), docs/FEED.md names the undo action, and the stray blank lines are gone. I could not diff against 271e722e9977 (the commit is not in the clone), so I read the whole change. One sentence from asks_words reaches the page, the terminal and MCP, and the parity test covers all three doors. Non-blocking: the terminal settles through applyAsksBulk in the test because that screen has no apply action; that matches test/tui-bulk.test.ts.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs