Skip to content

budget: capture first cost snapshot + bootstrap latest-report.md (task #287)#615

Merged
AceHack merged 3 commits intomainfrom
budget/first-cost-snapshot
Apr 26, 2026
Merged

budget: capture first cost snapshot + bootstrap latest-report.md (task #287)#615
AceHack merged 3 commits intomainfrom
budget/first-cost-snapshot

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented Apr 26, 2026

Summary

Ran the just-merged tools/budget/daily-cost-report.sh on main to capture the first cost snapshot. docs/budget-history/latest-report.md now exists as a glanceable Aaron-decision surface (cat to see costs in <2 seconds).

First snapshot summary

  • LFG Copilot: Business plan, 1 active seat, $19/month single-span projection (consistent with Aaron's $3.80 prorated mid-cycle observation today)
  • Zeta repo: 20 last-runs / 513s total / 0 billable_ms / 5 recent merged PRs
  • N=1 — projection text honestly says "insufficient data" until N≥3 accumulates

Test plan

  • Wrapper ran end-to-end without errors
  • snapshots.jsonl has 1 valid JSON line
  • latest-report.md rendered cleanly
  • Build clean (no .NET / test changes)

Composes with

…#287 sub-step 2 partial)

Ran tools/budget/daily-cost-report.sh on main (just landed via PR #611) to
bootstrap the first snapshot in docs/budget-history/snapshots.jsonl + the
glanceable latest-report.md.

## What this snapshot captures (LFG, 2026-04-26T13:57:01Z)

- Copilot: Business plan, 1 active seat, $19/month single-span projection
- Zeta repo: 20 last-runs / 513s total duration / 0 billable_ms (public-repo
  included minutes) / 5 recent merged PRs
- N=1 — projection is "insufficient data" per the script's honest reporting;
  needs N>=3 across >=2 LFG merges before decision-ready

## What this gives the maintainer

`cat docs/budget-history/latest-report.md` → see costs in <2 seconds.
Replaces manual GitHub UI checking (the failure mode Aaron surfaced 2026-04-26
with the LFG Copilot $1.90/$0 over-budget alert + the $3.80 actual seat-rate
clarification). The report's "Projection parameters" section makes the
$19/month single-seat assumption visible alongside the spend.

## Why N=1 is fine to commit now

Each future daily run (when scheduled) appends another snapshot row to
snapshots.jsonl AND overwrites latest-report.md. The N>=3 projection threshold
becomes meaningful with snapshot accumulation; the bootstrap-with-N=1 here
seeds the time-series.

Per Otto-275 log-don't-implement: NOT scheduling the daily routine in this
PR — that's task #287 sub-step 2 (full) pending Aaron's /schedule confirmation.
This commit is the manual one-shot to seed visibility today.

Composes with task #287, PR #611 (the wrapper), tools/budget/snapshot-burn.sh,
tools/budget/project-runway.sh, docs/budget-history/README.md.
Copilot AI review requested due to automatic review settings April 26, 2026 13:58
@AceHack AceHack enabled auto-merge (squash) April 26, 2026 13:58
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

Bootstraps the budget-monitoring visibility surfaces by committing the first captured cost snapshot and the corresponding generated “latest” markdown report under docs/budget-history/.

Changes:

  • Add initial docs/budget-history/snapshots.jsonl entry (first captured snapshot).
  • Add generated docs/budget-history/latest-report.md for quick “cat-to-view” cost/runway status.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
docs/budget-history/snapshots.jsonl Adds the first append-only JSONL snapshot used as projection input.
docs/budget-history/latest-report.md Adds the initial auto-generated markdown report derived from the snapshot/projection scripts.

Comment thread docs/budget-history/latest-report.md Outdated
AceHack and others added 2 commits April 26, 2026 10:29
…template

CI markdownlint flagged docs/budget-history/latest-report.md:84 with MD012 multiple-consecutive-blanks. Root cause was the heredoc template in tools/budget/daily-cost-report.sh having a blank line before EOF, which produced \n\n termination on every regenerated report. Fix removes the blank line in the heredoc and strips the trailing blank from the materialized file. Single-trailing-newline convention restored.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot review on PR #615 flagged P1 — the auto-generated latest-report.md was emitting an absolute filesystem path (`/Users/acehack/Documents/src/repos/Zeta/docs/budget-history/snapshots.jsonl`) leaking the generator's machine/username and breaking reproducibility for other clones.

Fix: strip the repo-root prefix in tools/budget/project-runway.sh emit using bash parameter expansion (`${file#"$repo_root"/}`). The displayed evidence path is now repo-relative (`docs/budget-history/snapshots.jsonl`). When users override via --file with an external path, the absolute path is preserved (correct — they're naming a file outside the repo).

Regenerated latest-report.md to apply the fix to the materialized report.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 26, 2026 14:37
@AceHack AceHack merged commit b027e1f into main Apr 26, 2026
22 checks passed
@AceHack AceHack deleted the budget/first-cost-snapshot branch April 26, 2026 14:39
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

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

docs/budget-history/snapshots.jsonl:2

  • P0: snapshots.jsonl currently has an extra blank line after the JSON object. project-runway.sh uses tail -n 1 to read the last snapshot; with a trailing empty line it will try to parse an empty string with jq, producing errors and potentially invalid projection output. Remove the trailing blank line (ensure the file is strict 1-JSON-object-per-line JSONL with no empty lines).
{"ts":"2026-04-26T13:57:01Z","factory_git_sha":"744e268dd6f57ba230deab8d77616ae19e38cf2f","org":"Lucent-Financial-Group","note":null,"copilot_billing":{"seat_breakdown":{"pending_invitation":0,"pending_cancellation":0,"added_this_cycle":1,"total":1,"active_this_cycle":1,"inactive_this_cycle":0},"seat_management_setting":"assign_selected","plan_type":"business","public_code_suggestions":"allow","ide_chat":"enabled","cli":"enabled","platform_chat":"enabled"},"repos":[{"repo":"Lucent-Financial-Group/Zeta","agg":{"total_runs":20,"total_duration_ms":513000,"billable_ubuntu_ms":0,"billable_macos_ms":0,"billable_windows_ms":0},"pr":{"recent_merged":5,"last_merged_at":"2026-04-26T13:54:29Z"},"last_20_runs":[{"id":24958345708,"name":"Copilot code review","conclusion":null,"run_started_at":"2026-04-26T13:56:13Z","updated_at":"2026-04-26T13:56:27Z"},{"id":24958344924,"name":"CodeQL","conclusion":"success","run_started_at":"2026-04-26T13:56:10Z","updated_at":"2026-04-26T13:56:32Z"},{"id":24958344908,"name":"gate","conclusion":null,"run_started_at":"2026-04-26T13:56:10Z","updated_at":"2026-04-26T13:56:14Z"},{"id":24958344765,"name":"Automatic Dependency Submission (NuGet)","conclusion":"success","run_started_at":"2026-04-26T13:56:10Z","updated_at":"2026-04-26T13:56:54Z"},{"id":24958344331,"name":"Code Quality: PR #614","conclusion":null,"run_started_at":"2026-04-26T13:56:08Z","updated_at":"2026-04-26T13:56:13Z"},{"id":24958344166,"name":".github/workflows/github-settings-drift.yml","conclusion":"failure","run_started_at":"2026-04-26T13:56:08Z","updated_at":"2026-04-26T13:56:08Z"},{"id":24958324676,"name":"Copilot code review","conclusion":null,"run_started_at":"2026-04-26T13:55:09Z","updated_at":"2026-04-26T13:55:20Z"},{"id":24958323549,"name":"gate","conclusion":null,"run_started_at":"2026-04-26T13:55:06Z","updated_at":"2026-04-26T13:55:09Z"},{"id":24958323544,"name":"CodeQL","conclusion":"success","run_started_at":"2026-04-26T13:55:06Z","updated_at":"2026-04-26T13:55:27Z"},{"id":24958322995,"name":"Code Quality: PR #613","conclusion":"success","run_started_at":"2026-04-26T13:55:04Z","updated_at":"2026-04-26T13:56:54Z"},{"id":24958318853,"name":".github/workflows/github-settings-drift.yml","conclusion":"failure","run_started_at":"2026-04-26T13:54:52Z","updated_at":"2026-04-26T13:54:52Z"},{"id":24958318721,"name":"Automatic Dependency Submission (NuGet)","conclusion":"success","run_started_at":"2026-04-26T13:54:51Z","updated_at":"2026-04-26T13:55:36Z"},{"id":24958316252,"name":"Automatic Dependency Submission (NuGet)","conclusion":"success","run_started_at":"2026-04-26T13:54:43Z","updated_at":"2026-04-26T13:55:23Z"},{"id":24958313052,"name":"gate","conclusion":null,"run_started_at":"2026-04-26T13:54:32Z","updated_at":"2026-04-26T13:54:36Z"},{"id":24958313042,"name":"CodeQL","conclusion":null,"run_started_at":"2026-04-26T13:54:32Z","updated_at":"2026-04-26T13:54:44Z"},{"id":24958313038,"name":"scorecard","conclusion":"success","run_started_at":"2026-04-26T13:54:32Z","updated_at":"2026-04-26T13:55:08Z"},{"id":24958312685,"name":".github/workflows/github-settings-drift.yml","conclusion":"failure","run_started_at":"2026-04-26T13:54:31Z","updated_at":"2026-04-26T13:54:31Z"},{"id":24958312663,"name":"Code Quality: Push on main","conclusion":"success","run_started_at":"2026-04-26T13:54:31Z","updated_at":"2026-04-26T13:56:16Z"},{"id":24958285907,"name":"Copilot code review","conclusion":"success","run_started_at":"2026-04-26T13:53:13Z","updated_at":"2026-04-26T13:54:43Z"},{"id":24958285505,"name":"gate","conclusion":null,"run_started_at":"2026-04-26T13:53:12Z","updated_at":"2026-04-26T13:53:15Z"}]}],"scope_coverage":{"has_read_org":true,"has_admin_org":false,"covered":["copilot-seats","actions-runs-per-run-timing"],"missing_requires_admin_org":["actions-billing","packages-billing","shared-storage-billing"]}}

## How to read this

- **`Actions billable_ms cumulative`** — cumulative GitHub-Actions billable runtime across captured snapshots. On public repos this is typically 0 (included minutes); meaningful for macOS / private-repo / Enterprise-plan accounts.
- **`Per-PR Actions ms (naive)`** — rolling-window estimate of per-merged-PR Actions cost. Caveats in the projection text below; treat as proxy until `N \geq 3` cumulative snapshots exist.
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.

The report text says “Caveats in the projection text below”, but the projection (including the caveats section) appears above this “How to read this” section. Also, N \geq 3 renders literally inside inline code in Markdown; consider using N >= 3 (or N ≥ 3) so it reads correctly without LaTeX rendering.

Suggested change
- **`Per-PR Actions ms (naive)`** — rolling-window estimate of per-merged-PR Actions cost. Caveats in the projection text below; treat as proxy until `N \geq 3` cumulative snapshots exist.
- **`Per-PR Actions ms (naive)`** — rolling-window estimate of per-merged-PR Actions cost. Caveats in the projection text above; treat as proxy until `N >= 3` cumulative snapshots exist.

Copilot uses AI. Check for mistakes.
AceHack added a commit that referenced this pull request Apr 26, 2026
…ation on row 14:51:40Z

Two #621 review threads addressed in single edit on row 14:51:40Z:

1. **Codex P2 (NM59qX...)**: row's summary listed #618 in the merged set ('#615/#617/#618/#620/#596 merged') but #618 was CLOSED/superseded by #620, not merged. Fixed: summary now reads '#615/#617/#620/#596 merged + #618 closed/superseded by #620'. Item (4) also corrected to clarify only #617 merged at 14:38Z; #618 became sibling-DIRTY post-merge and was superseded.

2. **Copilot P1 xref (NM59qX...)**: row claimed Otto-349 lineage memory 'landed as <filename> user-scope + MEMORY.md indexed' but the file isn't in-repo (the in-repo memory/MEMORY.md does exist; the lineage file does not). Fixed: explicit clarification that the file landed at user-scope per CLAUDE.md memory layout; the user-scope memory store is distinct from in-repo memory/ — both exist by design.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request Apr 26, 2026
…ad sweep) (#621)

* tick-history: 14:51:40Z — multi-tick consolidated burst row (5 PRs merged + #602 7-of-9 threads resolved)

Tick-history was 41min dark (last row 14:10:55Z); per the heartbeat-never-dark discipline + Otto-2026-04-26 hour-bundle pattern composed with Otto-275-YET burst-discipline, landing one consolidated row at the natural stopping point rather than 5 sibling-DIRTY per-tick PRs.

Coverage: Otto-349 lineage memory, Otto-275-YET refinement, #615 P1 privacy fix, #617+#618 markdownlint fixes, #620 clean-reapply, #596 review-fix (5 threads resolved + merged), #602 review-fix (7 of 9 threads resolved, 2 math threads deferred to task #286/Amara), Aaron's amara-files query, task #289 filed for #132 drain.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(tick-history): correct #618 status + Otto-349 user-scope clarification on row 14:51:40Z

Two #621 review threads addressed in single edit on row 14:51:40Z:

1. **Codex P2 (NM59qX...)**: row's summary listed #618 in the merged set ('#615/#617/#618/#620/#596 merged') but #618 was CLOSED/superseded by #620, not merged. Fixed: summary now reads '#615/#617/#620/#596 merged + #618 closed/superseded by #620'. Item (4) also corrected to clarify only #617 merged at 14:38Z; #618 became sibling-DIRTY post-merge and was superseded.

2. **Copilot P1 xref (NM59qX...)**: row claimed Otto-349 lineage memory 'landed as <filename> user-scope + MEMORY.md indexed' but the file isn't in-repo (the in-repo memory/MEMORY.md does exist; the lineage file does not). Fixed: explicit clarification that the file landed at user-scope per CLAUDE.md memory layout; the user-scope memory store is distinct from in-repo memory/ — both exist by design.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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.

2 participants