Skip to content

feat(#6778): add fullsend inference openai command family - #6779

Merged
waynesun09 merged 5 commits into
mainfrom
agent/6778-inference-openai-commands
Aug 30, 2026
Merged

feat(#6778): add fullsend inference openai command family#6779
waynesun09 merged 5 commits into
mainfrom
agent/6778-inference-openai-commands

Conversation

@fullsend-ai-coder

@fullsend-ai-coder fullsend-ai-coder Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Add three new subcommands under fullsend inference openai for OpenAI Workload Identity Federation enrollment:

  • request <owner/repo>[,...]: generates the provider/mapping
    request document an admin needs, with every value computed from
    the repository names. Supports --format json (versioned schema
    for future API submission) and --format md (copy-paste ticket).
  • import [reply.json]: takes the admin's reply and writes
    inference.openai into .fullsend/config.yaml via the existing
    SetInferenceOpenAI setter, or sets FULLSEND_OPENAI_* repository
    variables with --variables. Enforces the all-three-or-none rule.
  • status <owner/repo>: prints resolved identifiers and their
    source (config.yaml or env vars), flags a partial trio, and
    when inside GitHub Actions performs one exchange reporting scope
    and expiry without printing the token.

The commands need no credentials and do not call the OpenAI API. The JSON request schema is versioned so a future apply command can submit it unchanged when OpenAI exposes an API for providers.

Updates docs/cli/inference.md with the new command reference and adds route-B shortcut pointers in the OpenAI WIF guide.


Closes #6778

Post-script verification

  • Branch is not main/master (agent/6778-inference-openai-commands)
  • Secret scan passed (gitleaks — 35775003b1b177088a3eb6610111986358ed1322..HEAD)
  • PR body secret scan: N/A (commit body path)

Also folds in #6777 (docs)

PR #6777 rewrote the setup half of docs/guides/infrastructure/openai-workload-identity.md while this branch was being written; triage flagged the coordination. It is folded in here and #6777 is closed, because the guide change and these commands are the same piece of work — the commands exist to remove the hand-copying the guide used to describe.

  • Two routes instead of a prerequisite. The guide read as if managing the organization's Workload Identity Provider were required. In most companies an IT administrator owns Organization Settings and the provider, and a team owns (or requests) a project. The setup is now a fork: shared claims check first, then route A (you manage providers: add or reuse one, add the mapping) or route B (send the administrator a request, record the reply), with common steps from "tell fullsend the three identifiers" on.
  • Per-repository trust in both routes. One mapping per company-owned repository — never repository_owner, a wildcard, a prefix or a derived attribute, because a GitHub organization can contain repositories the company does not own. OpenAI mappings are AND-ed exact-value rows and have no list form, so this is also the only shape the console supports.
  • The commands are wired into that structure: route A points at request for the console fields, route B generates its ticket with request --format md (the hand-written template stays for readers who prefer it), B3 records the reply with import and checks it with status, and step 4 keeps a shortcut note.
  • The audience is described as whatever the provider has (any string, used verbatim — fullsend imposes no format), and docs/runtimes/pi.md's "three repository variables" wording is fixed.

Closes #6777.

Add three new subcommands under `fullsend inference openai` for
OpenAI Workload Identity Federation enrollment:

- `request <owner/repo>[,...]`: generates the provider/mapping
  request document an admin needs, with every value computed from
  the repository names. Supports --format json (versioned schema
  for future API submission) and --format md (copy-paste ticket).
- `import [reply.json]`: takes the admin's reply and writes
  inference.openai into .fullsend/config.yaml via the existing
  SetInferenceOpenAI setter, or sets FULLSEND_OPENAI_* repository
  variables with --variables. Enforces the all-three-or-none rule.
- `status <owner/repo>`: prints resolved identifiers and their
  source (config.yaml or env vars), flags a partial trio, and
  when inside GitHub Actions performs one exchange reporting scope
  and expiry without printing the token.

The commands need no credentials and do not call the OpenAI API.
The JSON request schema is versioned so a future `apply` command
can submit it unchanged when OpenAI exposes an API for providers.

Updates docs/cli/inference.md with the new command reference and
adds route-B shortcut pointers in the OpenAI WIF guide.

Closes #6778
@fullsend-ai-coder
fullsend-ai-coder Bot requested a review from a team as a code owner August 30, 2026 16:14
@fullsend-ai-coder fullsend-ai-coder Bot added the ready-for-review Triggers review agent dispatch label Aug 30, 2026
@waynesun09

Copy link
Copy Markdown
Member

/fs-fix-stop

@github-actions github-actions Bot added the fullsend-no-fix Skip bot-triggered fix agent runs label Aug 30, 2026
@github-actions

Copy link
Copy Markdown

Fix agent disabled for this PR. Remove the fullsend-no-fix label or use /fs-fix to re-engage.

Supersedes #6777, which rewrote the operator guide's setup half while
this branch was being written. The guide read as if managing the
organization's identity provider were a prerequisite; in most companies
an IT administrator owns Organization Settings and the GitHub Actions
provider, and a team owns (or requests) a project. It is now an explicit
fork: shared claims check first, then route A (you manage providers) or
route B (send the administrator a request), with common steps from
"tell fullsend the three identifiers" on.

Trust is stated as per repository for both routes: one mapping per
company-owned repository, never a wildcard or a pattern over the
organization, since an organization can contain repositories the company
does not own. Mappings match exact values only and have no list form.

The new commands are wired into that structure rather than bolted onto
the old sections: route A points at `request` for the console fields,
route B generates its ticket with `request --format md` (the hand-written
template stays for readers who prefer it), B3 records the reply with
`import` and checks it with `status`, and step 4 keeps a shortcut note.
Also fixes the pi runtime doc's "three repository variables" wording.

Assisted-by: Claude
Signed-off-by: Wayne Sun <gsun@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 30, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 4:16 PM UTC · Ended 4:16 PM UTC

Commit: e4d22cc · View workflow run →

@github-actions

github-actions Bot commented Aug 30, 2026

Copy link
Copy Markdown

Site preview

Preview: https://40f4728f-site.fullsend-ai.workers.dev

Commit: b8a47ccfbe33d226b4f837e674b7a504ef93ea16

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 30, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 4:18 PM UTC · Ended 4:33 PM UTC

Commit: 0cf11b5 · View workflow run →

@codecov

codecov Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 85.62368% with 68 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/cli/inference_openai.go 85.34% 39 Missing and 29 partials ⚠️

📢 Thoughts on this report? Let us know!

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 30, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 4:35 PM UTC · Ended 4:39 PM UTC

Commit: eaaa663 · View workflow run →

Review findings from Codex (gpt-5.6-sol) and Grok 4.6, which agreed on
the two blocking ones.

import could not read the document request generates. The request JSON
nests the fields an administrator fills under "reply", while import
unmarshalled them from the root, so returning the very file we sent
imported nothing. It now accepts both shapes, and picks the service
account for --repo out of a multi-repository reply instead of silently
importing none — an ambiguous reply says which repositories it names.

status resolved each identifier independently, env or config per field,
while a run takes the trio from one source: any FULLSEND_OPENAI_*
variable means all three come from variables. status could therefore
report a healthy trio, and exchange on it, that a run would refuse. It
now applies the same rule, names the source, and explains the gap.

Also in status: a malformed config is an error rather than "nothing
configured yet"; an exchange is refused when the job's own repository is
not the one being checked, since it could only ever prove that job's
identity; and a token broader than model access fails the way the run
path fails instead of printing "Exchange succeeded".

In request: --ref for repositories whose default branch is not main
(the assertion is exact, so a wrong ref fails every exchange), a guard
against deriving one owner's default audience for another owner's
mapping, duplicate repositories collapsed, an existing --service-account
no longer described as "create inline", the permission list rendered
rather than indexed, and the generated rules now name `sub` too.

import validates the config before writing it, as `github setup` does,
and a partial --variables write says which variables were set.

Docs: the inference command group is no longer described as GCP-only,
the "these commands do not call the OpenAI API" claim is qualified for
status, and the command tree and key-files table in cli-internals cover
the new subcommands.

Assisted-by: Claude (fix), Codex (review), Grok (review)
Signed-off-by: Wayne Sun <gsun@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 30, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 4:40 PM UTC · Completed 5:00 PM UTC

Commit: 14c970b · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $10.93

@fullsend-ai-review fullsend-ai-review Bot added the risk/moderate PR risk: moderate label Aug 30, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 30, 2026

Copy link
Copy Markdown

Risk Assessment: moderate (2/5)

Details

Re-review anchored to prior score. Large but mostly additive feature (new files + docs) from a bot author with good test coverage; elevated line count is offset by additive-only changes and clear acceptance criteria alignment. Only bug-fix changes since prior review; Tier 1 signals unchanged.

Previous run

Risk Assessment: moderate (2/5)

Details

Large but mostly additive feature (new files + docs) from a bot author with good test coverage; elevated line count is offset by additive-only changes and clear acceptance criteria alignment.

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 30, 2026

Copy link
Copy Markdown

Review

Findings

Medium

  • [stale-doc] docs/contributing/documentation.md:62 — The inference cross-reference table lists only internal/cli/inference.go as the Go source and omits the new internal/cli/inference_openai.go file. It also omits docs/guides/infrastructure/openai-workload-identity.md from the Guides row. Both were added by this PR and are already referenced in other documentation files updated here (e.g., docs/guides/dev/cli-internals.md lists the new Go source, and docs/cli/inference.md links to the OpenAI WIF guide).
    Remediation: Update the inference section to add internal/cli/inference_openai.go to the Go source row and docs/guides/infrastructure/openai-workload-identity.md to the Guides row.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run

Review

Findings

Medium

  • [stale-doc] docs/cli/README.md:19 — The CLI overview describes fullsend inference as "Manage GCP Workload Identity Federation for Agent Platform access," which is now incomplete — the command group also covers OpenAI WIF enrollment. The Go help text and docs/cli/inference.md were updated but this overview page was not.
    Remediation: Update the description to match the new scope, e.g., "Manage inference credentials (GCP Vertex WIF, OpenAI WIF)."

  • [stale-doc] docs/guides/getting-started/operations.md:90 — The standalone commands table lists only inference provision, deprovision, and status under the GCP Admin role. The new inference openai request, inference openai import, and inference openai status commands are not listed, even though they are designed for the split-responsibility workflow this table documents.
    Remediation: Add three rows for the new commands under a Developer/Maintainer role (they need neither GCP access nor an OpenAI key).

  • [stale-doc] docs/contributing/documentation.md:62 — The inference cross-reference table lists only internal/cli/inference.go in the Go source row and does not include the new internal/cli/inference_openai.go (833 lines). The Guides row also omits docs/guides/infrastructure/openai-workload-identity.md.
    Remediation: Add internal/cli/inference_openai.go to the Go source row and the OpenAI WIF guide to the Guides row.

Low

  • [edge-case] internal/cli/inference_openai.go:216parseRepoList deduplicates with exact-case map keys (seen[r]), but GitHub repository names are case-insensitive. Passing Acme/Widget,acme/widget produces two identical mappings in the request document. The same case sensitivity applies to serviceAccountFor, where filled[repo] does an exact key lookup. The status command already uses strings.EqualFold for the GITHUB_REPOSITORY comparison.
    Remediation: Normalize repo strings to lowercase after parseOrgOrRepo validation.

  • [error-handling-idiom] internal/cli/inference_openai.go:605runImportVariables returns fmt.Errorf("setting variable %s on %s: %w\n%s", ...) with an embedded newline and raw gh CLI output. While not unprecedented in this package, the more common pattern wraps only the error and logs diagnostics via the printer.
    Remediation: Print gh output via printer.StepInfo before returning, and drop the \n%s from the Errorf call.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

fullsend-ai-review[bot]

This comment was marked as outdated.

Second review pass by Codex (gpt-5.6-sol) against the fixes, which
confirmed five items closed and found four still open.

status announced "Exchange succeeded" and printed the granted scope
before checking it, so a token the run path refuses was reported as a
success and only then rejected. The scope is checked first now, and
nothing is called a success until it passes.

The repository guard failed open: with a valid OIDC endpoint but no
GITHUB_REPOSITORY, the mismatch check was skipped and the exchange ran,
attributing the result to whatever repository was on the command line.
An unknown job repository is now refused like a mismatched one.

status still diverged from the run path in one case: run ignores the
committed inference.openai block when there is no OIDC endpoint and
OPENAI_API_KEY is set (a developer's key is not overridden by the
repository's CI configuration), while status read the block anyway and
named it as the source. It now applies the same rule and says so.

import applied --service-account-id only after the reply document had
already failed on the ambiguity that flag exists to resolve; the flag is
now honoured first. Repository keys — deduplication, the mixed-owner
guard, and reply lookup — compare case-insensitively, as GitHub does.

Docs: the network claim is now a per-command table (request is offline,
import reaches GitHub only with --variables, status exchanges with
OpenAI inside Actions), --ref is documented, --repo's two roles are
spelled out, and the schema comment no longer promises compatibility
with an API OpenAI does not offer.

The guide now states the mapping's real trust boundary — any job in the
repository at the asserted ref that can request an OIDC token, not one
named workflow — so a reader weighing "is it safe to commit these
identifiers" sees that write access to main is the boundary that
matters, and the spend limit is what bounds it.

Tests: the scope path asserts the output carries no success line, the
unknown-repository and static-key cases are pinned, and every status
test now fixes OPENAI_API_KEY as well — one of them passed here only
because of a key in the author's own shell.

Assisted-by: Claude (fix), Codex (review), Grok (review)
Signed-off-by: Wayne Sun <gsun@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 30, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 5:08 PM UTC · Ended 5:24 PM UTC

Commit: 036f8f0 · View workflow run →

Third review pass by Grok 4.6, whose blocking finding was an
architectural one: `import --variables` shelled out to the gh CLI.
docs/contributing/forge-abstraction.md prohibits that outside
internal/forge/github, and forge.Client.CreateOrUpdateRepoVariable is
what `github setup` and `github set` already use. It now goes through
the same client and the same token resolution, so it needs no gh binary
on PATH and reports API errors like every other forge call; the
partial-write warning is kept, and a test fails the second write to
prove it.

Correctness, from the same pass:

- A full request document could lose the audience. An administrator
  reusing an existing provider is told to record its audience in the
  provider block, but import read only the reply section, so it kept the
  audience we had proposed and every exchange then failed the assertion.
  The provider block is now the fallback.
- status exited 0 for an unconfigured repository and for a partial trio
  — the two states a run refuses — so it could not gate a check the way
  the GCP status command does. Both now exit non-zero.
- status met an org-mode config with a generic "nothing configured";
  it now names it as import does (org mode is deprecated, ADR 0044).
- A reply naming several repositories with only one service account
  filled in was treated as unambiguous; filling the second in later
  would then have silently misattributed it. A selector is required
  whenever the reply names more than one repository.
- request now trims its flag values, so a whitespace-only --audience
  cannot slip past the mixed-owner guard into the document.

Docs: the inference group is described accurately in docs/cli/README.md
and the operations command index; --service-account's default column no
longer claims a value the flag does not have; the guide and the CLI
reference both say import writes locally and the file must be committed;
and the schema's long help matches the version constant's comment.

Assisted-by: Claude (fix), Codex (review), Grok (review)
Signed-off-by: Wayne Sun <gsun@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 30, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 5:26 PM UTC · Completed 5:42 PM UTC

Commit: b8a47cc · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $6.91

@fullsend-ai-review fullsend-ai-review 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.

See the review comment for full details.

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approving after three review rounds (Codex on gpt-5.6-sol, Grok 4.6, plus fullsend's own review agent), with every finding either fixed or answered on the thread.

Round 3's blocking finding was architectural and is fixed, not merged over: import --variables shelled out to the gh CLI, which docs/contributing/forge-abstraction.md prohibits outside internal/forge/github. It now uses forge.Client.CreateOrUpdateRepoVariable and the standard token resolution, like github setup; the partial-write warning is kept and covered by a test that fails the second write.

Also fixed in this round: a full request document could lose the audience when an administrator recorded it in the provider block (the shape the guide asks for); status exited 0 for an unconfigured repository and for a partial trio — the two states a run refuses — so it could not gate a check the way the GCP status does; an org-mode config is now named rather than reported as "nothing configured"; and a reply naming several repositories with only one service account filled in now requires a selector instead of being auto-picked.

Earlier rounds closed the round-trip bug (the document request generates is now the document import reads), aligned status's source resolution with resolveOpenAICredential including the static-key case, made the GITHUB_REPOSITORY guard fail closed, checked the token scope before anything is called a success, added --ref, and made repository keys case-insensitive.

The guide now states the mapping's real trust boundary — any job in the repository at the asserted ref that can request an OIDC token, not one named workflow — so a reader weighing "is it safe to commit these identifiers" sees that write access to main is what bounds it.

CI green on b8a47cc; all review threads resolved. Supersedes #6777.

@waynesun09
waynesun09 added this pull request to the merge queue Aug 30, 2026
Merged via the queue into main with commit e90aca9 Aug 30, 2026
62 checks passed
@waynesun09
waynesun09 deleted the agent/6778-inference-openai-commands branch August 30, 2026 17:58
@fullsend-ai-retro

fullsend-ai-retro Bot commented Aug 30, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 6:00 PM UTC · Completed 6:15 PM UTC

Commit: b8a47cc · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $5.71

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #6779fullsend inference openai command family

Timeline

  1. 15:45 UTC — Issue #6778 created by waynesun09 with a detailed spec for three new CLI subcommands.
  2. 15:47–15:53 — Triage agent ran successfully ($0.94, run 33320540474). Provided accurate implementation pointers and test case suggestions.
  3. 15:57/fs-code triggered by waynesun09.
  4. 15:59–16:14 — Code agent ran (run 33321079613, $5.90, 15 min). Produced a comprehensive 2,594-line implementation with 1,367 lines of tests across 9 files.
  5. 16:14 — PR #6779 created.
  6. 16:16–16:32 — waynesun09 pushed two commits folding PR docs(#6689): two setup routes and per-repository trust in the OpenAI WIF guide #6777 docs and fixing round-trip bugs.
  7. 16:16–16:39 — Three review runs cancelled due to new commits being pushed during review.
  8. 16:40–17:00 — First successful review (run 33323045251, $10.93). Found 3 medium stale-doc + 2 low findings. CHANGES_REQUESTED.
  9. 17:00 — waynesun09 disabled fix agent (/fs-fix-stop) to handle fixes manually.
  10. 17:06–17:23 — waynesun09 pushed two fix commits: case-insensitive dedup, and critically, replacing os/exec gh CLI calls with forge.Client.CreateOrUpdateRepoVariable.
  11. 17:23–17:42 — Second successful review (run 33325143756, $6.91). 1 medium stale-doc remaining. CHANGES_REQUESTED.
  12. 17:44 — waynesun09 approved with detailed rationale (three external review rounds: Codex, Grok, fullsend review agent).
  13. 17:58 — PR merged.

Total cost: $24.69 (triage $0.94 + code $5.90 + review $10.93 + $6.91).

What went well

  • Code agent output quality: The code agent produced a working, comprehensive implementation with 1,367 lines of tests in 15 minutes for $5.90. The core implementation was architecturally sound.
  • Review agent found real issues: All 5 review findings were valid. The 3 stale-doc findings caught documentation drift the code agent missed, and both low-severity findings (case-insensitive dedup, error handling) were real code quality issues.
  • Human review added value: waynesun09 independently discovered a forge-abstraction violation that neither the code agent nor review agent caught, and fixed it by replacing os/exec gh CLI calls with forge.Client — a deeper architectural fix than the review agent's surface-level error-handling finding on the same function.
  • Fast turnaround: Issue to merge in ~2 hours with three review rounds and substantial human fixes.

Key gap: forge-abstraction violation

The most significant finding is a forge-abstraction violation the code agent introduced and the review agent missed:

  • The code agent's runImportVariables function shelled out to gh variable set via os/exec to set repository variables, directly violating docs/contributing/forge-abstraction.md.
  • The code agent's transcript shows it found CreateOrUpdateRepoVariable in the forge client and intended to use it, but hit compile errors and fell back to os/exec — misinterpreting the AGENTS.md guidance about preferring go run ./cmd/fullsend as endorsement for shelling out to gh.
  • The review agent found an error-handling-idiom finding on the same function (embedded newline with raw gh output) but missed the root architectural violation. docs/contributing/forge-abstraction.md explicitly says: "When reviewing PRs: Flag any direct exec.Command("gh", ...) outside internal/forge/github/ as a medium-severity or higher finding."
  • waynesun09 caught this independently and fixed it in commit b8a47cc.

Root cause: AGENTS.md lists forge-abstraction.md in a "when to read" table with the trigger phrase "Adding forge operations", but the code agent didn't recognize "setting repository variables" as a forge operation and never followed through to read the document.

Evidence for existing issues

  • #3013 ("Add AGENTS.md guidance: update cross-referenced 'in progress' docs when implementing features"): The code agent missed 3 doc cross-reference updates (CLI README, operations table, documentation.md cross-reference table) that the review agent caught. This is the class of gap Add AGENTS.md guidance: update cross-referenced 'in progress' docs when implementing features #3013 addresses.
  • #6469 ("Expand AGENTS.md doc-update trigger to cover adding new user-facing configuration"): Same category — the code agent updated docs/cli/inference.md and the WIF guide but missed several other documentation touchpoints listed in docs/contributing/documentation.md's cross-reference table.

Note: unfixed finding merged

The review agent's round-2 finding — docs/contributing/documentation.md:62 cross-reference table missing inference_openai.go and the OpenAI WIF guide — was merged unfixed. The human approved acknowledging this gap. This is a minor documentation drift that should be addressed in a follow-up.

Proposals filed

waynesun09 added a commit that referenced this pull request Aug 30, 2026
Codex (gpt-5.6-sol) and Grok 4.6 reviewed the branch; these are the
findings both or either confirmed.

Move the mapping-scope decision out of ADR 0092 into ADR 0095. 0092 is
Accepted, and CONTRIBUTING says an accepted ADR takes cross-references,
not new decisions. 0092 never documented the ref assertion, so this is a
new decision rather than a rewrite of its own; 0092 keeps a pointer.
The new ADR also states the boundary plainly: fullsend's dispatch
authorization governs which runs fullsend starts and does not stand
between a repository workflow and OpenAI's token endpoint.

Refuse an import document whose provider block and reply disagree about
the audience. `request` pre-fills reply.audience, so the provider-block
fallback added in #6779 could never fire, and an administrator who
reused a provider and edited only the provider block had that edit
silently discarded -- recording an audience no mapping asserts, whose
every exchange then fails with a 4xx far from the cause. --audience
stays the way past it.

Render one reply row per repository rather than one per mapping: with
--ref the table asked twice for the same repository's service account,
which reads as two accounts.

Validate --ref as a full ref, and skip the companion mapping when the
value already is refs/pull/*, which produced two identical mappings.
Warn when a document exceeds OpenAI's 50 mappings per provider, since
--ref doubles the count and the excess cannot be installed as written.

Correct three doc claims: cli-internals still documented the old
refs/heads/main default; the guide said only someone who can merge to
the default branch can obtain a token, when a same-repository
pull_request run executes a workflow from the pushed branch; and the
help text and CLI reference said `import --variables` calls GitHub
through gh when it goes through the forge client.

Assisted-by: Claude (fix), Codex (review), Grok (review)
Signed-off-by: Wayne Sun <gsun@redhat.com>
RaphaelBut pushed a commit to RaphaelBut/fullsend that referenced this pull request Sep 4, 2026
…md bullet

Add a top-level bullet point in the "How to work in this repo" section
for the forge-abstraction rule, placed after the Go coverage gate and
before the secrets bullet. The rule was previously discoverable only
via the topic-guidance table, which required agents to recognize that
setting repository variables is a forge operation — a connection the
code agent on PR fullsend-ai#6779 failed to make. Promoting it to an inline
bullet mirrors the pattern used for other critical rules (DCO,
coverage gate, CLI docs) and makes the architectural invariant harder
to miss for both code and review agents.

Closes fullsend-ai#6781
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fullsend-no-fix Skip bot-triggered fix agent runs ready-for-review Triggers review agent dispatch risk/moderate PR risk: moderate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fullsend inference openai: generate the WIF provider/mapping request for admins, import the reply, check the exchange

1 participant