Skip to content

stack 3/5: add first-contributor trust lane - #902

Closed
Wibias wants to merge 7 commits into
agent/pr-readiness-gatefrom
agent/pr-trust-lane
Closed

stack 3/5: add first-contributor trust lane#902
Wibias wants to merge 7 commits into
agent/pr-readiness-gatefrom
agent/pr-trust-lane

Conversation

@Wibias

@Wibias Wibias commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator

Stack

3/5 — first-contributor trust lane

Base: agent/pr-readiness-gate (#901)
Next: deterministic anti-slop CI

Summary

  • allow only one active implementation PR per first-time contributor
  • cap first implementation PRs at 500 changed lines unless the linked issue has large-change-approved
  • require maintainer-sponsored for workflow, OAuth/authentication, release, and dependency surfaces
  • exempt docs-only changes, established contributors, and repository collaborators
  • use repository metadata rather than attempting AI-origin detection

Verification

  • node --test .github/scripts/pr-trust-lane.test.cjs — 8 passed, 0 failed
  • the tests caught and fixed an initial workflow-only classification hole
  • workflow YAML parsed successfully

Rollout

Tune the 500-line threshold and restricted path list during draft review before promoting the trusted workflow to the default branch.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (2)
  • ^dev$
  • ^preview$

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 421b82ce-23cc-4938-bbf1-9dc8b6db9e7e

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@Wibias Wibias added the chore Maintenance, CI, tests, refactors, or build changes (not a user-facing bug or feature). label Aug 2, 2026

Wibias commented Aug 2, 2026

Copy link
Copy Markdown
Collaborator Author

Stack navigation

  1. stack 1/5: add contribution intake firewall #900 — contribution intake firewall
  2. stack 2/5: gate review readiness and CodeRabbit #901 — readiness and CodeRabbit gate
  3. stack 3/5: add first-contributor trust lane #902 — first-contributor trust lane
  4. stack 4/5: add deterministic anti-slop CI #903 — deterministic anti-slop CI
  5. stack 5/5: define review lifecycle and governance rollout #905 — review lifecycle and governance rollout

Review and merge bottom-up. Each PR targets the preceding stack branch, so its Files changed view contains only that layer.

@Wibias
Wibias marked this pull request as ready for review August 3, 2026 01:50

Wibias commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator Author

[shipping-github] Verdict: approve-comment

PR: #902 — stack 3/5: add first-contributor trust lane
Head: 9361bd35 on agent/pr-readiness-gate (mergeable, updated from the current stack-2/5 head 53ed63a1)

Semantic propagation

  • Concepts audited: first-time-contributor classification, 500-line cap, maintainer-sponsored restricted surfaces, one-active-PR limit, implementation-path classification, approval-label semantics.
  • Authoritative sources: docs/superpowers/specs/2026-08-02-pr-trust-lane-design.md, .github/scripts/pr-trust-lane.cjs, stack 1/5: add contribution intake firewall #900's pr-admission.cjs (shared extractLinkedIssueNumbers consumer, implementation-file set).
  • Producers and consumers checked: pr-trust-lane.yml; stack 1/5: add contribution intake firewall #900 admission (same path classification, now with bunfig.toml); stack 2/5: gate review readiness and CodeRabbit #901 readiness (labels the blocked state as author_action via the failed check); stack 5/5: define review lifecycle and governance rollout #905 CI wiring and contributor docs.
  • Public/derived representations checked: path sets vs design doc; approval labels vs stack 1/5: add contribution intake firewall #900's open-issue requirement; blocked label intake: trust-lane-blocked; failure comment copy.
  • Material variant partitions checked: first-timer vs established vs maintainer; open/closed issues with approval labels; renames; bunfig.toml; restricted paths (.github/workflows/, src/auth/, src/oauth/, release/dependency files); docs-only PRs.
  • Positive and negative assertions checked: 11 trust-lane tests, 298/298 full script suite, end-to-end harness across 9 scenarios.
  • Unmapped surfaces: none.
  • Unproven equivalence assumptions: none.
  • Representation mismatches: bunfig.toml drift between stack 1/5: add contribution intake firewall #900 and stack 3/5: add first-contributor trust lane #902 fixed; intentional .github/workflows/ difference (stricter for first-timers) documented in the design doc.
  • Variant coverage gaps: none blocking.
  • Axis verdict: pass.

Usefulness

High: a concrete, metadata-based trust lane (one active implementation PR, 500-line cap, sponsorship for workflow/auth/release/dependency surfaces) that closes the "first PR is free" gap in the stack without AI-origin guessing. Without it the admission gate alone cannot protect security-sensitive surfaces from first-time contributors.

Bugs / correctness

  • Method: bug-review.md — Bugbot: n/a (Codex host, complementary only); complementary: done (silent_failures / resource_leaks / edge_cases).
  • F1 (P1, fixed in 842cd519): the workflow's embedded JavaScript was syntactically invalid - three errors: missing : in pull_number candidate.number and issue_number pull_number, and a stray comma in .),.join(", "). The gate would crash on its first run, so first-timer limits never applied. Full script now syntax-checks and runs in the harness.
  • F2 (P2, fixed in 1028cec9 + 842cd519): renamed files were classified by destination only, so src/auth/oauth.ts moved under docs/ skipped the implementation check and the maintainer-sponsored requirement. changedFiles now includes previous_filename.
  • F3 (P2, fixed in 1028cec9): bunfig.toml was missing from the duplicated implementation-file set (drifted from stack 1/5: add contribution intake firewall #900); parity restored.
  • F4 (P2, fixed in 1028cec9): approval labels on closed issues satisfied the gate forever; linkedIssueHasLabel now requires state === "open" (matching stack 1/5: add contribution intake firewall #900's approved-for-work rule).
  • F6 (fixed): merged the current 53ed63a1 parent (conflict-free).
  • Residual (no fix): the open-PR scan calls listFiles once per other open PR by the author (N+1) and pages over all open PRs; bounded by GitHub's limits, worth revisiting if the repo's PR count grows.

Security

  • Scope reviewed: pull_request_target trust boundary, token permissions, issue-label trust, restricted-surface enforcement, dispatch surface.
  • F5 (fixed in 842cd519): permissions moved into the trust-lane job with permissions: {} at workflow level.
  • F7 (fixed in 842cd519): guarded workflow_dispatch re-run added so a maintainer can re-evaluate after an issue gains large-change-approved / maintainer-sponsored; default-branch guard matches the stack 1/5: add contribution intake firewall #900/stack 2/5: gate review readiness and CodeRabbit #901 pattern, verified to reject branch-selected runs before any API call.
  • Findings: none confirmed after fixes. Trusted default-branch sparse checkout, persist-credentials: false, no PR-head execution, SHA pins verified.
  • Residual: none beyond the N+1 scan noted above.

Spec / standards

  • Spec source: PR body + design doc; all four summary claims now hold against the code, and the design doc is synced (renames, open-issue labels, dispatch).
  • Gaps: none blocking. Two PR-body claims are stale: "8 passed" (now 11) and "workflow YAML parsed successfully" (YAML parsed, but the script inside was broken until this review; it now parses and executes in the harness).

Reviews

  • Owners/maintainers: requested @Ingwannu and @lidge-jun; pending. Per MAINTAINERS.md this .github/** security-boundary change needs explicit maintainer security review before merge.
  • Bots: none - CodeRabbit skips auto-review on branch bases (will review once this targets dev).

Base / CI

  • Base: updated to 53ed63a1 (1b5092e5); mergeable: true, 0 behind.
  • Required checks: none configured for these paths (CI wiring is stack 5/5: define review lifecycle and governance rollout #905's stack job); React Doctor green on 9361bd35; CodeRabbit success (skipped).
  • Local tip compile/tests: 298/298 script tests, workflow YAML parses, full workflow script syntax-checked, 9-scenario harness passed (pass/block/size cap/open-closed labels/rename/maintainer exemption/dispatch guard/active-PR limit).

Gate

None: draft cleared, PR is ready for review. ship-gate.mjs could not run on this machine (gh token invalid); connector evidence used instead.

Simplification (approved S1)

Bottom line

Substantively clean and approve-worthy after the fix batch: the gate now actually runs, renames and closed issues cannot bypass it, bunfig.toml is classified consistently, permissions are job-scoped, and the branch is current with its parent. Merge still requires maintainer approval (requested), the synthetic fork test, and the remaining stack layers. When #903 is reviewed it will need the same base update - it is still based on the old cb508a68 head.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

@lidge-jun

Copy link
Copy Markdown
Owner

Same read as #900: the implementation is fine, the policy is the open question.

pr-trust-lane.cjs:70-123 caps a first-time contributor at one active implementation PR and 500 changed lines, with maintainer sponsorship required for workflow/auth/release/dependency surfaces. The sponsorship rule I agree with outright — those are the surfaces where a bad merge is expensive and hard to unwind.

The size and concurrency caps are where I hesitate. 500 lines rejects, for example, a provider preset with its registry rows, adapter wiring, tests, and five-locale docs — which is exactly the shape of a good first contribution here, and several have landed at more than that. The one-PR limit also penalizes someone who finds two unrelated bugs in an afternoon.

What I would merge without further discussion: the sponsorship requirement for sensitive surfaces, as its own check.

What needs a decision from me first: the caps. Leaving this open rather than closing it — if you feel strongly that the caps carry their weight, make that case and I will read it properly. My prior is that the deterministic hygiene gate in #903 catches most of what the size cap is proxying for, without telling a newcomer their fix is too big.

@lidge-jun

Copy link
Copy Markdown
Owner

Taking half of this, and closing the PR rather than leaving it open on a policy question I have now answered.

Kept — the sponsorship requirement, carried into #920 with your co-authorship: authentication, credential handling, workflows, release automation, and dependency installation need maintainer-sponsored before merge. Two changes from your version: it runs inside the existing hygiene job instead of adding a workflow, and it applies to every contributor rather than first-timers only. Blast radius does not depend on how many PRs someone has merged.

Dropped — the 500-line cap and the one-open-PR limit. A provider preset with its registry rows, adapter wiring, tests, and five locales clears 500 lines by itself, and several good first contributions here have. Someone who finds two unrelated bugs in an afternoon should be able to send both. Telling a newcomer their fix is too big is a worse failure than reviewing a large diff.

The restricted-path list in pr-trust-lane.cjs was carefully built and I reused it verbatim. Thanks for that part especially.

@lidge-jun lidge-jun closed this Aug 3, 2026
Wibias added a commit to n3wr1ch/opencodex that referenced this pull request Aug 3, 2026
…n the docs

Consolidates the parts of @Wibias's five-PR governance stack (lidge-jun#900, lidge-jun#902, lidge-jun#905)
that reduce risk without adding friction, and drops the parts that do the
opposite. The measurement behind the ordering: Windows was the last job to
finish in 23 of 23 recent CI runs at a 17m41s median, so lidge-jun#899 was the actual
bottleneck and everything here is judged by whether it makes the lane worse.

Kept, from lidge-jun#902's trust lane: authentication, credential handling, GitHub
Actions workflows, release automation, and dependency installation need a
maintainer to sponsor the change before it merges. MAINTAINERS.md already
requires security review for exactly these; this makes the requirement visible
on the pull request instead of relying on a reviewer noticing. It runs inside
the existing hygiene job rather than adding a workflow, and it applies to every
contributor — blast radius does not depend on how many PRs someone has merged,
which is why the upstream first-timer exemption is gone.

Dropped, from the same PR: the 500-line cap and the one-open-PR limit. A
provider preset with its registry rows, adapter wiring, tests, and five locales
clears 500 lines by itself, and several good first contributions here have.
Telling a newcomer their fix is too big is a worse failure than reviewing a
large diff.

Dropped, from lidge-jun#900: the admission gate requiring a pre-approved issue, and the
five-day auto-close. The DeepSeek reasoning replay, the Cursor Grok parameters,
the AgentRouter EOF tolerance, the tool-result image forwarding — every one
arrived as an unplanned PR from someone who hit the bug. A gate that required a
planning discussion first would have lost all of them.

Kept, from lidge-jun#905: CODEOWNERS entries for the high-impact runtime directories, and
the contributor documentation — rewritten to describe what is actually enforced.
The submitted version documented the approved-for-work gate, the size caps, and
the automatic closure timers, none of which exist here, and publishing rules the
repository does not enforce is worse than publishing none.

Not included: lidge-jun#901's readiness gate. It makes CodeRabbit's judgment blocking and
triggers per check_run, which scales with the job count lidge-jun#899 just raised.

Co-authored-by: Wibias <37517432+Wibias@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Maintenance, CI, tests, refactors, or build changes (not a user-facing bug or feature).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants