Skip to content

fix(ci): run fork gates from the trusted receiving repository - #461

Open
rita-aga wants to merge 4 commits into
mainfrom
codex/fork-token-minimum
Open

fix(ci): run fork gates from the trusted receiving repository#461
rita-aga wants to merge 4 commits into
mainfrom
codex/fork-token-minimum

Conversation

@rita-aga

@rita-aga rita-aga commented Sep 10, 2026

Copy link
Copy Markdown
Collaborator

Allow original fork contributions to use the existing private Stack gates. Trusted receiving-repository workflows fetch Stack, inspect contributor Git objects as data, and report results on the contributor commit. Evidence reruns follow the associated workflow. This fixes the STACK_TOKEN fork-secret mismatch without rehosting contributions.

Scope is token access and the required workflow/data-read/check-reporting changes only. Rita rejected and requested removal of the broader repair; the separate terminal-review schema/validator extension has been removed. Existing review requirements are unchanged. No MCP, proof-submission API, replacement chains, evidence-backend detection, or review-runner changes are included.

Tracks ARN-498. Companion: https://github.com/arni-labs/stack/pull/19 and #461. Verification after subtraction:68tests and10subtests passed. Prior review records remain historical and must not be represented as approval of this changed head. The previous exception request for the old heads is superseded by this scope correction. No merge or live fork-gate acceptance is claimed.

Decisions & Tradeoffs

Decisions

Decision: Run secret-bearing validation on the trusted receiving branch and inspect contribution objects without executing them.
Came up because: Fork pull_request jobs cannot receive STACK_TOKEN needed to fetch private Stack.
Options: Rehost contributions; distribute gate copies; correct workflow execution.
Chose workflow correction because: It preserves original contributions and the existing private tooling without another service. Builds stay unprivileged.
Where: Stack gates and Temper .github/workflows/sdlc-*.yml.

Decision: Use local isolated worktrees and GitHub directly for this effort.
Came up because: Temper MCP and health endpoint return HTTP 503.
Options: Wait indefinitely; repair the platform; use the local exception Rita explicitly approved.
Chose the approved exception because: It completes the narrow objective without reopening the broader platform work.
Where: Codex parent task 01a08157-a252-7b43-b1d9-facd84cd2695.

Decision: Preserve automatic-merge revocation when risk flags or workflow changes require human authorization, while never enabling auto-merge from the privileged validator.
Came up because: The original extraction removed that revocation together with automatic merge enabling.
Options: Remove both behaviors; retain revocation only.
Chose revocation only because: It preserves human control without granting the validator a new merge path. Revocation and Git/API failures remain visible failures.
Where: Stack gates/sdlc.yml and Temper sdlc-review.yml.

Decision: Use the documented Check Runs update fields and distinguish an absent feature map from a declared empty map.
Came up because: Review found a create-only field in the update request and a reproduced empty-map validation regression.
Options: Rely on undocumented extra-field handling and empty-set truthiness; preserve the existing contracts explicitly.
Chose explicit contracts because: A check is updated by its ID, while a declared feature map must reject unknown names even when it contains no features. The alleged HTTP422 was not observed; the API field correction follows GitHub's documented update contract.
Where: Contributor result reporters; Stack proof/validate.py and focused regressions.

Decision: Remove all additions outside the fork-token correction, including the terminal-review record extension.
Came up because: Rita explicitly rejected the extra work and authorized its cleanup.
Options: Retain the separate review-policy extension as a merge prerequisite; remove it.
Chose removal because: The accepted change is token access and its required workflow wiring. An unrelated gate limitation does not authorize another feature.
Where: Stack review files restored to the pre-effort versions; broad Stack17 and TemperPaw510 withdrawn; own additions to Temper436 removed.

Implemented and cleaned up by Codex (Astra), Codex desktop harness.

Greptile Summary

The PR moves private Stack validation into trusted pull_request_target workflows while treating contributor Git objects as data and publishing gate results against the contributor commit.

  • Adds contributor-commit check creation and completion reporting for decision, planning, review, and verification gates.
  • Fetches contributor objects without checking out or executing contributor code in secret-bearing jobs.
  • Retains auto-merge revocation for changes requiring human authorization without enabling auto-merge from the privileged validator.
  • Updates decision-intake reruns to locate contributor check records through trusted Stack tooling.
  • Documents the ARN-498 intent, contract, implementation plan, and tradeoffs.

Confidence Score: 4/5

The implementation has no newly introduced blocking defect since the previous review, but the outstanding repository requirement for an ADR must be satisfied before merging.

The earlier mutable-action finding remains outstanding because the trusted workflows still use version tags such as actions/github-script@v7 and actions/checkout@v6.0.2. The architecture-documentation finding also remains outstanding: the effort documents do not provide the required ADR under docs/adrs/ for the new trusted validation and contributor-check architecture. The previous base-commit finding was manually resolved without explanation.

Important Files Changed

Filename Overview
.github/workflows/sdlc-decision-intake.yml Replaces workflow-run lookup with trusted helper-based reruns of contributor review checks.
.github/workflows/sdlc-decisions.yml Moves decision validation into the receiving repository and reports its result on the contributor commit.
.github/workflows/sdlc-planning.yml Fetches contribution objects without checkout and runs trusted planning validation against them.
.github/workflows/sdlc-review.yml Runs trusted review validation, preserves required auto-merge revocation, and reports the result on the contributor SHA.
.github/workflows/sdlc-verification.yml Runs trusted proof validation against commit-bound contribution data and publishes the proof check on that commit.
docs/efforts/ARN-498/decisions.md Records the trusted-gate design decisions and narrows the effort by removing the terminal-review extension.
docs/efforts/ARN-498/spec.md Defines the trust boundary, commit-binding contract, and explicit exclusions for the workflow correction.

Sequence Diagram

sequenceDiagram
    participant Fork as Contributor fork
    participant GitHub as GitHub pull request
    participant Gate as Trusted receiving-repository gate
    participant Stack as Private Stack tooling
    participant Checks as Contributor commit checks

    Fork->>GitHub: Push contributor commit
    GitHub->>Gate: Trigger pull_request_target
    Gate->>Checks: Create in-progress check on contributor SHA
    Gate->>GitHub: Fetch PR Git objects without checkout
    Gate->>Stack: Fetch trusted validator with STACK_TOKEN
    Gate->>Gate: Validate contributor objects as data
    Gate->>GitHub: Confirm PR head is unchanged
    Gate->>Checks: Complete check on contributor SHA
Loading

Reviews (4): Last reviewed commit: "docs: restrict gate correction to fork t..." | Re-trigger Greptile

@rita-aga

Copy link
Copy Markdown
Collaborator Author

@greptile review

steps:
- name: Start the gate on the contributor commit
id: contributor_check
uses: actions/github-script@v7

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 security Mutable Actions In Trusted Gates

These trusted pull_request_target workflows use mutable references such as actions/github-script@v7 and actions/checkout@v6.0.2. If an upstream tag is compromised or repointed, its code runs with the receiving repository’s write-capable token and can forge contributor checks. A compromised checkout action could also persist environment or PATH changes that intercept the later secret-bearing Stack step. Pin every action used by these trusted workflows to a full commit SHA. The same pattern appears in the planning, review, and verification workflows.

How this was verified: The mutable action references execute in trusted jobs granted checks: write and pull-requests: write, before later steps receive STACK_TOKEN.

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/sdlc-decisions.yml
Line: 23

Comment:
**Mutable Actions In Trusted Gates**

These trusted `pull_request_target` workflows use mutable references such as `actions/github-script@v7` and `actions/checkout@v6.0.2`. If an upstream tag is compromised or repointed, its code runs with the receiving repository’s write-capable token and can forge contributor checks. A compromised checkout action could also persist environment or PATH changes that intercept the later secret-bearing Stack step. Pin every action used by these trusted workflows to a full commit SHA. The same pattern appears in the planning, review, and verification workflows.

**How this was verified:** The mutable action references execute in trusted jobs granted `checks: write` and `pull-requests: write`, before later steps receive `STACK_TOKEN`.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex Fix in Cursor

Comment on lines 9 to +16
types: [opened, edited, synchronize, reopened]
permissions:
contents: read
pull-requests: read
jobs:
decision-log:
permissions:
contents: read

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Architecture Change Lacks ADR

This PR introduces a new trusted pull_request_target validation and contributor-check reporting architecture across four workflows, but adds effort documentation instead of the required ADR under docs/adrs/. The repository requires an ADR before code for material architecture changes and new patterns. Document the security boundary, permissions, commit binding, and rollout order in an ADR before merging. The same issue applies to the planning, review, and verification workflows.

Context Used: CLAUDE.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: .github/workflows/sdlc-decisions.yml
Line: 9-16

Comment:
**Architecture Change Lacks ADR**

This PR introduces a new trusted `pull_request_target` validation and contributor-check reporting architecture across four workflows, but adds effort documentation instead of the required ADR under `docs/adrs/`. The repository requires an ADR before code for material architecture changes and new patterns. Document the security boundary, permissions, commit binding, and rollout order in an ADR before merging. The same issue applies to the planning, review, and verification workflows.

**Context Used:** CLAUDE.md ([source](https://github.com/nerdsane/temper/blob/main/CLAUDE.md))

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code Fix in Codex Fix in Cursor

@rita-aga

Copy link
Copy Markdown
Collaborator Author

ARN-498 review triage

Greptile — Temper bf8b5f6

  • Comment 3984638053, mutable official Action tags: not a confirmed defect in the fork correction. These same official actions already execute with repository secrets/write permissions for in-repository PRs. The changed boundary prevents contributor code from executing with secrets. Compromise of the trusted upstream provider is broader supply-chain hardening outside the accepted task; no evidence of compromise was reported. Keep the existing trusted-provider policy and record the risk.
  • Comment 3984638061, add an ADR: no application/kernel architecture or domain contract is introduced. The accepted workflow execution boundary, permissions, commit binding, and rollout are recorded in committed ARN-498 spec/plan/decisions. Adding another document is not a functional correction to the supplied diff. Reviewer criteria are Stack REVIEW.md and root REVIEW.md; the comment imports CLAUDE.md as another reviewer prompt. Dismiss as additional ceremony outside this scoped workflow correction.

@rita-aga

Copy link
Copy Markdown
Collaborator Author

@greptile review

Comment thread .github/workflows/sdlc-review.yml
@rita-aga

Copy link
Copy Markdown
Collaborator Author

Confirmation triage

The current Greptile findings do not require further source changes:

  • Temper 3984828847: checkout with fetch-depth: 0 fetches all branches and tags, even when the selected checkout ref is the default branch. The non-default base is not omitted as claimed. This is explicit in actions/checkout v6.0.2 source.
  • The mutable official Action-tag and additional ADR requests retain the previously recorded scope decisions. No upstream compromise or missing implementation behavior was demonstrated.
  • Stack 3984657773 refers to the old head and incorrectly said -r was missing from -rz. The separate, actual README-only map regression found by Codex has been fixed and tested.

@rita-aga

Copy link
Copy Markdown
Collaborator Author

ARN-498 independent verification

Verified Stack e8727047f288766d9d9740f5ebd0c4c1f44cd7c0 and Temper e26bed84fb93e20979d426fcb1f3fc1735e2c6ae without source edits.

  • /tmp/arn498-venv/bin/python -m pytest gates/test_record_posting.py gates/test_fork_workflow.py gates/test_auto_merge_revocation.py gates/test_effort_artifacts.py -q: 48 passed in 24.66s. Non-failing warning: sandbox denied pytest cache write in the source checkout.
  • PYTHONDONTWRITEBYTECODE=1 /tmp/arn498-venv/bin/python -m pytest review/test_terminal_review.py review/test_rubrics.py proof/test_features_commit.py -q -o cache_dir=/private/tmp/arn498-final/independent/pytest-cache --basetemp=/private/tmp/arn498-final/independent/validator-tmp: 44 passed, 10 subtests passed in 13.36s.
  • /tmp/arn498-venv/bin/python /private/tmp/arn498-final/independent/verify_temper_workflows.py: passed. All four actual Temper workflows use the same contributor-check start/final scripts exercised by Stack's success/failure/cancelled/stale-head cases. The three workflows needing repository objects use default-branch checkout and identical fetch-without-checkout steps. The decision-log workflow needs no repository checkout. The review revocation step and environment exactly match the six exercised CLI scenarios. Proof validation passes the contributor SHA through --features-commit.

The first equivalence probe compared all job permissions literally and stopped because standalone Temper workflows and the combined Stack workflow differ in extra permissions. The corrected probe checks the permissions required by the behavior (checks: write, contents: read) and records the actual permissions; this was an over-strict probe assumption, not a source defect. A read command also attempted a nonexistent standalone Stack workflow path; the actual source is gates/sdlc.yml and was subsequently used.

No confirmed defect. These are executed local regressions and comparison of the actual Temper workflow scripts against the tested scripts, with mocked GitHub/CLI boundaries in the tests. No live GitHub Actions execution is claimed. Source worktrees remained clean at the specified SHAs.

This proof covers the local gate implementation and workflow wiring. The live acceptance case is the corrected receiving-repository Actions run on Nick’s unchanged fork heads after this repair lands; that result will be recorded separately. No application image changes or deployment are part of this workflow/docs repair.

@rita-aga
rita-aga marked this pull request as ready for review September 11, 2026 01:11
@rita-aga

Copy link
Copy Markdown
Collaborator Author

Third-round review status — incomplete panel

Current-head Codex review: no findings. Independent verification:92tests and10subtests passed. Fable could not run because its subscription quota is exhausted. Grok failed to return a verdict within the bounded1200second attempt. These failures are not approvals. The normal one-model skip rule is not met.

The three-round stop has been reached. Arbitration is assessing the existing evidence; no fourth panel or broader tooling repair is being started. The owning task retains the user's authorization to merge, but does not reinterpret that as a panel-quorum waiver.

@rita-aga

Copy link
Copy Markdown
Collaborator Author

Verdict

The implementation loop is technically closed: every confirmed defect was fixed, the final heads passed available review and tests, and no implementation finding remains. The unresolved issue is panel availability, so a human must explicitly accept a one-time reviewer-minimum exception or pause.

Why

Findings concentrated in rounds 1–2 on concrete workflow defects; each was corrected and independently reverified. The fixes remained narrow, added only the bounded watcher/rerun needed for evidence correctness, introduced none of the prohibited machinery, and still match the authorized intent.

Round 3 found no defect: Codex was clean, 92 tests plus 10 subtests passed, and workflow equivalence and Temper CI passed. Fable exhausted quota and Grok timed out, leaving quorum unavailable rather than an adverse review result.

Recurring threads

  • API request, empty feature map, and auto-merge revocation: real defect, fixed before the final heads.
  • Active-run evidence reevaluation race: real defect, fixed and verified.
  • Fable quota and Grok execution failures: reviewer noise, not evidence of a code failure.
  • Reopening Nick docs: accept immutable typed reference design #411/docs: accept metadata-generated module SDK design #412’s terminal disposition: contested design already covered by an accepted decision; keep it separate.
  • Extra machinery: none.
  • Drift from intent: none.

Verification limits

No source checkout was available, so this judgment relies solely on the supplied history and reported evidence; the diff and test artifacts were not directly inspected. Full panel quorum was not achieved, no PR has merged, and live corrected-fork Actions acceptance can only be verified after landing.

Options

  • Accept a one-time reviewer-minimum exception for these exact two heads and land them subject to live receiving-workflow acceptance.
  • Pause this exact effort unchanged until the required reviewer quorum becomes available.

Recommendation: Accept the one-time exception; another review round would violate the stopping decision without addressing an open implementation defect.

Human question

Do you authorize a one-time reviewer-minimum exception for arni-labs/stack#19 at e8727047f288766d9d9740f5ebd0c4c1f44cd7c0 and nerdsane/temper#461 at e26bed84fb93e20979d426fcb1f3fc1735e2c6ae, permitting landing subject to live corrected-fork Actions acceptance while preserving Nick #411/#412 under their separate existing terminal approval?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant