Skip to content

fix(orch): read live PR state when Graphite cache is stale - #87

Closed
zeitlinb wants to merge 4 commits into
ericlitman:mainfrom
zeitlinb:codex/orch-graphite-frontier
Closed

zeitlinb wants to merge 4 commits into
ericlitman:mainfrom
zeitlinb:codex/orch-graphite-frontier

Conversation

@zeitlinb

@zeitlinb zeitlinb commented Sep 24, 2026 •

Copy link
Copy Markdown

Closes #86

What changed

Graphite can report cached OPEN state while its background PR refresh is still running, leaving a just-merged PR as the lowest unmerged frontier entry. Keep Graphite for stack order and PR identity, then read current lifecycle state from GitHub using the canonical repository in Graphite's adjacent PR URL. Fork remotes and GH_HOST cannot redirect the lookup. Cached status vocabulary no longer controls live-state resolution.

Missing or mismatched metadata, failed GitHub requests and invalid states preserve the existing frontier. Commit-body PR links are ignored. Branching graphs remain rejected; the playbook explains how to select the intended linear stack.

Verification

  • Bun tests, strict typecheck, static invariants, and plugin validation pass.
  • The exact candidate is installed in every affected harness.
  • The changed behavior passes from each real user surface.
  • The installed version, action, and observed result appear below.

The initial runtime change passed the full 158-test suite, configured and additional strict orch typechecks, static invariants, manifest parsing and Claude plugin validation. After the scoped identity corrections, all 17 orch tests and 88 assertions passed with strict orch typecheck and diff checks. Regression coverage includes stale cache, canonical base repository despite a fork remote, unknown cached status, unrelated commit-body links, and preservation of the prior frontier on identity or GitHub failures.

Live evidence: installed Open Pstack 1.4.0 on Codex desktop exhibited the cache race. The final candidate source CLI, run from the submitted linear-stack worktree, resolved the merged PR as MERGED with no lowest unmerged entry. A branching trunk remained rejected. The exact candidate has not been installed and qualified from both Claude and Codex plugin surfaces, so this PR remains a draft. No merge, tag, release or installed-plugin rollout is requested.

@greptile-apps

greptile-apps Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

The PR is not yet safe to merge because a fork or multiple-remote checkout can resolve PR state from the wrong repository.

Findings

  1. P1 Wrong repository for PR lookup ▶
  2. P2 Cached status still gates lookup ▶
  3. P2 Unbounded serial GitHub lookups ▶

Summary

The PR keeps Graphite as the source of stack order and PR mapping, while reading each PR's current state from GitHub. It documents the linear-stack checkout requirement and adds stale-cache and failure-path tests.

  • Repository inference can make the new lookup read the wrong PR in fork or multiple-remote checkouts.
  • The lookup retains an unnecessary dependency on Graphite's status vocabulary and adds unbounded serial remote calls.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A[frontier set] --> B[Graphite stack order and PR numbers]
  B --> C[GitHub state lookup for each PR]
  C --> D[Lowest open PR]
  D --> E[Atomic frontier write]
Loading

Reviews (1) · Last reviewed commit: "test(orch): preserve frontier on state e..."

try {
raw = execFileSync(
"gh",
["pr", "view", String(pr), "--json", "state", "--jq", ".state"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Wrong repository for PR lookup

If the stacker's checkout has a fork remote or multiple remotes, this gh pr view call has no explicit base repository, so it can look up the PR number in a different repository from the one Graphite used. PR numbers are repository-local: the lookup may read another PR's state or fail, leaving the lowest-unmerged frontier incorrect or unchanged. The PR workflow requires passing the canonical base repository to gh pr commands.

Knowledge Base Used: Poteto-mode automation

);
}
return parseGtPullRequest({ branch, detail: rows[0] ?? "" });
const cached = parseGtPullRequest({ branch, detail: rows[0] ?? "" });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Cached status still gates lookup

This parses and validates Graphite's cached status even though the result uses only its PR number. If Graphite introduces a new status, parsing throws before GitHub can provide the live state, so frontier recomputation stops unnecessarily. Parsing the PR identity independently would avoid tying the new lookup to Graphite's status vocabulary.

Comment on lines +1048 to +1056
raw = execFileSync(
"gh",
["pr", "view", String(pr), "--json", "state", "--jq", ".state"],
{
cwd: repo,
encoding: "utf8",
env: process.env,
stdio: ["ignore", "pipe", "pipe"],
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Unbounded serial GitHub lookups

Frontier recomputation now runs this synchronous remote call once for every branch, with no timeout. On a large stack, slow calls add up, and a hung call can block recomputation indefinitely while the previous frontier remains in place. A time bound and fewer serial requests would limit that cost.

Knowledge Base Used: Poteto-mode automation

@zeitlinb

Copy link
Copy Markdown
Author

Opened in error by an automated agent session without the account owner's approval. Withdrawn — sorry for the noise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Read live PR lifecycle state when Graphite frontier cache is stale

1 participant