Skip to content

ci(#6815): migrate behaviour tests to single-org ephemeral repos - #6820

Open
fullsend-ai-coder[bot] wants to merge 1 commit into
mainfrom
agent/6815-single-org-ephemeral-repos
Open

ci(#6815): migrate behaviour tests to single-org ephemeral repos#6820
fullsend-ai-coder[bot] wants to merge 1 commit into
mainfrom
agent/6815-single-org-ephemeral-repos

Conversation

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor

Replace the 12-org halfsend pool with a single fullsend-ai-test org using per-scenario ephemeral repos (bt-{uuid}-{slot}). This eliminates token exhaustion (#6702) and permission propagation races (#6701) that were artifacts of the pool model.

Key changes:

  • composedDriver generates unique bt-{uuid8}-{slot} repo names and
    deletes repos on deallocation (unless E2E_KEEP_REPOS=true)
  • New RunReposInstall in common/setup.go for --fullsend-ref installs
  • repoEnsurer gains fullsendRef field; when set, uses repos install
    --fullsend-ref instead of github setup --vendor
  • ValidatePerRepoPostInstallRefPinned skips vendored binary checks
  • suite_test.go uses BehaviourTestOrg constant instead of AcquireOrg
  • envFullsendRef() reads BEHAVIOUR_FULLSEND_REF / GITHUB_HEAD_REF /
    GITHUB_REF_NAME for ref-pinned install path
  • Documentation updated to reflect single-org ephemeral model

Note: pre-commit hooks could not run (network-restricted sandbox). gofmt, go vet, trailing-whitespace, and lychee link checks passed via direct execution.


Closes #6815

Post-script verification

  • Branch is not main/master (agent/6815-single-org-ephemeral-repos)
  • Secret scan passed (gitleaks — 1ac1750a661c6ccc170267c8b3919d2597cf7810..HEAD)
  • PR body secret scan: N/A (commit body path)

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown

Site preview

Preview: https://b45b4b73-site.fullsend-ai.workers.dev

Commit: 7c13e964a4e38ce5066f6a0fbd378e431fa96bec

@codecov

codecov Bot commented Aug 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 31, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:39 PM UTC · Completed 8:00 PM UTC

Commit: 28b2b91 · View workflow run →

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

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

fullsend-ai-review Bot commented Aug 31, 2026

Copy link
Copy Markdown

Risk Assessment: elevated (3/5)

Details

Tier 1 signals unchanged from prior assessment: large blast radius (22 files, 722 lines, score 5), CI workflow edit on protected path (score 4), bot author; Tier 2 confirms high fix density and churn across e2e infrastructure files; Tier 3 mitigates — well-scoped type/chore with no production code impact, resolving known token-exhaustion and permission-race issues (#6702, #6701).

Previous run

Risk Assessment: elevated (3/5)

Details

Tier 1 signals unchanged from prior assessment: large blast radius (score 5) across 22 files, CI workflow change (score 4), protected path edit (score 3). Tier 2 confirms high fix/revert density and active churn. Tier 3 remains low — well-scoped test-infrastructure chore with no production impact.

Previous run (2)

Risk Assessment: elevated (3/5)

Details

Score holds at 3 (elevated), unchanged from prior assessment. Tier 1 signals are identical: large blast radius (score 5) across 21 files in the install driver package, CI workflow change (score 4), and protected path edit (score 3). Tier 2 reinforces elevation with high fix/revert density (avg 7.9 commits/file in 90d, score 5) and active churn (avg 7.67 commits/file in 30d). Tier 3 remains low (1.5) — the change is well-scoped to its issue, test-infrastructure-only, and safely revertible.

Previous run (3)

Risk Assessment: elevated (3/5)

Details

Score holds at 3 (elevated), unchanged from prior assessment. PR is now 20 files / ~700 lines. Core risk drivers persist: large blast radius (score 5) across the install driver package, CI workflow change (score 4) to e2e.yml, and high Tier 2 churn in key files (ensure.go, e2e.yml, suite_test.go). Tier 3 remains low because the change is well-scoped to its issue, test-infrastructure-only, and safely revertible.

Previous run (4)

Risk Assessment: elevated (3/5)

Details

Score holds at 3 (elevated) after re-review. PR narrowed modestly from 21 to 19 files and 758 to 688 lines, but the core risk drivers persist: large blast radius (score 5) across the install driver package, CI workflow change (score 4) to e2e.yml, and exceptionally high Tier 2 churn — key files like ensure.go (10 fix commits), e2e.yml (24 fix commits), and suite_test.go (9 fix commits) indicate an actively unstable area. Tier 3 is low (1.67) because the change is well-scoped to its issue, test-infrastructure-only, and safely revertible.

Previous run (5)

Risk Assessment: elevated (3/5)

Details

Score remains 3 (elevated) despite significant PR narrowing (51 to 21 files, 2155 to 758 lines, 4 to 1 protected paths). Large blast radius (score 5), CI workflow change (score 4), and high Tier 2 churn (fix/revert counts of 10-26 across key files) keep the composite at elevated. Test infrastructure scope and good issue alignment provide Tier 3 mitigation.

Previous run (6)

Risk Assessment: elevated (3/5)

Details

Re-review anchoring: only 2 doc files changed since prior review and all Tier 1 signals remain unchanged (51 files, 2155 lines, large blast radius, 4 protected paths, CI workflows changed). Prior score of 3 (elevated) preserved per anchoring policy. Underlying risk driven by size exceeding 50-file and 2000-line thresholds, four protected path changes, and high recent churn/regression density in the touched files. Mitigated by bot authorship, no security-sensitive files, net code deletion, and strong alignment with issue acceptance criteria. Score unchanged from prior assessment.

Previous run (7)

Risk Assessment: elevated (3/5)

Details

Large refactoring PR (51 files, 2141 lines, net -705) migrating behaviour tests from 12-org pool to single-org ephemeral repos. Elevated risk driven by size (exceeds 50-file and 2000-line thresholds), four protected path changes (CI workflows, scaffold templates), and high recent churn/regression density in the touched files. Mitigated by bot authorship, no security-sensitive files, net code deletion, and strong alignment with issue acceptance criteria. Score unchanged from prior assessment.

Previous run (8)

Risk Assessment: elevated (3/5)

Details

Score increased from 2 to 3: PR grew from 19 files/609 lines to 50 files/2134 lines with production code changes (FetchURL retry removal, dispatch routing, pipeline schedule removal). Four protected paths and CI workflows changed.

Previous run (9)

Risk Assessment: moderate (2/5)

Details

Medium-sized PR (19 files, 609 lines) confined to behaviour test infrastructure, documentation, and e2e helpers with no production code impact. Git history shows moderate churn in the behaviourtest/drivers/install package. Issue scope aligns well with the PR and rollback is straightforward. Consistent with prior assessment.

Previous run (10)

Risk Assessment: moderate (2/5)

Details

Medium-sized PR (19 files, 576 lines) confined to behaviour test infrastructure, documentation, and e2e helpers with no production code impact. Git history shows moderate churn in the behaviourtest/drivers/install package. Issue scope aligns well with the PR and rollback is straightforward. Consistent with prior assessment.

Previous run (11)

Risk Assessment: moderate (2/5)

Details

Medium-sized PR (17 files, 518 lines) confined to test infrastructure and documentation with no production code impact. High recent fix/revert churn in the change area elevates the git-history regression dimension, but the Tier 2 composite remains moderate due to low code-age, revert-frequency, and sentiment scores. Issue scope aligns well with the PR and rollback is straightforward, keeping the overall risk at moderate.

Previous run (12)

Risk Assessment: moderate (2/5)

Details

Medium-sized PR (14 files, 483 lines) confined to test infrastructure and documentation with no production code impact. High recent churn in the change area elevates git-history risk, but issue scope aligns well with the PR and rollback is straightforward.

Previous run (13)

Risk Assessment: moderate (2/5)

Details

Medium-sized PR (11 files, 304 lines) confined to test infrastructure and documentation with no production code impact. High recent churn in the change area elevates git-history risk, but issue scope aligns well with the PR and rollback is straightforward.

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 31, 2026

Copy link
Copy Markdown

Review

Findings

Medium

Low

  • [edge-case] pkg/behaviourtest/drivers/install/composed.go — The UUID prefix is truncated to 4 hex characters (uuid.New().String()[:4]), yielding 65,536 distinct values. Under the birthday paradox, 50 concurrent CI runs in the same org have a ~1.9% collision probability. A collision means two runs generate identical bt-XXXX-NN repo names, so resetRepo in one run could destroy the other's active test repo mid-scenario.

  • [edge-case] pkg/behaviourtest/drivers/install/composed.goFinalize reclaims outstanding leases by returning names to the pool channel but does not call DeleteRepo or InvalidateCache for the leaked repos. With ephemeral bt-{uuid}-{slot} naming, orphaned repos won't collide with future runs but will accumulate in the fullsend-ai-test org until manually cleaned up.

  • [error-handling] pkg/behaviourtest/drivers/install/composed.goDeallocateRepo logs fork and repo deletion failures as warnings but does not return an error to the caller. The ensurer's resetRepo step provides self-healing by deleting existing repos before creation, but persistent API failures would leave repos accumulating.

  • [edge-case] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.goenvFullsendRef falls back through BEHAVIOUR_FULLSEND_REF \u2192 event payload SHA \u2192 GITHUB_HEAD_REF \u2192 GITHUB_REF_NAME. The GITHUB_HEAD_REF fallback can yield branch names with slashes (e.g., agent/xxx) rejected by IsValidRef. In CI this is mitigated by the explicit BEHAVIOUR_FULLSEND_REF set in the workflow.

  • [authorization-scope] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go:67 — CF preview mint's perRepoWIFRepos and workflowHostRepos changed from explicit repo list to wildcard *. Mitigations: (1) preview mint is ephemeral per CI run, (2) isolated from production, (3) OIDC audience scoping, (4) randomized alias. Functionally necessary for dynamically generated repo names.

  • [pattern-inconsistency] pkg/behaviourtest/drivers/install/composed.gonewComposedDriver reads os.Getenv("E2E_KEEP_REPOS") directly at construction time. Other env vars in the package (envPoolSize, envFullsendRef, envSuiteName, envAppSet) are read in factory/top-level functions and passed as parameters.

  • [pattern-inconsistency] pkg/behaviourtest/drivers/install/ensure.gonewRepoEnsurerWithRef duplicates the body of newRepoEnsurer, differing only in the fullsendRef field being set.

  • [pattern-inconsistency] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go — The envFullsendRef() \u2192 ensurer-selection branching is duplicated verbatim in buildCFMintDriver and NewRepoPoolExternalMint.

  • [code-organization] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.goenvFullsendRef() and prHeadSHAFromEvent() are defined in the cfmint-specific file but consumed by both factory functions across files.

Previous run

Review

Findings

Medium

  • [protected-path] .github/workflows/e2e.yml — This PR modifies a file under the .github/ protected path. The PR links to issue e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815 and the change adds BEHAVIOUR_FULLSEND_REF for ref-pinned installs in the behaviour test job. Human approval is always required for protected-path changes, regardless of context.

  • [docs-currency] docs/guides/dev/behaviour-testing.md — The Runner env code block does not include BEHAVIOUR_FULLSEND_REF, a new env var introduced in this PR (set in .github/workflows/e2e.yml and consumed by envFullsendRef() in the install driver). The prose section documents it but the canonical env reference table omits it.
    Remediation: Add BEHAVIOUR_FULLSEND_REF=... with a comment to the runner env code block alongside the other BEHAVIOUR_* variables.

Low

  • [edge-case] pkg/behaviourtest/drivers/install/composed.goFinalize reclaims outstanding leases by returning names to the pool channel but does not call DeleteRepo or InvalidateCache for the leaked repos. With ephemeral bt-{uuid}-{slot} naming, orphaned repos won't collide with future runs but will accumulate in the fullsend-ai-test org until manually cleaned up.

  • [error-handling] pkg/behaviourtest/drivers/install/composed.goDeallocateRepo logs fork and repo deletion failures as warnings but does not return an error to the caller. The ensurer's resetRepo step provides self-healing by deleting existing repos before creation, but persistent API failures would leave repos accumulating.

  • [edge-case] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.goenvFullsendRef falls back through BEHAVIOUR_FULLSEND_REF → event payload SHA → GITHUB_HEAD_REFGITHUB_REF_NAME. The GITHUB_HEAD_REF fallback can yield branch names with slashes (e.g., agent/xxx) rejected by IsValidRef. In CI this is mitigated by the explicit BEHAVIOUR_FULLSEND_REF set in the workflow.

  • [authorization-scope] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go:67 — CF preview mint's perRepoWIFRepos and workflowHostRepos changed from explicit repo list to wildcard *. Mitigations: (1) preview mint is ephemeral per CI run, (2) isolated from production, (3) OIDC audience scoping, (4) randomized alias. Functionally necessary for dynamically generated repo names.

  • [environment-coupling] pkg/behaviourtest/drivers/install/composed.gonewComposedDriver reads os.Getenv("E2E_KEEP_REPOS") directly at construction time. Other env vars in the package (envPoolSize, envFullsendRef, envSuiteName, envAppSet) are read in factory/top-level functions and passed as parameters.

  • [naming-coherence] pkg/behaviourtest/drivers/install/composed.go — The prefix parameter defaults to a 4-character UUID prefix (uuid.New().String()[:4]) when empty. Documentation references bt-{uuid}-{slot} with examples using 8 hex chars (e.g., bt-a1b2c3d4-01), but only 4 hex chars are generated. With 65,536 possibilities, concurrent CI collision probability is negligible.

  • [docs-currency] docs/guides/dev/behaviour-testing.md — The Runner env code block does not include E2E_KEEP_REPOS, a new env var introduced in this PR that preserves ephemeral repos for debugging. The PR documents it in prose but omits it from the env table.
    Remediation: Add E2E_KEEP_REPOS=false with a comment to the runner env code block.

  • [docs-currency] docs/guides/dev/behaviour-drivers.md:27 — The Runner configuration env block does not include BEHAVIOUR_FULLSEND_REF, a new env var introduced in this PR that controls the install path.
    Remediation: Add BEHAVIOUR_FULLSEND_REF=... to the env block in the Runner configuration section.


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 (2)

Review

Findings

Medium

Low

  • [edge-case] pkg/behaviourtest/drivers/install/composed.goFinalize reclaims outstanding leases by returning names to the pool channel but does not call DeleteRepo or InvalidateCache for the leaked repos. With ephemeral bt-{uuid}-{slot} naming, orphaned repos won't collide with future runs but will accumulate in the fullsend-ai-test org until manually cleaned up.

  • [error-handling] pkg/behaviourtest/drivers/install/composed.goDeallocateRepo logs fork and repo deletion failures as warnings but does not return an error to the caller. The ensurer's resetRepo step provides self-healing by deleting existing repos before creation, but persistent API failures would leave repos accumulating.

  • [edge-case] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.goenvFullsendRef falls back through BEHAVIOUR_FULLSEND_REF → event payload SHA → GITHUB_HEAD_REFGITHUB_REF_NAME. The GITHUB_HEAD_REF fallback can yield branch names with slashes (e.g., agent/xxx) rejected by IsValidRef. In CI this is mitigated by the explicit BEHAVIOUR_FULLSEND_REF set in the workflow.

  • [authorization-scope] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go:67 — CF preview mint's perRepoWIFRepos and workflowHostRepos changed from explicit repo list to wildcard "*". Mitigations: (1) preview mint is ephemeral per CI run, (2) isolated from production, (3) OIDC audience scoping, (4) randomized alias. Functionally necessary for dynamically generated repo names.

  • [environment-coupling] pkg/behaviourtest/drivers/install/composed.gonewComposedDriver reads os.Getenv("E2E_KEEP_REPOS") directly at construction time. Other env vars in the package (envPoolSize, envFullsendRef, envSuiteName, envAppSet) are read in factory/top-level functions and passed as parameters.

  • [naming-consistency] pkg/behaviourtest/drivers/install/composed.go — The prefix parameter defaults to a 4-character UUID prefix (uuid.New().String()[:4]) when empty. Documentation references bt-{uuid}-{slot} which is a shorthand notation. With 65,536 possibilities, concurrent CI collision probability is negligible (~256 concurrent runs needed for 50% collision), but the truncation could be documented more explicitly.

Previous run (3)

Review

Findings

Medium

Low

  • [edge-case] pkg/behaviourtest/drivers/install/composed.goFinalize reclaims outstanding leases by returning names to the pool channel but does not call DeleteRepo or InvalidateCache for the leaked repos. With ephemeral bt-{uuid}-{slot} naming, orphaned repos won't collide with future runs but will accumulate in the fullsend-ai-test org until manually cleaned up.

  • [error-handling] pkg/behaviourtest/drivers/install/composed.goDeallocateRepo logs fork and repo deletion failures as warnings but does not return an error to the caller. The ensurer's resetRepo step provides self-healing by deleting existing repos before creation, but persistent API failures would leave repos accumulating.

  • [edge-case] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.goenvFullsendRef falls back through BEHAVIOUR_FULLSEND_REF → event payload SHA → GITHUB_HEAD_REFGITHUB_REF_NAME. The GITHUB_HEAD_REF fallback can yield branch names with slashes (e.g., agent/xxx) rejected by IsValidRef. In CI this is mitigated by the explicit BEHAVIOUR_FULLSEND_REF set in the workflow.

  • [authorization-scope] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go:67 — CF preview mint's perRepoWIFRepos and workflowHostRepos changed from explicit repo list to wildcard "*". Mitigations: (1) preview mint is ephemeral per CI run, (2) isolated from production, (3) OIDC audience scoping, (4) randomized alias. Functionally necessary for dynamically generated repo names.

  • [scope-exceeds-authorization] pkg/behaviourtest/drivers/install/common/setup.go — The PR changes ~13 Go files vs issue e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815's ~5 file estimate. All additions (RunReposInstall, envFullsendRef, ValidatePerRepoPostInstallRefPinned, InvalidateCache, E2E_KEEP_REPOS) are integral to making ephemeral repos viable — no scope creep into unrelated subsystems.

  • [stale-doc] docs/runtimes/pi.md:51 — References "pool repositories" for OpenAI organization mapping. The corresponding reference in docs/guides/dev/behaviour-testing.md was updated to "test org repositories" in this PR, but pi.md was not.
    Remediation: Replace "the pool repositories" with "the test org repositories."

  • [environment-coupling] pkg/behaviourtest/drivers/install/composed.gonewComposedDriver reads os.Getenv("E2E_KEEP_REPOS") directly at construction time. Other env vars in the package (envPoolSize, envFullsendRef, envSuiteName, envAppSet) are read in factory/top-level functions and passed as parameters.

  • [unchecked-type-assertion] pkg/behaviourtest/drivers/install/validate.go — Pre-existing: ValidatePerRepoPostInstall uses an unchecked type assertion cfgW.(config.PerRepoConfigReader) that could panic, while the new ValidatePerRepoPostInstallRefPinned correctly uses a checked assertion. The inconsistency was highlighted by this PR introducing the safer pattern.

Previous run (4)

Review

Findings

High

  • [stale-doc] docs/ADRs/0066-behaviour-tests-with-gherkin-and-drivers.md:42 — The Consequences section states behaviour tests depend on "the shared halfsend org pool" and "share the halfsend org pool and lock mechanism with admin e2e tests." After this PR, behaviour tests use the dedicated fullsend-ai-test org with ephemeral bt-{uuid}-{slot} repos and no longer share the halfsend pool or lock mechanism. This would mislead anyone debugging behaviour test infrastructure.
    Remediation: Add a dated note (2026-09) clarifying the migration to fullsend-ai-test with ephemeral repos (ci(#6815): migrate behaviour tests to single-org ephemeral repos #6820), and annotate the pool-specific failure modes as no longer applicable to behaviour tests.

Medium

Low

  • [edge-case] pkg/behaviourtest/drivers/install/composed.go:800Finalize reclaims outstanding leases by returning names to the pool channel but does not call DeleteRepo or InvalidateCache for the leaked repos. With ephemeral bt-{uuid}-{slot} naming, orphaned repos won't collide with future runs but will accumulate in the fullsend-ai-test org until manually cleaned up.

  • [error-handling] pkg/behaviourtest/drivers/install/composed.go:779DeallocateRepo logs fork and repo deletion failures as warnings but does not return an error to the caller. The ensurer's resetRepo step provides self-healing by deleting existing repos before creation, but persistent API failures would leave repos accumulating.

  • [edge-case] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go:354envFullsendRef falls back through BEHAVIOUR_FULLSEND_REF → event payload SHA → GITHUB_HEAD_REFGITHUB_REF_NAME. The GITHUB_HEAD_REF fallback can yield branch names with slashes (e.g., agent/xxx) rejected by IsValidRef. In CI this is mitigated by the explicit BEHAVIOUR_FULLSEND_REF set in the workflow.

  • [authorization-scope] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go:67 — CF preview mint's perRepoWIFRepos and workflowHostRepos changed from explicit repo list to wildcard "*". Mitigations: (1) preview mint is ephemeral per CI run, (2) isolated from production, (3) OIDC audience scoping, (4) randomized alias. Functionally necessary for dynamically generated repo names.

  • [scope-exceeds-authorization] pkg/behaviourtest/drivers/install/common/setup.go:42 — The PR introduces RunReposInstall, envFullsendRef, ValidatePerRepoPostInstallRefPinned, and E2E_KEEP_REPOS beyond the ~5 files authorized by issue e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815. These are integral to making ephemeral repos viable (avoiding 50 MB vendored binaries per repo).

  • [stale-doc] docs/ADRs/0066-behaviour-tests-with-gherkin-and-drivers.md:32 — Decision section references halfsend org pool and github setup. Appropriate fix is a dated note rather than rewriting the Decision section.
    Remediation: Add a dated note referencing the migration to fullsend-ai-test and repos install --fullsend-ref.

  • [stale-doc] docs/ADRs/0066-behaviour-tests-with-gherkin-and-drivers.md:39 — July 2026 note references "Numbered behaviour pool repos (test-repo-NN)." Repos are now ephemeral bt-{uuid}-{slot}.
    Remediation: Add a dated note clarifying the naming change.

  • [stale-doc] docs/ADRs/0066-behaviour-tests-with-gherkin-and-drivers.md:45 — References "org pool, CLI runner, cleanup" in pkg/e2etest/. Behaviour tests no longer call CleanupStaleResources or AcquireOrg.
    Remediation: Update note to reference TokenForBehaviourOrg and BehaviourTestOrg.


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 (5)

Review

Findings

Medium

Low

  • [edge-case] pkg/behaviourtest/drivers/install/composed.go:118 — Finalize reclaims outstanding leases by returning names to the pool channel but does not call DeleteRepo or InvalidateCache for the leaked repos. With ephemeral bt-{uuid}-{slot} naming, orphaned repos won't collide with future runs but will accumulate in the fullsend-ai-test org until manually cleaned up.

  • [error-handling] pkg/behaviourtest/drivers/install/composed.go:127 — DeallocateRepo logs fork and repo deletion failures as warnings but does not return an error to the caller. A transient GitHub API error during deletion would leave an orphaned repo while the slot is returned to the pool.

  • [authorization-scope] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go:66 — The CF preview mint's perRepoWIFRepos and workflowHostRepos changed from an explicit repo list to wildcard "*". Mitigations: (1) preview mint is ephemeral per CI run, (2) isolated from production mint, (3) OIDC audience scoping limits reach. Wildcard is necessary because repo names are dynamically generated.


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 (6)

Review

Findings

Medium

  • [api-contract] internal/fetch/fetch.go — The retry/backoff logic (MaxRetries, RetryBackoff fields, transient error classification, exponential backoff with jitter) is removed entirely from FetchURL. DefaultPolicy previously used 4 total attempts for transient HTTP errors (429, 502, 503) and connection errors (ECONNRESET, ECONNREFUSED, timeouts). Production callers (internal/harness/compose.go, internal/cli/agent.go, internal/resolve/resolve.go, internal/cli/run.go) use DefaultPolicy and relied on implicit retry behavior. After this change, a single transient 503 from raw.githubusercontent.com will fail immediately. The docs/contributing/go-code.md update confirms this is intentional.
    Remediation: If transient failures are expected to be handled elsewhere (e.g., caller-level retry), document this. Otherwise, consider retaining retry logic for production callers that fetch from GitHub CDN endpoints.

  • [unauthorized-functional-change] internal/dispatch/router.go:76 — The needs-info re-triage restoration is a significant dispatch authorization policy change — it re-enables automatic triage triggers using a weaker gate (author_association != NONE or issue author). This was deliberately removed in Remove automatic needs-info re-triage on issue comments #6740 and documented across four ADRs (0033, 0034, 0054, 0067). Issue e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815 authorizes e2e test infrastructure migration, not dispatch authorization policy changes.
    Remediation: File a separate issue authorizing the needs-info re-triage restoration with rationale for reversing Remove automatic needs-info re-triage on issue comments #6740. Move router.go, dispatch.yml, scaffold dispatch.yml, and related ADR/doc changes to that separate PR.

  • [protected-path] .github/workflows/e2e.yml, .github/workflows/reusable-dispatch.yml, skills/nextwork/SKILL.md, skills/nextwork/scripts/nextwork.py — This PR modifies files under protected paths (.github/, skills/). The PR links to issue e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815 and explains the rationale. Human approval is always required for protected-path changes, regardless of context.

Low

  • [authorization-scope] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go:66 — The CF preview mint's perRepoWIFRepos and workflowHostRepos parameters changed from an explicit list of {org}/test-repo-NN repo names to wildcard "*". Mitigations: (1) preview mint is ephemeral per CI run with a unique alias, (2) isolated from production mint, (3) OIDC audience scoping limits which jobs can reach it. The blast radius is limited to the CI run's preview mint lifetime.

  • [guard-consistency] .github/workflows/reusable-dispatch.yml:264 — The shell dispatch needs-info re-triage block does not check ISSUE_IS_PR, while the Go router (internal/dispatch/router.go) restricts to Entity.Kind == "work_item". A comment on a PR labeled needs-info would trigger triage in the shell dispatch but not the Go router. This is by design per ADR 0067.

  • [cost-exposure] .github/workflows/reusable-dispatch.yml — This PR re-enables the needs-info automatic triage dispatch that was removed in Remove automatic needs-info re-triage on issue comments #6740. The gate (COMMENT_AUTHOR_ASSOC != "NONE" || is_issue_author) allows any GitHub user with a past contribution to trigger triage inference runs on needs-info issues. Mitigations: only the read-only triage stage is dispatched, bots are excluded, and the feature label blocks re-triage. ADR 0054 documents and accepts this as an intentional design tradeoff.

  • [scope-exceeded] The PR bundles changes beyond issue e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815's authorization (behaviour test migration): (1) needs-info re-triage restoration (dispatch.yml, router.go, ADRs/docs), (2) FetchURL retry removal (fetch.go), (3) pipeline schedule management removal (schedules.go, converge.go, probe.go), (4) GitLab scaffold MR [skip ci] PR title removal (repos.go). Items 3 and 4 are defensibly connected to repos install refactoring. Items 1 and 2 have no traceable authorization from e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815.
    Remediation: Consider splitting the needs-info re-triage restoration and FetchURL retry removal into separate PRs with their own linked issues.

  • [edge-case] pkg/behaviourtest/drivers/install/composed.goDeallocateRepo correctly deletes the ephemeral repo BEFORE returning the slot to the pool channel, fully addressing the prior race condition concern. Finalize reclaims outstanding leases by returning names to the pool channel but does not call DeleteRepo or InvalidateCache for the leaked repos. With ephemeral naming (bt-{uuid8}-{slot}), orphaned repos won't collide with future runs.

  • [stale-doc] docs/ADRs/0066-behaviour-tests-with-gherkin-and-drivers.md:32 — References 'halfsend org pool', 'test-repo-NN', and says behaviour tests 'share the halfsend org pool and lock mechanism with admin e2e'. After this PR, behaviour tests use fullsend-ai-test with ephemeral repos.
    Remediation: Add a dated note clarifying the migration to fullsend-ai-test (ci(#6815): migrate behaviour tests to single-org ephemeral repos #6820).

  • [stale-doc] docs/runtimes/pi.md:51 — Says 'pool repositories' where it should reference the test org's ephemeral repos.
    Remediation: Update to 'test org repositories'.


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 (7)

Review

Findings

Medium

  • [api-contract] internal/fetch/fetch.go — The retry/backoff logic (MaxRetries, RetryBackoff fields, transient error classification, exponential backoff with jitter) is removed entirely from FetchURL. DefaultPolicy previously used 4 total attempts for transient HTTP errors (429, 502, 503) and connection errors (ECONNRESET, ECONNREFUSED, timeouts). Production callers (internal/harness/compose.go, internal/cli/agent.go, internal/resolve/resolve.go, internal/cli/run.go) use DefaultPolicy and relied on implicit retry behavior. After this change, a single transient 503 from raw.githubusercontent.com will fail immediately. The docs/contributing/go-code.md update confirms this is intentional.
    Remediation: If transient failures are expected to be handled elsewhere (e.g., caller-level retry), document this. Otherwise, consider retaining retry logic for production callers that fetch from GitHub CDN endpoints.

  • [authorization-scope] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go — The CF preview mint's perRepoWIFRepos and workflowHostRepos parameters changed from an explicit list of {org}/test-repo-NN repo names to wildcard "*". This widens the token-mint allowlist to accept WIF and workflow-host requests from any repo name. Mitigations: (1) preview mint is ephemeral per CI run with a unique alias, (2) isolated from production mint, (3) OIDC audience scoping limits which jobs can reach it. The blast radius is limited to the CI run's preview mint lifetime.

  • [stale-doc] docs/guides/dev/behaviour-drivers.md:34 — Still says the suite "acquires a pool org via pkg/e2etest, runs pre-install cleanup". After this PR, behaviour tests use a single fullsend-ai-test org (no pool acquisition) and the CleanupStaleResources call was removed from suite_test.go.
    Remediation: Update to say the suite uses the dedicated fullsend-ai-test org and remove the "runs pre-install cleanup" clause.

  • [stale-doc] docs/guides/dev/behaviour-testing.md:394 — Harness-hosting repo example still uses test-repo-07 naming but repos are now named bt-{uuid8}-{slot}.
    Remediation: Update the example to use ephemeral naming, e.g. leased "bt-a1b2c3d4-01" → "bt-a1b2c3d4-01-url-harness-host".

  • [stale-doc] docs/guides/dev/behaviour-testing.md:425 — FetchPolicy section says the ensurer "always re-vendors the CLI binary (github setup --vendor)" and references "pool repos". After this PR, when BEHAVIOUR_FULLSEND_REF is set, the ensurer uses repos install --fullsend-ref instead of github setup --vendor.
    Remediation: Update to describe the two-path install logic: repos install --fullsend-ref (primary) vs github setup --vendor (fallback), and replace "pool repos" with "ephemeral repos".

  • [protected-path] .github/workflows/e2e.yml, .github/workflows/reusable-dispatch.yml, skills/nextwork/SKILL.md, skills/nextwork/scripts/nextwork.py — This PR modifies files under protected paths (.github/, skills/). The PR links to issue e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815 and explains the rationale. Human approval is always required for protected-path changes, regardless of context.

Low

  • [scope-exceeded] The PR bundles changes beyond issue e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815's authorization (behaviour test migration): (1) needs-info re-triage restoration (dispatch.yml, router.go, ADRs/docs), (2) FetchURL retry removal (fetch.go), (3) pipeline schedule management removal (schedules.go, converge.go, probe.go), (4) GitLab scaffold MR [skip ci] PR title removal (repos.go). The scope overlap is defensible — pipeline schedules and [skip ci] relate to repos install refactoring, and the needs-info restoration updates ADRs touched by the migration — but the bundling is notable.

  • [guard-consistency] internal/dispatch/router.go:83 — The shell dispatch (reusable-dispatch.yml, scaffold dispatch.yml) does not check whether the issue_comment is on a PR or a plain issue — needs-info re-triage fires for both. The Go router restricts to Entity.Kind == "work_item", filtering out PR comments. This is by design per the code comments and ADR 0067.

  • [cost-exposure] .github/workflows/reusable-dispatch.yml — This PR re-enables the needs-info automatic triage dispatch that was removed in Remove automatic needs-info re-triage on issue comments #6740. The gate (COMMENT_AUTHOR_ASSOC != "NONE" || is_issue_author) allows any GitHub user with a past contribution to trigger triage inference runs on needs-info issues. Mitigations: only the read-only triage stage is dispatched, bots are excluded, and the feature label blocks re-triage. ADR 0054 documents and accepts this as an intentional design tradeoff.

  • [edge-case] pkg/behaviourtest/drivers/install/composed.go — DeallocateRepo correctly deletes the ephemeral repo BEFORE returning the slot to the pool channel, fully addressing the prior race condition concern. Finalize reclaims outstanding leases by returning names to the pool channel but does not call DeleteRepo or InvalidateCache for the leaked repos. With ephemeral naming (bt-{uuid8}-{slot}), orphaned repos won't collide with future runs.

  • [stale-doc] docs/guides/dev/behaviour-testing.md:243 — Runner env comments still say "per pool repo" and "pool test-repo secrets". Behaviour tests now use the fullsend-ai-test org with ephemeral bt-{uuid}-{slot} repos.
    Remediation: Update comments to "per ephemeral repo" and "test-org repo secrets".


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 (8)

Review

Findings

Critical

  • [api-contract] pkg/behaviourtest/drivers/install/common/setup.go:78RunReposInstall passes --inference-wif-provider to fullsend repos install, but repos install does not define this flag. The command accepts --inference-project, --inference-project-number, and --inference-region — it auto-derives the WIF provider internally via the GCP API. When gcpProjectID is non-empty (the standard CI path via E2E_GCP_PROJECT_ID), cobra will reject the unknown flag, causing every ephemeral repo installation with inference to fail.
    Remediation: Remove --inference-wif-provider from the args slice. Pass only --inference-project (and optionally --inference-project-number / --inference-region). The convergence engine in repos install auto-provisions WIF from the project ID.

Medium

  • [api-contract] internal/fetch/fetch.go — The retry/backoff logic (MaxRetries, RetryBackoff fields, transient error classification, exponential backoff with jitter) is removed entirely from FetchURL. DefaultPolicy previously used 4 total attempts for transient HTTP errors (429, 502, 503) and connection errors (ECONNRESET, ECONNREFUSED, timeouts). Production callers (internal/harness/compose.go, internal/cli/agent.go, internal/resolve/resolve.go, internal/cli/run.go) use DefaultPolicy and relied on implicit retry behavior. After this change, a single transient 503 from raw.githubusercontent.com will fail immediately. The docs/contributing/go-code.md update confirms this is intentional.
    Remediation: If transient failures are expected to be handled elsewhere (e.g., caller-level retry), document this. Otherwise, consider retaining retry logic for production callers that fetch from GitHub CDN endpoints.

  • [authorization-scope] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go — The CF preview mint's perRepoWIFRepos and workflowHostRepos parameters changed from an explicit list of {org}/test-repo-NN repo names to wildcard "*". This widens the token-mint allowlist to accept WIF and workflow-host requests from any repo name. Mitigations: (1) preview mint is ephemeral per CI run with a unique alias, (2) isolated from production mint, (3) OIDC audience scoping limits which jobs can reach it. The blast radius is limited to the CI run's preview mint lifetime.

  • [stale-doc] docs/guides/infrastructure/mint-administration.md:79 — Still references halfsend-NN/test-repo-01 ... test-repo-12 enrollment for behaviour tests. Behaviour tests now use fullsend-ai-test org with ephemeral bt-{uuid}-{slot} repos.
    Remediation: Update the "Behaviour / e2e pool orgs" section to reference fullsend-ai-test org and ephemeral repo naming.

  • [protected-path] .github/workflows/e2e.yml, .github/workflows/reusable-dispatch.yml, skills/nextwork/SKILL.md, skills/nextwork/scripts/nextwork.py — This PR modifies files under protected paths (.github/, skills/). The PR links to issue e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815 and explains the rationale. Human approval is always required for protected-path changes, regardless of context.

Low

  • [scope-exceeded] The PR bundles changes beyond issue e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815's authorization (behaviour test migration): (1) needs-info re-triage restoration (dispatch.yml, router.go, ADRs/docs), (2) FetchURL retry removal (fetch.go), (3) pipeline schedule management removal (schedules.go, converge.go, probe.go), (4) GitLab scaffold MR [skip ci] PR title removal (repos.go). The scope overlap is defensible — pipeline schedules and [skip ci] relate to repos install refactoring, and the needs-info restoration updates ADRs touched by the migration — but the bundling is notable.

  • [guard-consistency] internal/dispatch/router.go:82 — The shell dispatch (reusable-dispatch.yml, scaffold dispatch.yml) does not check whether the issue_comment is on a PR or a plain issue — needs-info re-triage fires for both. The Go router restricts to Entity.Kind == "work_item", filtering out PR comments. This is by design per the code comments and ADR 0067.

  • [cost-exposure] .github/workflows/reusable-dispatch.yml — This PR re-enables the needs-info automatic triage dispatch that was removed in Remove automatic needs-info re-triage on issue comments #6740. The gate (COMMENT_AUTHOR_ASSOC != "NONE" || is_issue_author) allows any GitHub user with a past contribution to trigger triage inference runs on needs-info issues. Mitigations: only the read-only triage stage is dispatched, bots are excluded, and the feature label blocks re-triage. ADR 0054 documents and accepts this as an intentional design tradeoff.

  • [race-condition] pkg/behaviourtest/drivers/install/composed.go — DeallocateRepo now correctly deletes the ephemeral repo BEFORE returning the slot to the pool channel, fully addressing the prior medium-severity finding. The code comment explains the ordering: the channel send is what makes the slot available — delaying it until after deletion completes prevents the race.

  • [edge-case] pkg/behaviourtest/drivers/install/composed.go — Finalize reclaims outstanding leases by returning names to the pool channel but does not call DeleteRepo or InvalidateCache for the leaked repos. With ephemeral naming (bt-{uuid8}-{slot}), orphaned repos won't collide with future runs.

  • [defense-in-depth-reduction] internal/fetch/fetch.go — The SSRF-hardened FetchURL function had its retry logic removed. Core SSRF protections (HTTPS-only, domain allowlist, DNS pre-resolution with IP validation, redirect blocking, port restrictions, size limits) are all preserved. The removal reduces resilience against transient failures but does not weaken any security boundary.


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 (9)

Review

Findings

Medium

  • [api-contract] internal/fetch/fetch.go — The retry/backoff logic (MaxRetries, RetryBackoff fields, transient error classification, exponential backoff with jitter) is removed entirely from FetchURL. The DefaultPolicy previously used 4 total attempts for transient HTTP errors (429, 502, 503) and connection errors (ECONNRESET, ECONNREFUSED, timeouts). All production callers (internal/cli/agent.go, internal/harness/compose.go, internal/resolve/resolve.go, internal/cli/run.go) use DefaultPolicy and relied on implicit retry behavior. After this change, a single transient 503 from GitHub (e.g., raw.githubusercontent.com serving a harness config) will fail immediately. The docs/contributing/go-code.md update confirms this is intentional.
    Remediation: Confirm this is intentional. If transient failures are expected to be handled elsewhere (e.g., caller-level retry), document this. Otherwise, callers that fetch from GitHub CDN endpoints may need their own retry wrappers for resilience against GitHub's transient 5xx responses.

  • [stale-doc] docs/guides/dev/e2e-testing.md — Behaviour test sections (lines 41, 89, 91, 93, 102) still reference pool orgs (halfsend-01...halfsend-12), test-repo-NN naming, github setup --vendor, and pool org mint enrollment. Behaviour tests now use fullsend-ai-test org with ephemeral bt-{uuid}-{slot} repos and repos install --fullsend-ref.
    Remediation: Update behaviour test sections in e2e-testing.md to reflect the single-org ephemeral model.

  • [stale-doc] docs/guides/dev/behaviour-drivers.md — References pool org model, test-repo-01...test-repo-12 naming (line 41), pool org prerequisites (line 47), and halfsend org pool (line 74). The driver now uses ephemeral bt-{uuid}-{slot} repos in fullsend-ai-test.
    Remediation: Update to reflect single-org ephemeral model with bt-{uuid}-{slot} naming and DeallocateRepo deletion.

  • [protected-path] .github/workflows/e2e.yml, .github/workflows/reusable-dispatch.yml, skills/nextwork/SKILL.md, skills/nextwork/scripts/nextwork.py — This PR modifies files under protected paths (.github/, skills/). The PR links to issue e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815 and explains the rationale. Human approval is always required for protected-path changes, regardless of context.

Low

  • [guard-consistency] internal/dispatch/router.go:83 — The shell dispatch (reusable-dispatch.yml, scaffold dispatch.yml) does not check whether the issue_comment is on a PR or a plain issue — needs-info re-triage fires for both. The Go router restricts to Entity.Kind == "work_item", filtering out PR comments. This is by design: the Go router is used by the GitLab poll path where entity kind is explicitly set, while the shell runs on GitHub where issue_comment fires for both issues and PRs.

  • [race-condition] pkg/behaviourtest/drivers/install/composed.go — DeallocateRepo now correctly deletes the ephemeral repo BEFORE returning the slot to the pool channel, fully addressing the prior medium-severity finding. The code comment explains the ordering: the channel send is what makes the slot available — delaying it until after deletion completes prevents the race.

  • [edge-case] pkg/behaviourtest/drivers/install/composed.go — Finalize reclaims outstanding leases by returning names to the pool channel but does not call DeleteRepo or InvalidateCache for the leaked repos. With ephemeral naming (bt-{uuid}-{slot}), orphaned repos won't collide with future runs.

  • [cost-exposure] .github/workflows/reusable-dispatch.yml — This PR re-enables the needs-info automatic triage dispatch that was removed in Remove automatic needs-info re-triage on issue comments #6740. The gate (COMMENT_AUTHOR_ASSOC != "NONE" || is_issue_author) allows any GitHub user with a past contribution to trigger triage inference runs on needs-info issues. Mitigations: only the read-only triage stage is dispatched, bots are excluded, and the feature label blocks re-triage. ADR 0054 documents and accepts this as an intentional design tradeoff.

  • [scope-exceeded] The PR bundles changes beyond issue e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815's authorization (behaviour test migration): (1) needs-info re-triage restoration (dispatch.yml, router.go, ADRs/docs), (2) FetchURL retry removal (fetch.go), (3) pipeline schedule management removal (schedules.go, converge.go, probe.go), (4) GitLab scaffold MR [skip ci] PR title removal (repos.go). The scope overlap is defensible — pipeline schedules and [skip ci] relate to repos install refactoring, and the needs-info restoration updates ADRs touched by the migration — but the bundling is notable.

  • [stale-doc] docs/guides/dev/behaviour-testing.md:408 — The harness-hosting repository section still says "pool org". Should reference fullsend-ai-test org.
    Remediation: Replace "pool org" with "fullsend-ai-test org".


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 (10)

Review

Findings

Low

  • [race condition] pkg/behaviourtest/drivers/install/composed.go — DeallocateRepo now keeps the outstanding entry during the in-flight DeleteRepo call, addressing the prior medium-severity finding. The remaining window between delete(d.outstanding, repoName) and d.names <- repoName is minimal and the channel send is guaranteed non-blocking (buffer has room because the name was removed during AllocateRepo). In normal operation Finalize runs after all scenarios complete, so concurrent DeallocateRepo/Finalize is not expected.

  • [edge case] pkg/behaviourtest/drivers/install/composed.go — Finalize reclaims outstanding leases by returning names to the pool channel but does not delete the leaked ephemeral repos or invalidate the ensurer cache. With ephemeral naming the repos become orphaned but won't collide with future runs.

Previous run (11)

Review

Findings

Medium

  • [race condition] pkg/behaviourtest/drivers/install/composed.goDeallocateRepo releases the mutex before starting the DeleteRepo API call. Between the unlock and the channel send, the slot name exists neither in outstanding nor in the names channel. If Finalize runs during this window, it sees no outstanding lease for this slot and completes without waiting for the in-flight deletion, allowing the test process to exit while a DeleteRepo call is still in flight.
    Remediation: Keep the outstanding entry until after the deletion completes: move delete(d.outstanding, repoName) to just before the channel send, or add a sync.WaitGroup to Finalize that waits for in-flight deallocations.

  • [stale-doc] docs/guides/dev/behaviour-testing.md — The Runner env table comments still reference pool-org terminology: "install runs inference provision per pool repo" and "not written to pool test-repo secrets". Behaviour tests now use the dedicated fullsend-ai-test org with ephemeral repos.
    Remediation: Update the env var comments to use "ephemeral repo" instead of "pool repo" and "test org repo secrets" instead of "pool test-repo secrets".

  • [stale-doc] docs/guides/dev/behaviour-testing.md — The "FetchPolicy and binary freshness" section says the ensurer "always re-vendors the CLI binary (github setup --vendor)" and references "leased pool repos". The ensurer now uses repos install --fullsend-ref when BEHAVIOUR_FULLSEND_REF is set, and repos are ephemeral rather than pool-based.
    Remediation: Update the paragraph to note that when BEHAVIOUR_FULLSEND_REF is set, the ensurer uses repos install --fullsend-ref instead of github setup --vendor. Replace "leased pool repos" with "ephemeral repos".

Low

  • [consistency] pkg/behaviourtest/drivers/install/repopool_external_mint.goNewRepoPoolExternalMint passes an empty string as the prefix to newComposedDriver, relying on the internal fallback to generate a UUID. Unlike NewRepoPoolCFMintPreviews which generates the prefix early to share with buildEphemeralRepoList for mint deploy, the external mint path does not need the prefix early since it uses a pre-configured mint URL.

  • [test adequacy] pkg/behaviourtest/drivers/install/validate_test.go — No unit test for ValidatePerRepoPostInstallRefPinned with a wrong runtime value. The vendored ValidatePerRepoPostInstall has a WrongRuntime test case, but the ref-pinned variant only tests the OK path and the MissingShim path.
    Remediation: Add a TestValidatePerRepoPostInstallRefPinned_WrongRuntime test mirroring TestValidatePerRepoPostInstall_WrongRuntime.

  • [edge case] pkg/behaviourtest/drivers/install/composed.goFinalize reclaims outstanding leases by returning names to the pool channel but does not delete the ephemeral repos or invalidate the ensurer cache for those leaked slots. With ephemeral naming the repos become orphaned but won't collide with future runs.

  • [stale-doc] docs/guides/dev/behaviour-testing.md — The "Version pinning" section tells external runners to import pkg/e2etest "for org pool acquisition". Behaviour tests no longer use org pool acquisition; they use BehaviourTestOrg and TokenForBehaviourOrg.
    Remediation: Update to "for org/token resolution, env config, CLI build/run, and cleanup".


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 (12)

Review

Findings

Medium

  • [stale-doc] docs/guides/infrastructure/mint-administration.md:79 — The "Behaviour / e2e pool orgs" note still instructs operators to enroll halfsend-NN/test-repo-01 ... test-repo-12 for behaviour tests. Behaviour tests now use ephemeral bt-{uuid}-{slot} repos in fullsend-ai-test with dynamic per-repo naming each run, making static enrollment of numbered repo names obsolete for behaviour tests.
    Remediation: Update the note to separate admin e2e enrollment (halfsend-NN/test-repo, still valid) from behaviour test enrollment. Add a sentence explaining that behaviour tests use ephemeral repos in fullsend-ai-test whose per-repo mint enrollment is handled dynamically during install.

Low

  • [environment coupling in constructor] pkg/behaviourtest/drivers/install/composed.go:75newComposedDriver reads os.Getenv("E2E_KEEP_REPOS") directly at construction time. Other env vars in the package (envPoolSize, envFullsendRef, envSuiteName, envAppSet) are read in factory/top-level functions and passed as parameters.
    Remediation: Add a keepRepos bool parameter to newComposedDriver and read os.Getenv in the factory functions.

  • [test adequacy] pkg/behaviourtest/drivers/install/validate_test.go — No unit tests for ValidatePerRepoPostInstallRefPinned. This new validation function is called in the ref-pinned install path but has zero test coverage.
    Remediation: Add OK-path and missing-shim-path tests mirroring the existing ValidatePerRepoPostInstall tests.

  • [edge case] pkg/behaviourtest/drivers/install/composed.go:137DeallocateRepo silently swallows non-NotFound DeleteRepo errors by logging a warning and returning nil. Callers have no signal that cleanup partially failed.


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 (13)

Review

All prior findings from the previous review are resolved: the race condition in DeallocateRepo (deletion now occurs before returning the slot to the pool), the stale buildRepoList naming (replaced by buildEphemeralRepoList), the ensurer cache leak (InvalidateCache added), the missing deletion tests (four new test cases with fakeForgeClient), the unchecked type assertion in the new validation function (checked assertion used), the RunReposInstall inference flag omission (now passes --inference-project and --inference-wif-provider), and the DefaultPoolSize comment (updated to reflect ephemeral slots).

The remaining findings are documentation files outside this PR that still reference the old pool model.

Findings

High

  • [stale-doc] docs/guides/dev/e2e-testing.md:41 — Multiple references to halfsend pool orgs and test-repo-NN naming in the behaviour test sections. Behaviour tests now use fullsend-ai-test org with ephemeral bt-{uuid}-{slot} repos and install via repos install --fullsend-ref.
    Remediation: Update the behaviour test sections to reference fullsend-ai-test org, ephemeral bt-{uuid}-{slot} repos, and repos install --fullsend-ref.

Medium

  • [stale-doc] docs/guides/dev/behaviour-drivers.md — Multiple references to pool org acquisition, test-repo-01..12 naming, halfsend org pool, and pre-provisioned repos. The suite now uses a fixed fullsend-ai-test org with ephemeral repos, and DeallocateRepo deletes repos after use.
    Remediation: Update to reflect single-org ephemeral model with bt-{uuid8}-{slot} naming and DeallocateRepo deletion.

Low

  • [edge-case] pkg/behaviourtest/drivers/install/validate.go — Pre-existing: ValidatePerRepoPostInstall uses an unchecked type assertion cfgW.(config.PerRepoConfigReader) that could panic, while the new ValidatePerRepoPostInstallRefPinned correctly uses a checked assertion. The inconsistency was highlighted by this PR introducing the safer pattern.
    Remediation: Update ValidatePerRepoPostInstall to use a checked assertion matching the new function.

  • [error-handling] pkg/behaviourtest/drivers/install/composed.go:131DeallocateRepo silently swallows non-NotFound deletion errors (logs a warning but returns nil). Impact is limited since ephemeral repos use UUID-based names that never collide across runs — a failed deletion only leaves a stale repo in the test org rather than causing correctness issues.

  • [stale-doc] docs/ADRs/0066-behaviour-tests-with-gherkin-and-drivers.md:39 — References test-repo-NN naming and halfsend pool/lock mechanism in the Consequences section.
    Remediation: Append a dated note (2026-08) noting the migration to single-org ephemeral repos (PR ci(#6815): migrate behaviour tests to single-org ephemeral repos #6820).


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 (14)

Review

Findings

High

  • [race-condition] pkg/behaviourtest/drivers/install/composed.go:124DeallocateRepo returns the repo name to the pool channel (d.names <- repoName) and releases the mutex before deleting the repo from the forge. Another goroutine can immediately receive this name via AllocateRepo, call EnsureRepo, and begin operating on the repo while the deletion is still in progress. Combined with the ensurer’s ensured cache (which retains the “already ensured” entry after deallocation), a re-allocated slot will skip doEnsure entirely and attempt to use a deleted repo.
    Remediation: Move the DeleteRepo call before returning the name to the channel. The channel send is what makes the slot available — delaying it until after deletion completes prevents the race.

  • [stale-reference] pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go:366buildRepoList still generates test-repo-NN names for --per-repo-wif-repos and --workflow-host-repos during CF mint deploy, but the composed driver now creates repos named bt-{uuid8}-{slot}. The mint uses these lists to authorize per-repo token requests. Ephemeral repos won’t match the allowlist, causing mint token requests to fail for behaviour test repos.
    Remediation: Update buildRepoList to produce names matching the ephemeral naming scheme, or switch to dynamic per-repo enrollment during EnsureRepo.

Low

  • [logic-error] pkg/behaviourtest/drivers/install/ensure.go — The ensurer’s ensured cache retains entries after DeallocateRepo deletes the repo and returns the slot to the pool. If the same slot name is re-allocated within a run, EnsureRepo returns immediately (“already ensured”), skipping the create+install flow for the now-deleted repo.
    Remediation: Clear the ensured cache entry in DeallocateRepo, or ensure the deletion+re-allocation ordering prevents this path.

  • [stale-doc] docs/guides/dev/behaviour-testing.md:318 — The “Pool-org prerequisites” section still references test-repo-NN in the fork permission bullet point despite the rest of the document being updated to bt-{uuid}-{slot}.
    Remediation: Replace (test-repo-NN) with the ephemeral naming pattern.

  • [missing-test] pkg/behaviourtest/drivers/install/composed_test.go — All tests pass nil for the forge.Client parameter, leaving the new repo deletion logic in DeallocateRepo entirely untested (including keepRepos, IsNotFound handling, and the deletion-before-pool-return ordering).
    Remediation: Add tests with a fake forge.Client to exercise the deletion path.

  • [edge-case] pkg/behaviourtest/drivers/install/validate.go:70ValidatePerRepoPostInstallRefPinned uses an unchecked type assertion cfgW.(config.PerRepoConfigReader). Consistent with the existing ValidatePerRepoPostInstall pattern but a latent panic risk.
    Remediation: Use a checked type assertion: cfg, ok := cfgW.(config.PerRepoConfigReader); if !ok { return fmt.Errorf(...) }.

  • [naming-convention] pkg/behaviourtest/drivers/install/driver.goDefaultPoolSize comment still says “number of test-repo-NN repos in a pool org”; should reflect the ephemeral slot count.
    Remediation: Update the comment to describe the default number of concurrent ephemeral repo slots.

  • [pattern-inconsistency] pkg/behaviourtest/drivers/install/common/setup.goRunReposInstall discards the WIF provider from ProvisionInference and does not pass --inference-project/--inference-wif-provider, unlike the sibling RunGitHubSetup. If repos install needs these flags, inference configuration will be incomplete.


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.

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 8:02 PM UTC · Completed 8:14 PM UTC

Commit: 28b2b91 · View workflow run →

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

fullsend-ai-coder Bot added a commit that referenced this pull request Aug 31, 2026
- Fix race condition in DeallocateRepo: delete ephemeral repo BEFORE
  returning the slot to the pool channel, preventing another goroutine
  from re-allocating a repo that is still being deleted.
- Fix stale buildRepoList: rename to buildEphemeralRepoList and thread
  the UUID prefix from NewRepoPoolCFMintPreviews so mint deploy uses
  the same bt-{uuid}-{slot} names as the composed driver.
- Fix ensurer cache leak: add InvalidateCache to ensurer interface,
  called by DeallocateRepo after deletion so re-allocated slots
  trigger a fresh create+install cycle.
- Fix stale doc: update Pool-org prerequisites to reference
  bt-{uuid}-{slot} instead of test-repo-NN.
- Add tests for DeallocateRepo deletion path with fake forge.Client
  (delete, keepRepos, notFound, cache invalidation).
- Fix unchecked type assertion in ValidatePerRepoPostInstallRefPinned.
- Update DefaultPoolSize comment to reflect ephemeral slot count.
- Fix RunReposInstall to pass --inference-project/--inference-wif-provider
  flags, matching the sibling RunGitHubSetup pattern.

Addresses #6820
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 1 (bot-triggered)

Addressed all 8 review findings: fixed race condition in DeallocateRepo (delete before pool return), fixed stale buildRepoList naming for CF mint deploy, added ensurer cache invalidation after repo deletion, updated stale doc reference, added 4 deletion-path tests with fake forge.Client, used checked type assertion in validation, updated stale comment, and threaded inference flags through RunReposInstall.

Fixed (8):

  1. race-condition: DeallocateRepo returns repo name to pool before deleting it (pkg/behaviourtest/drivers/install/composed.go): Moved DeleteRepo call before the channel send that returns the slot to the pool. The channel send is what makes the slot available to other goroutines — delaying it until after deletion completes prevents a race where a new allocator begins EnsureRepo on a repo that is still being deleted.
  2. stale-reference: buildRepoList still generates test-repo-NN names for CF mint deploy (pkg/behaviourtest/drivers/install/repopool_cfmint_previews.go): Renamed buildRepoList to buildEphemeralRepoList, added prefix parameter, and hoisted UUID prefix generation into NewRepoPoolCFMintPreviews so the mint deploy and the composed driver use the same bt-{uuid}-{slot} repo names. Threaded prefix through buildCFMintDriver and newComposedDriver.
  3. logic-error: ensurer cache retains entries after DeallocateRepo deletes the repo (pkg/behaviourtest/drivers/install/ensure.go): Added InvalidateCache(org, repoName) method to the ensurer interface and repoEnsurer implementation. DeallocateRepo now calls InvalidateCache after deletion so re-allocated slots trigger a fresh create+install cycle instead of hitting the stale cache.
  4. stale-doc: Pool-org prerequisites still references test-repo-NN (docs/guides/dev/behaviour-testing.md): Replaced test-repo-NN with bt-{uuid}-{slot} in the fork scenario prerequisites section.
  5. missing-test: DeallocateRepo deletion logic untested with nil forge.Client (pkg/behaviourtest/drivers/install/composed_test.go): Added 4 tests with a fakeForgeClient: DeallocateDeletesRepo (verifies DeleteRepo is called), DeallocateKeepRepos (verifies E2E_KEEP_REPOS skips deletion), DeallocateDeleteNotFoundIgnored (verifies ErrNotFound is tolerated), and DeallocateInvalidatesCache (verifies ensurer cache is cleared after deletion).
  6. edge-case: unchecked type assertion in ValidatePerRepoPostInstallRefPinned (pkg/behaviourtest/drivers/install/validate.go): Replaced unchecked type assertion cfgW.(config.PerRepoConfigReader) with a checked assertion that returns a descriptive error if the cast fails.
  7. naming-convention: DefaultPoolSize comment still says test-repo-NN (pkg/behaviourtest/drivers/install/driver.go): Updated DefaultPoolSize comment to describe the default number of concurrent ephemeral repo slots.
  8. pattern-inconsistency: RunReposInstall discards WIF provider and omits inference flags (pkg/behaviourtest/drivers/install/common/setup.go): Updated RunReposInstall to capture the WIF provider from ProvisionInference and pass --inference-project and --inference-wif-provider flags, matching the sibling RunGitHubSetup pattern.

Tests: passed

Decision points
  • Whether to fix the unchecked type assertion in the existing ValidatePerRepoPostInstall as well (alternatives: Fix both functions, Fix only the new ValidatePerRepoPostInstallRefPinned; rationale: The reviewer flagged only the new function. Fixing the pre-existing one would be a scope creep beyond the review feedback.)

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

@fullsend-ai-review

fullsend-ai-review Bot commented Aug 31, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:16 PM UTC · Completed 8:34 PM UTC

Commit: 691b610 · View workflow run →

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

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 8:36 PM UTC · Completed 8:47 PM UTC

Commit: 691b610 · View workflow run →

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

@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 2 (bot-triggered)

Updated three documentation files (e2e-testing.md, behaviour-drivers.md, ADR 0066) to replace stale halfsend pool-model references with the new fullsend-ai-test ephemeral repo model. Fixed unchecked type assertion in ValidatePerRepoPostInstall. Disagreed with the error-handling finding on DeallocateRepo — the current log-and-continue behaviour is the correct trade-off.

Fixed (4):

  1. stale-doc: docs/guides/dev/e2e-testing.md references halfsend pool orgs and test-repo-NN in behaviour test sections (docs/guides/dev/e2e-testing.md): Updated behaviour test sections to reference fullsend-ai-test org, ephemeral bt-{uuid}-{slot} repos, repos install --fullsend-ref, and removed the stale nested enrollment loop for numbered behaviour pool repos
  2. stale-doc: docs/guides/dev/behaviour-drivers.md references pool org acquisition, test-repo-01..12, halfsend org pool, and pre-provisioned repos (docs/guides/dev/behaviour-drivers.md): Updated to reflect single-org ephemeral model: fullsend-ai-test org, bt-{uuid8}-{slot} naming, DeallocateRepo deletion, and dynamic per-repo mint enrollment
  3. edge-case: ValidatePerRepoPostInstall uses unchecked type assertion while ValidatePerRepoPostInstallRefPinned uses checked assertion (pkg/behaviourtest/drivers/install/validate.go): Changed unchecked type assertion to checked assertion with error return, matching the pattern in ValidatePerRepoPostInstallRefPinned
  4. stale-doc: docs/ADRs/0066-behaviour-tests-with-gherkin-and-drivers.md references test-repo-NN naming and halfsend pool/lock mechanism (docs/ADRs/0066-behaviour-tests-with-gherkin-and-drivers.md): Appended dated note (2026-08, e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install #6815 / PR ci(#6815): migrate behaviour tests to single-org ephemeral repos #6820) documenting the migration to single-org ephemeral repos, preserving the original Consequences text per ADR immutability conventions

Disagreed (1):

  1. error-handling: DeallocateRepo silently swallows non-NotFound deletion errors: The reviewer acknowledges impact is limited since ephemeral repos use UUID-based names that never collide. Returning an error from DeallocateRepo would block slot recycling in the pool and propagate to the scenario After hook, potentially masking the actual test result. The current behaviour (log warning, continue) is the correct trade-off: a failed deletion leaves a stale repo that will never be reused, while a returned error would break the test suite's cleanup flow.

Tests: passed

Decision points
  • Preserve DeallocateRepo error-swallowing behaviour for non-NotFound deletion errors (alternatives: Return the error to the caller, Log warning and continue (current behaviour); rationale: Returning an error would propagate to the scenario After hook and could mask the actual test result. A failed deletion only leaves a stale repo with a unique UUID-based name that will never be reused by another run.)

Next steps:

  • /fs-review — request a re-review of the changes
  • /fs-fix <your instruction> — run another fix pass with specific guidance
  • Push commits directly — review re-runs automatically on push
    Updated by fullsend fix agent

fullsend-ai-coder Bot added a commit that referenced this pull request Aug 31, 2026
Update e2e-testing.md, behaviour-drivers.md, and ADR 0066 to reflect
the migration from halfsend org pool with test-repo-NN naming to the
single fullsend-ai-test org with ephemeral bt-{uuid}-{slot} repos.
Also fix unchecked type assertion in ValidatePerRepoPostInstall to
match the checked pattern used by ValidatePerRepoPostInstallRefPinned.

Note: pre-commit hooks could not run (network-restricted sandbox).
gofmt, go vet, trailing-whitespace, and end-of-file checks passed
via direct execution.

Addresses #6820
@fullsend-ai-review

fullsend-ai-review Bot commented Aug 31, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:49 PM UTC · Completed 9:10 PM UTC

Commit: 95723d7 · View workflow run →

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

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-coder

fullsend-ai-coder Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 9:12 PM UTC · Completed 9:22 PM UTC

Commit: 95723d7 · View workflow run →

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

fullsend-ai-coder Bot added a commit that referenced this pull request Aug 31, 2026
- Update mint-administration.md to separate admin e2e enrollment from
  behaviour test enrollment, noting ephemeral repos in fullsend-ai-test
- Add keepRepos bool parameter to newComposedDriver, moving os.Getenv
  read to factory functions for consistency with other env vars
- Add unit tests for ValidatePerRepoPostInstallRefPinned (OK and
  missing-shim paths)
- Surface non-NotFound DeleteRepo errors from DeallocateRepo to callers
  instead of silently swallowing them; slot is still returned to pool

Pre-commit hooks could not run (network-restricted sandbox). gofmt,
go vet, and package tests passed via direct execution.

Addresses #6820
@fullsend-ai-review

fullsend-ai-review Bot commented Sep 1, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 3:42 AM UTC · Completed 4:02 AM UTC

Commit: 978d35d · View workflow run →

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

fullsend-ai-review[bot]

This comment was marked as outdated.

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review

fullsend-ai-review Bot commented Sep 1, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 4:06 AM UTC · Completed 4:26 AM UTC

Commit: b0a96a3 · View workflow run →

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

@fullsend-ai-review
fullsend-ai-review Bot dismissed stale reviews from themself September 1, 2026 04:26

Superseded by updated review

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label Sep 1, 2026
@ggallen
ggallen force-pushed the agent/6815-single-org-ephemeral-repos branch from b0a96a3 to 3c3e968 Compare September 1, 2026 04:30
@fullsend-ai-review

fullsend-ai-review Bot commented Sep 1, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 4:33 AM UTC · Completed 4:54 AM UTC

Commit: 3c3e968 · View workflow run →

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

fullsend-ai-review[bot]

This comment was marked as outdated.

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review

fullsend-ai-review Bot commented Sep 1, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 5:07 AM UTC · Completed 5:28 AM UTC

Commit: 22a30d8 · View workflow run →

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

fullsend-ai-review[bot]

This comment was marked as outdated.

fullsend-ai-review[bot]

This comment was marked as outdated.

Replace 12-org halfsend pool with single fullsend-ai-test org using
ephemeral bt-{uuid}-{slot} repos and repos install --fullsend-ref.

- Add composedDriver with per-scenario repo lifecycle (create/delete)
- Add RunReposInstall for ref-pinned installs with version-1 manifest
- Add prHeadSHAFromEvent fallback for pull_request_target workflows
- Add TokenForBehaviourOrg and BehaviourTestOrg to pkg/e2etest
- Update ADR 0066 and behaviour-testing docs for new architecture
- Set BEHAVIOUR_FULLSEND_REF in e2e workflow

Signed-off-by: Greg Allen <greg@fullsend.ai>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Greg Allen <gallen@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Sep 1, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 5:43 AM UTC · Completed 6:04 AM UTC

Commit: 7c13e96 · View workflow run →

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

@ifireball ifireball 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.

I think this should be implemented as a new install driver alongside the existing ones, rather then a change in place to the current drivers which makes their names make less sense.

The use of ephemeral repos was probably made possible by the fact we not have per-test mints, but I'm not quite sure why we also need to abandon the org pool, leaving the org pool in place while going to ephemeral repos would have probably solved the undelying issues as well while also making the code change less radical.

I had already planned to go for deleting and recreating the repos before each scenario, would that have solved the issue as well?

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 needs-human Agent loop needs human intervention ready-for-review Agent PR ready for human review requires-manual-review Review requires human judgment risk/elevated PR risk: elevated

Projects

None yet

Development

Successfully merging this pull request may close these issues.

e2e: migrate behaviour tests from 12-org pool to single fullsend-ai-test org with repos install

2 participants