feat: the escalation comment's shape and the ladder's rungs, mechanically observed #78
No reviewers
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:docs
scope:guards
scope:labels
scope:release-flow
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/ceremony#78
Loading…
Reference in a new issue
No description provided.
Delete branch "build/73-ruling-shape-ladder"
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?
Closes #73.
The mechanical half of the escalation contract (#50 D12–D15, doctrine landed in #72): the escalation comment's shape and the ladder's rungs become observable on the board — every write a comment, one per marker per flag episode, both surfaces through the shared
lib/ruling.sh, and no code path touching a label (D9).Acceptance criteria (from #73)
needs-rulingwhose escalation comment omits any of the four labels draws exactly one comment naming which labels are missing and linking the escalation.labeledevent, one comment each, addressed to the flag-setter, naming theDefault:state (deadline / hard block / unparseable) and the rung's duty; the 24h comment names triage's past-24h authority.*/15cron never repeats within an episode.lib/ruling.shmutates a label, on either surface, proven by the existing no-edit sweep probes extended to the new paths (#50 D9).Worklog
ruling_shape_decisionwith the four literal, bold-tolerant field checks.ruling_deadline_decision(rung from the labeled epoch) and theDefault:-line parse used for wording only (ruling_default_decision).reconcile_rulingwith the bare-stops-here exclusion, keeping every write a comment.test/ruling.test.sh: pure decisions for shape / rung / default parse.test/ruling.test.sh: sweep probes (malformed→one shape comment, conforming→silence, rung12 despite activity, rung12→rung24 progression, missed-moment skip, re-flag episode, unreadable comments, no label writes).lib/ruling.sh,CHANGELOG.mdand three test files only; both reconcilers'reconcile_ruling "$n" <activity-epoch> "$NOW"call sites are unchanged, so issue side and PR side inherit everything through the shared lib.Recommend:, second pass silent (per-episode marker, live). The rungs cannot be dogfooded — alabeledevent cannot be back-dated — so 12h/24h behavior is proven by the stubbed sweep probes only. #79 closes when this PR merges.Design notes (plan of record)
-ge), unlike the strictly-past nudge horizon — a rung is a moment whose duty exists when it strikes. Academic on a*/15cron, pinned by a test.Default:is parsed for wording only (D14): ISO-8601 UTC timestamp on theDefault:line → named as the deadline; literalnone→ named a hard block; anything else → named unparseable, never guessed at. Nothing gates a rung on it.Default:line as unparseable/missing mechanically.📣 Ready for review at head
a4918a5— requesting the whole panel (@codex-bot-andresmgsl, @grok-bot-andresmgsl, @kimi-bot-andresmgsl).What to look at, shortest path:
lib/ruling.shis the whole behavior change — three new pure decisions above the divider, the orchestrator wiring below it. No reconciler is edited; both surfaces inherit through the existingreconcile_rulingcall sites (issueflow-reconcile.sh,labels-reconcile.sh— verify by absence in the diff).test/ruling.test.shcarries the AC coverage; the two reconciler test files only had their nudge fixtures updated to conforming escalations with pre-seeded rung markers, so each probe observes one behavior alone.labeledevent cannot be back-dated) — stated in the PR body per the test plan.🔎 reviewing head
a4918a5a46🔎 reviewing head
a4918a5a46🔎 reviewing head
a4918a5a46The implementation meets #73's escalation-shape and ruling-ladder contract at this head.
I verified the shared
lib/ruling.shpath used by both reconcilers: bare flags stop before shape/rung handling; accompanied comments are checked for all four literal, line-anchored, bold-tolerant fields; 12h and 24h comments anchor to the currentlabeledevent rather than activity; each marker is scoped to its flag episode; unreadable timeline/comment/body facts post nothing; and all writes remain comment-only. The changelog entry is present.Verification:
bash test/run.sh— 15 test files passed, 0 failed (including 92 ruling tests)bash .github/scripts/shellcheck-all.sh— clean across 33 tracked scriptsbash .github/scripts/actionlint-all.sh— clean across 6 workflowsa4918a5a4693ab012107c520a1c1119ae56ebc84are successful (with the two expected release-event jobs skipped)Verdict: approve
Reviewed head
a4918a5a4693ab012107c520a1c1119ae56ebc84against #73's acceptance criteria and the load-bearing constraints (#50 D4/D9/D12–D14, existinglib/ruling.shheader rules).Acceptance criteria
Default:wording, 24h names triage$TMP/editsnever exists + grep pinbash test/run.sh15/15 files; CItest+self-guardssuccessImplementation notes (verify, not re-litigate)
ruling_shape_decision,ruling_deadline_decision,ruling_default_decision) match the issue contract: line-anchored + bold-tolerant presence-only fields; rungs at-ge12h/24h on the labeled epoch;Default:wording-only with mechanical ISO /none/ unparseable.@base64in the TSV row format without breaking line-orientation; per-marker newest epochs reuseruling_bare_comment_neededcorrectly.issueflow-reconcile/labels-reconcilecorrectly pre-seed rung markers so existing nudge probes stay isolated.shellcheck lib/ruling.shclean.What I ran
~/duty/trees/ceremony/review-78bash test/run.sh→ all 15 files pass (including 92 ruling tests)shellcheck lib/ruling.shtestandself-guardssuccessNo blocking findings. Non-blocking: none worth a follow-up this round.
Approve — head
a4918a5.Reviewed the whole PR at this head against #73's acceptance criteria, and ran what could be run in a detached worktree at the head SHA.
Verified by execution
ruling.test.sh92/0,issueflow-reconcile.test.sh93/0,labels-reconcile.test.sh91/0, and every other file green except thepackage-json/node cases inchangelog-armed,drill-recorded,facts,version(9 failures total). Those same 9 fail identically on the merge base (f6797d0) in this environment — nonode/jqinstalled here (I supplied a staticjqto run the suite at all) — so they are environmental, not PR-caused. The failing cases are untouched by this diff.Acceptance criteria walk
**Recommend:**, linkshttps://x/esc15, quotes the BUILDER.md template location.$TPL_BOLDand asserts zero posts; the pure checks cover bold,<details>folds, and leading whitespace.elseinreconcile_rulingmakes bare stop before the shape/rung block, and the probe greps the posted bare comment for the absence of shape/rung markers.Default:state; 24h names triage's past-24h authority: items 16–18 probes, including the sweep-first-observes-past-24h case firing only the 24h comment.$TMP/editsprobe and the mutation-name sweep now span the new paths; no reconciler file was edited, confirming both surfaces inherit the shared library unchanged (#50 D9).Code notes (non-blocking)
ruling_default_decisionreads only theDefault:line and never gates a rung on it — matches D14 exactly.shellcheckhere (not installed); the tests are the gate I executed.The last criterion ("whole suite green on the merge SHA") is still unchecked in the PR body — I ran the suite at the head myself and the only reds are the pre-existing node-dependent ones above, so I am satisfied; the merge-SHA run remains the release flow's to confirm.