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:
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.
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.
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.
- 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
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.
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:resolveAndValidateRepositoryLocalGitHubWorkStateSnapshotverifies 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.adapter-stdio.mjssupplies onlyrepoRootandexpectedDigestand 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.normalizeCheckNode()in the same library stores GraphQLCheckRun.databaseIdinrunId.capture-github-work-state.mjsdoes not request Actions WorkflowRun identity. A check-run ID must not be passed togh run viewas an Actions workflow-run ID.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
authoritySnapshotDigestand classify it as informational, task-scoped or authorization-related.checkRunId,checkSuiteId,workflowRunId,workflowRunAttemptand workflow identity only when observed. Preservenull/ not-observed for external providers without Actions runs. Do not reinterpret legacyrunIdsilently; document a compatibility reader or versioned migration.Acceptance / negative matrix
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.