[Epic] MCP Observability Lifecycle and Tooling Capabilities Expansion - #2612
Conversation
…lope (code, Implemented by ProPR AI using gpt-5.6-sol model. Implementation completed successfully.
…e lifecycle Implemented by ProPR AI using gpt-5.6-sol model. Implementation completed successfully.
Fixed the `Validate Changes` CI failure. - Refactored lifecycle outcome/cancellation logic in [operationLifecycle.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T01-11-33/packages/api/mcp/operationLifecycle.ts). - Extracted operation-state resolution in [operations.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T01-11-33/packages/api/mcp/operations.ts). - Preserved existing behavior while bringing both functions below ESLint’s complexity limit. Validation passed: - API strict lint (`--max-warnings 0`) - API typecheck - Focused operation tests: 6/6 - Full MCP suite: 114/114 - `git diff --check` No visual preview was created because this is an internal API refactor with no user-visible changes. PR: #2613 Comment by: @propr-dev[bot] (ID: 5881718524) Comment by: @github-actions[bot] (ID: 5881718710) Model: gpt-5.6-sol
Implemented F1–F5 only. - `list_operations` now revalidates repository, tool permission, and cancellation-source authorization before pagination. - Initial receipts remain `accepted` until backend execution is observed. - Initial mutation artifacts are persisted before returning and survive replay. - Tracker task/review failures populate durable error envelopes. - Tracker `unknown` states persist, preserve timestamps and terminal outcomes, and can resolve from later evidence. - Added focused authorization, pagination, concurrency, artifact, failure, and uncertainty regressions. Validation: - API typecheck passed. - Focused operation tests: 10/10 passed. - Full MCP suite: 118/118 passed. - `git diff --check` passed. - No visual preview needed. - Independent discoveries: none. PR: #2613 Comment by: @propr-ultrafix (ID: 0) Model: gpt-5.6-sol
…ry-standard documented `max-lines` exemption to the centralized MCP tool catalog in [tools.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T01-41-50/packages/api/mcp/tools.ts:1). Fixed the `Validate Changes` failure by adding the repository-standard documented `max-lines` exemption to the centralized MCP tool catalog in [tools.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T01-41-50/packages/api/mcp/tools.ts:1). Validation passed: - API lint with `--max-warnings 0` - API TypeScript build - `git diff --check` No visual preview was generated because this is a lint-only, non-visual change. PR: #2613 Comment by: @propr-dev[bot] (ID: 5882022708) Comment by: @github-actions[bot] (ID: 5882023203) Model: gpt-5.6-sol
Implemented F6 only. - Stale `accepted` receipts with no result now become durably `unknown` after 120 seconds using stable `accepted_at`. - Replay, `get_operation`, projection, and `list_operations` consistently reflect interruption. - Acknowledged queued operations remain active. - Late authoritative invocation results resolve the timeout race correctly. - Added focused regression coverage in [mcpOperations.test.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T01-58-26/packages/api/test/mcpOperations.test.ts:149). Validation passed: - Focused operation tests: 11/11 - Full MCP suite: 119/119 - API typecheck - API lint - `git diff --check` No visual preview was created because this is backend-only. No independent issues discovered. PR: #2613 Comment by: @propr-ultrafix (ID: 0) Model: gpt-5.6-sol
Implemented F7 only. - Legacy result-less `running` receipts now share the interruption predicate with `accepted` receipts and are durably transitioned to compatibility/lifecycle `unknown` ([operations.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T02-18-39/packages/api/mcp/operations.ts:53), [operations.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T02-18-39/packages/api/mcp/operations.ts:126)). - Added a migration regression covering backfill, active/unknown filtering, repeated polling, retry-hint removal, and persisted state ([mcpOperations.test.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T02-18-39/packages/api/test/mcpOperations.test.ts:388)). Validation: - Focused operation suite: 12/12 passed. - API typecheck passed. - Affected-file lint and `git diff --check` passed. - Broader MCP glob encountered unrelated Node 22 incompatibilities where existing tests require `mock.module`; the affected operation suite passed within that run. No visual preview was generated because this is API/database-only behavior. No additional defects were changed. PR: #2613 Comment by: @propr-ultrafix (ID: 0) Model: gpt-5.6-sol
Implemented F8 only. - Reconciles persisted terminal receipts with lifecycle state before replay, duplicate dispatch, lookup, and lifecycle-filtered listing. - Preserves the terminal receipt’s persisted timestamp as `finished_at`. - Added interruption regressions for synchronous invocation completion and tracker completion. - Updated [operations.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T02-39-56/packages/api/mcp/operations.ts:61), [tools.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T02-39-56/packages/api/mcp/tools.ts:361), and [mcpOperations.test.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T02-39-56/packages/api/test/mcpOperations.test.ts:117). Validation: - API typecheck passed. - API lint passed. - Full MCP suite passed: 122 tests. - No visual preview generated; this is non-visual persistence behavior. - No independent findings. PR: #2613 Comment by: @propr-ultrafix (ID: 0) Model: gpt-5.6-sol
Implemented F9 and F10. - Terminal recovery now restores receipt-derived artifacts and failure metadata with stale-receipt guards. - Repository-filtered listings resolve cancellation source repositories before filtering and pagination. - Added regressions for replay/list recovery and cancellation filtering. - No independent defects discovered. - No visual preview generated; changes are API/database-only. Validation: - MCP operations tests: 14/14 passed - Full MCP suite: 122/122 passed - API typecheck passed - API lint passed - `git diff --check` passed PR: #2613 Comment by: @propr-ultrafix (ID: 0) Model: gpt-5.6-sol
Implemented F11 and F12 only. - Goal operations now use their current task history as execution evidence, including already-completed/failed tasks, while terminality remains tied to the goal result. [tools.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T03-21-04/packages/api/mcp/tools.ts:343) [operationLifecycle.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T03-21-04/packages/api/mcp/operationLifecycle.ts:143) - Failed ultrafix loops now prioritize their own completion reason over successful task reasons, with an `Ultrafix loop failed.` fallback. [operationLifecycle.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T03-21-04/packages/api/mcp/operationLifecycle.ts:92) - Added focused persistence and end-to-end regressions for both paths. [mcpOperations.test.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T03-21-04/packages/api/test/mcpOperations.test.ts:350) [mcpWorkflows.test.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T03-21-04/packages/api/test/mcpWorkflows.test.ts:246) Validation: - API TypeScript check passed. - API lint completed successfully. - Full MCP suite passed: 122 tests. - No visual preview generated; changes are backend-only. - Independent discoveries: none. PR: #2613 Comment by: @propr-ultrafix (ID: 0) Model: gpt-5.6-sol
Fixed the `Validate Changes` failure. - Refactored lifecycle failure/start detection into focused helpers, resolving both complexity warnings. - Added the repository-standard documented `max-lines` exemption for the shared MCP workflow fixture. - Confirmed the `ubuntu-latest` migration message was unrelated. Validation passed: - API lint with `--max-warnings 0` - API typecheck - Full MCP suite: 122/122 tests - `git diff --check` No visual preview was needed because this is CI/internal logic only. PR: #2613 Comment by: @propr-dev[bot] (ID: 5883101945) Model: gpt-5.6-sol
Implemented F13 and F14 only. - Goal polling now captures `failure_reason`, task failure reasons, `current_task_id`, and `final_pr_number`. - Lifecycle normalization persists goal/task failures and task/PR artifacts. - Terminal task receipts can be enriched when `tasks.pr_number` arrives after completion, closing the avoidable stale-state window. - Added regressions proving failure/artifact durability after backend rows are removed. - Updated the task-submission fixture to match the production schema. Validation: - API TypeScript check passed. - Full MCP suite passed: 123/123 tests. - `git diff --check` passed. - No visual preview generated; changes are API/database-only. Independent discoveries: none. PR: #2613 Comment by: @propr-ultrafix (ID: 0) Model: gpt-5.6-sol
Fixed the `Validate Changes` CI failure. Root cause: two API functions exceeded ESLint’s complexity limit by one. I extracted the new normalization logic into focused helpers in: - [operationLifecycle.ts](/home/node/workspace/packages/api/mcp/operationLifecycle.ts) - [operationTracking.ts](/home/node/workspace/packages/api/mcp/operationTracking.ts) The Ubuntu migration message was informational, not the failure. Validation passed: - API ESLint with `--max-warnings 0` - API TypeScript build - Full MCP suite: 123 tests passed - `git diff --check` No visual preview was created because this is an internal refactor with no UI impact. PR: #2613 Comment by: @propr-dev[bot] (ID: 5883403398) Model: gpt-5.6-sol
Implemented the follow-up lint fixes: - Extracted receipt issue-number collection in [operationLifecycle.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T04-09-20/packages/api/mcp/operationLifecycle.ts). - Extracted pull-request context refresh in [operationTracking.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T04-09-20/packages/api/mcp/operationTracking.ts). - Preserved existing lifecycle and receipt behavior. Validation passed: - API lint with zero warnings - API TypeScript typecheck - 15/15 focused MCP operation tests - `git diff --check` No visual preview was generated because this is a backend-only refactor. PR: #2613 Comment by: @github-actions[bot] (ID: 5883403478) Model: gpt-5.6-sol
Implemented F15 only. - Recovery now promotes persisted `result.targetState` into the reconciliation receipt. - Missing failure, PR/task artifacts, and progress are restored without overwriting newer progress. - Added regression coverage using a real tracker-shaped terminal write, followed by listing and idempotency replay without live refresh. Changed: - [operations.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T04-26-15/packages/api/mcp/operations.ts) - [mcpOperations.test.ts](/tmp/git-processor/worktrees/integry/propr/pr-2613-followup-2026-09-29T04-26-15/packages/api/test/mcpOperations.test.ts) Validation passed: - API typecheck - Focused operation tests: 15/15 - Full MCP suite: 123/123 - ESLint and diff checks No independent discoveries or visual changes. PR: #2613 Comment by: @propr-ultrafix (ID: 0) Model: gpt-5.6-sol
Implemented F16 only. - Terminal reconciliation now reapplies durable confirmed cancellation receipts to their source operations. - Source updates are owner/grant-scoped, revalidate persisted evidence, preserve terminal outcomes, and use the confirmation timestamp. - Added regressions for interrupted tracker writes followed by replay and listing, plus grant isolation and terminal guards. - Updated live synchronization to use the same guarded propagation path. Validation: - Full MCP suite: 124 tests passed. - API TypeScript check passed. - Focused ESLint passed. - `git diff --check` passed. - No visual preview generated; this is backend-only. - No independent findings. PR: #2613 Comment by: @propr-ultrafix (ID: 0) Model: gpt-5.6-sol
Implemented F17. - Terminal progress and lifecycle now persist atomically. - Stale nonterminal tracker and delayed invocation writes cannot replace terminal receipts. - Stale callers reload the winning durable terminal observation. - Added regressions covering the GitHub-await ordering, delayed invocation results, history pruning, replay, and listing. - No visual preview was needed because the change is backend-only. Validation: - Focused operations suite: 18 passed - Full MCP suite: 125 passed - API typecheck: passed - API lint: passed - `git diff --check`: passed Independent discovery, left unchanged as out of scope: the pre-existing task-submission tracker has a similar unconditional write after an await in `toolsTaskSubmissions.ts`; it was not introduced or modified by this PR. PR: #2613 Comment by: @propr-ultrafix (ID: 0) Model: gpt-5.6-sol
Implemented the MCP legacy cleanup: - Folded lifecycle columns into the original MCP schema migration. - Removed the additive migration, backfill logic, legacy lifecycle mapping, and legacy receipt tests/fallbacks. - Required lifecycle metadata for all newly created MCP operations. - Preserved current crash recovery and fixed terminal recovery replacing stale progress. - Updated affected fixtures and tests. Validation passed: - Full MCP suite: 124/124 - API typecheck - API and core lint - `git diff --check` No visual preview was created because these are API/database-only changes. PR: #2613 Comment by: @integry (ID: 5885821150) Model: gpt-5.6-sol
Implemented F18, F19, and F20 only. - F18: verified the existing guarded recovery overwrites stale nonterminal progress with the durable terminal target snapshot; its interruption regression passes. - F19: terminal execution restoration now preserves live `targetState` fields and enriches them with task/PR identity. - F20: terminal lifecycle state now governs replay/list projections, removing contradictory polling hints and stale messages. - Added focused `get_operation`, replay, and listing regressions. Validation: - Full MCP suite: 125/125 passed - Focused operations suite: 17/17 passed - API typecheck passed - API lint passed - `git diff --check` passed Independent pre-existing findings, intentionally unchanged: resolved cancellation tracking can similarly clear a missing persisted target, and follow-up task lookup assumes a job ID is present. Both are outside PR-changed behavior. No visual preview was generated because the changes are API-only. PR: #2613 Comment by: @integry (ID: 5886663832) Model: gpt-5.6-sol
Implemented F21 only. - Removed timestamp-based interruption classification for tracker-confirmed `running` operations in [operations.ts](/home/node/workspace/packages/api/mcp/operations.ts:301). - Added regression coverage for `list_operations`, replay, and duplicate idempotency responses in [mcpOperations.test.ts](/home/node/workspace/packages/api/test/mcpOperations.test.ts:538). - Preserved result-less `accepted` invocation interruption handling. Validation passed: - Full MCP suite: 126/126 tests - API TypeScript check - Scoped ESLint - `git diff --check` No independent related defects found. No visual preview was needed for this API-only change. PR: #2613 Comment by: @integry (ID: 5887302103) Model: gpt-5.6-sol
…tion-receip-20260929-0054-naw [2594 by GPT-5.6 Sol] MCP: give operation receipts a readable lifecycle (accepted, running, completed, failed, cancelled) with timestamps, artifacts and list_operations
…letion and r Implemented by ProPR AI using gpt-5.6-sol model. Implementation completed successfully.
…lure stage, Implemented by ProPR AI using gpt-5.6-sol model. Implementation completed successfully.
…n progress t Implemented by ProPR AI using gpt-5.6-sol model. Implementation completed successfully.
…r recent tas Implemented by ProPR AI using gpt-5.6-sol model. Implementation completed successfully.
…ional on app Implemented by ProPR AI using gpt-5.6-sol model. Implementation completed successfully.
…ecks: fail w Implemented by ProPR AI using gpt-5.6-sol model. Implementation completed successfully.
…t_doc (bound Implemented by ProPR AI using gpt-5.6-sol model. Implementation completed successfully.
…h a build ma Implemented by ProPR AI using gpt-5.6-sol model. Implementation completed successfully.
|
/fix |
|
✅ Applied the requested follow-up changes in commit be451f3
Summary of ChangesF6 is fixed: a plan left What changed
I chose the renewal variant over the "claim age plus Octokit timeout" variant from the finding. A slow but live 20-task publication can legitimately outlast a fixed age, and a takeover then could duplicate its in-flight issue. Behaviour to know about
Regressions added in
Independent discovery, not fixed No visual preview was produced, since the change is not visible in the UI. 🤖 Implementation Details
Undo Changes • View Task Execution 💡 ProPR Slash Commands
🤖 Generated by ProPR |
…cation after an API container restart can now be resumed. The publish-plan tests, the related MCP suites, the API typecheck and lint on the changed files all pass.
F6 is fixed: a plan left `executing` with an `active` publication after an API container restart can now be resumed. The publish-plan tests, the related MCP suites, the API typecheck and lint on the changed files all pass.
**What changed**
- **Claim lease.** The publishing attempt now writes a renewal timestamp into the active publication before each issue is created or adopted. Each issue POST is aborted one minute after that renewal.
- **Bounded takeover.** `publish_plan` with `resume: true` takes over an active claim that has gone unrenewed for two minutes. It needs no `/proc` access, so it works after a restart into a new PID namespace. The existing marker lookup still runs before every POST, so an issue the dead attempt created is adopted, not duplicated.
- **Early resume.** A resume inside the lease still fails with `PRECONDITION_FAILED`. The message now says the prior attempt may still be running, and `details.claimLapsesAt` gives the earliest takeover time.
- **Docs.** `docs/mcp.md` describes the lapse and takeover.
I chose the renewal variant over the "claim age plus Octokit timeout" variant from the finding. A slow but live 20-task publication can legitimately outlast a fixed age, and a takeover then could duplicate its in-flight issue.
**Behaviour to know about**
- Each renewal advances the plan's `mcp_revision` by one, because the existing draft trigger bumps it on every write. A revision read mid-publication can therefore go stale, and the caller re-reads the plan before resuming.
- A takeover is safe only against an owner running this code. An owner that renews between a resume's read and its claim wins, and the resume fails without contacting GitHub.
- One race remains and cannot be closed: GitHub may still create an issue from a request aborted at the deadline. The one-minute grace before takeover and the marker lookup cover it.
**Regressions added** in `packages/api/test/mcpPublishPlan.test.ts`; the first three fail against the previous tool code.
- A foreign-namespace claim with a result-less `unknown` receipt is refused inside its lease, then taken over once lapsed, adopting the marked issue.
- An owner renewal that lands during a takeover's evidence gathering defeats the takeover.
- The owner stores a renewal before each POST, and a hung POST is aborted at the lease deadline and leaves a resumable partial publication.
- Boundary checks for the lapse calculation.
**Independent discovery, not fixed**
The MCP GitHub client is built with `request: { timeout: 10_000 }` in `packages/api/mcp/policy.ts`. The installed `@octokit/request` 10 ignores that option and honours only an abort signal, so other MCP GitHub calls have no timeout. The finding's premise that no POST can outlive the Octokit timeout does not hold, which is why the issue POST now carries its own deadline.
No visual preview was produced, since the change is not visible in the UI.
PR: #2612
Comment by: @integry (ID: 5913591843)
Model: claude-fable-5-1
|
/review fable astra |
|
✅ AI Code Review Complete requested by @integry Posted 2 reviews: |
🔍 AI Code Review — fableOverall EvaluationThis epic PR delivers the "observable MCP surface": a structured error envelope with redaction, a durable operation lifecycle ( ✅ Publication claim is fenced end to end — ✅ Stale-poll protection is real, not aspirational — ✅ Secret redaction is applied at every durable boundary — The PR needs one small correction to the new provenance feature before merge; everything else is suggestion-level. Merge blockersEvery finding below was introduced by this PR and must be resolved before merging. F7: 🔴 Refinement writes
|
🔍 AI Code Review — astraOverall EvaluationThis PR substantially expands MCP observability through durable lifecycles, structured errors, publication recovery, documentation, and visual previews. It needs changes before merge because terminal receipt responses can contradict their persisted lifecycle, and refinement answers can corrupt plan provenance. ✅ Shared preview authorization — HTTP and MCP media retrieval reuse the same association checks, trusted-host redirects, content validation, and size limits. ✅ Explicit uncertainty — Error classification preserves upstream causes while distinguishing uncertain mutation outcomes from definitive refusals. ✅ Targeted regression coverage — Added tests exercise concurrent receipt polling, publication-related recovery helpers, secret redaction, and both MCP protocol eras. The supplied status reports 28 passed checks and no blocking failures or pending checks. This review is static; no commands were run. Seven explicitly omitted files, including two substantial test files, limit verification. Merge blockersEvery finding below was introduced by this PR and must be resolved before merging. F8: 🔴 Terminal receipt responses can change outcome
F9: 🔴 Non-modifying answers overwrite plan provenance
SuggestionsThese are optional follow-ups and are not sent to S25: 🟢 Bound lifecycle recovery scans
ScoreThe implementation has substantial focused coverage and passing authoritative checks, but two verified inconsistencies remain in the new observability contract. Both admit localized corrections. Score: 6/10 🤖 Review Details
Files omitted from review diff7 files were omitted from the review diff. Large, binary, generated, and lockfile changes are deprioritized. Did not fit the review context budget
🤖 Review by ProPR |
|
/fix |
|
✅ Applied the requested follow-up changes in commit a7b325c
Summary of ChangesF7, F8 and F9 are fixed, with regressions for each. The API typecheck, lint on the changed files, the MCP suite and the planner suites pass, apart from one intermittent publish-plan lease test. That test failed in two of five runs; it uses mocked timers and never reaches the changed code. What changed
Decisions worth knowing
Regressions added
I confirmed the new tests fail when the fixes are removed. Independent discoveries, not changed
No visual preview was produced, since the change is backend only. 🤖 Implementation Details
Undo Changes • View Task Execution 💡 ProPR Slash Commands
🤖 Generated by ProPR |
… typecheck, lint on the changed files, the MCP suite and the planner suites pass, apart from one intermittent publish-plan lease test. That test failed in two of five runs; it uses mocked timers and never reaches the changed code. F7, F8 and F9 are fixed, with regressions for each. The API typecheck, lint on the changed files, the MCP suite and the planner suites pass, apart from one intermittent publish-plan lease test. That test failed in two of five runs; it uses mocked timers and never reaches the changed code. ## What changed - **F7 and F9, plan provenance:** both refinement save paths now share one helper in `planRevisions.ts`. An `answered` or `clarify` result keeps the existing `plan_cause`. A `modified` result writes `refinement` only when the saved plan differs from the stored one. - **F8, terminal receipts:** `get_operation` no longer lets a later reading of the draft or goal replace a terminal lifecycle outcome. The guard covers `generate_plan`, `refine_plan` and `create_goal` receipts. The response's top-level state is also aligned to the durable lifecycle after the final re-read, which closes the window where a concurrent poll settles the receipt first. ## Decisions worth knowing - **Answers still save the caller's plan.** The editor sends its in-memory copy, which carries client-side task ids, so the stored JSON can change on an answer. I kept that write and preserved the cause, because the content still came from the original source. - **`persistGenerationCompletion` is unchanged.** Its only caller always writes a freshly generated plan, so the mislabel is not reachable there. - **The state alignment is limited to receipts whose stored state stays `accepted`.** Those record their outcome only in the lifecycle. Applying it to every receipt broke an existing test, described below. ## Regressions added - **Provenance:** `answered` and `clarify` keep `generation` in both handlers, including when the caller's copy with ids is saved. A later manual edit snapshots the old plan as `generation`, not `refinement`. `modified` records `refinement`, and an identical `modified` result keeps the prior cause. - **Receipts:** a completed generation receipt stays completed after a later failed generation, and the reverse. A failed goal receipt stays failed after the goal is resumed and completes. A stale poll interleaved with a settling poll reports the durable outcome. I confirmed the new tests fail when the fixes are removed. ## Independent discoveries, not changed - **Retried task submissions disagree with their lifecycle.** A failed `create_task` receipt whose submission is retried returns `state: queued` from `get_operation` while its lifecycle stays `failed`. An existing test that predates this PR asserts the `queued` result, so resolving it needs a product decision. - **Generation receipts are not matched to a run.** From reading the code, a `generate_plan` receipt that was never polled would adopt the outcome of a later generation of the same draft. I did not reproduce this. - **Editor id normalisation may relabel plans.** From reading the code, after a refinement the editor re-saves the plan with generated ids if tasks lack them, which the update route would record as a manual edit. I did not reproduce this. No visual preview was produced, since the change is backend only. PR: #2612 Comment by: @integry (ID: 5914948627) Model: claude-fable-5-1
|
/review fable |
|
ℹ️ Analyzed the follow-up request by @propr-dev[bot] Analysis SummaryReview of PR #2612 (branch Correctness
Efficiency
Design and cleanup
No code changes were necessary based on the current state of the branch. 🤖 Analysis Details
💡 ProPR Slash Commands
🤖 Generated by ProPR |
|
Fix the review findings |
|
✅ Applied the requested follow-up changes in commit 496e588 Summary of ChangesAll nine findings from the latest review are fixed, each with a regression test. The API typecheck, lint on the changed files, and every MCP and planner suite I ran pass. The connect integration suite is skipped by design without a live routing repository. What changedCorrectness
Efficiency
Design and cleanup
DocsThe error table in VerificationI confirmed the merge regression fails with the tagging removed. The line-count lint warning my change introduced in the planning tools file was trimmed back under the limit. No visual preview was produced because the change is backend only. 🤖 Implementation Details
Undo Changes • View Task Execution 💡 ProPR Slash Commands
🤖 Generated by ProPR |
…th a regression test. The API typecheck, lint on the changed files, and every MCP and planner suite I ran pass. The connect integration suite is skipped by design without a live routing repository. All nine findings from the latest review are fixed, each with a regression test. The API typecheck, lint on the changed files, and every MCP and planner suite I ran pass. The connect integration suite is skipped by design without a live routing repository. ## What changed **Correctness** - **Merge read-phase failures fail as ordinary errors.** A new helper in the error envelope module tags any error thrown by a mutation's read phase as raised before side effects, and `classifyError` then keeps the ordinary code instead of `OUTCOME_UNKNOWN`. The shared pull-request read and the merge tool's GraphQL read plus check-context paging are wrapped. Malformed pagination now throws a stable `GITHUB_RESPONSE_INVALID` code, marked retryable, instead of a plain error. - **Pre-upgrade in-flight receipts settle.** The lifecycle migration now maps the old runner's `running` rows without a result to `accepted`. The interruption predicates in the operations runner also accept `running`, so a database that already ran the migration is covered too. - **Retryable `PUBLISH_FAILED` reports the current revision.** The release path reads the draft's revision after releasing the claim and includes it as `details.currentRevision`, so a retry does not hit `STALE_REVISION`. **Efficiency** - **`list_operations` bounds its recovery sweep** to the requested `sinceMinutes` window. Older receipts are still repaired on their own read or replay. - **Terminal receipts are no longer rewritten on every poll.** The resolved create_task branch compares the refreshed projection canonically and skips the write when nothing changed. While testing this I found that artifact recording also rewrote `updated_at` every poll, so that write now only runs when the patch changes something. **Design and cleanup** - **Target authorisation fails closed by default.** A target must declare `optional: true` to skip the check on a missing argument. Only `list_visual_previews` opts in. - **The draft merge guard is inlined** through a small shared helper instead of rebuilding a snapshot from a snapshot. - **Refinement normalisation lives in one place.** A new helper in the planner helpers resolves what a refinement saves. A result that already reports `merged` came from core and is saved as is; anything else is normalised there. Both handlers now call it. - **The interrupted-marking call in `publish_plan`** now runs after the stopped-attempt decision with a comment stating it only reclassifies the prior receipt for pollers. It was kept because an existing test asserts that observable effect. ## Docs The error table in `docs/mcp.md` lists the new GitHub code and the `currentRevision` detail, and the uncertainty section states that read-phase failures keep their ordinary code. ## Verification I confirmed the merge regression fails with the tagging removed. The line-count lint warning my change introduced in the planning tools file was trimmed back under the limit. No visual preview was produced because the change is backend only. PR: #2612 Comment by: @integry (ID: 5917055063) Model: claude-fable-5-1
|
/review fable |
|
✅ AI Code Review Complete requested by @integry Posted 1 review: |
🔍 AI Code Review — fableOverall EvaluationThis epic PR adds the "observable MCP surface": a structured, secret-redacted error envelope for every tool call, a persisted operation lifecycle ( I traced the main changed paths (operation runner and recovery, tracker/lifecycle synchronization, publish claim/lease/fail paths, merge precondition ordering, refinement normalization, trigger-access revision handshake, docs indexing/chunking, preview rendering) and did not find a defect I can drive from a reachable trigger to an incorrect observable outcome. Caveat: several unchanged helpers the new code depends on ( ✅ Publication recovery is fenced end to end — ✅ Read-phase failures no longer masquerade as uncertain outcomes — ✅ Lifecycle writes are monotonic under concurrent polls — The PR is merge-ready within scope; the items below are optional follow-ups. Merge blockersNo merge blockers. SuggestionsThese are optional follow-ups and are not sent to S26: 🟢 Wire the new publication and provenance tests into a CI entry point
S27: 🟢 Reconcile
|
|
/fix S26 S27 S28 S29 S30 |
|
✅ Applied the requested follow-up changes in commit 658ae50
Summary of ChangesAll five selected suggestions are applied, each with a regression where behaviour changed. The API, root worker and UI typechecks, lint on the changed files, and every affected test suite pass. Nothing here is visually perceptible, so no preview files were created. S26, CI wiring. The three API suites for publish-plan claim/lease/takeover, plan provenance and the preview fetch service now sit in the S27, ultrafixCycle contract. The UI history metadata type now accepts a number or the legacy S28, path redaction. Whole-string basename reduction now applies only to path-like keys such as S29, duplicate epoch read. The state-lost branch now reads the epoch once and derives reason and outcome from the same value. The regression simulates state cleared between load and record, asserts exactly one epoch read after the loss, and checks both pairings. S30, preview route ordering. The route again checks visual-preview enablement before resolving the GitHub credential, so a user without a credential gets 404 for a disabled repository as before the extraction. The service still performs its own check, but the route hands it the result it already read, so enablement is read once per request. Keeping the preview-specific error ahead of the GitHub access handler is correct and now documented in code: the preview 404s were direct responses before, and the status-based handler would otherwise rewrite them into the repository-access 404. Two regressions cover the no-credential path, the single read, and the distinct 404 bodies. One independent observation, not acted on: non-comment receipts still use a two-minute pickup window in the tracking code. That is separate from the PR command deadline the doc sentence describes and is outside the selected records. 🤖 Implementation Details
Undo Changes • View Task Execution 💡 ProPR Slash Commands
🤖 Generated by ProPR |
…ession where behaviour changed. The API, root worker and UI typechecks, lint on the changed files, and every affected test suite pass. Nothing here is visually perceptible, so no preview files were created. All five selected suggestions are applied, each with a regression where behaviour changed. The API, root worker and UI typechecks, lint on the changed files, and every affected test suite pass. Nothing here is visually perceptible, so no preview files were created. **S26, CI wiring.** The three API suites for publish-plan claim/lease/takeover, plan provenance and the preview fetch service now sit in the `test:mcp` script, together with the root ultrafix continuation metadata test. The core refinement-output test and the docs manifest test went into `test:unit`, because the change classifier only allows `api` files in `test:mcp`. The full-suite discovery already globs all of these on every PR. The CI deduplication and classification tests confirm the new entries are discovered units. **S27, ultrafixCycle contract.** The UI history metadata type now accepts a number or the legacy `true`, and gains the `ultrafixOutcome` union. The task-info flag stays boolean because the API normalizes it there. The only strict `=== true` uses in the tree are test fixtures, and the activity digest never reads the field, so no other consumer needed changes. The coverage doc now says a PR command receipt goes `unknown` with a `COMMAND_NOT_PICKED_UP` failure after ten minutes. **S28, path redaction.** Whole-string basename reduction now applies only to path-like keys such as `path`, `logsPath`, `files`, `repoRoot` or `cwd`, with array items inheriting their key. Free-text fields such as `reason`, `error` or a plan task title keep a leading slash, so a `/merge` or `/fix S26` string survives intact. Multi-segment absolute paths embedded in prose are still stripped, so credential and home-directory leakage is unchanged. A regression covers both classes of key across the tracked-result wrappers. **S29, duplicate epoch read.** The state-lost branch now reads the epoch once and derives reason and outcome from the same value. The regression simulates state cleared between load and record, asserts exactly one epoch read after the loss, and checks both pairings. **S30, preview route ordering.** The route again checks visual-preview enablement before resolving the GitHub credential, so a user without a credential gets 404 for a disabled repository as before the extraction. The service still performs its own check, but the route hands it the result it already read, so enablement is read once per request. Keeping the preview-specific error ahead of the GitHub access handler is correct and now documented in code: the preview 404s were direct responses before, and the status-based handler would otherwise rewrite them into the repository-access 404. Two regressions cover the no-credential path, the single read, and the distinct 404 bodies. One independent observation, not acted on: non-comment receipts still use a two-minute pickup window in the tracking code. That is separate from the PR command deadline the doc sentence describes and is outside the selected records. PR: #2612 Comment by: @integry (ID: 5919124925) Model: claude-fable-5-1
|
/merge |
|
🔀 Auto-merged No conflicts were found — the merge was verified by an AI agent. 🤖 Verification Details
System-triggered merge conflict resolution |
…c-mcp-observability-cf6
Merge docs/0.9.0-user-docs-cleanup (now containing main with #2612 and #2628). Apply the doc fixes found for #2612 now that it has merged: list the notifications resources (and allow the token in the observable-surface doc test), retitle the optional-expectedHead step, drop stale epic process text from mcp-operator-surface.md, and document that a non-empty trigger whitelist is exclusive, ignores the [bot] suffix and skips the blacklist, and that empty follow-up keywords trigger on every allowed comment. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
MCP Observability Lifecycle and Tooling Capabilities Expansion
This Epic PR aggregates all changes for the plan: MCP Observability Lifecycle and Tooling Capabilities Expansion
Issues in this Epic
Auto-close
When this PR is merged, the following issues will be automatically closed:
Fixes #2593
Fixes #2594
Fixes #2595
Fixes #2596
Fixes #2597
Fixes #2598
Fixes #2599
Fixes #2600
Fixes #2601
Fixes #2602
Fixes #2603
Fixes #2604
Fixes #2605
Fixes #2606
Fixes #2607
Fixes #2608
Fixes #2609
Created automatically by ProPR