Skip to content

ops(ci): weekly budget-snapshot-cadence workflow (task #297, follow-up to #287)#25

Open
AceHack wants to merge 1 commit intomainfrom
ops/2026-04-26-task-297-budget-cadence-workflow
Open

ops(ci): weekly budget-snapshot-cadence workflow (task #297, follow-up to #287)#25
AceHack wants to merge 1 commit intomainfrom
ops/2026-04-26-task-297-budget-cadence-workflow

Conversation

@AceHack
Copy link
Copy Markdown
Owner

@AceHack AceHack commented Apr 26, 2026

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

  • New workflow .github/workflows/budget-snapshot-cadence.yml (~240 lines)
  • Weekly cron Sundays 16:23 UTC (off-the-hour weekend slot per GHA thundering-herd avoidance + non-competition with PR cadence)
  • workflow_dispatch with optional note input for ad-hoc runs
  • On each run: checkout → verify tooling → run snapshot-burn.sh → if diff exists, open auto-merge-armed PR using AgencySignature v1 canonical commit shape with github-actions[bot] as Credential-Identity and Human-Review-Evidence: signed-policy

Authored 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 via env: into run blocks and quoted as "$VAR" per the GitHub Actions injection guide. No expressions interpolated directly inside run-block scripts. The workflow_dispatch note input is routed through env: to neutralise potentially-malicious content.

Honest limits

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

…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>
@AceHack AceHack added the agent-otto PR opened by Otto agent (Claude Code on Aaron's gh credentials) label Apr 26, 2026
Copilot AI review requested due to automatic review settings April 26, 2026 20:01
@AceHack AceHack enabled auto-merge (squash) April 26, 2026 20:01
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

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 plus workflow_dispatch for ad-hoc snapshots with an optional note.
  • Runs tools/budget/snapshot-burn.sh, detects whether docs/budget-history/snapshots.jsonl changed, 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.

Comment on lines +77 to +82
- name: Checkout
uses: actions/checkout@v4
with:
# Need full history so snapshot-burn.sh can compute
# factory_git_sha correctly.
fetch-depth: 0
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Comment on lines +66 to +67
# Only one cadence run at a time per branch. Cancelling an
# in-flight run on retrigger avoids duplicate snapshots.
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
# 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.

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +45
# 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.
Copy link

Copilot AI Apr 26, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 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 }}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge 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 👍 / 👎.

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

Labels

agent-otto PR opened by Otto agent (Claude Code on Aaron's gh credentials)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants