Skip to content

[ACP-REVIEW-410] Authority consumerの対象bindingとCheckRun/WorkflowRun IDを明確化する #3676

Description

@ootakazuhiko

Parent: #3655
Review origin: #3675
Builds on: completed #3657; related #3659, #3660, #3667.
Scheduling: follow-up implementation after the active recovery; NOT a new acceptance requirement for #3672 / PR #3674 or #3671 / PR #3673. Do not edit those branches.

Confirmed source observations

Inspected main c5da6115638fdbfeebbc458b39fa6916db66afb0:

  1. resolveAndValidateRepositoryLocalGitHubWorkStateSnapshot verifies repository-local path, regular/non-symlink file, Schema, semantic digest and an expected digest. Its options do not include expected repository, Issue, PR, base/head or lifecycle. This is an integrity check, not a check that the snapshot is the current task's authority.
  2. adapter-stdio.mjs supplies only repoRoot and expectedDigest and forwards the validated digest. A structurally valid copied snapshot is not rejected solely for belonging to a different task; source-level finding, not a claim of a demonstrated remote attack.
  3. normalizeCheckNode() in the same library stores GraphQL CheckRun.databaseId in runId. capture-github-work-state.mjs does not request Actions WorkflowRun identity. A check-run ID must not be passed to gh run view as an Actions workflow-run ID.
  4. Snapshot reads use unbounded readFileSync/JSON.parse; stdio input also grows without a byte bound. Existing path protection is useful but does not bound parsing resources or reject duplicate JSON keys.

GitHub identity reference: https://docs.github.com/en/graphql/reference/actions . Review the current primary documentation during implementation; do not infer identity equivalence from numeric appearance.

Goal

Make integrity validation, task-scope validation, observation freshness and authorization four explicit, separate decisions. No digest or successful parse grants merge/release authority.

Preflight

Read AGENTS, CODEX-ISSUE-RUNBOOK, #3657 implementation, TaskRequest/TaskResponse, handoff consumers, #3659/#3660 planned contracts and Context Pack/Boundary Map. Search existing work before creating a branch. Use one clean worktree, one Issue, one Draft PR. Re-fetch current source; the revision above is evidence, not a required current head.

Implementation scope

  • Inventory every consumer of authoritySnapshotDigest and classify it as informational, task-scoped or authorization-related.
  • Add a trusted expected-subject input: repository identity, Issue/PR numbers, expected source head, and optional base/lifecycle as required by the use case. Derive it from the operator/control plane, not from the same untrusted snapshot or model output being checked. Fail on mismatch for task-scoped consumption. Informational imports may remain allowed but must be marked non-authoritative.
  • Keep Schema/digest validation network-free. Implement optional live revalidation as a separate trusted step. An old signed or hashed observation is still old; freshness policy requires an injected evaluation time and declared maximum age, not wall-clock mutation of deterministic content.
  • Introduce distinct checkRunId, checkSuiteId, workflowRunId, workflowRunAttempt and workflow identity only when observed. Preserve null / not-observed for external providers without Actions runs. Do not reinterpret legacy runId silently; document a compatibility reader or versioned migration.
  • Distinguish workflow head, PR source head, test-merge SHA and main merge SHA. Require a recorded relationship where an acceptance surface deliberately executes the test-merge commit.
  • Add bounded UTF-8/JSON input reads and duplicate-key rejection shared by snapshot entry points where appropriate. Keep symlink protections; do not claim atomic filesystem provenance or authenticated GitHub origin from a self-recomputed digest.
  • Do not add a new mandatory gate to every PR in this Issue. Use explicit task-scoped opt-in and migration notes.

Acceptance / negative matrix

  • A valid snapshot for repository A cannot satisfy an authority requirement for repository B.
  • Same repository with wrong Issue, wrong PR, wrong head, or required lifecycle mismatch is rejected.
  • Model-supplied expected identity cannot replace trusted expected identity.
  • Old but internally valid snapshots are informational or rejected according to explicit freshness policy; freshness checks do not alter the semantic digest.
  • Check-run and workflow-run IDs differ in fixtures and resolve through the correct API/CLI path; no numeric-ID guessing.
  • Non-Actions checks and unavailable workflow metadata are represented honestly.
  • Oversized, malformed, duplicate-key, traversal and symlink inputs are rejected before unsafe/unbounded processing.
  • Existing validated informational use has a documented compatibility path.
  • Tests prove integrity-valid is not task-valid, task-valid is not fresh, and fresh is not human-approved.

Validation / stop

Focused authority/handoff/stdio tests, full relevant unit suite, Schema self-validation, build, api:check, check:schemas, check:doc-consistency, verify:lite, Context Pack/Boundary Map and exact-head required CI. Record unavailable executions honestly. Finish as Draft with zero unresolved actionable review threads and clean worktree. No merge, Issue close, branch-protection changes, publication, or edits to PR #3674/#3673.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:contractsSchemas and contractsassurance-control-planeAgent-neutral assurance control plane roadmapcodex-readyIssue body is structured for Codex CLI executionpriority:p1Important next slicerisk:highHigh risk PR (approval and gate labels required)type:taskImplementation task

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions