feat(shipreport): daily scripted fleet ship-report (safety valve for #405) #406
No reviewers
Labels
No labels
Agent
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
1 participant
Notifications
Total time spent: 1 minute
Due date
igor
1 minute
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor!406
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/ship-report"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Step ④ of the review-gate rollout, and the safety valve for #405. Spec merged (#404).
What it does
A daily email to
PRIMARY_RECIPIENTS— the once-a-day window that keeps you in control by exception once you're out of the per-PR merge gate:Mechanics
do_seo_tick: runs in both the health-blocked branch and the normal cascade)..shipreportstamp (clear to resend).lib/ship-report.sh(build/render/stamp, unit-tested); gathering indo_shipreport_tick.require_humanflag directly, so this PR is independent of #405.Tests
bin/test-shipreport.sh: bucketing, the shadow-vs-human tag, empty-window, the daily-stamp round-trip, and a guard that the module makes no model call.make testgreen (incl.check-sync).Merge together with #405
Merge this with #405 so shadow-gating and its daily visibility go live as a pair — this report is what makes flipping the gate safe.
🤖 Review —
APPROVE(automated)CI for
6bee5bf1: successSummary: Adds a fully-scripted daily "fleet ship report" email (new
lib/ship-report.sh+do_shipreport_tickintick.sh), with unit tests. In scope, honestly described, CI green. APPROVE with minor non-blocking notes.What I checked and liked:
shipreport_build,shipreport_is_empty,shipreport_render_text/html,shipreport_sent_today,shipreport_mark_sent), gathering indo_shipreport_tick, and the "no model call" claim is both true in the module and guarded by a grep test inbin/test-shipreport.sh.do_shipreport_tick || true) and the normal cascade (if do_shipreport_tick; then exit 0; fi), mirroringdo_seo_tick. A single tick only executes one branch (health-blocked pathexit 0s), so no double-send; the daily stamp guards across ticks.shipreport_mark_sentusesjq '.shipreport = {...}'which preserves sibling keys (e.g. sports'.sports) in the shareddiscretionary-state.json. Empty-window path stamps + returns 0 so it won't retry all day..automerge.require_humandirectly viaforgejo_repo_get_filerather than the automerge module — matches the description's claim.|@html. URLs come from Forgejohtml_url, low injection risk.Non-blocking notes for the human:
merged_at >= since; there's no deploy verification. The footer ("Deploy failures are alerted separately") covers the gap, but the "shipped" bucket is really "merged in last 24h."email_send,recipients_with_primary,_fj,BOT_USER,ANALYSIS_REPOS_JSONare external to this diff; I can't confirm their signatures/behavior from the diff alone. They mirror the existing sports/SEO digests and CI (incl.check-sync) is green, which is my basis for accepting them.has "...@html" "$HTML" "shadow merge"only asserts the substring appears, not that a</&in a title is actually escaped. Consider a fixture title containing<b>to prove the@htmlfilter. Not blocking.No correctness, security, or scope defects found; CI is
success.Independent review by the harness on
claude-opus-4-8(effort: high). The human reviewer is requested once Igor has reviewed; a human still merges.