From 4eb5889f1e7e58ddcdeca2be6c21baa6faf38427 Mon Sep 17 00:00:00 2001 From: Amr Elsayed Date: Mon, 6 Jul 2026 11:14:57 +0700 Subject: [PATCH 01/18] chore(porch): 1139 init pir --- .../status.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 codev/projects/1139-vscode-backlog-reference-issue/status.yaml diff --git a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml new file mode 100644 index 000000000..2ad977cbf --- /dev/null +++ b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml @@ -0,0 +1,18 @@ +id: '1139' +title: vscode-backlog-reference-issue +protocol: pir +phase: plan +plan_phases: [] +current_plan_phase: null +gates: + plan-approval: + status: pending + dev-approval: + status: pending + pr: + status: pending +iteration: 1 +build_complete: false +history: [] +started_at: '2026-07-06T04:14:56.991Z' +updated_at: '2026-07-06T04:14:56.992Z' From 8f34a7617422d7e15ee53fb4cc68dab41a78ab71 Mon Sep 17 00:00:00 2001 From: Amr Elsayed Date: Mon, 6 Jul 2026 11:17:56 +0700 Subject: [PATCH 02/18] [PIR #1139] Plan draft --- .../1139-vscode-backlog-reference-issue.md | 65 +++++++++++++++++++ codev/state/pir-1139_thread.md | 11 ++++ 2 files changed, 76 insertions(+) create mode 100644 codev/plans/1139-vscode-backlog-reference-issue.md create mode 100644 codev/state/pir-1139_thread.md diff --git a/codev/plans/1139-vscode-backlog-reference-issue.md b/codev/plans/1139-vscode-backlog-reference-issue.md new file mode 100644 index 000000000..31f216c42 --- /dev/null +++ b/codev/plans/1139-vscode-backlog-reference-issue.md @@ -0,0 +1,65 @@ +# PIR Plan: Backlog "Reference issue in architect" honors the QuickPick selection + +## Understanding + +In a multi-architect workspace, clicking the inline "Reference issue in architect" button on a Backlog row shows a QuickPick to choose the target architect, but the reference text is always injected into `architect:main` regardless of the pick. The picker is effectively a no-op for the injection. Single-architect workspaces are unaffected. + +Root cause (verified against the current source): + +1. `codev.openArchitectTerminal` (`packages/vscode/src/extension.ts:751`) resolves the target architect (explicit arg → QuickPick when >1 architects → default `'main'`) into a local `targetName` and opens that terminal. The handler returns nothing, so the resolution is lost to callers. +2. `codev.referenceIssueInArchitect` (`extension.ts:1019`) awaits `executeCommand('codev.openArchitectTerminal')` (which may run the picker), then calls `injectArchitectText(text)` with no architect name (`extension.ts:1029`). +3. `injectArchitectText` (`packages/vscode/src/terminal-manager.ts:146`) defaults `architectName` to `'main'` (a deliberate Spec 786 Phase 6 choice, before the Issue 841 Gap 2 picker existed), so injection always keys `architect:main`. +4. `codev.referencePRInArchitect` (`extension.ts:1034`, the PR-sidebar mirror per #1043) has the identical shape at `extension.ts:1039`. + +Two independently-correct changes (786 Phase 6's default, 841 Gap 2's picker) crossed wires: the picker's selection is used for "which terminal to open" but never for "which terminal to inject into". + +## Proposed Change + +Follow the fix sketch from the issue — two surgical changes plus a docstring cleanup: + +1. **`codev.openArchitectTerminal` returns the resolved architect name** (`string | undefined`): + - Success path (terminal found and opened): return `targetName`. + - All failure paths return `undefined`: not connected, picker dismissed, no matching architect (warning shown), and the catch block. + - The `reg` helper (`extension.ts:732`) passes handler return values straight to `registerCommand`, so `executeCommand(...)` receives the value with no plumbing changes. + - The single-architect path also returns the resolved name (`'main'`), so callers rely on the return value uniformly. + +2. **Both reference commands pass the resolved name through**: + - `codev.referenceIssueInArchitect`: capture `const resolvedName = await vscode.commands.executeCommand('codev.openArchitectTerminal')`. If `resolvedName` is undefined (picker cancelled or open failed), return without injecting — the open path already surfaced its own error/warning where one is warranted, and a picker cancel is a deliberate user action that should be silent. Otherwise call `injectArchitectText(text, resolvedName)`. + - `codev.referencePRInArchitect`: same change. + - The existing "Codev: Architect terminal not available" warning stays for the residual case where open succeeded but the terminal lookup misses. + +3. **Docstring cleanup** at `terminal-manager.ts:139-144`: remove the "the Backlog button always targets `main` regardless of how many sibling architects exist" claim, note that reference-injection callers now pass the picker-resolved name, and that the `'main'` default remains for name-less callers. No behavior change in this file. + +## Files to Change + +- `packages/vscode/src/extension.ts:751-803` — `codev.openArchitectTerminal` handler returns `targetName` on success, `undefined` on every early-out (not connected, picker dismissed, architect not found, catch). +- `packages/vscode/src/extension.ts:1019-1033` — `codev.referenceIssueInArchitect` captures the returned name; skips injection when undefined; passes the name to `injectArchitectText`. +- `packages/vscode/src/extension.ts:1034-1043` — `codev.referencePRInArchitect` same change. +- `packages/vscode/src/terminal-manager.ts:133-145` — docstring only: drop the "always targets main" design claim, document the new caller contract. +- `packages/vscode/src/__tests__/extension-architect-commands.test.ts:145-159` — replace the "no name → defaults to 'main'" sentinel (which documents the old behavior) with assertions that (a) the resolved name is captured from `executeCommand` and passed as the second arg to `injectArchitectText`, and (b) injection is skipped when the resolved name is undefined. Add an assertion on the `codev.openArchitectTerminal` block that it `return targetName` on success (the new contract callers depend on). +- `packages/vscode/src/__tests__/reference-pr-in-architect.test.ts` — add the mirrored assertions for `codev.referencePRInArchitect` (resolved name passed through, no-inject on undefined). + +Note on test style: this suite is deliberately source-level sentinel tests (reading `extension.ts` as text) because activating the extension requires mocking the whole `vscode` module. The updated tests keep that pattern — they anchor on the new source shape (`injectArchitectText(buildArchitectReferenceInjection(...), resolvedName)` and the early return) rather than executing the handlers. + +## Risks & Alternatives Considered + +- **Risk: double-picker UX.** None introduced — the picker still runs at most once, inside `openArchitectTerminal`; the reference commands only consume its result. +- **Risk: other callers of `codev.openArchitectTerminal` observing a new return value.** Verified all in-repo invokers: the two reference commands (`extension.ts:1028`, `extension.ts:1038`) are the only `executeCommand` call sites; the Workspace view row (`views/workspace.ts:287`) and the Builders architect-group header (`views/builders.ts:317`) invoke via TreeItem `command` bindings with an explicit name and ignore the return; the command-relay mapping (`command-relay.ts:53`) likewise ignores it. Returning a value is additive for all of them. +- **Risk: behavior change on failure.** Previously a failed/cancelled open still attempted injection and produced the "Architect terminal not available" warning. After the fix a cancelled picker exits silently. This is intentional (cancel is a deliberate user action) and matches the issue's fix sketch ("When the user cancels the picker, do not inject"). +- **Alternative: have `injectArchitectText` itself resolve "the last opened architect".** Rejected — introduces hidden state in the terminal manager and breaks the single-source-of-truth resolution that already lives in `openArchitectTerminal`. +- **Alternative: duplicate the picker logic in the reference commands.** Rejected — two pickers to keep in sync; the return-value approach reuses the existing resolution untouched. +- **Out of scope** (per the issue): the single-architect default behavior, PR sidebar semantics beyond the mirror injection, other Backlog inline actions, and the sibling `afx workspace recover` attribution bug. + +## Test Plan + +- **Unit** (`pnpm --filter codev-vscode test`, or vitest from `packages/vscode/`): + - Updated sentinel: `codev.referenceIssueInArchitect` passes the resolved architect name as the second argument to `injectArchitectText`, and early-returns when the resolved name is undefined. + - New sentinel: `codev.openArchitectTerminal` returns `targetName` on the success path. + - Mirrored sentinels for `codev.referencePRInArchitect`. + - Full existing suite passes (notably `extension-architect-commands.test.ts`, `reference-pr-in-architect.test.ts`, `terminal-manager.test.ts`). +- **Manual** (at the dev-approval gate, in a workspace with ≥2 architects): + 1. Click the "Reference issue in architect" inline button on a Backlog row → QuickPick appears → pick a non-main architect → verify the reference text (`# "" `) lands in *that* architect's terminal input, focused, not submitted. + 2. Same flow, pick `main` → text lands in main. + 3. Same flow, press Escape on the picker → no injection, no warning toast. + 4. Repeat 1 with the PR sidebar's reference button → same routing. + 5. Single-architect workspace: button injects into main with no picker (unchanged). diff --git a/codev/state/pir-1139_thread.md b/codev/state/pir-1139_thread.md new file mode 100644 index 000000000..f63b67a61 --- /dev/null +++ b/codev/state/pir-1139_thread.md @@ -0,0 +1,11 @@ +# Builder thread — pir-1139 + +Issue #1139: vscode Backlog "Reference issue in architect" ignores QuickPick selection (always injects into main). + +## Plan phase + +- Verified the issue's root-cause analysis against source: `openArchitectTerminal` (extension.ts:751) resolves arg → picker → 'main' into a local `targetName` and discards it; both reference commands (extension.ts:1019, :1034) then call `injectArchitectText(text)` with no name, which defaults to 'main' (terminal-manager.ts:146, a Spec 786 Phase 6 decision that predates the 841 Gap 2 picker). +- Confirmed the `reg` helper passes handler return values through to `registerCommand`, so returning the resolved name from the command needs no extra plumbing. +- Audited every invoker of `codev.openArchitectTerminal`: only the two reference commands use `executeCommand`; sidebar rows / builders group header / command-relay pass explicit names or ignore the return. Returning a value is additive. +- Plan written to `codev/plans/1139-vscode-backlog-reference-issue.md`. Approach = the issue's fix sketch: return resolved name from `openArchitectTerminal`, thread it into `injectArchitectText` in both reference commands, skip injection on undefined (picker cancel), docstring cleanup in terminal-manager.ts, update the sentinel test that codified the old "always main" behavior. +- Sitting at `plan-approval` gate. From 61dd6466370735f7dfa1a1ffa7c622f95755ef02 Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Mon, 6 Jul 2026 11:18:06 +0700 Subject: [PATCH 03/18] chore(porch): 1139 plan-approval gate-requested --- codev/projects/1139-vscode-backlog-reference-issue/status.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml index 2ad977cbf..8632ec5c2 100644 --- a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml +++ b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml @@ -7,6 +7,7 @@ current_plan_phase: null gates: plan-approval: status: pending + requested_at: '2026-07-06T04:18:06.892Z' dev-approval: status: pending pr: @@ -15,4 +16,4 @@ iteration: 1 build_complete: false history: [] started_at: '2026-07-06T04:14:56.991Z' -updated_at: '2026-07-06T04:14:56.992Z' +updated_at: '2026-07-06T04:18:06.893Z' From 684f32dd435c0c971457e4a95ffea8006118d0c6 Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:55:42 +0700 Subject: [PATCH 04/18] chore(porch): 1139 plan-approval gate-approved --- .../projects/1139-vscode-backlog-reference-issue/status.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml index 8632ec5c2..9821a7e39 100644 --- a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml +++ b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml @@ -6,8 +6,9 @@ plan_phases: [] current_plan_phase: null gates: plan-approval: - status: pending + status: approved requested_at: '2026-07-06T04:18:06.892Z' + approved_at: '2026-07-07T02:55:42.842Z' dev-approval: status: pending pr: @@ -16,4 +17,4 @@ iteration: 1 build_complete: false history: [] started_at: '2026-07-06T04:14:56.991Z' -updated_at: '2026-07-06T04:18:06.893Z' +updated_at: '2026-07-07T02:55:42.842Z' From abe7ea2f77da7ad423a57040a64d6b67416d1e1d Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:55:52 +0700 Subject: [PATCH 05/18] chore(porch): 1139 implement phase-transition --- .../projects/1139-vscode-backlog-reference-issue/status.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml index 9821a7e39..daf1f847e 100644 --- a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml +++ b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml @@ -1,7 +1,7 @@ id: '1139' title: vscode-backlog-reference-issue protocol: pir -phase: plan +phase: implement plan_phases: [] current_plan_phase: null gates: @@ -17,4 +17,4 @@ iteration: 1 build_complete: false history: [] started_at: '2026-07-06T04:14:56.991Z' -updated_at: '2026-07-07T02:55:42.842Z' +updated_at: '2026-07-07T02:55:52.403Z' From 2e0ca369a6c95cb667e83cf86216a4cdb4f77971 Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:59:42 +0700 Subject: [PATCH 06/18] [PIR #1139] Honor QuickPick selection in architect reference injection codev.openArchitectTerminal now returns the resolved architect name (explicit arg, picker choice, or single-architect default); the two reference commands pass it through to injectArchitectText and skip injection when the picker is cancelled. Sentinel tests updated from the old always-main behavior. --- .../extension-architect-commands.test.ts | 47 +++++++++++++------ .../reference-pr-in-architect.test.ts | 19 ++++++++ packages/vscode/src/extension.ts | 35 ++++++++++---- packages/vscode/src/terminal-manager.ts | 12 ++--- 4 files changed, 83 insertions(+), 30 deletions(-) diff --git a/packages/vscode/src/__tests__/extension-architect-commands.test.ts b/packages/vscode/src/__tests__/extension-architect-commands.test.ts index 10b89c4fe..a44d148fe 100644 --- a/packages/vscode/src/__tests__/extension-architect-commands.test.ts +++ b/packages/vscode/src/__tests__/extension-architect-commands.test.ts @@ -14,9 +14,10 @@ * with a fallback to the scalar `state.architect` for older Tower. * 3. `codev.removeArchitect` is registered, refuses 'main', shows a modal * confirmation, and calls `workspaceProvider.refresh()` on success. - * 4. `codev.referenceIssueInArchitect` still calls `injectArchitectText` - * with no name arg → defaults to 'main' (the explicit Phase 6 decision - * to keep the Backlog button targeting main regardless of N). + * 4. `codev.openArchitectTerminal` returns the resolved architect name and + * `codev.referenceIssueInArchitect` passes it to `injectArchitectText`, + * so the Backlog button honors the multi-architect QuickPick selection + * (Issue 1139) instead of always targeting main. */ import { describe, it, expect } from 'vitest'; @@ -142,20 +143,36 @@ describe('Spec 786 Phase 6 — extension.ts architect commands', () => { expect(removeBlock).toMatch(/workspaceProvider\.refresh\(\)/); }); - it("codev.referenceIssueInArchitect calls injectArchitectText with no name → defaults to 'main'", () => { - // The Backlog inline button's documented Phase 6 behaviour: always - // targets main, regardless of how many sibling architects exist. The - // signature default (`architectName: string = 'main'`) makes the no-arg - // call route to main. + it('codev.openArchitectTerminal returns the resolved architect name on success', () => { + // Issue 1139: callers (the reference-injection commands) depend on the + // command returning the name that was actually opened, whether it came + // from an explicit arg, the multi-architect QuickPick, or the + // single-architect 'main' default. + const openBlock = EXT_SRC.split("reg('codev.openArchitectTerminal'")[1] ?? ''; + expect(openBlock).toMatch(/Promise<string \| undefined>/); + expect(openBlock).toMatch(/return targetName/); + }); + + it('codev.referenceIssueInArchitect injects into the architect resolved by the open command', () => { + // Issue 1139: the Backlog inline button previously called + // injectArchitectText with no name, so the QuickPick selection made in + // codev.openArchitectTerminal was ignored and the text always landed in + // architect:main. The command now captures the open command's resolved + // name and passes it through to the injection. // - // Post-#808 the injection text comes from buildArchitectReferenceInjection - // (so the call is `injectArchitectText(buildArchitectReferenceInjection(...))` - // instead of an inline template literal). The assertion now anchors on the - // helper call rather than the literal `#${issueId} ` template — the - // architect-name default behaviour is still the point of this test. + // Post-#808 the injection text comes from buildArchitectReferenceInjection. + const refBlock = EXT_SRC.split("regCli('codev.referenceIssueInArchitect'")[1] ?? ''; + expect(refBlock).toMatch( + /const resolvedName = await vscode\.commands\.executeCommand<string \| undefined>\('codev\.openArchitectTerminal'\)/ + ); + expect(refBlock).toMatch(/injectArchitectText\(buildArchitectReferenceInjection\([^)]*\), resolvedName\)/); + }); + + it('codev.referenceIssueInArchitect skips injection when the open is cancelled or fails', () => { + // A dismissed picker (or a failed open) resolves to undefined; the + // command must not fall back to injecting into main. const refBlock = EXT_SRC.split("regCli('codev.referenceIssueInArchitect'")[1] ?? ''; - // The injection call passes only the text — no architect name. - expect(refBlock).toMatch(/injectArchitectText\(buildArchitectReferenceInjection\(/); + expect(refBlock).toMatch(/if \(!resolvedName\) \{ return; \}/); }); it('workspaceProvider is held in a const so commands can call .refresh()', () => { diff --git a/packages/vscode/src/__tests__/reference-pr-in-architect.test.ts b/packages/vscode/src/__tests__/reference-pr-in-architect.test.ts index def44ca3a..f6b9f6145 100644 --- a/packages/vscode/src/__tests__/reference-pr-in-architect.test.ts +++ b/packages/vscode/src/__tests__/reference-pr-in-architect.test.ts @@ -13,6 +13,9 @@ * 4. extension.ts registers `codev.referencePRInArchitect` and calls * `buildArchitectReferenceInjection` for the injection text. * 5. The injection format for a PR with title matches `#<id> "<title>" `. + * 6. The injection targets the architect resolved by + * `codev.openArchitectTerminal` and is skipped when the open is + * cancelled (Issue 1139). */ import { describe, it, expect } from 'vitest'; @@ -93,6 +96,22 @@ describe('codev.referencePRInArchitect — extension.ts', () => { const block = EXT_SRC.split("regCli('codev.referencePRInArchitect'")[1] ?? ''; expect(block).toMatch(/instanceof PullRequestTreeItem/); }); + + it('injects into the architect resolved by the open command (Issue 1139)', () => { + // Mirror of the codev.referenceIssueInArchitect fix: capture the name + // resolved by codev.openArchitectTerminal (QuickPick choice in + // multi-architect workspaces) and pass it to injectArchitectText. + const block = EXT_SRC.split("regCli('codev.referencePRInArchitect'")[1] ?? ''; + expect(block).toMatch( + /const resolvedName = await vscode\.commands\.executeCommand<string \| undefined>\('codev\.openArchitectTerminal'\)/ + ); + expect(block).toMatch(/injectArchitectText\(buildArchitectReferenceInjection\([^)]*\), resolvedName\)/); + }); + + it('skips injection when the open is cancelled or fails (Issue 1139)', () => { + const block = EXT_SRC.split("regCli('codev.referencePRInArchitect'")[1] ?? ''; + expect(block).toMatch(/if \(!resolvedName\) \{ return; \}/); + }); }); describe('injection format for PR rows', () => { diff --git a/packages/vscode/src/extension.ts b/packages/vscode/src/extension.ts index 4a7219ff2..3222ed7ba 100644 --- a/packages/vscode/src/extension.ts +++ b/packages/vscode/src/extension.ts @@ -748,14 +748,20 @@ export async function activate(context: vscode.ExtensionContext) { const workspace = connectionManager?.getWorkspacePath() ?? 'none'; vscode.window.showInformationMessage(`Codev: ${state} | Workspace: ${workspace}`); }), - reg('codev.openArchitectTerminal', async (architectName?: string) => { + reg('codev.openArchitectTerminal', async (architectName?: string): Promise<string | undefined> => { // Spec 786 Phase 6: the command accepts an optional architect name. // Sidebar children pass their architect name via `command.arguments`. + // + // Issue 1139: returns the architect name that was actually opened + // (arg, picker choice, or the single-architect default) so callers + // like `codev.referenceIssueInArchitect` can inject into the same + // terminal the user picked. Every failure path (not connected, + // picker dismissed, architect not found) returns undefined. const client = connectionManager?.getClient(); const workspacePath = connectionManager?.getWorkspacePath(); if (!client || !workspacePath || connectionManager?.getState() !== 'connected') { vscode.window.showErrorMessage('Codev: Not connected to Tower'); - return; + return undefined; } try { const state = await client.getWorkspaceState(workspacePath); @@ -782,7 +788,7 @@ export async function activate(context: vscode.ExtensionContext) { const picked = await vscode.window.showQuickPick(items, { placeHolder: 'Select an architect terminal to open', }); - if (!picked) { return; } // user dismissed the picker + if (!picked) { return undefined; } // user dismissed the picker targetName = picked.name; } else { targetName = 'main'; @@ -794,11 +800,13 @@ export async function activate(context: vscode.ExtensionContext) { const target = match ?? fallback; if (target?.terminalId) { await terminalManager?.openArchitect(target.terminalId, targetName, true); - } else { - vscode.window.showWarningMessage(`Codev: No '${targetName}' architect found — is the workspace activated?`); + return targetName; } + vscode.window.showWarningMessage(`Codev: No '${targetName}' architect found — is the workspace activated?`); + return undefined; } catch { vscode.window.showErrorMessage('Codev: Failed to get workspace state'); + return undefined; } }), // Issue 1104: architect creation is now CONVERSATIONAL, not a direct @@ -1025,8 +1033,14 @@ export async function activate(context: vscode.ExtensionContext) { const issueId = extractIssueId(arg); if (!issueId) { return; } const title = extractIssueTitle(arg); - await vscode.commands.executeCommand('codev.openArchitectTerminal'); - const ok = terminalManager?.injectArchitectText(buildArchitectReferenceInjection(issueId, title)); + // Issue 1139: the open command resolves the target architect (arg, + // QuickPick in multi-architect workspaces, or the 'main' default) + // and returns the resolved name; inject into that same terminal. + // Undefined means the open failed or the user dismissed the picker, + // so skip the injection (a cancel is deliberate, stay silent). + const resolvedName = await vscode.commands.executeCommand<string | undefined>('codev.openArchitectTerminal'); + if (!resolvedName) { return; } + const ok = terminalManager?.injectArchitectText(buildArchitectReferenceInjection(issueId, title), resolvedName); if (!ok) { vscode.window.showWarningMessage('Codev: Architect terminal not available'); } @@ -1035,8 +1049,11 @@ export async function activate(context: vscode.ExtensionContext) { // Inline-button action on a PR row in the Pull Requests sidebar: // mirror of codev.referenceIssueInArchitect for PR rows (#1043). if (!(arg instanceof PullRequestTreeItem)) { return; } - await vscode.commands.executeCommand('codev.openArchitectTerminal'); - const ok = terminalManager?.injectArchitectText(buildArchitectReferenceInjection(arg.prId, arg.prTitle)); + // Issue 1139: same resolved-name pass-through as + // codev.referenceIssueInArchitect above. + const resolvedName = await vscode.commands.executeCommand<string | undefined>('codev.openArchitectTerminal'); + if (!resolvedName) { return; } + const ok = terminalManager?.injectArchitectText(buildArchitectReferenceInjection(arg.prId, arg.prTitle), resolvedName); if (!ok) { vscode.window.showWarningMessage('Codev: Architect terminal not available'); } diff --git a/packages/vscode/src/terminal-manager.ts b/packages/vscode/src/terminal-manager.ts index 15b7fb9d8..50e2fa450 100644 --- a/packages/vscode/src/terminal-manager.ts +++ b/packages/vscode/src/terminal-manager.ts @@ -136,12 +136,12 @@ export class TerminalManager { * registered in this window — callers should ensure it's open first (via * `codev.openArchitectTerminal`) before injecting. * - * Spec 786 Phase 6: defaults `architectName` to `'main'` so existing - * callers (notably `codev.referenceIssueInArchitect` — the Backlog inline - * button) keep targeting main without modification. This is the - * conservative call documented in the Phase 6 plan deliverable: the - * Backlog button always targets `main` regardless of how many sibling - * architects exist. + * `architectName` defaults to `'main'` (Spec 786 Phase 6) for name-less + * callers. The reference-injection commands (`codev.referenceIssueInArchitect` + * and `codev.referencePRInArchitect`) pass the name resolved by + * `codev.openArchitectTerminal` (explicit arg, QuickPick choice in + * multi-architect workspaces, or the single-architect default), so the + * injection lands in the terminal the user actually picked (Issue 1139). */ injectArchitectText(text: string, architectName: string = 'main'): boolean { const key = `architect:${architectName}`; From dd29bbbee73182cd6faf9702b93c2064588a0262 Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Tue, 7 Jul 2026 10:00:00 +0700 Subject: [PATCH 07/18] [PIR #1139] Thread: implement phase notes --- codev/state/pir-1139_thread.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/codev/state/pir-1139_thread.md b/codev/state/pir-1139_thread.md index f63b67a61..48d968057 100644 --- a/codev/state/pir-1139_thread.md +++ b/codev/state/pir-1139_thread.md @@ -9,3 +9,12 @@ Issue #1139: vscode Backlog "Reference issue in architect" ignores QuickPick sel - Audited every invoker of `codev.openArchitectTerminal`: only the two reference commands use `executeCommand`; sidebar rows / builders group header / command-relay pass explicit names or ignore the return. Returning a value is additive. - Plan written to `codev/plans/1139-vscode-backlog-reference-issue.md`. Approach = the issue's fix sketch: return resolved name from `openArchitectTerminal`, thread it into `injectArchitectText` in both reference commands, skip injection on undefined (picker cancel), docstring cleanup in terminal-manager.ts, update the sentinel test that codified the old "always main" behavior. - Sitting at `plan-approval` gate. +- Gate approved 2026-07-07. + +## Implement phase + +- Applied the plan as written (commit 2e0ca369): `openArchitectTerminal` returns the resolved name (undefined on every early-out incl. picker dismissal), both reference commands capture it via `executeCommand<string | undefined>` and pass it to `injectArchitectText`, early-return on undefined; terminal-manager docstring corrected. +- Replaced the sentinel test that codified the old "no name → main" behavior; added return-contract, pass-through, and cancel-path sentinels in both test files. +- Worktree gotcha for siblings: `codev-vscode` has no `build` script; use `pnpm compile`. Fresh worktree also needs `pnpm --filter @cluesmith/codev-types --filter @cluesmith/codev-core build` once or 14 vitest files fail at import resolution. +- `pnpm compile` green; `pnpm test:unit` green (47 files, 547 tests). +- Sitting at `dev-approval` gate. From 53a9de3b299252bc995655c7e0e052560461dbf8 Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Tue, 7 Jul 2026 10:00:50 +0700 Subject: [PATCH 08/18] chore(porch): 1139 dev-approval gate-requested --- codev/projects/1139-vscode-backlog-reference-issue/status.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml index daf1f847e..0a367318a 100644 --- a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml +++ b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml @@ -11,10 +11,11 @@ gates: approved_at: '2026-07-07T02:55:42.842Z' dev-approval: status: pending + requested_at: '2026-07-07T03:00:50.307Z' pr: status: pending iteration: 1 build_complete: false history: [] started_at: '2026-07-06T04:14:56.991Z' -updated_at: '2026-07-07T02:55:52.403Z' +updated_at: '2026-07-07T03:00:50.308Z' From ff70ba1ff0ba1080eb9a9271d26632e3f9d01d70 Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:39:23 +0700 Subject: [PATCH 09/18] chore(porch): 1139 dev-approval gate-approved --- .../projects/1139-vscode-backlog-reference-issue/status.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml index 0a367318a..d1ccdd785 100644 --- a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml +++ b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml @@ -10,12 +10,13 @@ gates: requested_at: '2026-07-06T04:18:06.892Z' approved_at: '2026-07-07T02:55:42.842Z' dev-approval: - status: pending + status: approved requested_at: '2026-07-07T03:00:50.307Z' + approved_at: '2026-07-08T05:39:22.972Z' pr: status: pending iteration: 1 build_complete: false history: [] started_at: '2026-07-06T04:14:56.991Z' -updated_at: '2026-07-07T03:00:50.308Z' +updated_at: '2026-07-08T05:39:22.972Z' From e2149647e8739bcb791dd45700039656ef97b0e2 Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:47:31 +0700 Subject: [PATCH 10/18] chore(porch): 1139 review phase-transition --- .../projects/1139-vscode-backlog-reference-issue/status.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml index d1ccdd785..a18259498 100644 --- a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml +++ b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml @@ -1,7 +1,7 @@ id: '1139' title: vscode-backlog-reference-issue protocol: pir -phase: implement +phase: review plan_phases: [] current_plan_phase: null gates: @@ -19,4 +19,4 @@ iteration: 1 build_complete: false history: [] started_at: '2026-07-06T04:14:56.991Z' -updated_at: '2026-07-08T05:39:22.972Z' +updated_at: '2026-07-08T05:47:31.556Z' From 0643b99d2fed4cf9e304e28c1d9da9a207fb04fa Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:49:16 +0700 Subject: [PATCH 11/18] [PIR #1139] Review + retrospective --- codev/resources/lessons-learned.md | 1 + .../1139-vscode-backlog-reference-issue.md | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 codev/reviews/1139-vscode-backlog-reference-issue.md diff --git a/codev/resources/lessons-learned.md b/codev/resources/lessons-learned.md index d6d096589..c45e9c89d 100644 --- a/codev/resources/lessons-learned.md +++ b/codev/resources/lessons-learned.md @@ -82,6 +82,7 @@ Generalizable wisdom extracted from review documents, ordered by impact. Updated - [From #1018] Against a *moving runtime*, only a deterministic guard holds — instructions, per-agent memory, and `git bisect` do not. The builder write-into-main-checkout bug is intrinsic model/CLI path-synthesis behavior (the model anchors a synthesized absolute path at the inferred repo root, dropping its `.builders/<id>/` worktree segment) that drifts across upgrades in both directions. The fix that survives version churn is a `PreToolUse` hook that converts a silent wrong-rooted write into a loud, correctable deny; the role-doc instruction is only a backstop. When a bug's root cause is "the model guessed wrong and got no corrective signal," reach for a runtime invariant, not a better prompt. - [From #1018] A guard's *surface* and its *blast radius* must match the actual hazard, not the role. The write-guard is builder-only and write-only by design: (a) the architect legitimately owns `main`, so the same hook there is a structural no-op (root resolves to the main checkout) and was deliberately not installed; (b) reads are left unguarded so codev's intentional cross-checkout reads (architect↔builder threads, sibling threads) keep working. Guarding "outside the worktree" symmetrically across roles or across read+write would have broken designed-in behavior. Scope the invariant to where the silent failure actually occurs. - [From #1018] `fs.writeFileSync` does not create missing parent dirs, and a git worktree only materializes directories that contain *tracked* files — git never checks out an empty dir. A path like `.claude/hooks/` (holding only a generated, intentionally-untracked file) therefore does not exist in a fresh worktree, and even `.claude/` may be absent in an adopter repo that tracks nothing under it. Any code that writes a generated file into a worktree subdir must `mkdir -p` its parent first; don't assume a dir exists just because a sibling tracked dir (e.g. `.claude/skills/`) does. +- [From #1139] When you add an interactive resolution step (a picker, a prompt) in front of an API that has a documented defaulting parameter, the resolution must flow to every consumer of that default: return the resolved value from the command/function that owns the interaction and audit downstream callers. Two independently-correct changes composed into a silent no-op here. Spec 786 Phase 6 deliberately defaulted `injectArchitectText(architectName = 'main')` so the Backlog button kept working, and Issue 841 Gap 2 later added a QuickPick upstream in `codev.openArchitectTerminal`, but the picker's choice was consumed only for "which terminal to open," never returned, so the reference commands kept injecting into `main` no matter what the user picked. Neither change was wrong; the seam between them was. The tell to grep for: a `showQuickPick`/resolution whose result is used locally but not returned, sitting upstream of a call site that relies on a default the resolution was meant to supersede. - [From 810] The builder-overview shape is defined twice — the `OverviewBuilder` wire type (`packages/types`) and a structurally-identical local `BuilderOverview` interface in `overview.ts`, kept in sync by hand. Adding a field to only the wire type compiles for clients (vscode/dashboard) but breaks the codev build at the server-side `builders.push({...})` sites. Compounding footgun: the codev package has no `check-types` script, so the mismatch is invisible until a full `pnpm build` runs `tsc` over `codev/src` — vscode/dashboard type-checks pass meanwhile. When touching the overview projection, build the codev package, not just the client type-check. - [From 0395] Prompt-based instructions beat programmatic file manipulation for flexible document generation — the Builder already has context and can write natural responses, while code would need fragile parsing and placeholder logic - [From 0395] Keep specs and plans clean as forward-looking documents — append review history (consultation feedback, lessons learned) to review files, not to the documents being reviewed diff --git a/codev/reviews/1139-vscode-backlog-reference-issue.md b/codev/reviews/1139-vscode-backlog-reference-issue.md new file mode 100644 index 000000000..6a5822d2c --- /dev/null +++ b/codev/reviews/1139-vscode-backlog-reference-issue.md @@ -0,0 +1,57 @@ +# PIR Review: Backlog "Reference issue in architect" honors the QuickPick selection + +Fixes #1139 + +## Summary + +In multi-architect workspaces, the Backlog row's "Reference issue in architect" button (and its PR-sidebar mirror) showed a QuickPick to choose the target architect but always injected the reference text into `architect:main`, making the picker a no-op. The fix makes `codev.openArchitectTerminal` return the architect name it actually resolved (explicit arg, picker choice, or single-architect default), and both reference commands now pass that name through to `injectArchitectText`. A cancelled picker skips injection silently instead of falling back to main. + +## Files Changed + +- `packages/vscode/src/extension.ts` (+28 / -7): `openArchitectTerminal` returns `Promise<string | undefined>`; both reference commands capture and pass the resolved name, early-returning on undefined +- `packages/vscode/src/terminal-manager.ts` (+6 / -6): docstring only, removed the stale "the Backlog button always targets main" design claim +- `packages/vscode/src/__tests__/extension-architect-commands.test.ts` (+36 / -11): replaced the sentinel that codified the old always-main behavior with return-contract, name-pass-through, and cancel-path sentinels +- `packages/vscode/src/__tests__/reference-pr-in-architect.test.ts` (+19 / -0): mirrored sentinels for the PR-sidebar command +- `codev/plans/1139-vscode-backlog-reference-issue.md` (+65): plan artifact +- `codev/state/pir-1139_thread.md` (+20): builder thread +- `codev/resources/lessons-learned.md`: one new Architecture entry (see Lessons Learned Updates) + +## Commits + +- `8f34a761` [PIR #1139] Plan draft +- `2e0ca369` [PIR #1139] Honor QuickPick selection in architect reference injection +- `dd29bbbe` [PIR #1139] Thread: implement phase notes +- plus porch state-transition commits (`chore(porch): ...`) + +## Test Results + +- `pnpm compile` (tsc + tsc webview + eslint + esbuild): pass +- `pnpm test:unit` (vitest): pass, 47 files, 547 tests (4 sentinel tests new or rewritten) +- Manual verification: approved by the human reviewer at the `dev-approval` gate, exercising the running worktree + +## Architecture Updates + +No arch changes: this PR fixes command wiring inside the VS Code extension (a return value threaded between two existing commands). No module boundaries, state, or cross-subsystem contracts changed. The `injectArchitectText` `'main'` default remains for name-less callers. + +## Lessons Learned Updates + +One COLD-tier entry added to `codev/resources/lessons-learned.md` (Architecture section): two independently-correct changes composed into this bug. Spec 786 Phase 6 deliberately defaulted `injectArchitectText` to `'main'`; Issue 841 Gap 2 later added a QuickPick upstream in `openArchitectTerminal`. The picker's resolution was consumed for "which terminal to open" but never returned, so downstream consumers of the default silently kept the pre-picker behavior. The lesson: when adding an interactive resolution step in front of an API with a documented default, return the resolution and audit every consumer of that default. + +Nothing HOT-tier: the rule is narrow to command-composition inside the extension, not a behavior-changing cross-cutting invariant. + +## Things to Look At During PR Review + +- The deliberate behavior change on cancel: previously a dismissed picker still attempted injection into main (surfacing a "terminal not available" warning when main's terminal wasn't registered); now a cancel exits silently. This matches the issue's fix sketch. +- Every early-out of `codev.openArchitectTerminal` now explicitly `return undefined` (not connected, picker dismissed, architect not found, workspace-state fetch failure) so callers get a uniform contract. +- The tests are source-level sentinels (the suite's established pattern, since activating the extension requires mocking the whole `vscode` module); they anchor on the new source shape rather than executing handlers. + +## How to Test Locally + +- **View diff**: VSCode sidebar, right-click builder pir-1139, **View Diff** +- **Run dev server**: VSCode sidebar **Run Dev Server**, or `afx dev pir-1139` +- **What to verify** (needs a workspace with 2+ architects): + - Backlog row mention button: pick a non-main architect in the QuickPick; `#<id> "<title>" ` lands in that architect's terminal, focused, not submitted + - Same flow picking `main`: text lands in main + - Same flow pressing Escape: no injection, no warning + - PR sidebar mention button: same routing behavior + - Single-architect workspace: no picker, injects into main, unchanged From ba836d1debca86b6647910d15bf1c6e7016f6d73 Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:49:39 +0700 Subject: [PATCH 12/18] chore(porch): 1139 record PR #1157 --- .../1139-vscode-backlog-reference-issue/status.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml index a18259498..6111b0390 100644 --- a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml +++ b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml @@ -19,4 +19,9 @@ iteration: 1 build_complete: false history: [] started_at: '2026-07-06T04:14:56.991Z' -updated_at: '2026-07-08T05:47:31.556Z' +updated_at: '2026-07-08T05:49:39.188Z' +pr_history: + - phase: review + pr_number: 1157 + branch: builder/pir-1139 + created_at: '2026-07-08T05:49:39.187Z' From dade4b19c18bb1d29c40bce64e3fb5ec051219df Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:49:49 +0700 Subject: [PATCH 13/18] chore(porch): 1139 review build-complete --- .../projects/1139-vscode-backlog-reference-issue/status.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml index 6111b0390..82b593cab 100644 --- a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml +++ b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml @@ -16,10 +16,10 @@ gates: pr: status: pending iteration: 1 -build_complete: false +build_complete: true history: [] started_at: '2026-07-06T04:14:56.991Z' -updated_at: '2026-07-08T05:49:39.188Z' +updated_at: '2026-07-08T05:49:49.266Z' pr_history: - phase: review pr_number: 1157 From bd0dc4dca1c6c27023198ef4e962eb35e9683fe6 Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:53:17 +0700 Subject: [PATCH 14/18] [PIR #1139] Review: address consult findings (extension test steps, frontmatter rebuttal) --- .../reviews/1139-vscode-backlog-reference-issue.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/codev/reviews/1139-vscode-backlog-reference-issue.md b/codev/reviews/1139-vscode-backlog-reference-issue.md index 6a5822d2c..9d8c09505 100644 --- a/codev/reviews/1139-vscode-backlog-reference-issue.md +++ b/codev/reviews/1139-vscode-backlog-reference-issue.md @@ -45,10 +45,22 @@ Nothing HOT-tier: the rule is narrow to command-composition inside the extension - Every early-out of `codev.openArchitectTerminal` now explicitly `return undefined` (not connected, picker dismissed, architect not found, workspace-state fetch failure) so callers get a uniform contract. - The tests are source-level sentinels (the suite's established pattern, since activating the extension requires mocking the whole `vscode` module); they anchor on the new source shape rather than executing handlers. +## Consultation Findings and Dispositions (single advisory pass) + +PIR runs one consultation pass with no automated re-review, so both codex findings are recorded here for the human at the `pr` gate: + +- **codex REQUEST_CHANGES: plan file lacks `approved`/`validated` YAML frontmatter.** Rebutted, no change made. The frontmatter rule (CLAUDE.md, "Approved specs/plans need YAML frontmatter") applies to artifacts the architect creates and approves on `main` *before spawning a builder*, so porch can no-op the corresponding phase. This plan was authored inside the porch-driven PIR flow; its approval is structured porch state (`plan-approval` gate approved, commit `684f32dd`, recorded in `status.yaml` history). Adding `validated: [gemini, codex, claude]` would be factually wrong: PIR's plan phase is human-only review by design. +- **codex REQUEST_CHANGES: "How to Test Locally" didn't explain how to load the modified extension.** Accepted, documentation fix applied below (this is a review-file correction, not a code defect, so no regression test applies). The claude consult returned APPROVE with no findings. + ## How to Test Locally +This is a VS Code extension change, so the dev server alone does not load the modified bundle. To exercise the fix: + +1. Open the worktree as its own window: VSCode sidebar, right-click builder pir-1139, **Open Worktree as Workspace** (or `code .builders/pir-1139`). +2. In that window, press F5 ("Run Codev Extension", the repo's `.vscode/launch.json` config). The pre-launch task builds the extension and an Extension Development Host window opens running the modified extension. +3. Alternative without the dev host: `cd packages/vscode && pnpm vsix`, then install the generated `.vsix` via the Extensions view ("Install from VSIX...") in your normal window, and reload. + - **View diff**: VSCode sidebar, right-click builder pir-1139, **View Diff** -- **Run dev server**: VSCode sidebar **Run Dev Server**, or `afx dev pir-1139` - **What to verify** (needs a workspace with 2+ architects): - Backlog row mention button: pick a non-main architect in the QuickPick; `#<id> "<title>" ` lands in that architect's terminal, focused, not submitted - Same flow picking `main`: text lands in main From a5aded41d720430f7f3c12662164cd53a8813565 Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:53:53 +0700 Subject: [PATCH 15/18] chore(porch): 1139 pr gate-requested --- .../projects/1139-vscode-backlog-reference-issue/status.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml index 82b593cab..75b39a62c 100644 --- a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml +++ b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml @@ -15,13 +15,15 @@ gates: approved_at: '2026-07-08T05:39:22.972Z' pr: status: pending + requested_at: '2026-07-08T05:53:53.412Z' iteration: 1 build_complete: true history: [] started_at: '2026-07-06T04:14:56.991Z' -updated_at: '2026-07-08T05:49:49.266Z' +updated_at: '2026-07-08T05:53:53.413Z' pr_history: - phase: review pr_number: 1157 branch: builder/pir-1139 created_at: '2026-07-08T05:49:39.187Z' +pr_ready_for_human: true From 0f7005c83b4210a6966cc06e4572fed8b5af282a Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:54:41 +0700 Subject: [PATCH 16/18] [PIR #1139] Thread: review phase notes --- codev/state/pir-1139_thread.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/codev/state/pir-1139_thread.md b/codev/state/pir-1139_thread.md index 48d968057..9fc94c297 100644 --- a/codev/state/pir-1139_thread.md +++ b/codev/state/pir-1139_thread.md @@ -18,3 +18,11 @@ Issue #1139: vscode Backlog "Reference issue in architect" ignores QuickPick sel - Worktree gotcha for siblings: `codev-vscode` has no `build` script; use `pnpm compile`. Fresh worktree also needs `pnpm --filter @cluesmith/codev-types --filter @cluesmith/codev-core build` once or 14 vitest files fail at import resolution. - `pnpm compile` green; `pnpm test:unit` green (47 files, 547 tests). - Sitting at `dev-approval` gate. +- Gate approved 2026-07-08 after a side discussion on scope (fix covers both reference-injection surfaces: Backlog + PR sidebar) and the `return undefined` idiom (matches the codebase's consistent-return style in value-returning functions). + +## Review phase + +- Review file written; one COLD lesson routed to lessons-learned.md Architecture ("interactive resolution added in front of a defaulting API must return the resolution; audit consumers of the default"). No arch.md changes (command wiring only). +- PR #1157 opened, recorded with porch. +- Consultation (single advisory pass; porch's verify block ran a 2-way claude+codex per this project's config): claude=APPROVE; codex=REQUEST_CHANGES with (1) plan frontmatter missing, rebutted (rule targets pre-spawn architect artifacts; PIR plan approval is porch state; 'validated' would be false for a human-only phase) and (2) How-to-Test lacked extension-load steps, accepted and fixed in bd0dc4dc (Extension Dev Host / vsix instructions), PR body re-synced. Rebuttal file in codev/projects/1139-*/1139-review-iter1-rebuttals.md. +- Architect notified with the REQUEST_CHANGES dispositions. Sitting at `pr` gate. From e613413396e3bac8cdbc9607aaa931b59282ce3b Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Wed, 8 Jul 2026 13:03:17 +0700 Subject: [PATCH 17/18] chore(porch): 1139 pr gate-approved --- .../1139-vscode-backlog-reference-issue/status.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml index 75b39a62c..aebf7a943 100644 --- a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml +++ b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml @@ -14,16 +14,17 @@ gates: requested_at: '2026-07-07T03:00:50.307Z' approved_at: '2026-07-08T05:39:22.972Z' pr: - status: pending + status: approved requested_at: '2026-07-08T05:53:53.412Z' + approved_at: '2026-07-08T06:03:17.518Z' iteration: 1 build_complete: true history: [] started_at: '2026-07-06T04:14:56.991Z' -updated_at: '2026-07-08T05:53:53.413Z' +updated_at: '2026-07-08T06:03:17.519Z' pr_history: - phase: review pr_number: 1157 branch: builder/pir-1139 created_at: '2026-07-08T05:49:39.187Z' -pr_ready_for_human: true +pr_ready_for_human: false From 64eab6eca508b0beca55631548ecc681aa3dd1b7 Mon Sep 17 00:00:00 2001 From: Amr Elsayed <amrmelsayed@users.noreply.github.com> Date: Wed, 8 Jul 2026 13:03:27 +0700 Subject: [PATCH 18/18] chore(porch): 1139 protocol complete --- .../projects/1139-vscode-backlog-reference-issue/status.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml index aebf7a943..66a1ea327 100644 --- a/codev/projects/1139-vscode-backlog-reference-issue/status.yaml +++ b/codev/projects/1139-vscode-backlog-reference-issue/status.yaml @@ -1,7 +1,7 @@ id: '1139' title: vscode-backlog-reference-issue protocol: pir -phase: review +phase: verified plan_phases: [] current_plan_phase: null gates: @@ -21,7 +21,7 @@ iteration: 1 build_complete: true history: [] started_at: '2026-07-06T04:14:56.991Z' -updated_at: '2026-07-08T06:03:17.519Z' +updated_at: '2026-07-08T06:03:27.969Z' pr_history: - phase: review pr_number: 1157