[issue-3393][slice-2/6] List-shaped submission + uniform... - #3423
Merged
Conversation
List-shaped submission outcomes (multi-repo list fidelity, same-name/ different-owner distinctness, per-repo base_branch, primary defaulting, N=1 back-compat) asserted green at the model layer. Coder-dependent behavior (repos-list forwarding in _handle_submit_task; the validate_visibility_uniformity / validate_auth_mode_uniformity gateway helpers) is authored and skip-guarded pending the parallel coder's slice-2 integration, activating at convergence. Interface handed to the coder via task-2-1/task-2-2 coverage gaps. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…idation
task-2-1 (list-shaped submission): submit_task (mcp_tools/_tool_defs.py,
_submit.py) accepts a 'repos' list of {repo, base_branch, primary?} in addition
to the single 'repo' (back-compat); handler normalizes canonically primary-first
and mirrors the primary onto the legacy repo/base_branch scalars; required
relaxed to [description]. POST /api/v1/pipelines (routes/pipelines.py) threads
the full list through via _normalize_submission_repos and constructs the
Pipeline with repos: list[RepoSpec] (no repos[0] collapse). state_store.
create_pipeline gains an optional 'repos' param onto Pipeline.repos; N=1 stays
byte-for-byte unchanged (repos=None => slice-1 validator synthesizes from the
singleton).
task-2-2 (uniform visibility/auth): _assert_repo_set_uniform rejects mixed-
visibility or mixed-auth repo sets at submission with an actionable, repo-naming
400; single repo is trivially uniform (no gateway round-trip). assert_uniform_auth
added to config/repo_config.py (canonical home of get_auth_mode, bundled into
both images) and imported by the orchestrator; visibility resolved via
GatewayClient.get_repo_visibility (mirrors _compute_gateway_mode). Same-short-
name-different-owner repos are NOT rejected.
Runtime-boundary deviation: the orchestrator image ships config/repo_config.py
but NOT gateway/, so the uniformity guards live where the submission path can
actually reach them (auth in repo_config, visibility inline via HTTP
GatewayClient) rather than as dead helpers in gateway modules. Behavioral
acceptance met in full; flagged for reviewer_contract.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Distilled slice-2 change model + the runtime-boundary deviation rationale so one-shot re-spawns stay consistent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…into egg/issue-3393-slice-2-coder/work
…ester task-2-3) Add validate_visibility_uniformity + validate_auth_mode_uniformity to gateway/repo_visibility.py matching the exact interface the tester's task-2-3 tests expect (gateway/tests/test_repo_visibility.py + orchestrator/tests/ test_pipelines.py): raise ValueError naming offenders on a mixed set; internal shares the private posture; same-name/different-owner NOT rejected; single/ uniform is a no-op. validate_auth_mode_uniformity delegates to config/repo_config.py assert_uniform_auth so the auth rule has one source of truth. The orchestrator's submission-time _assert_repo_set_uniform is documented as the HTTP-boundary twin of validate_visibility_uniformity (the orchestrator image does not ship gateway/, so it mirrors the check via GatewayClient). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…curity v1) Address reviewer_security NACK: the visibility uniformity check silently dropped a repo from the vote when its visibility resolved to None (if vis is None: continue), which could ADMIT a genuinely-mixed private+public multi-repo set whenever a secondary momentarily failed to resolve — the exact leak vector the control blocks, with no downstream re-check (_compute_gateway_mode reads only the primary repo). Fix in both twins (orchestrator _assert_repo_set_uniform and gateway validate_visibility_uniformity): for a multi-repo set, a repo whose visibility is not a known public|private|internal bucket (None OR unrecognized label) now FAILS CLOSED with an actionable, repo-naming rejection instead of being excluded from the vote. N=1 short-circuits before any lookup (the gateway helper now also short-circuits len<=1), so the common case pays nothing. The auth check's config-read exception path is likewise made fail-closed for consistency. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
jwbron
approved these changes
Jul 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Make submission genuinely list-shaped end to end and enforce the two uniformity rules.
submit_taskandPOST /api/v1/pipelinesaccept a list of {repo, base_branch}; a bare single repo stays accepted (back-compat). Submission-time validation rejects mixed-visibility sets and mixed-auth-mode sets with actionable errors (reusingget_repo_visibilityand per-repoget_auth_mode). Same-name repo sets are NOT rejected (operator ruling #6). One repo is designated primary (first unless flagged) for naming and slice-default.Base PR: #3418
What's in this PR
Commits (6):
This slice
List-shaped submission + uniform visibility/auth validation
Files affected:
orchestrator/mcp_tools/_submit.pyorchestrator/routes/pipelines.pygateway/repo_visibility.pygateway/git_client/_credentials.pyorchestrator/tests/test_pipelines.pygateway/tests/test_repo_visibility.pyTasks (3) + acceptance criteria
repo+base_branchat :78-79): accept either a single repo/base_branch (back-compat) or a list of {repo, base_branch} entries; normalize to the list-shaped Pipeline repo set from slice 1 with the first entry (or an explicitly flagged one) as primary. In orchestrator/routes/pipelines.py: thread the repo list through thePOST /api/v1/pipelineshandler and pipeline construction so the full list reaches Pipeline; do not collapse to a single repo. Do not add the uniformity validators here (TASK-2-2) and do not touch the three collapse sites (slice 3).get_repo_visibility(owner, repo)to require all repos in a run to be uniformly private or uniformly public, and gateway/git_client/_credentials.pyget_auth_mode(repo)to require a single uniform auth mode across the run. On a mixed set, reject the submission with an actionable error naming the offending repos and which dimension (visibility vs auth) diverged. Do NOT reject same-name repo sets — the collision is resolved by the owner/repo re-key in slice 3 (operator ruling Phase 4: CLI implementation #6). Add small, focused helper functions (e.g.assert_uniform_visibility,assert_uniform_auth) on the gateway modules where the per-repo lookups live, and call them from the submission path in orchestrator/routes/pipelines.py.make test(narrowed) andmake test-allgreen.Stack
issue-3393egg/issue-3393/slice-1