Repository navigation
feat(fork): port GitHub Issues onto v2 - #179
Conversation
Agent work on this PREstimated cost unknown · 0 responses · 40 sessions · 4.5 h wall time
Flags: 3 human corrections · 59 large tool outputs · 37 repeated commands · 8 repeated failures · 62 repeated reads · 5 repeated skill loads · 39 sessions with usage bound to no task · 1 session without usage records Details: snapshot, prices, coverage, counters
Token counters by model (native counter semantics; never added across semantics): Selected rates (USD per million tokens). These rates value the report at the selected schedule date; they do not establish historical prices or subscription spending.
Other output and reasoning are priced without double counting inclusive native output. Missing rates remain unknown. Local measurement from native records; usage totals are not billing. Updated in place by |
… onto v2 (#171) Upstream's v2 removed the gh CLI client and the v1 projection reads the fork's Issues features used. This ports them onto upstream's GitHubApi (GraphQL variables, the shared pager, credential pinning per host), v2 thread reads, McpToolAccess and native subagent lineage, keeps fork_thread_issue_links unchanged across the v1 import, and requires source-control:write for Issue comment and close (D27). Feature map and allowlist list the four features. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: unavailable · PR result: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
|
What: Review of PR #179 at head Exact-head finding
Reviewer and limitsReviewer runtime: GPT-6-Luna ( Elon recordRequirements and who asked: #171 and #166 D7.7 require the Issues port; the user requested independent review of the exact PR head. |
17ec084 to
8b7ce7b
Compare
|
What Independent review finds a blocking P2 multi-host credential isolation defect at head Finding: P2, blocks the accepted partial-host behaviorapps/server/src/issues/IssueService.ts:285 yields The expected partial-host contract is explicit in packages/contracts/src/issues.ts:147: failed hosts are reported in Review record
Requirements and who asked: User-approved #171 port of existing Issues browse, links, computed status, and in-app open on native v2; accepted #166 D7.7/D8a and fixed D27 apply. |
|
What The reported multi-host CorrectionThe earlier finding in comment #6066102195 was incorrect. I verified the installed source at This correction supersedes the finding; the exact-head review is still in progress. Requirements and who asked: User-approved #171 port of Issues browse, links, status, and in-app open on native v2; accepted #166 D7.7/D8a and fixed D27 apply. Reviewer: Codex harness, GPT-6-Luna, max effort. No tests or browser were run by reviewer. |
|
What: Independent review of PR #179 at Exact candidate and verdict
Resolved credential concernThe earlier claim in comment #6066102195 is withdrawn in the public correction. The installed Review coverage and evidenceI read the full PR diff against the exact base, including the server, contracts, client, UI, tests, documentation, fork inventory, and affected consumers. I checked the accepted #166 scope and D27 authorization choice: Issue comment/close/reopen remain guarded by I inspected the exact-candidate evidence at Issue #171 comment #6066042049 and its logs under At the time checked, CI Build, Check, Lint, Typecheck, Test, Test Web, Test Server 1-6, Rust, Release Smoke, and Fork Stack Model passed. LimitsThe user explicitly deferred the browser/UI before-and-after pass until the ports are integrated in fork/v2; no browser or client UI pass was run for this review. The live GitHub mutation remained gated and skipped. These are stated proof limits, not code findings or changes to the accepted scope. Elon record
Reviewer: Codex / GPT-6-Luna, T3 Code harness, max reasoning effort. |
What: GitHub Issues work again on
fork/v2: browsing, links to threads, computed status, and opening Issue links in the app, now built on upstream's GitHub client and v2 threads.Why: Upstream's orchestration v2 removed the
ghCLI client and the v1 thread reads these fork features used, and upstream has no Issues feature of its own.So what: Focused proof, fresh code CI and independent exact-head review pass. GitHub reports this PR merged by
lukemajduring final handoff; the dispatcher issued no merge command. UI evidence remains pending the planner's integrated pass, as explicitly agreed.Problem
The fork's Issues features (#25 and follow-ups) read GitHub through the
ghCLI and read threads from the v1 projection. Onfork/v2neither exists, so Issues browse, thread links, computed status and in-app Issue links do not build or run. Thread links stored by v1 Chromeria (fork_thread_issue_links) must still show after the user's data moves to the v2 database.Change
The fork's existing implementation is ported with the smallest edits to upstream files. Behavior stays the same except for the user decisions listed below.
ghcalls are replaced by upstream'sGitHubApi. Search text, URLs and numbers travel as GraphQL variables. Batched reads use the sharedaliasedGraphQlDocument, and the Issues search usesreadGraphQlPageswithfromset to the client's cursor andmaxPages: 1, so each call still makes one request and "Load more" works as before. Each Issues list uses one credential per host for all its searches. The closing-reference cache is keyed by credential, as upstream's PR caches are. The server reads only hosts that hold one of its GitHub projects.identity.origin, otherwise the canonical one), so a fork lists its own Issues (D8a). PR lookup is unchanged.OrchestratorV2.getThreadShellandProjectService. Reads across many threads (threads for Issues, pull requests of Issue threads, child threads, pruning) query the live v2 projection table, the way upstream'spullRequest/linkedThreads.tsdoes. They never read the frozen v1 tables.subagentlineage (nativeparentThreadId). Conversation forks and anything below them are excluded. This matches v1, which rolled up only the threads its threads toolkit spawned.runtime.status, plus backgroundsubagent/background_taskwork). A spawned thread's work counts for its ancestors.link_issue/unlink_issueuseMcpToolAccess.actsAsCallerandlist_thread_issuesusesreadsAsCaller, all behind thepull-requestscapability./issues/Nlinks keep upstream's behavior, including the PR panel's not-found state (#14242).docs/fork-features.mdadds four features: issues-browse, issues-links, issues-status and issues-open-links. This PR edits 28 upstream files.scripts/fork-upstream-edits.txtadds 25 of them, each with exactly one owner in these features. The other three,server.ts,ws.tsandSidebarChrome.tsx, keep their existing owners and are listed as shared.Permission change (user decision D27)
Commenting on, closing or reopening an Issue now requires
source-control:write, the scope upstream uses for pull request writes. v1 requiredorchestration:operate. Both the server and the client guard (CLIENT_GUARDED_RPC_SCOPES, plus the command'spermissionAtomin the Issue panel) check the new scope.orchestration:operatebut withoutsource-control:writecan no longer comment on, close or reopen Issues. It can still read them and link them to threads.source-control:writebut withoutorchestration:operatecan now comment on, close and reopen them.npx t3 pair --scope orchestration:read --scope orchestration:operate --scope source-control:write, or a standard pairing from Settings → Connections. Open the link in the browser, or use Add Environment for a saved remote or mobile environment; pairing the same environment replaces its saved grant. Reconnecting alone does not change permissions. See Manage or revoke access; the Issues section ofdocs/user/source-control.mdnow says this.Stored links across the v1 import
This PR adds no write backfill. The v2 database starts as a copy of v1, so
fork_thread_issue_linksis carried over unchanged, and the importer keeps thread ids and deletion times. Startup still runs the fork backfill hook (runForkV1Backfills()afterreconcileShells), which is idempotent here. The proof that the hook recovers from a failed step without duplicate rows is #167's runner test (forkV1Backfills.test.ts), not this PR.Scope and approval
Port 5 of 11 under the per-feature port plan in Absorb upstream main (533 commits behind) #166 (D1–D7, D7.7 "Issues features: Port", D8a origin-first Issues). This PR closes Port the GitHub Issues features #171.
D27 (user):
source-control:writefor Issue writes, and the shared pager withfrom+maxPages: 1.Upstream checked first:
mainhas no Issues feature. Two open PRs overlap and were inspected but not adopted (findings on #171):issues.detailRPC name as ours.Both collisions need a decision at the next upstream absorption if either PR merges.
Not ported:
issueStatus.live.test.ts: it creates branches and workflows on GitHub throughgh.IssueLinks.live.test.ts: its closing-reference read now lives inIssueService.live.test.ts.ThreadLinksPanel.test.tsx: a static-markup test, which AGENTS.md rules out; logic tests cover its state mapping.Verification
Candidate
8b7ce7b7c979d1b79271339799dbcac9520a9404(one commit) on baseorigin/fork/v26e1653b6719565db2cc5094670e19e6efd3fc1ce(#178, squash of the #167 foundation). The upstream merge base is12069eefd707.Environment: macOS, Node v24.13.1, the host-neutral environment from
docs/fork.md(Homebrew removed fromPATH,ELECTRON_RUN_AS_NODEunset, resolvedTMPDIR). Script and logs:/tmp/171-v2/final-8b7ce7b7c9/(run.sh,results.txt, one log per step). Every step exited 0.The previous head
17ec0845edfailed CI's knip check on one unused export,CREATED_ATinapps/server/src/issueLinks/IssueLinks.testFixtures.ts. It is used only inside that file, so only itsexportkeyword was removed; the commit is otherwise identical. Every step below was rerun on the new head. Fresh CI passes, including knip, full test shards, typecheck, build and release smoke; Fork Stack Model passes. Preview deployment/EAS and unchanged-mobile analysis are conditional workflow skips, not executed UI or live-write proof. The current-head bot transfer report passes every ceiling; it has no successful main baseline yet. No unresolved bot finding remains.scripts/fork-check.sh12069eefd7, 2 commits (foundation + this PR), all 86 upstream edits in the stack allowlisted with one owner each, 12 features.vp test run apps/server/src/issues apps/server/src/issueLinks packages/client-runtime/src/state/issueCommandPermissions.test.ts packages/contracts/src/issue{s,Links,Status}.test.ts apps/web/src/components/issues apps/web/src/components/threadDescendants.logic.test.ts apps/web/src/components/pullRequest/pullRequestFilterSearch.logic.test.tsvp test runon 21 files: RpcAuthorization, ServerEnvironment, McpHttpServer, worktree registration, RpcInstrumentation, ws, ChatMarkdown (3 files), ChatView.logic, CommandPalette.logic, RightPanelTabs (2 files), PullRequestListFilters, openPullRequestLink, reopenClosedView, rightPanelStore, state/pullRequests, client-runtime rpc client, contracts environment and rpcCHROMERIA_V1_SNAPSHOT_SOURCE=$HOME/.t3/userdata/state.sqlite vp test run apps/server/src/issueLinks/IssueLinks.carryover.test.tsT3CODE_ISSUES_LIVE=1 vp test run apps/server/src/issues/IssueService.live.test.ts(withghonPATH)tsc --noEmitin packages/contracts, packages/client-runtime, apps/server, apps/webvp linton all 85 changed TS/TSX filesReal-data carryover. The source is opened read-only and copied with
VACUUM INTO. The real importer and the startup hook then run on the private copy. The live threads' stored rows, with every persisted field (thread_id, host, repository, number, url, source, linked_at), are deep-equal (isDeepStrictEqual) to the v1 rows before the import, after the reads and prune, and after a repeatedreconcileShells+runForkV1Backfills. Every stored link shows on its thread and is found from its Issue. Failure messages print only counts and digests, never rows. The test does not report the size of the snapshot it compared. Separately, a read-only count of the source taken just after the run found 163 stored links on 101 live threads, allagent-sourced; that count is not the test's input. Dismissed, manual and started links are covered by the synthetic test.Skip audit. The default run skips exactly 10 tests, all opt-in by environment variable:
apps/server/src/issues/IssueService.live.test.ts, whose suite isdescribe.skipIf(!live), whereliveisT3CODE_ISSUES_LIVE === "1". These are 8 read-only tests and 1 write fixture test. The write test is alsoskipIf(!hasFixture)and runs only whenT3CODE_ISSUES_LIVE_FIXTUREnames a disposable Issue. That variable stayed unset, so the write test never ran: no GitHub write happened.apps/server/src/issueLinks/IssueLinks.carryover.test.ts, the real-data test, which runs only whenCHROMERIA_V1_SNAPSHOT_SOURCEis set.Both files then ran separately with their variables set: 8 live read-only tests passed and the write test stayed skipped; both carryover tests (1 synthetic, 1 real) passed.
Behavior these tests prove:
issueRpcAuthorization.test.ts): an operate-only grant is refused on comment and close withrequiredPermission: source-control:write, before the handler runs. A source-control-only grant reaches both handlers.issueCommandPermissions.test.ts): with operate only,permissionAtomis false andauthorizefails; with source-control only, it is true andauthorizepasses.after: nulland returns the cursor asnextCursors; the continuation makes one request with that cursor.pull-requestscapability is required, a caller from outside a T3 thread is refused, and link, list and unlink act on the caller's own thread.Test rewritten: upstream's
RightPanelTabs.keyboard.test.tsxused the menu label "Linked pull requests" to show that the Mod+T menu had opened. The ported label is "Linked PRs and Issues", so only that string changed. All the keyboard, focus and selection assertions are unchanged, and the file is allowlisted under issues-links.Not verified:
fork/v2. Browser use was not authorized for this port; the focused logic tests above prove the behavior in scope.Elon record
source-control:writeplus the shared pager (D27).ghCLI calls and the v1 projection reads, replaced by upstream's GitHub client and v2 reads; three tests (issueStatus.live,IssueLinks.live,ThreadLinksPanel) not ported.mainhas no Issues feature, and #6315/#16552 are open and unmerged. The v2 database starts as a full copy of v1, and the importer keeps thread ids anddeletedAt. A read-onlyVACUUM INTOsnapshot of real data reads back with exactly equal stored rows after the import and after a repeat. The rewritten GitHub queries pass against real GitHub. Final exact-head proof and CI were inspected on8b7ce7b7c979d1b79271339799dbcac9520a9404; independent review passed and the cost report was published with an explicit attribution gap.Closes #171
Independent review: passed. Final findings: no actionable defect after full diff and consumer review. Prism selected Codex /
gpt-6-luna, effective effortmax. Newestreview/independentstatus issuccesson exact head8b7ce7b7c979d1b79271339799dbcac9520a9404, posted by authenticatedlukemajand independently verified by the dispatcher. The speculative credential finding was withdrawn with installed-source evidence; no hypothetical patch was made. All final code CI jobs pass, including the native fingerprint job that was pending when the reviewer checked. The ready-event size-label metadata job is still running; it does not change the code-proof disposition.Cost: published. Agent Observer report. Cost remains unknown because response usage is not fully attributed; this is a measurement gap, not zero cost.
Coordination: Codex /
gpt-6.1-sol, effective effortmedium, inside T3 Code.Model and harness: Claude Opus 5.5 (
claude-opus-5-5) in Claude Code (claudeAgent, inside T3 Code). Effective effort is unknown because the runtime does not report it.🤖 Generated with Claude Code