Permissions and fork security
Quality Graph separates execution from publication.
The pull_request workflow executes repository code with read-only permissions, no secrets,
and checkout credentials disabled. Forks and same-repository branches follow the same rule in
this pre-release.
The publisher runs trusted code from the default branch through workflow_run. It never
checks out pull-request code. Downloaded artifacts are treated as untrusted data and checked
for metadata digest, archive size, file count, ZIP traversal, symlinks, node identity, pull
request, head SHA, run, attempt, and graph digest before JSON parsing.
For reruns, result admission uses the last execution of each declared job at or before the publication attempt, resolved through GitHub attempt-specific job history. Retained artifacts are accepted only for that execution; a rerun with no result cannot reuse an older success. Future attempts and conflicting results for the same node and attempt fail validation. Identical duplicate results are accepted. Missing, ambiguous, or incomplete job evidence fails closed. Raw passed results cannot override failed or cancelled job evidence. Approval policy is applied only after admission, preserving approvals of valid quality findings. The publisher, watcher, and administrator commands share this admission path. First attempts accept only attempt-1 artifacts and need no historical job lookup.
One publisher invocation owns the live dashboard for the complete workflow run. It polls authoritative GitHub job state and merges every node by its stable graph identity, so parallel jobs cannot overwrite each other's lifecycle. The watcher finalizes artifact-derived state when all declared jobs are terminal, while the completed event shares the same concurrency group and independently repairs the final state. Both paths update the same check run through its stable workflow-run identity.
Governance configuration always comes from the pull request base SHA. A pull request may propose graph changes for review, but proposed roles, labels, and controls do not receive trusted authority before merge.
Generated permissions are job-specific:
- execution:
contents: reador less; - publication:
actions: read,checks: write,issues: write,pull-requests: write; - commands: the same read access plus
actions: writefor rerunning failed jobs.
Dashboard Markdown is not an authorization source. Checkbox edits are converted to canonical commands, rolled back, authorized through current collaborator permission, and persisted as append-only, bot-owned, unedited ledger records.
Do not add secret-bearing PR jobs or replace the trusted publisher with pull_request_target.
Credential-bearing execution requires a separate threat-model design.