Skip to content

ci(af01): establish workflow trust baseline - #43

Merged
TheHalfMoon merged 76 commits into
mainfrom
feat/af01-stack-a-workflow-trust
Aug 27, 2026
Merged

ci(af01): establish workflow trust baseline#43
TheHalfMoon merged 76 commits into
mainfrom
feat/af01-stack-a-workflow-trust

Conversation

@TheHalfMoon

@TheHalfMoon TheHalfMoon commented Aug 26, 2026

Copy link
Copy Markdown
Owner

AF-01 Stack A — workflow trust baseline

Canonical base at PR creation:

main: eeecb0bc03c7040bb18b70bce8b69d618384f783
tree: d5abe932f1436a9612f45bf130ba29aadbc5a133

This PR implements AF-01 Phase 1 / Stack A only. It does not change commandF product semantics, CF-06 oracle identity, CF-10 corpus authority, package/diff/terminology/impact rules, or dependency policy.

T010 — inventory

Adds stack-a-inventory.md covering every tracked workflow and Action metadata file, external uses: authority, job runners, effective permissions, timeouts, proof containers, checkout credentials, and lockfile-consuming Cargo commands at the canonical planning base.

T011/T012 — machine-checkable policy + deterministic audit

Adds:

  • .github/workflow-trust-policy.json
  • .github/scripts/audit_workflow_trust.py

The audit discovers all tracked .github/workflows/*.yml|*.yaml and every tracked action.yml|action.yaml at any depth, rejects unplanned workflows/jobs, mutable external uses: references, mutable latest runner labels, missing/excessive timeouts, unresolved/default or overbroad token permissions, checkout credentials left enabled, mutable job/service container identities, and configured lockfile-consuming Cargo commands without --locked. Local ./ actions remain allowed.

Output is deterministic JSON and exceptions require explicit rule/path/reason/revisit evidence.

T013/T016 — counterexamples and future-file coverage

Adds a repository-owned test suite covering:

  • tag/branch/short-SHA external refs;
  • nested action.yaml mutable uses;
  • both Action metadata filename forms at arbitrary depth;
  • missing checkout persist-credentials: false;
  • unresolved/default and overbroad permissions;
  • mutable *-latest runner labels;
  • missing/excessive timeouts;
  • mutable job and service container images;
  • unlocked Cargo commands;
  • malformed workflow input;
  • newly tracked workflow coverage;
  • deterministic repeat output;
  • invalid exception metadata.

T014/T015 — current workflow hardening

ci.yml now uses full-SHA checkout/rust-toolchain references, credentialless checkout, ubuntu-24.04, explicit 30-minute timeout, and executes the AF-01 audit tests plus live repository audit before Rust gates.

cf06-oracle.yml preserves all existing oracle commands/evidence while fixing runners to ubuntu-24.04, bounding all three jobs, and reducing the aggregation-only oracle-proof job to permissions: {}.

registry-download-smoke.yml moves its runner from ubuntu-latest to ubuntu-24.04; existing timeout, pinned actions, credentials, and semantic smoke behavior remain unchanged.

The CF-11/CF-11G/CF-12/CF-13 proof workflows already satisfied the selected Stack A baseline and are not semantically rewritten.

Qualification required before merge

  • exact-head mandatory ci;
  • every path-applicable existing proof/oracle workflow terminal green;
  • fresh exact-head CodeRabbit and Qodo review;
  • zero unresolved substantive findings;
  • exact-head merge only;
  • post-merge main/tree verification.

No PASS is assumed from queue state or review launch.


Summary by cubic

Establishes AF-01 Stack A's deterministic workflow trust baseline so CI rejects mutable runners, unpinned action references, unlocked Cargo commands, and untrusted executable shell surfaces before Rust gates run. Every tracked workflow must match the checked-in policy or the audit fails closed.

Changes

  • Adds the trust policy, workflow inventory, core, executable-surface, and cross-step environment-channel audit scripts, counterexample suites, and live CI gates that fail on drift.
  • Audits external action SHAs, nested Action metadata, checkout credentials, runners, permissions, timeouts, container digests, locked Cargo commands, executable shell surfaces, and GITHUB_PATH/GITHUB_ENV writes that can alter later-step command resolution.
  • Fails closed on unknown rules, malformed syntax, quoted keys, retry wrappers, shell indirection at the executable position, indirect environment channel authority, shell startup environment (BASH_ENV/ENV/ZDOTDIR) writes, direct relative action script paths, unresolved action env wrappers, Action PATH mutation including builtin and dynamic variable-name writers, and wrapper heredocs or hash commands at the execution boundary; scopes Cargo detection so unrelated substitution text is not flagged.
  • Treats heredoc bodies and shell test expressions as data; allows plain or toolchain-selected cargo version calls. Dynamic variable-name writers are parsed quote-aware so quoted patterns are not flagged.
  • Pins runners and actions, adds timeouts, drops unneeded permissions, disables checkout credential persistence, and rewrites the registry smoke retry into an explicit loop.
  • Binds the Action runner to the built commandF path via CARGO_TARGET_DIR instead of an externally supplied executable.
  • Leaves commandF semantics, CF-06 oracle identity, and CF-10 corpus authority unchanged.

Written for commit 28d9e39. Summary will update on new commits.

Review in cubic

@qodo-code-review

Copy link
Copy Markdown

ⓘ Your Qodo trial ends soon. Ask your workspace admin to set up billing to keep reviews running after the trial. Manage billing

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

Copy link
Copy Markdown
Owner Author

@qodo review

Please review exact current head e844f5b306cbf201cc31fa893539d2ed0875486c. Focus on AF-01 Stack A only: deterministic workflow/action discovery, full-SHA external uses: enforcement, checkout credential checks, effective permission normalization/allowlist behavior, fixed runner and timeout policy, job/service container digest enforcement, Cargo --locked detection, exception fail-closed behavior, counterexample adequacy, and whether the workflow hardening preserves existing CF-06/CI/registry semantics. Do not infer approval from prior PRs.

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Please perform a fresh review of exact current head e844f5b306cbf201cc31fa893539d2ed0875486c. Focus on audit parser correctness and fail-closed behavior, security coverage gaps, false-positive/false-negative risks, test validity, workflow permission/runner/timeout hardening, immutable external references and containers, and accidental changes to existing product/oracle/proof semantics. No PASS is assumed.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Establish machine-checkable GitHub Actions trust baseline

✨ Enhancement 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Defines policy-backed auditing for immutable dependencies, bounded authority, and reproducible
 Cargo execution.
• Adds counterexample tests and runs trust validation before Rust CI gates.
• Hardens runners, action pins, checkout credentials, timeouts, and oracle permissions.
Diagram

graph TD
  A["Tracked files"] --> C["Trust audit"] --> D["JSON findings"] --> E{"Policy passes?"} -->|Yes| F["Rust gates"]
  B["Trust policy"] --> C
  E -->|No| G["Fail CI"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Standard YAML parser plus policy checks
  • ➕ Handles broader valid YAML syntax and structures
  • ➕ Reduces risks from indentation and scalar edge cases
  • ➖ Adds a runtime dependency to the mandatory trust gate
  • ➖ Still requires custom GitHub Actions semantic validation
2. Third-party workflow security scanner
  • ➕ Provides established checks and broader ecosystem coverage
  • ➕ May identify additional GitHub Actions security risks
  • ➖ Cannot directly encode the repository's exact workflow and job allowlist
  • ➖ Introduces another external tool and update authority into the trust path

Recommendation: Keep the repository-owned policy-driven audit because it provides exact fail-closed authority, deterministic output, and no new dependency. The custom parser intentionally supports a constrained workflow subset; complementing it later with a standard scanner is preferable to replacing the repository-specific policy checks.

Files changed (7) +915 / -10

Enhancement (1) +411 / -0
audit_workflow_trust.pyAdd deterministic workflow trust auditor +411/-0

Add deterministic workflow trust auditor

• Introduces tracked-file discovery and fail-closed checks for planned workflows and jobs, immutable action and container identities, fixed runners, bounded timeouts, explicit permissions, credentialless checkout, and locked Cargo commands. Produces sorted JSON findings and supports narrowly documented policy exceptions.

.github/scripts/audit_workflow_trust.py

Tests (1) +263 / -0
test_audit_workflow_trust.pyCover workflow trust policy counterexamples +263/-0

Cover workflow trust policy counterexamples

• Adds repository-owned unit tests for deterministic success output and failures involving mutable references, new files, credentials, permissions, runners, timeouts, containers, Cargo commands, malformed input, and invalid exceptions.

.github/scripts/test_audit_workflow_trust.py

Documentation (1) +110 / -0
stack-a-inventory.mdDocument canonical workflow trust inventory +110/-0

Document canonical workflow trust inventory

• Records the planning-base workflow and Action metadata authority, job permissions, runners, timeouts, action references, checkout behavior, containers, and lockfile-consuming Cargo commands. Defines the Stack A machine-checkable target and scope boundary.

specs/015-af-01-trusted-development-baseline/stack-a-inventory.md

Other (4) +131 / -10
workflow-trust-policy.jsonDeclare workflow and job trust authority +110/-0

Declare workflow and job trust authority

• Defines global trust rules and the expected jobs, effective permissions, fixed runners, and timeout ceilings for every tracked GitHub Actions workflow. Starts with no policy exceptions.

.github/workflow-trust-policy.json

cf06-oracle.ymlBound CF-06 oracle workflow authority +8/-4

Bound CF-06 oracle workflow authority

• Pins all oracle jobs to Ubuntu 24.04 and adds job-specific timeout limits. Removes repository token permissions from the aggregation-only proof job while preserving oracle validation behavior.

.github/workflows/cf06-oracle.yml

ci.ymlEnforce trust auditing before Rust gates +11/-4

Enforce trust auditing before Rust gates

• Pins the runner and external actions, disables persisted checkout credentials, and bounds the CI job duration. Runs the audit test suite and live repository audit before existing Rust checks.

.github/workflows/ci.yml

registry-download-smoke.ymlPin registry smoke runner image +2/-2

Pin registry smoke runner image

• Replaces the mutable Ubuntu latest runner label with Ubuntu 24.04 while retaining the existing timeout and registry smoke behavior.

.github/workflows/registry-download-smoke.yml

@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== HEAD =='
git rev-parse HEAD
printf '%s\n' '== STATUS =='
git status --short
printf '%s\n' '== MERGE BASE =='
git merge-base HEAD main || true
printf '%s\n' '== CHANGED FILES VS MAIN =='
git diff --name-status "$(git merge-base HEAD main)" HEAD
printf '%s\n' '== AF-01 CANDIDATE FILES =='
fd -HI -t f . .github | sort
printf '%s\n' '== PYTHON OUTLINE =='
ast-grep outline .github/scripts/audit_workflow_trust.py --items all 2>/dev/null || true
printf '%s\n' '== TEST OUTLINES =='
fd -HI -t f -e py .github | while IFS= read -r f; do
  case "$f" in
    *test*|*Test*) printf '%s\n' "--- $f"; ast-grep outline "$f" --items all 2>/dev/null || true ;;
  esac
done
printf '%s\n' '== WORKFLOW DIFF STAT =='
git diff --stat "$(git merge-base HEAD main)" HEAD -- .github

Length of output: 4380


🏁 Script executed:

#!/bin/bash
set -euo pipefail

base="$(git merge-base HEAD main)"

printf '%s\n' '== AUDIT IMPLEMENTATION: 1-230 =='
sed -n '1,230p' .github/scripts/audit_workflow_trust.py
printf '%s\n' '== AUDIT IMPLEMENTATION: 230-430 =='
sed -n '230,430p' .github/scripts/audit_workflow_trust.py
printf '%s\n' '== POLICY =='
cat .github/workflow-trust-policy.json
printf '%s\n' '== TEST FILE =='
cat .github/scripts/test_audit_workflow_trust.py
printf '%s\n' '== INVENTORY =='
cat specs/015-af-01-trusted-development-baseline/stack-a-inventory.md
printf '%s\n' '== WORKFLOW DIFFS =='
git diff --find-renames --find-copies "$base" HEAD -- \
  .github/workflows/cf06-oracle.yml \
  .github/workflows/ci.yml \
  .github/workflows/registry-download-smoke.yml
printf '%s\n' '== CURRENT WORKFLOWS =='
for f in .github/workflows/*.yml .github/workflows/*.yaml; do
  [ -f "$f" ] || continue
  printf '\n--- %s ---\n' "$f"
  cat "$f"
done

Length of output: 82811


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== AUDIT LINE NUMBERS: USES, CARGO, YAML ERROR HANDLING =='
nl -ba .github/scripts/audit_workflow_trust.py | sed -n '145,185p;230,335p'
printf '%s\n' '== TEST LINE NUMBERS =='
nl -ba .github/scripts/test_audit_workflow_trust.py | sed -n '100,245p'
printf '%s\n' '== ROOT ACTION METADATA =='
if [ -f action.yml ]; then
  nl -ba action.yml
fi
if [ -f action.yaml ]; then
  nl -ba action.yaml
fi
printf '%s\n' '== YAML SPECIAL-FORM SEARCH =='
rg -n --glob '*.yml' --glob '*.yaml' \
  '^\s*(["'\''](?:uses|runs-on|timeout-minutes|permissions|image)["'\'']|<<:|[^#]*&[A-Za-z0-9_-]+|[^#]*\*[A-Za-z0-9_-]+)' \
  .github action.yml action.yaml 2>/dev/null || true
printf '%s\n' '== CARGO LINE-CONTINUATION/GLOBAL-OPTION SEARCH =='
rg -n -U --glob '*.yml' --glob '*.yaml' \
  'cargo\s*(\\\s*\n|(?:--[A-Za-z0-9-]+(?:[ =][^[:space:]]+)?\s+|\+[A-Za-z0-9_.-]+\s+))' \
  .github action.yml action.yaml 2>/dev/null || true
printf '%s\n' '== DIFF WHITESPACE =='
git diff --check "$(git merge-base HEAD main)" HEAD
printf '%s\n' '== ALL CHANGES OUTSIDE AF-01 =='
git diff --name-only "$(git merge-base HEAD main)" HEAD -- . ':(exclude).github' ':(exclude)specs/015-af-01-trusted-development-baseline'

Length of output: 1634


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== AUDIT LINE NUMBERS: USES, CARGO, YAML ERROR HANDLING =='
cat -n .github/scripts/audit_workflow_trust.py | sed -n '145,185p;230,335p'
printf '%s\n' '== TEST LINE NUMBERS =='
cat -n .github/scripts/test_audit_workflow_trust.py | sed -n '100,245p'
printf '%s\n' '== ROOT ACTION METADATA =='
if [ -f action.yml ]; then
  cat -n action.yml
fi
if [ -f action.yaml ]; then
  cat -n action.yaml
fi
printf '%s\n' '== YAML SPECIAL-FORM SEARCH =='
rg -n --glob '*.yml' --glob '*.yaml' \
  '^\s*(["'\''](?:uses|runs-on|timeout-minutes|permissions|image)["'\'']|<<:|[^#]*&[A-Za-z0-9_-]+|[^#]*\*[A-Za-z0-9_-]+)' \
  .github action.yml action.yaml 2>/dev/null || true
printf '%s\n' '== CARGO LINE-CONTINUATION/GLOBAL-OPTION SEARCH =='
rg -n -U --glob '*.yml' --glob '*.yaml' \
  'cargo\s*(\\\s*\n|(?:--[A-Za-z0-9-]+(?:[ =][^[:space:]]+)?\s+|\+[A-Za-z0-9_.-]+\s+))' \
  .github action.yml action.yaml 2>/dev/null || true
printf '%s\n' '== DIFF WHITESPACE =='
git diff --check "$(git merge-base HEAD main)" HEAD
printf '%s\n' '== ALL CHANGES OUTSIDE AF-01 =='
git diff --name-only "$(git merge-base HEAD main)" HEAD -- . ':(exclude).github' ':(exclude)specs/015-af-01-trusted-development-baseline'

Length of output: 21294


@TheHalfMoon I reviewed exact commit e844f5b306cbf201cc31fa893539d2ed0875486c.

I found two substantive AF-01 Stack A findings.

  1. P1 — Quoted YAML keys bypass the uses: and checkout credential checks.
    .github/scripts/audit_workflow_trust.py Line 166 only matches an unquoted uses: key. YAML accepts quoted mapping keys. For example, this valid workflow step bypasses both rules:

    - "uses": actions/checkout@v5

    The audit does not report mutable_uses or checkout_credentials because _all_uses() ignores "uses":. The same gap applies to quoted uses keys in tracked action.yml and action.yaml files. Use a YAML parser and validate the parsed workflow or Action structure. At minimum, reject unsupported YAML syntax instead of treating it as safe. Add counterexamples for quoted uses keys in both workflow and Action metadata inputs.

  2. P1 — Valid Cargo invocation forms bypass --locked enforcement.
    .github/scripts/audit_workflow_trust.py Line 305 only detects cargo followed immediately by a tracked subcommand on one physical line. A workflow can run a lockfile-consuming command without detection by using valid shell and Cargo syntax such as:

    run: cargo +1.97.1 test --workspace

    A line continuation also bypasses the detector:

    run: |
      cargo \
        test --workspace

    Neither form matches CARGO_RE, so the audit returns success without --locked. Parse each run script as shell input, or fail closed when a Cargo invocation cannot be normalized. Add negative tests for toolchain selectors, Cargo global options, and line continuations.

The workflow diff preserves the existing CF-06 commands and registry smoke commands. The CI changes add the audit gates before Rust gates. The aggregation-only oracle-proof job now has permissions: {}. I found no product, oracle, or proof semantic changes outside the AF-01 scope.

I verified that the requested commit and canonical merge base match. I also verified that no changed paths exist outside .github and the AF-01 inventory specification. I did not execute repository scripts or tests because the review sandbox prohibits executing repository files.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b57dac82-3397-4143-850f-e8379646e0ac

Warning

Your free Security trial is over. An organization admin can activate billing to continue.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@qodo-code-review

Copy link
Copy Markdown

review

Please review exact current head e844f5b306cbf201cc31fa893539d2ed0875486c. Focus on AF-01 Stack A only: deterministic workflow/action discovery, full-SHA external uses: enforcement, checkout credential checks, effective permission normalization/allowlist behavior, fixed runner and timeout policy, job/service container digest enforcement, Cargo --locked detection, exception fail-closed behavior, counterexample adequacy, and whether the workflow hardening preserves existing CF-06/CI/registry semantics. Do not infer approval from prior PRs.

I reviewed the supplied e844f5b306cbf201cc31fa893539d2ed0875486c diff as a fresh review. I found three issues in the AF-01 audit implementation.

Findings

  1. High — Cargo lock enforcement can be bypassed by unrelated text on the same line (.github/scripts/audit_workflow_trust.py:305-313)

    • The check searches from the cargo <subcommand> match to the end of the raw YAML line and only tests whether --locked appears anywhere in that suffix.
    • Consequently, an invocation such as cargo test --workspace && echo --locked passes, as does an unlocked first invocation followed by a locked second invocation on the same line. Comments and quoted text can also satisfy the check.
    • Parse shell commands sufficiently to associate --locked with each invocation, or conservatively reject ambiguous command lines. Add counterexamples covering chained commands, comments, quoted text, and multiple Cargo invocations.
  2. Medium — Timeout policy is bounded, not fixed to the declared value (.github/scripts/audit_workflow_trust.py:267-277)

    • A policy value of 30 accepts any timeout from 1 through 30 minutes. Thus a change from the declared CI timeout of 30 minutes to 1 minute passes the audit, despite the policy/inventory presenting timeout_minutes as the job’s configured timeout.
    • If AF-01 requires the declared timeout to be authoritative, compare for equality; otherwise rename/document this explicitly as a maximum and add tests proving the intended lower-bound behavior.
  3. Medium — Policy validation is not fail-closed for malformed job/rule schemas (.github/scripts/audit_workflow_trust.py:342-367)

    • The validator checks only schema and that rules is a dictionary. It does not validate that workflow entries and job entries are dictionaries, that expected permissions are valid allowlisted GitHub permission maps, or that timeout_minutes/runner have valid types.
    • A malformed policy can therefore raise KeyError/AttributeError during audit_repository; when invoked through main, those exceptions are not in the handled exception list, so the tool emits a traceback instead of its deterministic JSON failure result. An invalid permission policy can also become the comparison authority rather than being rejected.
    • Validate the complete policy schema before auditing, including an explicit permission-key/value allowlist, and convert all policy-shape failures into invalid_policy findings.

Areas that look correct

  • Discovery is deterministic over tracked files, covers both workflow extensions under .github/workflows/, and finds action.yml/action.yaml at arbitrary tracked paths.
  • Current external action references are full 40-character SHAs; local ./ actions are correctly treated as repository-owned rather than external.
  • Checkout steps in the changed workflows use persist-credentials: false; current job/service container images are digest-bound.
  • Current workflow permissions, runners, and timeouts match the policy, and the CF-06 oracle-proof job’s explicit {} permissions do not alter its validation logic.
  • The registry workflow’s restored done and the CF-06 proof assertion preserve the apparent existing semantics; the CI changes add pinned setup, the audit gates, and bounded execution without changing the Rust test commands.

Counterexample coverage

The tests cover the main happy path and several direct mutations, but they do not cover malformed policy shapes, unknown permission keys, multiple checkout steps, ambiguous/chained Cargo commands, quoted/commented Cargo text, or whether timeout equality versus maximum semantics is intended. These should be added before treating the audit as a complete fail-closed control.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

Copy link
Copy Markdown
Owner Author

@qodo review

Fresh exact-head review required after self-review hardening. Review current head 0be4766d3f2631f1dba24f03706da8ffe81f3279; prior review activity on e844f5b306cbf201cc31fa893539d2ed0875486c is stale. Specifically verify the shared workflow/action-metadata checkout credential enforcement, invalid-policy fail-closed path, narrowed job/service container discovery, and all previously requested AF-01 Stack A trust invariants. No PASS is assumed.

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Fresh exact-head review required after self-review hardening. Review current head 0be4766d3f2631f1dba24f03706da8ffe81f3279; prior review activity on e844f5b306cbf201cc31fa893539d2ed0875486c is stale. Focus on parser correctness/fail-closed behavior, action-metadata checkout credentials, container discovery precision, policy validation, test adequacy, workflow hardening, and any remaining false-negative authority escape. No PASS is assumed.

@qodo-code-review

qodo-code-review Bot commented Aug 26, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Malformed rules disable enforcement ✓ Resolved 🐞 Bug ⛨ Security
Description
The validator only checks that rules is an object, while cargo_locked_subcommands is blindly
passed to set; setting it to the JSON string "test" produces a character set and silently
disables matching for every configured Cargo subcommand. Other malformed rule values can raise
uncaught TypeError or use string truthiness, so policy corruption is neither consistently rejected
nor fail-closed.
Code

.github/scripts/audit_workflow_trust.py[R344-345]

+    if policy.get("schema") != 1 or not isinstance(policy.get("rules"), dict):
+        findings.append(Finding("invalid_policy", ".github/workflow-trust-policy.json", "", "unsupported policy schema"))
Relevance

●●● Strong

Malformed policy handling directly protects the same fail-closed trust enforcement accepted in prior
hardening.

PR-#12
PR-#32

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Repository-level validation verifies only schema and that rules is a dictionary, but enforcement
assumes specific nested types. In particular, `set(policy["rules"].get("cargo_locked_subcommands",
[]))` accepts a string and changes it into individual characters, making all multi-character
subcommands fail membership checks; main does not catch the resulting type errors from other
malformed values.

.github/scripts/audit_workflow_trust.py[298-317]
.github/scripts/audit_workflow_trust.py[342-350]
.github/scripts/audit_workflow_trust.py[387-403]
.github/scripts/test_audit_workflow_trust.py[244-259]
specs/015-af-01-trusted-development-baseline/tasks.md[25-31]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Individual rule values are not type- or value-validated before enforcement. A malformed but parseable policy can silently disable checks or terminate the audit with an uncaught exception.

## Issue Context
The policy is a security boundary and malformed-input behavior is required to fail closed. Validate all nested workflow, job, rule, and exception structures before invoking any audit logic, then return deterministic `invalid_policy` findings without applying exceptions to schema errors.

## Fix Focus Areas
- .github/scripts/audit_workflow_trust.py[205-227]
- .github/scripts/audit_workflow_trust.py[241-305]
- .github/scripts/audit_workflow_trust.py[342-369]
- .github/scripts/audit_workflow_trust.py[387-403]
- .github/scripts/test_audit_workflow_trust.py[244-259]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Checkout setting is unscoped ✓ Resolved 🐞 Bug ⛨ Security
Description
_checkout_has_credentials_disabled accepts any later line named persist-credentials: false
before the next step, without requiring it to be under that checkout step's with mapping. Placing
the same key under env leaves checkout's credential persistence enabled but makes the audit pass.
Code

.github/scripts/audit_workflow_trust.py[R199-201]

+    for line in lines[uses_index + 1 : end]:
+        if re.match(r"^\s*persist-credentials:\s*false\s*(?:#.*)?$", line):
+            return True
Relevance

●●● Strong

Accepted checkout-security precedent supports enforcing credential settings on the actual checkout
step.

PR-#12

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The implementation scans every line until the next list item and checks only indentation-agnostic
text matching; it never verifies a with: parent. The policy enables this rule, and the plan
requires persist-credentials: false specifically on checkout steps.

.github/scripts/audit_workflow_trust.py[188-202]
.github/scripts/audit_workflow_trust.py[318-324]
.github/workflow-trust-policy.json[14-16]
specs/015-af-01-trusted-development-baseline/plan.md[76-78]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The checkout credential check searches text within a step rather than validating the checkout step's `with.persist-credentials` input. An unrelated nested key can satisfy the audit while checkout still uses its credential-persisting default.

## Issue Context
The policy and AF-01 plan require the checkout input itself to be set to false. The current test only covers complete omission and does not cover a same-named key in another mapping.

## Fix Focus Areas
- .github/scripts/audit_workflow_trust.py[188-202]
- .github/scripts/audit_workflow_trust.py[315-324]
- .github/scripts/test_audit_workflow_trust.py[185-190]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Comments satisfy Cargo locking ✓ Resolved 🐞 Bug ☼ Reliability
Description
The Cargo check treats any --locked text after the subcommand as proof that the invocation is
locked, including shell comments such as cargo test --workspace # --locked. It also misses
line-continued invocations where cargo and the subcommand are on separate lines, so
lockfile-consuming commands can run unlocked without a finding.
Code

.github/scripts/audit_workflow_trust.py[R308-310]

+            for match in CARGO_RE.finditer(command):
+                subcommand = match.group(1)
+                if subcommand in locked_subcommands and "--locked" not in command[match.start() :]:
Relevance

●●● Strong

The team explicitly accepted adding locked enforcement to all lockfile-consuming Cargo commands.

PR-#2

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The implementation scans one stripped physical line at a time and searches the raw remainder for
--locked, without removing comments or reconstructing continued shell commands. The inventory
explicitly defines these commands as lockfile-consuming and requires every invocation to be locked.

.github/scripts/audit_workflow_trust.py[305-313]
.github/scripts/test_audit_workflow_trust.py[237-242]
specs/015-af-01-trusted-development-baseline/stack-a-inventory.md[79-105]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The audit performs a substring check on each physical YAML line, so non-executed comment text can satisfy `--locked` and shell line continuation can hide the Cargo subcommand. This allows unlocked dependency resolution despite the configured policy.

## Issue Context
The inventory defines the relevant lockfile-consuming Cargo subcommands and says all configured invocations must use `--locked`. Unsupported shell syntax should fail closed rather than be silently accepted.

## Fix Focus Areas
- .github/scripts/audit_workflow_trust.py[21-21]
- .github/scripts/audit_workflow_trust.py[305-313]
- .github/scripts/test_audit_workflow_trust.py[237-242]
- specs/015-af-01-trusted-development-baseline/stack-a-inventory.md[79-105]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View high (1)
4. Inline uses escape scanning ✓ Resolved 🐞 Bug ⛨ Security
Description
_all_uses only recognizes lines whose first YAML key is uses, so a valid flow-style step such as
steps: [{uses: owner/action@v1}] is never audited. A workflow or composite action can therefore
execute a mutable external action while the trust audit reports no mutable_uses finding.
Code

.github/scripts/audit_workflow_trust.py[R170-173]

+    for index in range(start, end):
+        matched = USES_RE.match(lines[index])
+        if matched:
+            result.append((index, _scalar(matched.group(2))))
Relevance

●●● Strong

Accepted security-hardening precedents favor complete immutable-action coverage.

PR-#12
PR-#32

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The scanner only matches a whole line beginning with optional whitespace/dash followed immediately
by uses:, then both workflow and Action audits rely exclusively on that result. The checked-in
AF-01 requirements explicitly require every external reference in both file types to be inspected.

.github/scripts/audit_workflow_trust.py[17-20]
.github/scripts/audit_workflow_trust.py[166-174]
.github/scripts/audit_workflow_trust.py[315-339]
specs/015-af-01-trusted-development-baseline/plan.md[71-81]
PR-#34

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The line-oriented `USES_RE` scan misses external `uses` keys embedded in valid YAML flow mappings/sequences, allowing mutable actions or reusable workflows to evade the full-SHA policy.

## Issue Context
The AF-01 plan requires inspection of all external `uses:` references in both workflows and Action metadata. The same `_all_uses` implementation is used for both file classes, so the bypass affects both.

## Fix Focus Areas
- .github/scripts/audit_workflow_trust.py[166-185]
- .github/scripts/audit_workflow_trust.py[315-339]
- .github/scripts/test_audit_workflow_trust.py[151-183]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

5. Malformed exceptions crash audit ✓ Resolved 📘 Rule violation ☼ Reliability
Description
A non-object entry in externally supplied exceptions is recognized as invalid, but _excepted()
still calls .get() on it and raises an uncaught exception. The audit can therefore abort instead
of returning its documented fail-closed JSON result for malformed policy data.
Code

.github/scripts/audit_workflow_trust.py[220]

+        if exception.get("rule") != finding.code or exception.get("path") != finding.path:
Relevance

●●● Strong

Fail-closed audit behavior is consistent with the repository’s accepted security-hardening
direction.

PR-#12
PR-#32

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Compliance rule 2717388 requires externally supplied malformed data to produce an error result
rather than abort processing. _valid_exception() explicitly accepts object and rejects
non-dictionaries, but _excepted() later unconditionally invokes exception.get; the repository
audit calls this filtering path even after adding an invalid_policy finding.

Rule 2717388: Library functions must not panic on externally supplied data
.github/scripts/audit_workflow_trust.py[205-215]
.github/scripts/audit_workflow_trust.py[218-226]
.github/scripts/audit_workflow_trust.py[342-369]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Malformed external policy data can crash the workflow trust audit because `_excepted()` assumes every exception is a dictionary even after validation reports otherwise.

## Issue Context
Keep the existing `invalid_policy` finding, but ensure malformed exception entries such as `null`, strings, or lists cannot raise `AttributeError` while findings are filtered. Add a deterministic regression test proving the audit returns `ok: false` and `invalid_policy` rather than throwing.

## Fix Focus Areas
- .github/scripts/audit_workflow_trust.py[218-226]
- .github/scripts/audit_workflow_trust.py[342-369]
- .github/scripts/test_audit_workflow_trust.py[253-259]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Named checkout steps falsely fail ✓ Resolved 🐞 Bug ≡ Correctness
Description
For a standard named checkout step where - name: precedes an indented `uses:
actions/checkout@..., _all_uses finds the action but _checkout_has_credentials_disabled`
immediately returns false because it requires - uses: on that same line. Even with a correct
with.persist-credentials: false, the audit emits checkout_credentials, preventing valid workflow
refactors.
Code

.github/scripts/audit_workflow_trust.py[R188-191]

+def _checkout_has_credentials_disabled(lines: list[str], uses_index: int) -> bool:
+    matched = STEP_USES_RE.match(lines[uses_index])
+    if not matched:
+        return False
Relevance

●●● Strong

Checkout credential hardening was explicitly accepted; named-step compatibility is a deterministic
fix.

PR-#12

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
_all_uses accepts an indented uses: key, but the checkout-specific helper requires
STEP_USES_RE, whose pattern mandates a dash immediately before uses, and returns false
otherwise. Existing workflows demonstrate that named action steps with indented uses are an
established repository style.

.github/scripts/audit_workflow_trust.py[18-20]
.github/scripts/audit_workflow_trust.py[166-202]
.github/workflows/cf11-multi-version-proof.yml[177-183]
.github/workflows/cf13-quality-gate-proof.yml[111-117]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The checkout checker assumes `uses` is the first key in a step. Valid named checkout steps are therefore rejected even when credentials are correctly disabled.

## Issue Context
Other repository action steps already use the common `- name:` followed by indented `uses:` layout, so this is a realistic future edit pattern. Structural YAML traversal should locate the enclosing step independent of key order.

## Fix Focus Areas
- .github/scripts/audit_workflow_trust.py[18-20]
- .github/scripts/audit_workflow_trust.py[166-202]
- .github/scripts/test_audit_workflow_trust.py[185-190]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


7. Trust rules lack rationale ✓ Resolved 📘 Rule violation ▣ Testability
Description
The three public boolean trust rules are published only as configuration keys, without a rationale
field or corresponding documentation explaining why each rule exists. Their positive and
counterexample tests do not satisfy the checklist's separate rationale requirement.
Code

.github/workflow-trust-policy.json[R14-16]

+    "require_container_digest": true,
+    "require_checkout_credentials_disabled": true,
+    "require_external_uses_full_sha": true
Relevance

●● Moderate

Rationale documentation is subjective; no closely matching accepted or rejected precedent appeared.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Compliance rule 2717385 requires every public rule to include explicit rationale in addition to
positive, negative, and deterministic tests. The repository-owned policy exposes
require_container_digest, require_checkout_credentials_disabled, and
require_external_uses_full_sha as rules, but these entries contain only boolean values and no
rationale metadata.

Rule 2717385: Require rationale, positive and negative tests, and deterministic behavior for public rules
.github/workflow-trust-policy.json[14-16]
.github/scripts/test_audit_workflow_trust.py[122-126]
.github/scripts/test_audit_workflow_trust.py[151-190]
.github/scripts/test_audit_workflow_trust.py[223-242]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The public workflow trust policy defines three boolean rules without documenting the rationale for each rule.

## Issue Context
Preserve the current machine-readable values and audit behavior. Add an explicit rationale field supported by the policy format, or a clearly linked documentation section that explains why digest-bound containers, credentialless checkout, and full-SHA external references are required.

## Fix Focus Areas
- .github/workflow-trust-policy.json[14-16]
- specs/015-af-01-trusted-development-baseline/stack-a-inventory.md[96-106]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
✅ Compliance rules (platform): 13 rules
Review mode: ⚖️ Balanced: Downgraded extended -> standard: change is below the extended eligibility bar (hunks 12/18, lines 925/200; both must reach the floor). Router rationale: This introduces substantial security-sensitive audit logic with custom parsing, policy enforcement, broad workflow coverage, and many independent hardening changes where a redundant review could catch subtle defects.

Grey Divider

Tip of the day
💡 Did you know, you can ask Qodo to dismiss a finding you disagree with, with your reason on record

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread .github/scripts/audit_workflow_trust.py
Comment thread .github/workflow-trust-policy.json
Comment thread .github/scripts/audit_workflow_trust.py
Comment thread .github/scripts/audit_workflow_trust.py Outdated
Comment thread .github/scripts/audit_workflow_trust.py Outdated
Comment thread .github/scripts/audit_workflow_trust.py Outdated
Comment thread .github/scripts/audit_workflow_trust.py Outdated
@qodo-code-review

Copy link
Copy Markdown

review

Fresh exact-head review required after self-review hardening. Review current head 0be4766d3f2631f1dba24f03706da8ffe81f3279; prior review activity on e844f5b306cbf201cc31fa893539d2ed0875486c is stale. Specifically verify the shared workflow/action-metadata checkout credential enforcement, invalid-policy fail-closed path, narrowed job/service container discovery, and all previously requested AF-01 Stack A trust invariants. No PASS is assumed.

Review findings

The requested invariants are enforced for the currently tracked workflows: all runners and timeouts are explicit, checkout steps use persist-credentials: false, external uses references are SHA-pinned, permissions are checked, and job/service container images are restricted to digest references. The shared _uses_findings path also scans both workflows and discovered action.yml/action.yaml files.

However, I would not mark this fully passing yet:

  • Semantic policy validation is incomplete and can crash instead of returning the defined fail-closed result. _policy_errors() only validates that workflows is a dictionary; it does not validate that workflow keys are strings or that each workflow/job policy has the required shape (.github/scripts/audit_workflow_trust.py:450-471). A policy containing a non-string workflow key can reach root / path at lines 501-508 and raise TypeError, which is not caught by main()'s exception list (525-551). Mixed-type job keys can likewise fail during sorting. Add recursive schema/type validation before using policy paths and keys, and cover malformed semantic policies with tests.

  • Workflow/action YAML syntax is not actually validated. The audit only rejects tabs and checks for a top-level jobs:/runs: marker (297-304, 432-447). A syntactically invalid YAML document can therefore pass the trust checks if its relevant lines happen to match the scanner. This undermines the fail-closed invariant; parse YAML (or explicitly reject unsupported syntax) before applying the line scanner, with malformed nested mappings/sequences covered by tests.

The narrowed container discovery itself correctly limits checks to job container.image and service image fields, and the current workflow inventory appears reconciled. These two fail-closed gaps remain blocking review issues.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

Copy link
Copy Markdown
Owner Author

@qodo review

Final fresh review request for current exact head 95a2b4829c7b1a832b1460a4a97aada107e23877. All earlier review activity is stale. Verify the new action-metadata checkout credential regressions, non-container image false-positive regression, invalid-policy fail-closed regression, and the complete AF-01 Stack A authority model. Please report material bugs/rule violations/requirement gaps only; no prior PASS is assumed.

@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='0be4766d3f2631f1dba24f03706da8ffe81f3279'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\n' "$actual" "$expected"
if [ "$actual" != "$expected" ]; then
  printf 'ERROR: checkout is not the requested exact head\n' >&2
  exit 2
fi

base="$(git merge-base HEAD main)"
printf 'MERGE_BASE=%s\n' "$base"
printf '\n== changed files ==\n'
git diff --name-status "$base" HEAD
printf '\n== changed AF-01 stat ==\n'
git diff --stat "$base" HEAD -- .github specs/015-af-01-trusted-development-baseline
printf '\n== audit outline ==\n'
ast-grep outline .github/scripts/audit_workflow_trust.py --items all 2>/dev/null || true
printf '\n== test outline ==\n'
ast-grep outline .github/scripts/test_audit_workflow_trust.py --items all 2>/dev/null || true
printf '\n== implementation ==\n'
cat -n .github/scripts/audit_workflow_trust.py
printf '\n== tests ==\n'
cat -n .github/scripts/test_audit_workflow_trust.py
printf '\n== policy ==\n'
cat -n .github/workflow-trust-policy.json
printf '\n== workflow diffs ==\n'
git diff --find-renames "$base" HEAD -- .github/workflows
printf '\n== current workflow/action metadata files ==\n'
fd -HI -t f -e yml -e yaml .github action.yml action.yaml 2>/dev/null | sort | while IFS= read -r f; do
  printf '\n--- %s ---\n' "$f"
  cat -n "$f"
done
printf '\n== static source checks ==\n'
python3 -m py_compile .github/scripts/audit_workflow_trust.py .github/scripts/test_audit_workflow_trust.py
python3 -m json.tool .github/workflow-trust-policy.json >/dev/null
git diff --check "$base" HEAD
printf 'STATIC_CHECKS=OK\n'

Length of output: 48470


🏁 Script executed:

#!/bin/bash
set -euo pipefail

previous='e844f5b306cbf201cc31fa893539d2ed0875486c'
current='0be4766d3f2631f1dba24f03706da8ffe81f3279'

printf '%s\n' '== incremental diff from prior reviewed head =='
git diff --find-renames "$previous" "$current" -- \
  .github/scripts/audit_workflow_trust.py \
  .github/scripts/test_audit_workflow_trust.py \
  .github/workflow-trust-policy.json \
  .github/workflows \
  specs/015-af-01-trusted-development-baseline/stack-a-inventory.md

printf '%s\n' '== tracked security files =='
git ls-files -z | python3 -c '
import sys
from pathlib import PurePosixPath
for path in sorted(p for p in sys.stdin.buffer.read().decode().split("\0") if p):
    name = PurePosixPath(path).name
    if (path.startswith(".github/workflows/") and name.endswith((".yml", ".yaml"))) or name in {"action.yml", "action.yaml"}:
        print(path)
'

printf '%s\n' '== full current workflow source =='
while IFS= read -r f; do
  printf '\n--- %s ---\n' "$f"
  cat -n "$f"
done < <(git ls-files | awk '($0 ~ /^\.github\/workflows\/.*\.(yml|yaml)$/) || ($0 ~ /(^|\/)action\.ya?ml$/)')

printf '%s\n' '== parser-relevant implementation and test locations =='
rg -n -C 4 \
  'USES_RE|STEP_USES_RE|CARGO_RE|def _container_images|def _job_ranges|def _parse_permissions|def _policy_errors|quoted|continuation|toolchain|container|persist-credentials' \
  .github/scripts/audit_workflow_trust.py .github/scripts/test_audit_workflow_trust.py

printf '%s\n' '== static checks =='
python3 -m py_compile .github/scripts/audit_workflow_trust.py .github/scripts/test_audit_workflow_trust.py
python3 -m json.tool .github/workflow-trust-policy.json >/dev/null
git diff --check "$(git merge-base HEAD main)" HEAD
printf '%s\n' 'STATIC_CHECKS=OK'

Length of output: 20520


@TheHalfMoon I reviewed exact head 0be4766d3f2631f1dba24f03706da8ffe81f3279.

I found three substantive AF-01 findings.

  1. P1 — The policy can disable mandatory trust rules without an invalid_policy finding.
    .github/scripts/audit_workflow_trust.py Line 457 through Line 460 only validate that rules is an object. Later code uses permissive defaults. For example, if a pull request removes require_external_uses_full_sha or sets it to false, _uses_findings() does not check external references. If it removes require_container_digest, the container check does not run. If it removes cargo_locked_subcommands, the lockfile check uses an empty set. The repository audit can then pass with mutable uses:, mutable containers, or unlocked Cargo commands. Validate the complete required rule set and its types. Require the mandatory boolean rules to be true. Require the required Cargo subcommands. Add negative tests for missing, false, and incorrectly typed rule values.

  2. P1 — Quoted YAML keys still bypass uses: and checkout credential enforcement.
    .github/scripts/audit_workflow_trust.py Line 18 and Line 19 only match bare uses: keys. GitHub Actions YAML accepts quoted mapping keys. This valid step bypasses immutable-reference and checkout credential checks:

    - "uses": actions/checkout@v5

    The shared _uses_findings() helper extends the check to Action metadata, but it retains the same parser limitation. The bypass applies to workflows and composite Action metadata. Parse YAML and inspect the parsed mapping structure, or reject unsupported YAML syntax before treating the file as compliant. Add tests for quoted uses keys in both workflow and action.yml or action.yaml inputs.

  3. P1 — Cargo --locked enforcement still misses valid invocations.
    .github/scripts/audit_workflow_trust.py Line 21 requires the tracked subcommand immediately after cargo on one physical line. Line 414 through Line 426 applies that pattern per source line. These valid commands bypass the rule:

    run: cargo +1.97.1 test --workspace
    run: |
      cargo \
        test --workspace

    Neither form matches CARGO_RE, so the audit reports no cargo_unlocked finding. Normalize shell commands before inspection, or fail closed for unsupported Cargo invocation syntax. Add counterexamples for toolchain selectors, Cargo global options, and line continuations.

The incremental hardening correctly moves normal checkout credential checks into shared workflow and Action metadata handling. It also narrows the container scan to job and service containers. These changes do not resolve the parser bypasses above.

I verified the requested exact head and canonical merge base. I did not execute repository code or tests. The read-only inspection commands terminated before their final static-check section, so compilation and full file enumeration remain unverified.

You are interacting with an AI system.

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Final fresh review request for current exact head 95a2b4829c7b1a832b1460a4a97aada107e23877. All earlier review activity is stale. Focus on false negatives/false positives in the constrained parser, action-metadata checkout credential enforcement, container discovery precision, invalid policy handling, test coverage, workflow hardening, and preservation of existing CF/proof semantics. No approval is assumed.

@qodo-code-review

Copy link
Copy Markdown

review

Final fresh review request for current exact head 95a2b4829c7b1a832b1460a4a97aada107e23877. All earlier review activity is stale. Verify the new action-metadata checkout credential regressions, non-container image false-positive regression, invalid-policy fail-closed regression, and the complete AF-01 Stack A authority model. Please report material bugs/rule violations/requirement gaps only; no prior PASS is assumed.

Fresh review of 95a2b4829c7b1a832b1460a4a97aada107e23877 found these material gaps:

  • finding 1 — action required: Policy validation only checks that rules is an object. Malformed nested values are then used as trusted types: for example, cargo_locked_subcommands: null raises TypeError, while a string silently becomes a character set and disables Cargo locking checks. This violates fail-closed policy handling (.github/scripts/audit_workflow_trust.py:450-471, 413-419).
  • finding 2 — action required: Checkout credential detection is not scoped to the checkout step’s with mapping. A persist-credentials: false under env or another nested mapping can satisfy the audit while checkout credentials remain enabled (.github/scripts/audit_workflow_trust.py:221-235).
  • finding 3 — action required: Cargo locking scans raw physical lines and treats comments as arguments, so cargo test --workspace # --locked passes. It also misses line-continued invocations (.github/scripts/audit_workflow_trust.py:413-425).
  • finding 4 — action required: uses discovery is line-based and misses valid flow-style YAML such as steps: [{uses: owner/action@v1}], leaving mutable external references unaudited (.github/scripts/audit_workflow_trust.py:197-207).
  • finding 6 — remediation recommended: Named checkout steps (- name: Checkout followed by an indented uses:) are discovered by _all_uses, but _checkout_has_credentials_disabled only accepts - uses: on the same line and falsely reports valid steps as insecure (.github/scripts/audit_workflow_trust.py:221-226).
  • finding 7 — remediation recommended: The three public boolean rules in .github/workflow-trust-policy.json:14-16 have no explicit rationale, leaving the AF-01 rule documentation requirement incomplete.

Verified requested regressions:

  • Action-metadata checkout checks are present, but the named-step scoping bug above still applies to action metadata.
  • The non-container image false-positive regression is covered by _container_images; it only treats job container.image and service image as authorities, so the current implementation does not report ordinary job env.image values.
  • Invalid top-level policy handling now fails closed before scanning (.github/scripts/audit_workflow_trust.py:474-486). However, nested rule-shape validation remains incomplete, as described in finding 1.
  • The checked-in Stack A policy enumerates all seven tracked workflows and the discovery code scans both action.yml and action.yaml at tracked paths. No additional authority-model omission was identified beyond the enforcement/parser gaps above.

Finding 5 is already implemented in the current control flow: _policy_errors() returns before malformed exceptions reach _excepted().

@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='95a2b4829c7b1a832b1460a4a97aada107e23877'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\n' "$actual" "$expected"
if [ "$actual" != "$expected" ]; then
  printf '%s\n' 'ERROR: checkout is not the requested exact head' >&2
  exit 2
fi

base="$(git merge-base HEAD main)"
printf 'MERGE_BASE=%s\n' "$base"

printf '\n== changed files ==\n'
git diff --name-status "$base" HEAD

printf '\n== incremental changes from prior head ==\n'
git diff --find-renames 0be4766d3f2631f1dba24f03706da8ffe81f3279 HEAD -- \
  .github/scripts/audit_workflow_trust.py \
  .github/scripts/test_audit_workflow_trust.py \
  .github/workflow-trust-policy.json \
  .github/workflows \
  specs/015-af-01-trusted-development-baseline/stack-a-inventory.md

printf '\n== audit outline ==\n'
ast-grep outline .github/scripts/audit_workflow_trust.py --items all 2>/dev/null || true

printf '\n== audit implementation ==\n'
cat -n .github/scripts/audit_workflow_trust.py

printf '\n== audit tests ==\n'
cat -n .github/scripts/test_audit_workflow_trust.py

printf '\n== policy ==\n'
cat -n .github/workflow-trust-policy.json

printf '\n== inventory ==\n'
cat -n specs/015-af-01-trusted-development-baseline/stack-a-inventory.md

printf '\n== workflow diffs ==\n'
git diff --find-renames "$base" HEAD -- .github/workflows

printf '\n== tracked workflow and Action metadata ==\n'
while IFS= read -r f; do
  printf '\n--- %s ---\n' "$f"
  cat -n "$f"
done < <(git ls-files | awk '($0 ~ /^\.github\/workflows\/.*\.(yml|yaml)$/) || ($0 ~ /(^|\/)action\.ya?ml$/)')

printf '\n== parser and policy focus locations ==\n'
rg -n -C 5 \
  'USES|uses|CARGO|cargo|persist-credentials|container|service|image|policy|permissions|runs-on|timeout|exception|yaml|YAML' \
  .github/scripts/audit_workflow_trust.py \
  .github/scripts/test_audit_workflow_trust.py \
  .github/workflow-trust-policy.json

printf '\n== whitespace errors ==\n'
git diff --check "$base" HEAD

Length of output: 57473


🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='95a2b4829c7b1a832b1460a4a97aada107e23877'
test "$(git rev-parse HEAD)" = "$expected"
base="$(git merge-base HEAD main)"

printf '%s\n' '== tracked workflow and Action metadata paths =='
git ls-files | awk '($0 ~ /^\.github\/workflows\/.*\.(yml|yaml)$/) || ($0 ~ /(^|\/)action\.ya?ml$/)' | sort

printf '%s\n' '== current workflow and Action metadata source =='
git ls-files | awk '($0 ~ /^\.github\/workflows\/.*\.(yml|yaml)$/) || ($0 ~ /(^|\/)action\.ya?ml$/)' | sort | while IFS= read -r f; do
  printf '\n--- %s ---\n' "$f"
  cat -n "$f"
done

printf '%s\n' '== full changes outside AF-01 configuration and inventory =='
git diff --name-only "$base" HEAD -- . ':(exclude).github' ':(exclude)specs/015-af-01-trusted-development-baseline'

printf '%s\n' '== workflow changes with function-context =='
git diff --unified=12 "$base" HEAD -- .github/workflows

printf '%s\n' '== parser function regions =='
sed -n '15,240p;270,475p' .github/scripts/audit_workflow_trust.py | cat -n

printf '%s\n' '== test cases that cover parser exceptions and policies =='
sed -n '120,310p' .github/scripts/test_audit_workflow_trust.py | cat -n

printf '%s\n' '== changed file end-of-line checks =='
git diff --check "$base" HEAD

Length of output: 91075


@TheHalfMoon I reviewed exact head 95a2b4829c7b1a832b1460a4a97aada107e23877.

I found three material AF-01 Stack A findings.

  1. P1 — Quoted YAML keys bypass uses: and checkout credential enforcement.
    .github/scripts/audit_workflow_trust.py Line 18 and Line 19 only match bare uses: keys. GitHub Actions accepts quoted YAML mapping keys. This valid workflow step is not found by _all_uses():

    - "uses": actions/checkout@v5

    The audit reports neither mutable_uses nor checkout_credentials. The same bypass applies to composite Action metadata because audit_action_metadata() uses the shared _uses_findings() function. Parse the YAML mapping structure, or reject quoted and other unsupported key forms before the audit reports success. Add workflow and Action metadata regressions for quoted uses keys.

  2. P1 — Valid Cargo command forms bypass --locked enforcement.
    .github/scripts/audit_workflow_trust.py Line 21 only accepts cargo followed immediately by the tracked subcommand on one source line. The audit therefore misses valid commands such as:

    run: cargo +1.97.1 test --workspace

    It also misses shell continuations:

    run: |
      cargo \
        test --workspace

    Neither form matches CARGO_RE, so the audit can pass without --locked. Normalize the shell command before inspection, or reject unsupported Cargo invocation forms. Add negative tests for toolchain selectors, Cargo global options, and line continuations.

  3. P1 — The policy can disable mandatory rules without an invalid_policy finding.
    .github/scripts/audit_workflow_trust.py Line 450 through Line 471 only require rules to be an object. A policy change can remove require_external_uses_full_sha, set it to false, remove require_container_digest, or set cargo_locked_subcommands to an empty list. The audit then skips these mandatory checks and can return success.

    Require every Stack A rule. Validate each rule type. Require both boolean authority rules to be true. Require the complete lockfile-consuming Cargo subcommand set. Add regressions for missing, false, and incorrectly typed rule values.

The new Action metadata checkout tests and the non-container image regression test cover their intended cases. They do not cover the parser bypasses above. The invalid-policy-root test covers only an absent rules object. It does not cover rule removal or rule disablement.

I verified the workflow changes preserve the existing CF-06 oracle commands, CI product smoke commands, and registry smoke commands. The changes only add the AF-01 audit gates, pin runners and Actions, add timeouts, disable checkout credential persistence, and reduce the aggregation-only oracle-proof job permissions to {}.

I confirmed the requested exact head and canonical merge base. I did not execute repository code or tests because the review sandbox prohibits executing repository files. I do not approve this head while these fail-open paths remain.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

Copy link
Copy Markdown
Owner Author

@qodo review

Fresh exact-head AF-01 Stack A review for 0fc0607dc5b3057f59e26c3c583a28747a20c036 only. All prior reviews/findings are stale.

Exact-head qualification is terminal green:

  • ci run 33041605113 SUCCESS, including AF-01 unit/core/executable-surface gates, the independent cross-step environment-channel gate, Format/Clippy/workspace tests, CF-08/CF-09, real FHIR/terminology, local source-backed Action integration, and output verification;
  • cf06-oracle run 33041605065 SUCCESS including oracle-proof;
  • registry-download-smoke run 33041605078 SUCCESS.

Please review the full current diff and re-check all prior remediations. Latest fixes close both prior findings:

  • cross-step environment authority is now an independent CI gate executed directly before Rust gates;
  • tracked workflow/Action/shell authority rejects exact GITHUB_PATH/GITHUB_ENV names, shell indirect parameter expansion ${!...}, and standalone GITHUB_ fragments that can construct those names; $GITHUB_OUTPUT and normal full GitHub variable names remain allowed. Counterexamples cover direct/braced channels, indirect-name expansion, split/name-fragment construction, extensionless shell sources, deterministic repeat output, and live repository enforcement.

Also re-check PATH/builtin writers/nameref, command-resolution mutation, wrapper heredocs, direct/path-like execution, exact $GITHUB_ACTION_PATH/... recursion, wrapper operands, source/dot, tracked targets/cycles, Cargo syntax/provenance, immutable refs, checkout credentials, permissions, fixed runners/timeouts, containers, CI wiring, and preservation of CF-06/registry/product semantics.

Report any remaining substantive finding; no PASS is inferred.

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Fresh exact-head AF-01 Stack A review for 0fc0607dc5b3057f59e26c3c583a28747a20c036 only. All prior CodeRabbit reviews/requests are stale.

Exact-head gates are terminal green: ci 33041605113, cf06-oracle 33041605065 including oracle-proof, and registry-download-smoke 33041605078.

Please review the full current diff. Re-check your prior P1: the cross-step environment-channel auditor is now invoked as an independent CI step before Rust gates, in addition to its unit/counterexample suite. Re-check the adjacent Qodo remediation: exact GITHUB_PATH/GITHUB_ENV names, indirect shell parameter expansion ${!...}, and standalone GITHUB_ name fragments are fail-closed in tracked workflow/Action/shell authority, while $GITHUB_OUTPUT and normal complete GitHub variable names remain allowed.

Also re-check all earlier authority classes: PATH assignments/builtin writers/nameref, hash/alias/enable resolution mutation, wrapper heredocs, direct/path-like execution, exact $GITHUB_ACTION_PATH/... recursion, source/dot, wrapper operands, tracked-target/cycle handling, Cargo syntax/provenance, immutable uses, checkout credentials, permissions, runners/timeouts, containers, independent CI wiring, CF-08/CF-09, local Action integration, and accidental CF-06/registry/product drift.

Report any remaining material issue; no PASS is assumed.

@qodo-code-review

Copy link
Copy Markdown

review

Fresh exact-head AF-01 Stack A review for 0fc0607dc5b3057f59e26c3c583a28747a20c036 only. All prior reviews/findings are stale.

Exact-head qualification is terminal green:

  • ci run 33041605113 SUCCESS, including AF-01 unit/core/executable-surface gates, the independent cross-step environment-channel gate, Format/Clippy/workspace tests, CF-08/CF-09, real FHIR/terminology, local source-backed Action integration, and output verification;
  • cf06-oracle run 33041605065 SUCCESS including oracle-proof;
  • registry-download-smoke run 33041605078 SUCCESS.

Please review the full current diff and re-check all prior remediations. Latest fixes close both prior findings:

  • cross-step environment authority is now an independent CI gate executed directly before Rust gates;
  • tracked workflow/Action/shell authority rejects exact GITHUB_PATH/GITHUB_ENV names, shell indirect parameter expansion ${!...}, and standalone GITHUB_ fragments that can construct those names; $GITHUB_OUTPUT and normal full GitHub variable names remain allowed. Counterexamples cover direct/braced channels, indirect-name expansion, split/name-fragment construction, extensionless shell sources, deterministic repeat output, and live repository enforcement.

Also re-check PATH/builtin writers/nameref, command-resolution mutation, wrapper heredocs, direct/path-like execution, exact $GITHUB_ACTION_PATH/... recursion, wrapper operands, source/dot, tracked targets/cycles, Cargo syntax/provenance, immutable refs, checkout credentials, permissions, fixed runners/timeouts, containers, CI wiring, and preservation of CF-06/registry/product semantics.

Report any remaining substantive finding; no PASS is inferred.

I found no remaining substantive findings in the current diff.

Re-checked the trust-audit policy and implementation, including:

  • Fail-closed handling for unsupported YAML/shell syntax, Cargo indirection and syntax, lockfile-consuming commands, immutable Action/container references, checkout credentials, permissions, pinned runners, and timeouts.
  • Executable-surface coverage for wrapper heredocs, PATH and command-resolution mutation, builtins/namerefs, direct and path-like execution, source/., exact $GITHUB_ACTION_PATH/... targets, recursive tracked targets, and cycle handling.
  • Independent cross-step detection of GITHUB_PATH/GITHUB_ENV, indirect parameter expansion, and standalone GITHUB_ fragments while allowing $GITHUB_OUTPUT.
  • CI wiring: the repository, executable-surface, and environment-channel audits run before the Rust quality and product gates; all external Actions are full-SHA pinned and checkout disables persisted credentials.
  • The reviewed workflow policies consistently constrain permissions, runners, timeouts, and container/reference behavior, while the existing CF-06, registry, CF-08, and CF-09 paths remain represented in the current workflows.

The prior remediations represented by findings 1–7 appear incorporated; no new actionable finding is warranted from this head.

@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='0fc0607dc5b3057f59e26c3c583a28747a20c036'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\n' "$actual" "$expected"
test "$actual" = "$expected"

base="$(git merge-base HEAD main)"
printf 'MERGE_BASE=%s\n' "$base"

printf '\n== CHANGED FILES ==\n'
git diff --name-status "$base" HEAD

printf '\n== LATEST DIFF ==\n'
git diff --find-renames --unified=18 \
  99a7ab666fdde94766505039b4c9933c4fb5089b HEAD -- \
  .github/scripts .github/workflows .github/workflow-trust-policy.json \
  action.yml action.yaml scripts

printf '\n== OUTLINES ==\n'
for f in \
  .github/scripts/audit_workflow_trust.py \
  .github/scripts/audit_workflow_trust_surface.py \
  .github/scripts/audit_workflow_trust_environment_channels.py \
  .github/scripts/test_audit_workflow_trust.py \
  .github/scripts/test_audit_workflow_trust_surface.py \
  .github/scripts/test_audit_workflow_trust_environment_channels.py \
  .github/scripts/test_audit_workflow_trust_syntax.py
do
  if [ -f "$f" ]; then
    printf '\n--- %s ---\n' "$f"
    ast-grep outline "$f" --items all 2>/dev/null || true
  fi
done

printf '\n== CI AND POLICY ==\n'
cat -n .github/workflows/ci.yml
cat -n .github/workflow-trust-policy.json

printf '\n== ENVIRONMENT-CHANNEL AUDITOR AND TESTS ==\n'
cat -n .github/scripts/audit_workflow_trust_environment_channels.py
cat -n .github/scripts/test_audit_workflow_trust_environment_channels.py

printf '\n== SURFACE AUTHORITY REGIONS ==\n'
sed -n '1,180p;180,430p;430,720p' \
  .github/scripts/audit_workflow_trust_surface.py | cat -n

printf '\n== CORE AUTHORITY REGIONS ==\n'
sed -n '1,250p;430,760p;760,1200p' \
  .github/scripts/audit_workflow_trust.py | cat -n

printf '\n== ENVIRONMENT / SHELL / ACTION SOURCES ==\n'
git ls-files | awk \
  '($0 ~ /^\.github\/workflows\/.*\.(yml|yaml)$/) || ($0 ~ /(^|\/)action\.ya?ml$/) || ($0 ~ /\.sh$/)' |
sort |
while IFS= read -r f; do
  printf '\n--- %s ---\n' "$f"
  cat -n "$f"
done

printf '\n== ENVIRONMENT-CHANNEL AND EXECUTION-AUTHORITY REGRESSIONS ==\n'
rg -n -A45 -B5 \
  '^    def test_.*(github|environment|channel|path|hash|alias|enable|heredoc|wrapper|deleg|source|dot|direct|cargo|variable|cycle|bash_env)' \
  .github/scripts/test_audit_workflow_trust*.py

printf '\n== ALL TRACKED CHANNEL REFERENCES ==\n'
git grep -n -E '\$\{?GITHUB_(PATH|ENV|OUTPUT)\}?|GITHUB_(PATH|ENV|OUTPUT)|BASH_ENV|ENV=' -- \
  ':!target' || true

printf '\n== WORKFLOW/ACTION DIFF AND STATIC VALIDATION ==\n'
git diff --find-renames --unified=16 "$base" HEAD -- \
  .github/workflows action.yml action.yaml scripts
git diff --check "$base" HEAD

Length of output: 181395


🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='0fc0607dc5b3057f59e26c3c583a28747a20c036'
test "$(git rev-parse HEAD)" = "$expected"

printf '%s\n' '== ENVIRONMENT-CHANNEL AUDITOR =='
cat -n .github/scripts/audit_workflow_trust_environment_channels.py

printf '%s\n' '== ENVIRONMENT-CHANNEL TESTS =='
cat -n .github/scripts/test_audit_workflow_trust_environment_channels.py

printf '%s\n' '== SURFACE PARSING AND ACTION ENVIRONMENT HANDLING =='
rg -n -A90 -B12 \
  '^def (_scripts|_shell_heredoc_findings|_direct_cargo_findings|_action_local_targets|_path_search_mutation_is_unsupported|audit_action_text|audit_repository_surface)|shlex\.split|except ValueError|BASH_ENV|env' \
  .github/scripts/audit_workflow_trust_surface.py

printf '%s\n' '== CORE YAML PARSING, DISCOVERY, AND POLICY VALIDATION =='
rg -n -A90 -B12 \
  '^def (_tracked_files|_load_yaml|_all_uses|_run_scripts|audit_action_metadata|audit_workflow|audit_repository|load_policy|_validate)|yaml|safe_load|action\.ya?ml|persist-credentials|container|permissions' \
  .github/scripts/audit_workflow_trust.py

printf '%s\n' '== YAML PARSER DEPENDENCIES =='
rg -n -C2 'PyYAML|yaml|ruamel' requirements.txt pyproject.toml Cargo.toml .github 2>/dev/null || true

printf '%s\n' '== SOURCE FILE EXECUTABLE AUTHORITY FORMS =='
rg -n -U -C2 \
  '(^|[;&|[:space:]])(eval|exec|source|\.|command|builtin|hash|alias|unalias|enable|env|bash|dash|ksh|sh|zsh|read|mapfile|readarray|getopts|printf|declare|typeset|local|readonly|export|unset)[[:space:]]|BASH_ENV|ENV=|PATH=|GITHUB_(PATH|ENV)' \
  action.yml scripts .github/workflows --glob '*.sh' --glob '*.yml' --glob '*.yaml' 2>/dev/null || true

printf '%s\n' '== DISCOVERY TESTS =='
rg -n -A38 -B4 \
  'def test_.*(discover|tracked|nested|action_yaml|workflow|quoted|flow|checkout|permission|container|timeout|uses|policy|malformed)' \
  .github/scripts/test_audit_workflow_trust.py \
  .github/scripts/test_audit_workflow_trust_syntax.py

printf '%s\n' '== VERIFY REPORTED RUN HEADS =='
for run in 33041605113 33041605065 33041605078; do
  gh run view "$run" --repo TheHalfMoon/commandF \
    --json databaseId,headSha,status,conclusion,name 2>/dev/null || true
done

Length of output: 139187


@TheHalfMoon I reviewed exact head 0fc0607dc5b3057f59e26c3c583a28747a20c036.

I found one material AF-01 Stack A finding.

  1. P1 — BASH_ENV still bypasses recursive Action shell-source auditing.
    .github/scripts/audit_workflow_trust_surface.py Line 47 through Line 48 extracts only run: scripts. audit_action_text() at Line 559 through Line 570 does not inspect the env: mapping of a composite Action step.

    Bash sources the file specified by BASH_ENV before each non-interactive bash execution. A composite Action can execute a tracked Action-root script without a visible delegation in run::

    runs:
      using: composite
      steps:
        - shell: bash
          env:
            BASH_ENV: $GITHUB_ACTION_PATH/scripts/build.sh
          run: echo ok
    # scripts/build.sh
    cargo test --workspace

    The surface audit evaluates echo ok. It does not recursively audit scripts/build.sh. It does not emit unsupported_action_script or cargo_unlocked.

    Reject BASH_ENV in workflow and composite Action environment mappings. Alternatively, allow only an exact tracked $GITHUB_ACTION_PATH/<relative-path> value and recursively audit the target. Add locked and unlocked regressions. Apply the same review to startup-file environment variables for every supported shell interpreter.

The independent cross-step environment-channel gate is present in .github/workflows/ci.yml Line 33 through Line 34. It runs before Rust gates. The environment-channel auditor rejects direct and braced GITHUB_PATH and GITHUB_ENV names, indirect parameter expansion, and standalone GITHUB_ fragments. It permits GITHUB_OUTPUT.

I confirmed that ci run 33041605113, cf06-oracle run 33041605065, and registry-download-smoke run 33041605078 succeeded on the requested HEAD.

The current workflow changes preserve the CF-06 commands, registry retry behavior, and CI product smoke commands. I used static inspection only.

You are interacting with an AI system.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

Copy link
Copy Markdown
Owner Author

@qodo review

Fresh exact-head AF-01 Stack A review for 7fd664af6a77989dda8b5d79095671b564fb9c2a only. All prior reviews/findings are stale.

Exact-head qualification is terminal green:

  • ci run 33042082554 SUCCESS, including AF-01 unit/core/executable-surface gates, independent environment/startup-authority gate, Format/Clippy/workspace tests, CF-08/CF-09, real FHIR/terminology, local source-backed Action integration, and output verification;
  • cf06-oracle run 33042082675 SUCCESS including oracle-proof;
  • registry-download-smoke run 33042082530 SUCCESS.

Please review the full current diff and re-check all prior remediations. Latest CodeRabbit P1 is closed conservatively: tracked workflow/Action/shell authority now rejects shell startup-file authority through exact BASH_ENV, ENV, and ZDOTDIR names, plus BASH_/ZDOT name fragments that can construct startup variables. Regressions cover composite Action BASH_ENV with both locked and unlocked hidden Action-root scripts, workflow BASH_ENV, ksh ENV, zsh ZDOTDIR, name-fragment construction, and precision for lowercase env:/similar non-authority names. The independent CI gate remains direct and green.

Also re-check GITHUB_PATH/GITHUB_ENV direct/indirect authority, PATH/builtin writers/nameref, command-resolution mutation, wrapper heredocs, direct/path-like execution, exact $GITHUB_ACTION_PATH/... recursion, wrapper operands, source/dot, tracked targets/cycles, Cargo syntax/provenance, immutable refs, checkout credentials, permissions, runners/timeouts, containers, CI wiring, and preservation of CF-06/registry/product semantics.

Report any remaining substantive finding; no PASS is inferred.

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Fresh exact-head AF-01 Stack A review for 7fd664af6a77989dda8b5d79095671b564fb9c2a only. All prior CodeRabbit reviews/requests are stale.

Exact-head gates are terminal green: ci 33042082554, cf06-oracle 33042082675 including oracle-proof, and registry-download-smoke 33042082530.

Please review the full current diff. Re-check your prior P1: hidden shell startup-file authority is now fail-closed in the same independent environment-authority gate. Exact BASH_ENV, ENV, and ZDOTDIR names are rejected in tracked workflows, Action metadata, and shell authority; BASH_/ZDOT construction fragments are also rejected. Regressions cover locked/unlocked Action-root scripts hidden behind composite Action BASH_ENV, workflow BASH_ENV, ksh ENV, zsh ZDOTDIR, name fragments, and precision for lowercase env:/similar safe names.

Also re-check all earlier classes: GITHUB_PATH/GITHUB_ENV direct/indirect authority, PATH assignments/builtin writers/nameref, hash/alias/enable resolution mutation, wrapper heredocs, direct/path-like execution, exact $GITHUB_ACTION_PATH/... recursion, source/dot, wrapper operands, tracked-target/cycle handling, Cargo syntax/provenance, immutable uses, checkout credentials, permissions, fixed runners/timeouts, containers, independent CI wiring, CF-08/CF-09, local Action integration, and accidental CF-06/registry/product drift.

Report any remaining material issue; no PASS is assumed.

@qodo-code-review

Copy link
Copy Markdown

review

Fresh exact-head AF-01 Stack A review for 7fd664af6a77989dda8b5d79095671b564fb9c2a only. All prior reviews/findings are stale.

Exact-head qualification is terminal green:

  • ci run 33042082554 SUCCESS, including AF-01 unit/core/executable-surface gates, independent environment/startup-authority gate, Format/Clippy/workspace tests, CF-08/CF-09, real FHIR/terminology, local source-backed Action integration, and output verification;
  • cf06-oracle run 33042082675 SUCCESS including oracle-proof;
  • registry-download-smoke run 33042082530 SUCCESS.

Please review the full current diff and re-check all prior remediations. Latest CodeRabbit P1 is closed conservatively: tracked workflow/Action/shell authority now rejects shell startup-file authority through exact BASH_ENV, ENV, and ZDOTDIR names, plus BASH_/ZDOT name fragments that can construct startup variables. Regressions cover composite Action BASH_ENV with both locked and unlocked hidden Action-root scripts, workflow BASH_ENV, ksh ENV, zsh ZDOTDIR, name-fragment construction, and precision for lowercase env:/similar non-authority names. The independent CI gate remains direct and green.

Also re-check GITHUB_PATH/GITHUB_ENV direct/indirect authority, PATH/builtin writers/nameref, command-resolution mutation, wrapper heredocs, direct/path-like execution, exact $GITHUB_ACTION_PATH/... recursion, wrapper operands, source/dot, tracked targets/cycles, Cargo syntax/provenance, immutable refs, checkout credentials, permissions, runners/timeouts, containers, CI wiring, and preservation of CF-06/registry/product semantics.

Report any remaining substantive finding; no PASS is inferred.

I found no remaining substantive issues in the current diff.

Re-checked the implemented remediations and current repository wiring, including:

  • Core trust policy enforcement for immutable uses refs, checkout credentials, permissions, pinned runners, timeouts, container digests, Cargo --locked coverage, and malformed-policy handling.
  • Executable-surface handling for heredocs, dynamic executable resolution, wrapper operands, PATH/resolution mutation, namerefs and built-in writers, exact $GITHUB_ACTION_PATH/... recursion, tracked targets, cycles, source/., and Cargo syntax/provenance.
  • Independent environment-channel coverage for GITHUB_PATH, GITHUB_ENV, indirect expansion, startup variables (BASH_ENV, ENV, ZDOTDIR), and their constructed name fragments.
  • CI wiring and the updated CF-08, CF-09, CF-06, and registry smoke workflows. The checked-in workflows use ubuntu-24.04, bounded timeouts, explicit permissions, immutable external Actions, and disabled checkout credentials.
  • The Action runner now derives the executable from CARGO_TARGET_DIR rather than accepting a caller-selected binary path, while preserving the existing CF-08/CF-09 output and failure semantics.

The findings index contains no active findings; findings 1–7 are already implemented.

@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='7fd664af6a77989dda8b5d79095671b564fb9c2a'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\n' "$actual" "$expected"
test "$actual" = "$expected"

base="$(git merge-base HEAD main)"
printf 'MERGE_BASE=%s\n' "$base"

printf '\n== CHANGED FILES ==\n'
git diff --name-status "$base" HEAD

printf '\n== OUTLINES ==\n'
for f in \
  .github/scripts/audit_workflow_trust.py \
  .github/scripts/audit_workflow_trust_surface.py \
  .github/scripts/audit_workflow_trust_environment_channels.py \
  .github/scripts/test_audit_workflow_trust.py \
  .github/scripts/test_audit_workflow_trust_surface.py \
  .github/scripts/test_audit_workflow_trust_environment_channels.py \
  .github/scripts/test_audit_workflow_trust_syntax.py
do
  if [ -f "$f" ]; then
    printf '\n--- %s ---\n' "$f"
    ast-grep outline "$f" --items all 2>/dev/null || true
  fi
done

printf '\n== CI AND POLICY ==\n'
cat -n .github/workflows/ci.yml
cat -n .github/workflow-trust-policy.json

printf '\n== ENVIRONMENT/STARTUP AUTHORITY AUDITOR ==\n'
cat -n .github/scripts/audit_workflow_trust_environment_channels.py

printf '\n== ENVIRONMENT/STARTUP AUTHORITY REGRESSIONS ==\n'
cat -n .github/scripts/test_audit_workflow_trust_environment_channels.py

printf '\n== CORE AUDITOR: DISCOVERY, YAML, POLICY, EXECUTION ==\n'
sed -n '1,360p;430,760p;760,1220p' .github/scripts/audit_workflow_trust.py | cat -n

printf '\n== SURFACE AUDITOR: EXECUTION AND DELEGATION ==\n'
cat -n .github/scripts/audit_workflow_trust_surface.py

printf '\n== CURRENT WORKFLOWS, ACTIONS, AND SHELL SOURCES ==\n'
git ls-files | awk \
  '($0 ~ /^\.github\/workflows\/.*\.(yml|yaml)$/) || ($0 ~ /(^|\/)action\.ya?ml$/) || ($0 ~ /\.sh$/)' |
sort |
while IFS= read -r f; do
  printf '\n--- %s ---\n' "$f"
  cat -n "$f"
done

printf '\n== LATEST ENVIRONMENT/STARTUP AUTHORITY DIFF ==\n'
git diff --find-renames --unified=20 \
  0fc0607dc5b3057f59e26c3c583a28747a20c036 HEAD -- \
  .github/scripts .github/workflows .github/workflow-trust-policy.json \
  action.yml action.yaml scripts

printf '\n== AUTHORITY CONSTRUCTION / SHELL FEATURE SEARCH ==\n'
rg -n -U -C3 \
  'GITHUB_(PATH|ENV)|BASH_ENV|ZDOTDIR|(^|[^[:alnum:]_])ENV([^[:alnum:]_]|$)|GITHUB_|BASH_|ZDOT|\
\$\{!|\$\{[^}]*\}|\$\(|`|(^|[;&|[:space:]])(?:eval|exec|source|\.|command|builtin|hash|alias|unalias|enable|env|bash|dash|ksh|sh|zsh|read|mapfile|readarray|getopts|printf|declare|typeset|local|readonly|export|unset)[[:space:]]|PATH=' \
  .github action.yml action.yaml scripts --glob '*.py' --glob '*.sh' --glob '*.yml' --glob '*.yaml' 2>/dev/null || true

printf '\n== WORKFLOW/ACTION DIFF VS BASE ==\n'
git diff --find-renames --unified=16 "$base" HEAD -- \
  .github/workflows action.yml action.yaml scripts

printf '\n== SCOPE AND WHITESPACE ==\n'
git diff --name-only "$base" HEAD -- . \
  ':(exclude).github' \
  ':(exclude)action.yml' \
  ':(exclude)action.yaml' \
  ':(exclude)scripts' \
  ':(exclude)specs/015-af-01-trusted-development-baseline'
git diff --check "$base" HEAD

printf '\n== REPORTED RUNS ==\n'
for run in 33042082554 33042082675 33042082530; do
  gh run view "$run" --repo TheHalfMoon/commandF \
    --json databaseId,headSha,status,conclusion,name,jobs 2>/dev/null || true
done

Length of output: 182607


🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='7fd664af6a77989dda8b5d79095671b564fb9c2a'
test "$(git rev-parse HEAD)" = "$expected"

printf '%s\n' '== ENVIRONMENT AUTHORITY AUDITOR: COMPLETE =='
cat -n .github/scripts/audit_workflow_trust_environment_channels.py

printf '%s\n' '== SURFACE: VARIABLE, WRAPPER, AND SHELL EXECUTION PATHS =='
sed -n '1,180p;185,345p;345,570p;570,720p' \
  .github/scripts/audit_workflow_trust_surface.py | cat -n

printf '%s\n' '== CORE: TOKEN RESOLUTION AND CARGO SHELL SEGMENTS =='
sed -n '430,650p' .github/scripts/audit_workflow_trust.py | cat -n

printf '%s\n' '== STARTUP AUTHORITY REGRESSION SEARCH =='
rg -n -A35 -B6 \
  'BASH_ENV|ZDOTDIR|(^|[^A-Za-z0-9_])ENV([^A-Za-z0-9_]|$)|BASH_|ZDOT|startup|environment.*fragment|fragment.*environment|export.*\$\{|declare.*\$\{|typeset.*\$\{' \
  .github/scripts/test_audit_workflow_trust*.py \
  .github/scripts/audit_workflow_trust*.py

printf '%s\n' '== VARIABLE-CONSTRUCTION FORMS IN CURRENT AUTHORITY SOURCES =='
rg -n -U -C3 \
  '(export|declare|typeset|readonly|local|env)[[:space:]].*(\$\{[^}]+\}|[A-Za-z_][A-Za-z0-9_]*=)|\
[A-Za-z_][A-Za-z0-9_]*=.*(\$\{[^}]+\}|"\$[A-Za-z_][A-Za-z0-9_]*")|\
(bash|sh|dash|ksh|zsh)[[:space:]]+(-c|--command)' \
  action.yml scripts .github/workflows .github/scripts --glob '*.sh' --glob '*.yml' --glob '*.yaml' --glob '*.py' 2>/dev/null || true

printf '%s\n' '== AUDITOR TEST FIXTURE HELPERS =='
sed -n '1,220p' .github/scripts/test_audit_workflow_trust_environment_channels.py | cat -n
sed -n '1,200p' .github/scripts/test_audit_workflow_trust_surface_precision.py | cat -n

printf '%s\n' '== WORKFLOW TRUST POLICY RULES =='
cat -n .github/workflow-trust-policy.json

Length of output: 131490


@TheHalfMoon I reviewed exact head 7fd664af6a77989dda8b5d79095671b564fb9c2a.

I found one material AF-01 Stack A finding.

  1. P1 — Startup-variable construction still bypasses the environment/startup-authority gate.
    .github/scripts/audit_workflow_trust_environment_channels.py Line 16 through Line 23 only rejects exact BASH_ENV and a standalone BASH_ fragment. It does not reject valid shell construction from BASH and _ENV.

    A composite Action shell source can export BASH_ENV without matching any current forbidden pattern:

    prefix=BASH
    export "${prefix}_ENV=$GITHUB_ACTION_PATH/scripts/hidden.sh"
    bash "$GITHUB_ACTION_PATH/scripts/entry.sh"

    Bash expands the export argument to BASH_ENV=.... It then sources scripts/hidden.sh before it executes scripts/entry.sh.

    If scripts/hidden.sh contains an unlocked Cargo command, the surface audit recursively audits scripts/entry.sh but does not audit scripts/hidden.sh. The environment/startup-authority audit does not report this input. The text contains neither BASH_ENV nor the standalone BASH_ fragment.

    Apply fail-closed detection to startup-variable construction, not only selected string fragments. At minimum, reject shell assignments or export arguments that combine a variable expansion with startup-variable suffixes such as _ENV. Add regressions for prefix=BASH; export "${prefix}_ENV=..." with locked and unlocked hidden Action scripts. Add equivalent construction cases for ZDOTDIR and ENV.

The independent environment/startup-authority CI gate is present and runs before Rust gates. The reported ci, cf06-oracle, and registry-download-smoke runs succeeded on the requested head. The workflow changes preserve the CF-06 oracle commands and registry smoke behavior. I used static source inspection only. I did not execute repository scripts or tests.

You are interacting with an AI system.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Your trial has ended. Reactivate Greptile to resume code reviews.

Copy link
Copy Markdown
Owner Author

@qodo review

Fresh exact-head AF-01 Stack A review for 28d9e39da1bc1bc6059a8b9f9c46327fe47ad99f only. All prior reviews/findings are stale.

Exact-head qualification is terminal green:

  • ci run 33043285246 SUCCESS, including AF-01 unit/core/executable-surface/environment-startup gates, dynamic startup-writer regressions, quote-aware parser precision, Format/Clippy/workspace tests, CF-08/CF-09, real FHIR/terminology, local source-backed Action integration, and output verification;
  • cf06-oracle run 33043285220 SUCCESS including oracle-proof;
  • registry-download-smoke run 33043285224 SUCCESS.

Please review the full current diff. Re-check all prior remediations and especially the latest CodeRabbit P1 closure: shell variable-writing builtins now fail closed on dynamically constructed variable names/targets (export/declare/local/readonly/typeset, printf -v, read/mapfile/readarray/unset, getopts, and dynamic env assignments/operands). This closes construction of BASH_ENV, ENV, ZDOTDIR, GITHUB_PATH, or GITHUB_ENV through variable expansion rather than literal fragments. Regressions cover locked and unlocked hidden Action scripts behind dynamic BASH_ENV, dynamic POSIX ENV, zsh ZDOTDIR, printf -v, env, and safe static-name/dynamic-value precision.

The dynamic-writer parser is now quote-aware: quoted semicolons remain data while real shell separators still expose subsequent dynamic writers. A permanent regression covers the exact existing CF-09 quoted-semicolon path that previously produced a false positive.

Also re-check PATH/builtin writers/nameref, command-resolution mutation, wrapper heredocs, direct/path-like execution, exact $GITHUB_ACTION_PATH/... recursion, source/dot, wrapper operands, tracked-target/cycle handling, Cargo syntax/provenance, immutable uses, checkout credentials, permissions, runners/timeouts, containers, independent CI wiring, CF-06/registry/product preservation, and all cross-step/startup environment authority.

Report any remaining substantive finding; no PASS is inferred.

Copy link
Copy Markdown
Owner Author

@coderabbitai review

Fresh exact-head AF-01 Stack A review for 28d9e39da1bc1bc6059a8b9f9c46327fe47ad99f only. All prior CodeRabbit reviews/requests are stale.

Exact-head gates are terminal green: ci 33043285246, cf06-oracle 33043285220 including oracle-proof, and registry-download-smoke 33043285224.

Please re-check your prior P1 and the full current diff. The dynamic startup-variable construction bypass is now closed by a general fail-closed dynamic variable-writer boundary: variable-expanding targets/names are rejected for assignment builtins, printf -v, target-writing builtins, getopts, and env. Permanent regressions cover your exact prefix=BASH; export "${prefix}_ENV=..." pattern with both locked and unlocked hidden Action-root scripts, plus dynamic POSIX ENV, zsh ZDOTDIR, printf -v, env, and safe static-name/dynamic-value precision.

The parser used by this boundary is now quote-aware, so a quoted semicolon such as local fsh_index="$case_dir/fsh index;literal.json" remains data while actual command separators still expose later dynamic writers. The live repository gate and a dedicated precision test cover this.

Also re-check all earlier authority classes: direct/indirect GITHUB_PATH/GITHUB_ENV and shell-startup authority, PATH assignments/builtin writers/nameref, hash/alias/enable resolution mutation, wrapper heredocs, direct/path-like execution, exact $GITHUB_ACTION_PATH/... recursion, source/dot, wrapper operands, tracked-target/cycle handling, Cargo syntax/provenance, immutable external refs, checkout credentials, permissions, fixed runners/timeouts, containers, independent CI wiring, CF-08/CF-09, local Action integration, and accidental CF-06/registry/product drift.

Report any remaining material issue; no PASS is assumed.

@qodo-code-review

Copy link
Copy Markdown

review

Fresh exact-head AF-01 Stack A review for 28d9e39da1bc1bc6059a8b9f9c46327fe47ad99f only. All prior reviews/findings are stale.

Exact-head qualification is terminal green:

  • ci run 33043285246 SUCCESS, including AF-01 unit/core/executable-surface/environment-startup gates, dynamic startup-writer regressions, quote-aware parser precision, Format/Clippy/workspace tests, CF-08/CF-09, real FHIR/terminology, local source-backed Action integration, and output verification;
  • cf06-oracle run 33043285220 SUCCESS including oracle-proof;
  • registry-download-smoke run 33043285224 SUCCESS.

Please review the full current diff. Re-check all prior remediations and especially the latest CodeRabbit P1 closure: shell variable-writing builtins now fail closed on dynamically constructed variable names/targets (export/declare/local/readonly/typeset, printf -v, read/mapfile/readarray/unset, getopts, and dynamic env assignments/operands). This closes construction of BASH_ENV, ENV, ZDOTDIR, GITHUB_PATH, or GITHUB_ENV through variable expansion rather than literal fragments. Regressions cover locked and unlocked hidden Action scripts behind dynamic BASH_ENV, dynamic POSIX ENV, zsh ZDOTDIR, printf -v, env, and safe static-name/dynamic-value precision.

The dynamic-writer parser is now quote-aware: quoted semicolons remain data while real shell separators still expose subsequent dynamic writers. A permanent regression covers the exact existing CF-09 quoted-semicolon path that previously produced a false positive.

Also re-check PATH/builtin writers/nameref, command-resolution mutation, wrapper heredocs, direct/path-like execution, exact $GITHUB_ACTION_PATH/... recursion, source/dot, wrapper operands, tracked-target/cycle handling, Cargo syntax/provenance, immutable uses, checkout credentials, permissions, runners/timeouts, containers, independent CI wiring, CF-06/registry/product preservation, and all cross-step/startup environment authority.

Report any remaining substantive finding; no PASS is inferred.

I found no remaining substantive finding in the current AF-01 Stack A diff.

  • The constrained core audit still fails closed for malformed policy/YAML, mutable uses, checkout credentials, permissions, runners/timeouts, container digests, and lockfile-consuming Cargo commands.
  • The executable-surface audit covers shell heredocs, dynamic/indirect Cargo execution, wrappers, path/resolution mutation, builtin and nameref writers, exact $GITHUB_ACTION_PATH delegation, tracked recursive scripts, and cycle handling.
  • The environment-channel audit is quote-aware and rejects both literal and dynamically constructed GITHUB_PATH/GITHUB_ENV and shell-startup authority, including the listed writer builtins and dynamic operands.
  • The inspected policy supplies complete rationales and explicit workflow/job constraints with no exceptions.

The prior seven Qodo findings are already marked implemented, and I have no new finding to report from this head. This is a review result, not an independent confirmation of the cited CI run statuses.

@coderabbitai

coderabbitai Bot commented Aug 27, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='28d9e39da1bc1bc6059a8b9f9c46327fe47ad99f'
actual="$(git rev-parse HEAD)"
printf 'HEAD=%s\nEXPECTED=%s\n' "$actual" "$expected"
test "$actual" = "$expected"

base="$(git merge-base HEAD main)"
printf 'MERGE_BASE=%s\n' "$base"

printf '\n== CHANGED FILES VS MERGE BASE ==\n'
git diff --name-status "$base" HEAD

printf '\n== AUDITOR AND TEST OUTLINES ==\n'
for f in \
  .github/scripts/audit_workflow_trust.py \
  .github/scripts/audit_workflow_trust_surface.py \
  .github/scripts/audit_workflow_trust_environment_channels.py \
  .github/scripts/test_audit_workflow_trust.py \
  .github/scripts/test_audit_workflow_trust_surface.py \
  .github/scripts/test_audit_workflow_trust_surface_precision.py \
  .github/scripts/test_audit_workflow_trust_environment_channels.py \
  .github/scripts/test_audit_workflow_trust_syntax.py
do
  if [ -f "$f" ]; then
    printf '\n--- %s ---\n' "$f"
    ast-grep outline "$f" --items all 2>/dev/null || true
  fi
done

printf '\n== ENVIRONMENT/STARTUP AUTHORITY AUDITOR ==\n'
cat -n .github/scripts/audit_workflow_trust_environment_channels.py

printf '\n== DYNAMIC VARIABLE-WRITER IMPLEMENTATION ==\n'
rg -n -A85 -B15 \
  'dynamic|variable.writer|variable.*target|assignment.*builtin|printf|mapfile|readarray|getopts|nameref|BASH_ENV|ZDOTDIR|GITHUB_(PATH|ENV)|env' \
  .github/scripts/audit_workflow_trust_environment_channels.py \
  .github/scripts/audit_workflow_trust_surface.py \
  .github/scripts/audit_workflow_trust.py

printf '\n== ENVIRONMENT AND PRECISION REGRESSIONS ==\n'
rg -n -A55 -B6 \
  '^    def test_.*(dynamic|startup|bash_env|zdotdir|github_(path|env)|printf|env|read|mapfile|readarray|getopts|semicolon|precision|live|determin)' \
  .github/scripts/test_audit_workflow_trust_environment_channels.py \
  .github/scripts/test_audit_workflow_trust_surface.py \
  .github/scripts/test_audit_workflow_trust_surface_precision.py \
  .github/scripts/test_audit_workflow_trust_syntax.py \
  .github/scripts/test_audit_workflow_trust.py

printf '\n== CORE AND SURFACE AUTHORITY IMPLEMENTATION ==\n'
sed -n '1,260p;430,760p;760,1220p' .github/scripts/audit_workflow_trust.py | cat -n
sed -n '1,220p;220,500p;500,760p' .github/scripts/audit_workflow_trust_surface.py | cat -n

printf '\n== CI AND POLICY ==\n'
cat -n .github/workflows/ci.yml
cat -n .github/workflow-trust-policy.json

printf '\n== CURRENT WORKFLOWS, ACTION METADATA, AND SHELL SOURCES ==\n'
git ls-files | awk \
  '($0 ~ /^\.github\/workflows\/.*\.(yml|yaml)$/) || ($0 ~ /(^|\/)action\.ya?ml$/) || ($0 ~ /\.sh$/)' |
sort |
while IFS= read -r f; do
  printf '\n--- %s ---\n' "$f"
  cat -n "$f"
done

printf '\n== FULL WORKFLOW/ACTION/SHELL DIFF ==\n'
git diff --find-renames --unified=18 "$base" HEAD -- \
  .github/workflows action.yml action.yaml scripts .github/scripts \
  .github/workflow-trust-policy.json \
  specs/015-af-01-trusted-development-baseline/stack-a-inventory.md

printf '\n== AUTHORITY-SENSITIVE SOURCE FORMS ==\n'
rg -n -U -C3 \
  'GITHUB_(PATH|ENV)|BASH_ENV|ZDOTDIR|(^|[^[:alnum:]_])ENV([^[:alnum:]_]|$)|GITHUB_|BASH_|ZDOT|\
\$\{!|(^|[;&|[:space:]])(?:eval|exec|source|\.|command|builtin|hash|alias|unalias|enable|env|bash|dash|ksh|sh|zsh|read|mapfile|readarray|getopts|printf|declare|typeset|local|readonly|export|unset)[[:space:]]|PATH=|<<-?[[:space:]]*|(^|[;&|[:space:]])cargo([[:space:];|&]|$)' \
  .github action.yml action.yaml scripts --glob '*.py' --glob '*.sh' --glob '*.yml' --glob '*.yaml' 2>/dev/null || true

printf '\n== SCOPE, WHITESPACE, AND REPORTED RUNS ==\n'
git diff --name-only "$base" HEAD -- . \
  ':(exclude).github' \
  ':(exclude)action.yml' \
  ':(exclude)action.yaml' \
  ':(exclude)scripts' \
  ':(exclude)specs/015-af-01-trusted-development-baseline'
git diff --check "$base" HEAD
for run in 33043285246 33043285220 33043285224; do
  gh run view "$run" --repo TheHalfMoon/commandF \
    --json databaseId,headSha,status,conclusion,name 2>/dev/null || true
done

Length of output: 186267


🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected='28d9e39da1bc1bc6059a8b9f9c46327fe47ad99f'
test "$(git rev-parse HEAD)" = "$expected"

printf '%s\n' '== ENVIRONMENT AUTHORITY AUDITOR: COMPLETE =='
cat -n .github/scripts/audit_workflow_trust_environment_channels.py

printf '%s\n' '== SURFACE: EVALUATION, SHELL SYNTAX, AND ACTION-SCRIPT DELEGATION =='
rg -n -A100 -B15 \
  'eval|command substitution|_logical_shell_segments|shlex\.split|ValueError|unsupported_.*(shell|action|cargo)|_action_local_targets|audit_action_text|audit_repository_surface' \
  .github/scripts/audit_workflow_trust_surface.py \
  .github/scripts/audit_workflow_trust.py

printf '%s\n' '== ENVIRONMENT-AUTHORITY TESTS: EVALUATION AND DYNAMIC NAMES =='
rg -n -A55 -B8 \
  'def test_.*(eval|dynamic|substitution|startup|bash_env|zdotdir|environment|fragment|indirect|shell_syntax)|eval|BASH_ENV|ZDOTDIR|GITHUB_(PATH|ENV)' \
  .github/scripts/test_audit_workflow_trust_environment_channels.py \
  .github/scripts/test_audit_workflow_trust_environment_channels_precision.py \
  .github/scripts/test_audit_workflow_trust_surface.py \
  .github/scripts/test_audit_workflow_trust_surface_precision.py \
  .github/scripts/test_audit_workflow_trust_syntax.py

printf '%s\n' '== CURRENT EXECUTION-EVALUATION FORMS =='
rg -n -U -C3 \
  '(^|[;&|[:space:]])(?:eval|source|\.|bash|dash|ksh|sh|zsh)[[:space:]]|\$\(|`|\$\{!|BASH_ENV|ZDOTDIR|GITHUB_(PATH|ENV)' \
  action.yml scripts .github/workflows .github/scripts \
  --glob '*.sh' --glob '*.py' --glob '*.yml' --glob '*.yaml' 2>/dev/null || true

Length of output: 244684


@TheHalfMoon I reviewed exact head 28d9e39da1bc1bc6059a8b9f9c46327fe47ad99f.

I found no material AF-01 Stack A issue.

The dynamic startup-variable writer boundary closes the prior P1. The environment-authority audit rejects dynamically constructed variable names for assignment builtins, printf -v, variable-target builtins, getopts, and env. The regression suite covers the prefix=BASH; export "${prefix}_ENV=..." form, POSIX ENV, ZDOTDIR, and safe dynamic values with static variable names.

The quote-aware tokenizer keeps quoted semicolons as data. It still splits real command separators. The dedicated precision regression covers the CF-09 fsh_index value.

I also checked adjacent authority paths. The implementation rejects indirect parameter expansion, GITHUB_ and startup-variable fragments, PATH mutation and variable writers, namerefs, command-resolution mutation, wrapper heredocs, dynamic or non-Action-root script delegation, shell -c, and unresolved executable provenance. The surface audit recursively checks exact tracked $GITHUB_ACTION_PATH/... shell sources and bounds cycles.

The CI workflow invokes the environment/startup-authority audit as an independent step. It runs after the core and surface gates and before Rust gates. All reported required workflow runs completed successfully on the reviewed head.

The workflow diff preserves the CF-06 oracle commands and the registry retry behavior. The source-backed Action now executes only $CARGO_TARGET_DIR/debug/commandf. I found no product, oracle, proof, or registry semantic drift outside the AF-01 scope.

I used static source inspection. I did not execute repository code or tests.

You are interacting with an AI system.

@TheHalfMoon
TheHalfMoon merged commit 4858757 into main Aug 27, 2026
7 checks passed
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