FE-1187: Make cancelled exchanges self-describing#331
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
PR SummaryLow Risk Overview Walkthrough evidence: Two new Product/design direction: New Planning & process: Reviewed by Cursor Bugbot for commit 60c740c. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 9f6a59e. Configure here.
There was a problem hiding this comment.
Pull request overview
This PR makes “cancelled” structured exchanges self-describing and easier to interpret (for both humans and the agent), while also adding a CLI “tripwire” probe to detect capture-sweep debt in session JSONL and improving dev-mode /introspect legibility.
Changes:
- Canonicalize cancellation rendering via a shared
CANCELLED_TERMINALstring and update formatters/tests/snapshots accordingly. - Add a sweep-debt tripwire probe (
src/probes/sweep-debt-tripwire.ts) with strict CLI argument parsing and comprehensive Vitest coverage. - Improve Pi dev-mode introspection output (top-level field summaries + actionable mirror pointer) and add standalone ask cancellation status guidance in the Pi exchange extension.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/probes/sweep-debt-tripwire.ts | New CLI/library probe to assess sweep debt from session JSONL. |
| src/probes/tests/sweep-debt-tripwire.test.ts | Tests for sweep-debt assessment, JSONL parsing diagnostics, and CLI exit behavior. |
| src/probes/tests/structured-exchange-ordering-proof.test.ts | Updates ordering proof to include the new ui:setStatus event. |
| src/agents/contexts/exchanges/request-response/review.ts | Uses canonical cancellation terminal for request-review rendering. |
| src/agents/contexts/exchanges/request-response/choices.ts | Uses canonical cancellation terminal for request-choices rendering. |
| src/agents/contexts/exchanges/request-response/choice.ts | Uses canonical cancellation terminal for request-choice rendering. |
| src/agents/contexts/exchanges/request-response/answer.ts | Uses canonical cancellation terminal for request-answer rendering. |
| src/agents/contexts/exchanges/option-echo.ts | Introduces CANCELLED_TERMINAL shared cancellation terminal text. |
| src/agents/contexts/exchanges/ask.ts | Renders ask cancellation via CANCELLED_TERMINAL and elides cancelled.message. |
| src/agents/contexts/exchanges/tests/request-response.test.ts | Asserts all request-response cancellations render as the canonical terminal. |
| src/agents/contexts/exchanges/tests/ask.test.ts | Asserts ask cancellation uses canonical terminal (and not trailing italic). |
| src/agents/contexts/exchanges/snapshots/review-set-tuples.md | Snapshot updates reflecting canonical cancellation terminal text. |
| src/agents/contexts/exchanges/snapshots/question-tuples.md | Snapshot updates reflecting canonical cancellation terminal text. |
| src/agents/contexts/exchanges/snapshots/digest-tuples.md | Snapshot updates reflecting canonical cancellation terminal text. |
| src/agents/contexts/exchanges/snapshots/ask-tuples.md | Snapshot updates reflecting canonical cancellation terminal text. |
| src/.pi/extensions/exchanges/TOPOLOGY.md | Documents revised standalone cancellation guidance and lifecycle. |
| src/.pi/extensions/exchanges/ask.ts | Sets/clears a brunch.ask status hint on standalone cancellation/answer. |
| src/.pi/extensions/dev-mode/introspection/TOPOLOGY.md | Documents more actionable /introspect output (field-level + mirror pointer). |
| src/.pi/extensions/dev-mode/introspection/index.ts | Implements top-level summarization + conditional mirror pointer output. |
| src/.pi/extensions/tests/exchanges-present-request.test.ts | Verifies standalone cancellation sets status hint and clears on next answer. |
| src/.pi/extensions/tests/dev-mode-introspection.test.ts | Tests new /introspect output shape and mirror pointer gating. |
| memory/PLAN.md | Updates progress tracking and execution pointer for FE-1187 remediation tranche. |
| memory/cards/walkthrough-remediation-2--consolidated-outer-checkpoint.md | Adds a human-gated consolidated checkpoint card for outer verification. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export function parseSessionJsonl(source: string): readonly TranscriptEntryLike[] { | ||
| return source | ||
| .split(/\r?\n/u) | ||
| .filter((line) => line.trim().length > 0) | ||
| .map((line, index) => { | ||
| try { | ||
| return requireEntry(JSON.parse(line) as unknown); | ||
| } catch (error) { | ||
| const detail = error instanceof Error ? error.message : String(error); | ||
| throw new Error(`Invalid session JSONL at line ${index + 1}: ${detail}`); | ||
| } | ||
| }); | ||
| } |
e72e030 to
e6730fc
Compare
9f6a59e to
06cb306
Compare
06cb306 to
9b78289
Compare
| if ('digest' in details) { | ||
| return { | ||
| exchangeId: details.exchange_id, | ||
| lens: 'intent', | ||
| mode: 'review', | ||
| mode: 'text', |
| export const zAskContinuationParams = z | ||
| .object({ | ||
| body: zNonBlankMarkdown, | ||
| options: z.array(zAskContinuationOption).min(1), | ||
| options: z.array(zAskContinuationOption).min(1).optional(), | ||
| multiple: z.boolean().optional(), |
| if (question.kind === 'multi-select' && this.#multi.size) | ||
| answer = { questionId: question.id, kind: 'multi-select', optionIds: [...this.#multi] }; |
Sort top-level field keys and exclude arrays from the record guard so `/introspect` output is stable and never mislabels an array payload as a numeric-index record. Drop the digest false-proof from the continuation picker test (digest routes to the editor, not a decision picker; the editor path is already proven separately) and fix walkthrough-note typos. Co-authored-by: Cursor <cursoragent@cursor.com>
| if (question.kind === 'multi-select' && this.#multi.size) | ||
| answer = { questionId: question.id, kind: 'multi-select', optionIds: [...this.#multi] }; |
| return acceptedTextResponse( | ||
| pending.exchangeId, | ||
| answerText, | ||
| 'request_answer', | ||
| formatRequestAnswer(details), | ||
| details, | ||
| ); |
| body: zNonBlankMarkdown, | ||
| options: z.array(zAskContinuationOption).min(1), | ||
| options: z.array(zAskContinuationOption).min(1).optional(), | ||
| multiple: z.boolean().optional(), | ||
| allowOther: z.boolean().optional(), | ||
| allowNone: z.boolean().optional(), |
| toolResultMessage: { | ||
| role: 'toolResult', | ||
| toolName: 'ask', | ||
| toolName: 'request_answer', | ||
| content: [{ text: '## Answer\n\nA local product specification workspace.' }], |


FE-1187: Make cancelled exchanges self-describing
FE-1187: Guide standalone ask cancellation
fix(dev): make introspection notices actionable
fix(dev): only advertise written prompt mirror
FE-1187: Add sweep debt tripwire
fix(probes): document tripwire source invocation
FE-1187: Scope consolidated outer checkpoint
fix(probes): judge latest closed sweep interval
test(probes): pin malformed sweep JSONL diagnostics
fix(probes): parse tripwire options strictly
docs(plan): retire tripwire correction scope
fix(exchanges): canonicalize cancellation terminal