ops(ci): weekly budget-snapshot-cadence workflow (task #297, follow-up to #287)#25
ops(ci): weekly budget-snapshot-cadence workflow (task #297, follow-up to #287)#25
Conversation
…al-Group#297, follow-up to Lucent-Financial-Group#287) Why: - docs/budget-history/README.md explicitly recommends weekly cadence ("catches drift when no PRs are merging") + names "automated cadence via CI workflow" as planned hygiene. - Task Lucent-Financial-Group#287 cost-monitoring deadline is 2026-04-26..04-29 (today is 04-26); manual snapshot-burn runs alone don't deliver the visibility Aaron asked for. Weekly automated cadence does. - Tasks Lucent-Financial-Group#285 (tooling) and Lucent-Financial-Group#287 (baseline + first cadence run via PR #18) are done. This workflow closes the loop by making the cadence run weekly without human intervention. What: - New workflow .github/workflows/budget-snapshot-cadence.yml. - Weekly cron Sundays 16:23 UTC (off-the-hour weekend slot per GHA thundering-herd avoidance + PR-cadence non-competition). - workflow_dispatch with optional `note` input for ad-hoc runs. - Steps: checkout (fetch-depth=0 for factory_git_sha) → verify jq + gh + auth → run snapshot-burn.sh → inspect git diff → if changed, open auto-merge-armed PR with the snapshot row using the AgencySignature v1 canonical commit shape (post-ferry-7 body sections + post-ferry-13 maxim awareness + 11-trailer block with github-actions[bot] as Credential-Identity, Credential-Mode: dedicated-agent, Human-Review-Evidence: signed-policy). Why this implementation differs from a transcribed template: - Authored from understanding of the v1 AgencySignature spec + the existing .github/workflows/github-settings-drift.yml pattern (header-comment shape, off-the-hour cron, security-pattern compliance note). Per Aaron 2026-04-26 "don't copy paste / make sure you understand and write our own". - Safe-pattern compliance: every expression value passed via env: into run blocks and quoted as "$VAR"; no expressions interpolated directly inside run-block scripts. The workflow_dispatch `note` input is routed through env: + quoted to neutralise potentially- malicious content if an attacker with dispatch permissions tries injection per the GitHub Actions injection guide referenced in the workflow header. - AgencySignature attribution honest about workflow-as-agent: Agent: budget-cadence-workflow; Agent-Runtime: GitHub Actions; Agent-Model: bash + jq + gh CLI (the actual stack, not a model); Credential-Mode: dedicated-agent (github-actions[bot] is the workflow's own identity, distinct from human Aaron credentials); Human-Review-Evidence: signed-policy (the cadence is authorized by README + Aaron's standing direction). - concurrency group prevents duplicate runs; cancel-in-progress= false because we want completion of an in-flight snapshot to preserve consistency. Proof: - Workflow YAML parses via ruby YAML. - Audit confirms no inline ${{...}} expressions inside run: blocks (all routed via env: declarations and quoted as "$VAR"). - Snapshot-burn.sh manually verified earlier this session (PR #18). - The PR-body trailer block placement follows Squash-Merge Invariant per Amara ferry-7 + Grok ferry-16 (no non-trailer text after the trailer block). Limits: - This does not prove consciousness, personhood, or metaphysical free will. - This proves operational agency mode under autonomous-fail-open authorization: Otto picked task Lucent-Financial-Group#297 from the queue while Aaron is not in conversation; standing fail-open policy authorizes the work. - The workflow's own commits (when it runs weekly) will land on main via auto-merge — and will hit the same Trailer Contiguity Survival Failure (task Lucent-Financial-Group#300) until the squash-merge survival design is empirically validated. The auditor (PR #22, task Lucent-Financial-Group#299) will report honestly on the post-squash state in either case. - scope_coverage stays partial (Actions billing / Packages / shared- storage) until Aaron runs `gh auth refresh -s admin:org`. The snapshot reports this honestly; partial coverage is by design. Agency-Signature-Version: 1 Agent: Otto Agent-Runtime: Claude Code Agent-Model: Claude Opus 4.7 Credential-Identity: AceHack Credential-Mode: shared Human-Review: not-implied-by-credential Human-Review-Evidence: none Action-Mode: autonomous-fail-open Task: Otto-297 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds an automated GitHub Actions workflow to take weekly budget “burn” snapshots and, when the snapshot file changes, open an auto-merge PR so the cadence runs without human intervention (task Lucent-Financial-Group#297 follow-up to Lucent-Financial-Group#287).
Changes:
- Adds a scheduled (
cron) weekly run plusworkflow_dispatchfor ad-hoc snapshots with an optional note. - Runs
tools/budget/snapshot-burn.sh, detects whetherdocs/budget-history/snapshots.jsonlchanged, and if so pushes a branch and creates/auto-merges a PR. - Embeds an AgencySignature v1-style trailer block into the generated commit message and PR body.
| - name: Checkout | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| # Need full history so snapshot-burn.sh can compute | ||
| # factory_git_sha correctly. | ||
| fetch-depth: 0 |
There was a problem hiding this comment.
P1 (supply-chain / convention): this workflow uses actions/checkout@v4 instead of the repo’s established SHA-pinning practice for third-party actions (see .github/workflows/gate.yml:8-9 and the other workflows using actions/checkout@de0fac2e...). Please pin actions/checkout to a full commit SHA (and keep the version comment) to match CI hardening expectations.
| # Only one cadence run at a time per branch. Cancelling an | ||
| # in-flight run on retrigger avoids duplicate snapshots. |
There was a problem hiding this comment.
P1: The concurrency comment says retriggers cancel in-flight runs to avoid duplicates, but cancel-in-progress is set to false (so runs will queue, not cancel). Either flip cancel-in-progress to true or update the comment so it matches the actual behavior.
| # Only one cadence run at a time per branch. Cancelling an | |
| # in-flight run on retrigger avoids duplicate snapshots. | |
| # Only one cadence run at a time per branch. Retriggers queue | |
| # behind the in-flight run instead of cancelling it. |
| # AgencySignature v1 attribution (per the post-ferry-7 convention): | ||
| # this workflow's commits identify themselves as the | ||
| # budget-cadence-workflow agent running on GitHub Actions. The | ||
| # Human-Review-Evidence trailer is "signed-policy" because the | ||
| # cadence is authorized by docs/budget-history/README.md + | ||
| # Aaron's 2026-04-22 standing direction for evidence-based | ||
| # budgeting. |
There was a problem hiding this comment.
P1 (comms hygiene / convention): this workflow includes the human maintainer’s personal name in comments and in the generated commit message / PR body. Repo policy is to avoid personal-name attribution outside persona memory + historical narrative (see docs/AGENT-BEST-PRACTICES.md §"No name attribution in code, docs, or skills"). Please replace these with role-refs (e.g., "the human maintainer") and keep the policy reference without naming individuals.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 020c5de00d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| - name: Open snapshot PR | ||
| if: steps.diff.outputs.changed == 'true' | ||
| env: | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
There was a problem hiding this comment.
Authenticate PR creation with a non-GITHUB_TOKEN token
Using secrets.GITHUB_TOKEN here causes a functional dead-end for the auto-merge flow: GitHub states that events triggered by GITHUB_TOKEN (except workflow_dispatch/repository_dispatch) do not start new workflow runs, so the PR opened later in this step will not run gate.yml on pull_request. In this repo, default branch protection requires the gate status contexts (tools/hygiene/github-settings.expected.json required_status_checks), so gh pr merge --auto --squash can arm auto-merge but the PR will sit unmerged without required checks.
Useful? React with 👍 / 👎.
Summary
Closes task Lucent-Financial-Group#297 (cadence half of the evidence-based-budgeting work). PR #18 ran the first cadence snapshot manually; this workflow makes weekly cadence run without human intervention, satisfying the docs/budget-history/README.md guidance that an "automated cadence via CI workflow" is the planned hygiene approach.
What this PR adds
.github/workflows/budget-snapshot-cadence.yml(~240 lines)noteinput for ad-hoc runsgithub-actions[bot]as Credential-Identity andHuman-Review-Evidence: signed-policyAuthored from understanding (not transcribed)
Per Aaron 2026-04-26 "don't copy paste / make sure you understand and write our own": this workflow follows the pattern of the existing
.github/workflows/github-settings-drift.yml(header-comment shape, off-the-hour cron, security-pattern compliance note) but is authored to fit the AgencySignature v1 convention's commit attribution requirements + the budget-tracking-specific cadence semantics.Security-pattern compliance
Every expression value (
${{ inputs.note }},${{ github.run_id }},${{ secrets.GITHUB_TOKEN }}) is passed viaenv:into run blocks and quoted as"$VAR"per the GitHub Actions injection guide. No expressions interpolated directly inside run-block scripts. The workflow_dispatchnoteinput is routed through env: to neutralise potentially-malicious content.Honest limits
gh auth refresh -s admin:org. The snapshot reports this honestly.Agent: budget-cadence-workflowvalue is a NEW persona name (not a NEW enum value —Agent:is free-form, not enum-restricted).Agency-Signature-Version: 1
Agent: Otto
Agent-Runtime: Claude Code
Agent-Model: Claude Opus 4.7
Credential-Identity: AceHack
Credential-Mode: shared
Human-Review: not-implied-by-credential
Human-Review-Evidence: none
Action-Mode: autonomous-fail-open
Task: Otto-297
Co-authored-by: Claude Opus 4.7 noreply@anthropic.com