Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
bee81f1
docs: checkpoint dispatch fallback discovery
khaliqgant Aug 8, 2026
b9bb454
fix: fall back to GitHub API for stale issue projection
khaliqgant Aug 8, 2026
848b210
fix: allow targeted fallback past stale projection preflight
khaliqgant Aug 8, 2026
886327a
fix: use direct GitHub API for stale projection
khaliqgant Aug 8, 2026
733e63f
docs: record fallback red checks
khaliqgant Aug 8, 2026
ef88320
fix: scope provider fallback to stale targeted issues
khaliqgant Aug 8, 2026
cff7303
fix: ignore pull requests during issue fallback
khaliqgant Aug 8, 2026
e350588
docs: record Relayfile PR permission blocker
khaliqgant Aug 8, 2026
1cef8c3
fix: validate qualified GitHub issue selectors against every configur…
Aug 9, 2026
3eb01ca
fix: stop treating unauthenticated 404s as authoritative GitHub issue…
Aug 9, 2026
0d3bda6
fix: short-circuit the issue-level GET when a repo is confirmed private
Aug 9, 2026
fccdfe6
fix: resolve a qualified label selector routed outside repos.org
Aug 9, 2026
39a7d33
fix: stop posting issueResolution.detail to public GitHub issue comments
Aug 9, 2026
6836c23
fix: restore restart-lost fallback eligibility and bound the eligibil…
Aug 9, 2026
07b2a25
fix: rename a test whose title contradicted its own assertions
Aug 9, 2026
48def31
fix: normalize qualified GitHub issue selectors through one canonical…
Aug 9, 2026
793f252
fix: derive GitHub API fallback eligibility instead of registering it…
Aug 9, 2026
f6512a1
fix: stop the round-4 red check from passing on a pre-restart retry race
Aug 9, 2026
91add5f
fix: widen GitHub API fallback eligibility derivation to durable clar…
Aug 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .agent-notes/factory-dispatch-unblock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Factory dispatch API fallback lane

## 2026-08-08 discovery

- Branch: `agent/factory-dispatch-api-fallback`, created from `origin/main` at `33cda42` (Factory PR #220 merge).
- The shared Factory checkout was not edited; it contains unrelated untracked files.
- Veto MCP methods requested by the workspace instructions are not exposed in this session.
- Current targeted resolution is projection-only: `runFactoryCommand` calls `readIssueArg`, which calls `findIssuePath`; GitHub resolution tries canonical repo-scoped paths, then lists configured Relayfile GitHub issue roots, and throws on zero matches before triage can run.
- The resolved mounted record is parsed by `parseGithubFactoryIssue`; `Factory.dispatch` then re-reads the same projection path and applies the existing scope, readiness, dispatchability, and repo-label routing gates.
- PR #220's `localMountDegraded` and daemon `eventListener` values are currently only assembled for `factory status`; targeted issue resolution does not consult or report them.
- Planned seam: a read-only, Relayfile-workspace-token GitHub API client on `MountClient`, projection-first targeted lookup, an authoritative provider lookup only after zero projection matches, explicit source/health metadata on triage and dispatch records, and provider re-read during dispatch safety validation.

## Constraints retained

- No queue, Cloudflare, mount, daemon, or launchd mutations.
- No `gh` process for the fallback.
- No merge and no default-branch push.

## 2026-08-08 implementation checkpoint

- Added `RelayfileGithubConnectionRead`, which calls the Cloud GitHub GraphQL read route through `WorkspaceHandle.requestJson`; the SDK supplies the Relayfile workspace token and Factory never handles a GitHub token.
- Added `integration:github:read` to Factory's requested Relayfile workspace scopes.
- Targeted GitHub resolution now checks the Relayfile projection first, calls the API only after zero matches, and treats an authoritative empty API result as not found.
- Triage and dispatch results carry `issueResolution`; fallback records also include PR #220's `localMountDegraded`, `localMountDegradedReason`, and `eventListener` state.
- Dispatch re-reads a fallback issue through the provider before applying the existing scope/readiness/dispatchability/repo-label gates.
- Focused build/tests: exit 0; 153 tests passed across the new connection reader, mount client, and CLI suites.
- Live preflight exposed a necessary unblock: the connected GitHub projection currently reports `degraded, complete`, and the old preflight rejected the command before resolution. Targeted triage/dispatch now proceeds only when the SDK GitHub read seam exists; missing connections and run-loop/canary flows retain the existing preflight. The command prints a warning and still checks the projection first.
- Updated focused build/tests: exit 0; 154 tests passed.

## 2026-08-08 live correction

- The connection-backed GraphQL attempt reached Cloud but exited 1 `Forbidden`: that route additionally requires a deployed sponsor persona, which the local Factory workspace join is not. Replaced it with a read-only direct GitHub REST client; GitHub writes remain on Relayfile app-authored writeback.
- Fallback eligibility now uses PR #220's health facts: a degraded local mount or listener state other than `subscribed`/`polling` means the projection cannot answer. A healthy projection miss fails without calling GitHub.
- Added configured `repo#number` and `owner/repo#number` selectors so a targeted fallback performs one authoritative lookup and avoids ambiguous org-wide probes.
- Live `factory triage factory#222` reached the empty projection, reported the listener `unknown`, resolved via `github-api-fallback`, and routed to `AgentWorkforce/factory`. It emitted its successful decision; the existing one-shot shutdown path remained open until SIGINT, then returned 0. The shutdown hang is separate from issue resolution.

## 2026-08-08 verification

- Live CLI through `runFleetCli` with a no-op reporter: `factory#222` exit 0, source `github-api-fallback`, projection `no-match`, routed only to `AgentWorkforce/factory`; `factory#999999` exit 1, no decision emitted.
- Focused build and three-suite check: exit 0; 157 tests passed.
- Projection-preference mutation check: forced projection hits past the preferred branch; targeted test exited 1. Restored source; same check exited 0.
- Safety mutation check: made the intentionally unsafe fallback fixture satisfy the existing GitHub label/title markers; targeted rejection test exited 1. Restored unsafe fixture; same check exited 0.
- Default-timeout full suite: exit 1; 1,461 passed and six timing-sensitive tests failed. Rerun of the three affected non-orchestrator files with a 20-second ceiling exited 0 (65 tests). One pre-existing heartbeat timing assertion still exits 1 even in isolation (`600 < 500`); the other affected orchestrator test passed in isolation.
- Manual diff review caught an over-broad orchestrator read fallback. It is now scoped to issue identities explicitly resolved by the targeted fallback, so ordinary healthy ingestion misses never call GitHub. The existing integration connection status is also included in the projection-health record and can independently prove a connected-but-not-ready projection cannot answer.
- Final focused build/check after that correction: exit 0; 158 tests passed. Live `factory#222` remained exit 0 through the fallback and routed only to Factory.
- A bare-number live check exposed GitHub's REST issues endpoint returning PRs. Those are now authoritative issue misses instead of malformed records. After the correction, live `factory triage 222` exited 0 and selected/routed `AgentWorkforce/factory` through the fallback.
- Live safety and dispatch checks: dry-run dispatch of an existing issue missing both Factory markers exited 1 with no dispatch; dry-run dispatch of `factory#222` exited 0 and carried `github-api-fallback` in both the result and its dispatch comment.

## 2026-08-08 PR publication blocker

- The implementation branch is pushed to `origin/agent/factory-dispatch-api-fallback`; no default branch was pushed or merged.
- PR publication was attempted only through `RelayfileGithubConnectionWrite`, whose draft explicitly requests `author: 'app'`. No `gh` command or alternate GitHub identity was used.
- The guarded Relayfile draft writes were accepted, but all three durable operations failed before a provider attempt (`attemptCount: 0`) with GitHub HTTP 403 resource-access semantics. A direct readback of the minted Relayfile token confirmed that its normalized grants include scoped write access to `/github/**`, so the remaining denial is at the GitHub App repository/permission boundary.
- A read-only GitHub API check confirmed that zero open pull requests exist for the pushed head branch. Repeating the same write cannot satisfy the gate until the app permission/install state changes.
Loading