Skip to content

fix(delivery): admit PRs on any-language and fork-headed checkouts - #2173

Merged
ScriptedAlchemy merged 1 commit into
masterfrom
fleet/pr-admission-non-rust
Sep 26, 2026
Merged

ScriptedAlchemy merged 1 commit into
masterfrom
fleet/pr-admission-non-rust

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Fixes #2109

Root cause

Language gate. feedback_document_identity_from_generation in crates/tracedecay-code-index-runtime/src/code_index_scheduler/registry.rs built the project-open feedback cycle's provider seed from the first indexed file with extension rs. It failed with feedback-code-index-rust-document-unavailable when there was none. Both advisory mount paths (the initial mount and the deferred retry) pass no document. So on any checkout without Rust the deferred mount went terminal, the advisory owner never mounted, and pull-request discovery never ran. The explicit cycle answered "not mounted yet" for the daemon's whole life.

Fork lookup. discover_exact_commit_pull_request_v1 used GET /repos/{owner}/{repo}/commits/{sha}/pulls. GitHub answers [] for a fork-headed commit, so a fork PR was never found.

What changed

  • Language gate removed. The seed now takes any indexed document of the ready generation. Readiness is the same generation-ready ladder every other consumer uses; there is no language test on top of it.

  • Compiler provider mounts only for Rust. The cargo compiler publication provider was the one consumer that needed a Rust document, via provider_seed.language == "rust". It now gets its own optional compiler_seed from feedback_language_document_identity_from_generation and mounts only when the generation has a Rust document.

  • Proximity drift check fixed. The proximity check compared the saved document's file against the arbitrary seed file. It now compares generation identity only. A generation is immutable, so an unchanged generation already pins the saved document's identity.

  • Fork discovery. Discovery runs one static GraphQL query: the checkout repository's pull requests with headRefName equal to the local branch. It pins the exact head commit and resolves the head repository from headRepositoryOwner / headRepository. The base repository must equal the checkout's remote; the base repo is no longer assumed to be the head repo. The daemon logs the typed outcome as github_pull_request_discovery: found (with the head repository), not found, ambiguous, rate limited, denied, unavailable, or not attempted (with the source-access state).

  • Typed no-index states. Before a generation mounts the cycle, the explicit advisory cycle names why none can:

    • feedback.advisory-cycle.code-index-disabled for a disabled linked-worktree index;
    • feedback.advisory-cycle.no-indexable-source for a checkout with no indexable source.

    Both are kind unsupported. The retryable warming state keeps its code, with a message that says what it waits for.

Fail before / pass after

Both "before" runs used this branch with only the fix reverted: the .rs seed selection restored in registry.rs, and master's REST commit-pulls scan swapped into the discovery seam.

daemon::production_harness::advisory_cycle_language_journey_test::typescript_only_checkout_runs_the_pull_request_advisory_cycle calls tracedecay_feedback_advisory_cycle over MCP on a TypeScript-only repository. Before:

WARN ... deferred feedback cycle could not mount event="feedback_advisory_mount" outcome="deferred_failed" ... reason=config error: project-open provider code-index identity failed: feedback-code-index-rust-document-unavailable
[tracedecay] event=advisory_deferred_attempt ... phase=classified_failure attempt=terminal
panicked at .../advisory_cycle_language_journey_test.rs:64:9:
the advisory cycle never mounted on a TypeScript-only checkout: {... "code":"feedback.advisory-cycle.unavailable", ...}
test result: FAILED. 0 passed; 1 failed

After: ok. The cycle returns an evidence outcome with providers git_hub_review, ci_localization, proximity.

advisory::github_runtime::discovery::tests::fork_headed_pull_request_is_found_with_its_head_repository replays GitHub's cached answers for dtolnay/anyhow#463 (fixture advisory/fixtures/fork_head_pull_request.json). Before:

assertion `left == right` failed
  left: NotFound
 right: Found(GitHubExactCommitPullRequestV1 { target: GitHubRepositoryTargetV1 { owner: "dtolnay", repository: "anyhow", pull_request_number: 463, pull_request_id: GitHubPullRequestIdV1("4597599038") }, head_repository_owner: "sb123sb123", head_repository_name: "anyhow", ... })

After: ok. The same test also asserts that a local head the PR no longer points at stays NotFound.

New typed state: checkout_without_indexable_source_names_why_the_advisory_cycle_cannot_run asserts kind unsupported, code feedback.advisory-cycle.no-indexable-source, and legal action reconcile. On master the same call answers "not mounted yet".

Runtime journey

Built binary tracedecay 1.0.0-beta.53+0bd85ef1fe (debug, --features production). The daemon ran under systemd-run --user --scope -p MemoryMax=6G -p MemorySwapMax=1G with an isolated HOME, TRACEDECAY_DATA_DIR and XDG_*. The profile config.toml registers [[github_review_sources]] rust-lang/log access="public".

$ git -C log log --oneline -1          # rust-lang/log at PR #741's head, branch ci/msrv-build-vs-test
1a4b67c remove win32 build target
$ tracedecay init
initialized .../log; daemon code-index reconciliation requested
$ tracedecay status
Reconciled 26s ago  Sealed 29s ago  fresh   Branch: ci/msrv-build-vs-test
Symbols 1,087 │ Edges 1,256 │ Source 273.5 KB
daemon: event="github_pull_request_discovery" outcome="not_attempted" source_access=Denied
$ tracedecay tool configuration_protected_apply (bind_source git_hub rust-lang/log)
outcome: effect
# daemon restart
daemon: event="github_pull_request_discovery" outcome="found" pull_request=741 head_repository=rust-lang/log
daemon: event="feedback_advisory_mount" outcome="mounted" deferred=true
$ tracedecay tool feedback_advisory_cycle --document-uri file://.../src/lib.rs
attempt 1: evidence
advisory_provider_states: git_hub_review unavailable, ci_localization supported_completed_complete, proximity unavailable
$ tracedecay tool pr_context --base-ref master
base_oid: 8034743dd9d7…  head_oid: 1a4b67cfc412…  merge_base: 8034743dd9d7…  files_changed: 1
changes: .github/workflows/main.yml modified
commits: 1a4b67c remove win32 build target; 0eb3a1a split MSRV used to build from MSRV used to test

Discovery now admits PR #741 and the advisory owner mounts with it. The Delivery pull_requests lane and the dashboard Journey view still read not_published, for a separate reason, filed as #2158. The GraphQL review-thread read returns 200, then the decoder drops the whole PR ingest: one comment body starting Nit: ... is sniffed as YAML and quarantined by the provider-metadata sanitizer. The GitHub source binding the journey had to add by hand, and the preview/apply ordering mismatch hit while adding it, are filed as #2159.

Checks

  • cargo test -p tracedecay-application --lib: 470 passed.
  • cargo test -p tracedecay -p tracedecay-code-index-runtime --lib -- production_harness project_open_owners feedback_identity advisory feedback_impact: 34 + 1 passed before the rebase.
    • After the rebase, the full batch hit four harness failures ("code index did not publish after 20001 ms", with 15 compositions waiting on a loaded host). All four pass when run alone.
    • After the final rebase, the focused rerun passed: 14 + 16 + 1.
  • cargo clippy -p tracedecay-code-index-runtime -p tracedecay-application -p tracedecay --all-targets -- -D warnings: clean.
  • cargo fmt --all -- --check: clean.

The project-open feedback cycle minted its provider seed from the first
indexed `.rs` file, so every checkout without Rust failed its advisory
mount with `feedback-code-index-rust-document-unavailable` and never
reached pull-request discovery. The seed now takes any indexed document
of the ready generation; only the cargo compiler publication provider
still asks for a Rust document, and mounts only when one exists. The
proximity drift check compares generation identity, which already pins
the saved document, instead of the arbitrary seed file.

Pull-request discovery used GitHub's commit-associated REST route, which
answers `[]` for fork heads. It now queries the checkout repository's
pull requests by head ref through GraphQL, pins the exact head commit,
and resolves the head repository from `headRepositoryOwner` /
`headRepository`. The daemon logs the typed discovery outcome.

Before a generation mounts the cycle, the explicit advisory cycle names
why none can: a disabled linked-worktree index or a checkout with no
indexable source is a typed `unsupported` state, not "not mounted yet".
@changeset-bot

changeset-bot Bot commented Sep 26, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 2823d1f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-26T06:07:41.455460Z 2823d1f PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ScriptedAlchemy
ScriptedAlchemy merged commit 1016f47 into master Sep 26, 2026
1 check passed
@ScriptedAlchemy
ScriptedAlchemy deleted the fleet/pr-admission-non-rust branch September 26, 2026 06:03

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2823d1f999

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +293 to +295
if let Some(authorization) = authorization.as_ref() {
post = post.header("Authorization", authorization.as_str());
}

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 Badge Keep public discovery working without a gh login

When a public repository has no registered credential and gh is absent or unauthenticated, public_repository_read_credential_v1 intentionally returns an anonymous credential, so this request omits Authorization; GitHub's GraphQL endpoint rejects anonymous requests, as the new function documentation itself notes, and discovery always returns Denied, preventing the GitHub advisory owner from mounting. The previous REST discovery route supported anonymous public reads, while the fixture server incorrectly accepts this unauthenticated GraphQL request; retain an anonymous-capable fallback or require a real authenticated credential before selecting GraphQL.

AGENTS.md reference: AGENTS.md:L167-L169

Useful? React with 👍 / 👎.

Comment on lines +2324 to +2328
discover_exact_commit_pull_request_v1(
&owner,
&repository,
&head_ref_name,
&head_commit_id,

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 Badge Resolve the base repository before querying fork PRs

In the common fork-clone setup where remote.origin.url is the contributor's fork, owner and repository here identify that fork, but repository.pullRequests lists PRs filed against that repository rather than outgoing PRs filed against the upstream project. Consequently the upstream fork-headed PR is never returned. The added fixture bypasses production remote resolution by supplying dtolnay/anyhow directly, so it does not cover this journey; discovery must resolve or search the PR's base repository instead of assuming origin is the base.

AGENTS.md reference: AGENTS.md:L167-L169

Useful? React with 👍 / 👎.

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.

fix(delivery): feedback cycle mounts only for repos with a Rust file

1 participant