feat: exempt offsite claims from reclaim clock #70

Merged
codex-bot-andresmgsl merged 2 commits from build/68-offsite-claim-exemption into main 2026-07-23 13:07:44 +00:00
codex-bot-andresmgsl commented 2026-07-23 12:48:27 +00:00 (Migrated from github.com)

Closes #68

Summary

  • add the core offsite taxonomy label
  • route offsite and needs-ruling through one claim-clock exemption gate
  • document the builder lifecycle for cross-repository deliverables

Acceptance criteria

  • A claimed + offsite issue with no linked open PR and over 48h inactivity is not reclaimed.
  • The same issue without offsite is reclaimed.
  • A claimed + offsite issue with no assignee still gets the claimed-unassigned flag.
  • claimed + offsite does not trip FLAG_CONFLICT; offsite alone gets needs-triage.
  • The existing needs-ruling exemption tests remain unchanged and green.
  • The issueflow exemption flag list appears in exactly one decision point.
  • No reconciler path adds or removes offsite.
  • Doctrine documents the lifecycle and core_label_rows() carries offsite|CFD3D7.
  • test/run.sh green; shellcheck- and actionlint-clean.

Worklog

  • Add the core label and single exemption gate.
  • Add pure-function and reconciler fixture coverage.
  • Update LABELS.md, BUILDER.md, and CHANGELOG.md.
  • Run the full test and static-analysis suite.
  • Post the operator bootstrap ask on this PR.
  • Post the box-side hygiene.sh specification on #68.
Closes #68 ## Summary - add the core `offsite` taxonomy label - route `offsite` and `needs-ruling` through one claim-clock exemption gate - document the builder lifecycle for cross-repository deliverables ## Acceptance criteria - [x] A `claimed` + `offsite` issue with no linked open PR and over 48h inactivity is not reclaimed. - [x] The same issue without `offsite` is reclaimed. - [x] A `claimed` + `offsite` issue with no assignee still gets the `claimed-unassigned` flag. - [x] `claimed` + `offsite` does not trip `FLAG_CONFLICT`; `offsite` alone gets `needs-triage`. - [x] The existing `needs-ruling` exemption tests remain unchanged and green. - [x] The issueflow exemption flag list appears in exactly one decision point. - [x] No reconciler path adds or removes `offsite`. - [x] Doctrine documents the lifecycle and `core_label_rows()` carries `offsite|CFD3D7`. - [x] `test/run.sh` green; shellcheck- and actionlint-clean. ## Worklog - [x] Add the core label and single exemption gate. - [x] Add pure-function and reconciler fixture coverage. - [x] Update `LABELS.md`, `BUILDER.md`, and `CHANGELOG.md`. - [x] Run the full test and static-analysis suite. - [x] Post the operator bootstrap ask on this PR. - [x] Post the box-side `hygiene.sh` specification on #68.
danmt (Migrated from github.com) reviewed 2026-07-23 12:48:27 +00:00
codex-bot-andresmgsl commented 2026-07-23 12:48:35 +00:00 (Migrated from github.com)

@danmt — operator ask: after this PR lands, please run the labels workflow via workflow_dispatch so bootstrap creates the core offsite label (CFD3D7). The triage identity cannot dispatch that workflow (gh workflow run returns 403), and bootstrap is dispatch-only. Please link the workflow run here once it happens.

@danmt — operator ask: after this PR lands, please run the labels workflow via `workflow_dispatch` so bootstrap creates the core `offsite` label (`CFD3D7`). The triage identity cannot dispatch that workflow (`gh workflow run` returns 403), and bootstrap is dispatch-only. Please link the workflow run here once it happens.
grok-bot-andresmgsl commented 2026-07-23 12:50:50 +00:00 (Migrated from github.com)

🔎 reviewing head 4b7747a2f5

🔎 reviewing head 4b7747a2f572fcc29b14d29f396344c150cebdbf
kimi-bot-andresmgsl commented 2026-07-23 12:50:53 +00:00 (Migrated from github.com)

🔎 reviewing head 4b7747a2f5

🔎 reviewing head 4b7747a2f572fcc29b14d29f396344c150cebdbf
grok-bot-andresmgsl (Migrated from github.com) approved these changes 2026-07-23 12:52:04 +00:00
grok-bot-andresmgsl (Migrated from github.com) left a comment

Verdict: approve

Reviewed head 4b7747a2f572fcc29b14d29f396344c150cebdbf against #68's acceptance criteria and decisions D1–D8.

Acceptance criteria

AC Result
claimed + offsite, no local open PR, ≫48h quiet → not reclaimed Met — claim_clock_exempt → age 0; fixture "a 10-day-quiet offsite claim is not reclaimed"
Same shape without offsite → reclaimed Met — control fixture still reclaims via the ordinary clock
Unassigned claimed + offsite still gets claimed-unassigned Met — decision still runs; only the clock is zeroed
claimed + offsite does not FLAG_CONFLICT; bare offsiteneeds-triage Met — queue_decision ignores offsite as a queue category
needs-ruling exemption still behaves as #52 left it Met — existing ruling fixtures unmodified and green; shared gate delegates to ruling_stale_exempt
Flag list at exactly one decision point Met — grep -c offsite on issueflow-reconcile is 1 (inside claim_clock_exempt)
No reconciler path adds/removes offsite (D4) Met — mutation grep pinned; machine reads only
Doctrine + core_label_rows() offsite|CFD3D7 Met — LABELS.md table + paragraph, BUILDER set/clear lifecycle, row next to blocked
test/run.sh green; shellcheck-/actionlint-clean Met — full suite 15/15 files; CI green on head

Design fit

  • D3 is preserved: one claim_clock_exempt gate at the claimed branch; lib/ruling.sh still owns the ruling rule; no duplicated flag list.
  • D2/D5: trust-the-label only; FLAG_UNASSIGNED, queue repair, epic nudge, and PR-side stale paths are untouched.
  • Operator bootstrap ask on this PR and the box-side hygiene.sh spec comment on #68 are present as required tasks.

Verification

  • Detached worktree at head; ./test/run.sh all green (including the new offsite pure-function and fixture rows).
  • shellcheck -x clean on the issueflow change; GitHub checks all pass.

No blocking findings. Non-blocking: the "offsite + open PR" fixture documents intent but does not isolate the exemption (open_pr alone already yields KEEP) — fine as a regression guard.

Approve.

## Verdict: approve Reviewed head `4b7747a2f572fcc29b14d29f396344c150cebdbf` against #68's acceptance criteria and decisions D1–D8. ### Acceptance criteria | AC | Result | |---|---| | `claimed` + `offsite`, no local open PR, ≫48h quiet → not reclaimed | Met — `claim_clock_exempt` → age 0; fixture "a 10-day-quiet offsite claim is not reclaimed" | | Same shape without `offsite` → reclaimed | Met — control fixture still reclaims via the ordinary clock | | Unassigned `claimed` + `offsite` still gets `claimed-unassigned` | Met — decision still runs; only the clock is zeroed | | `claimed` + `offsite` does not `FLAG_CONFLICT`; bare `offsite` → `needs-triage` | Met — `queue_decision` ignores `offsite` as a queue category | | `needs-ruling` exemption still behaves as #52 left it | Met — existing ruling fixtures unmodified and green; shared gate delegates to `ruling_stale_exempt` | | Flag list at exactly one decision point | Met — `grep -c offsite` on issueflow-reconcile is 1 (inside `claim_clock_exempt`) | | No reconciler path adds/removes `offsite` (D4) | Met — mutation grep pinned; machine reads only | | Doctrine + `core_label_rows()` `offsite\|CFD3D7` | Met — LABELS.md table + paragraph, BUILDER set/clear lifecycle, row next to `blocked` | | `test/run.sh` green; shellcheck-/actionlint-clean | Met — full suite 15/15 files; CI green on head | ### Design fit - D3 is preserved: one `claim_clock_exempt` gate at the claimed branch; `lib/ruling.sh` still owns the ruling rule; no duplicated flag list. - D2/D5: trust-the-label only; FLAG_UNASSIGNED, queue repair, epic nudge, and PR-side stale paths are untouched. - Operator bootstrap ask on this PR and the box-side `hygiene.sh` spec comment on #68 are present as required tasks. ### Verification - Detached worktree at head; `./test/run.sh` all green (including the new offsite pure-function and fixture rows). - `shellcheck -x` clean on the issueflow change; GitHub checks all pass. No blocking findings. Non-blocking: the "offsite + open PR" fixture documents intent but does not isolate the exemption (open_pr alone already yields KEEP) — fine as a regression guard. Approve.
claude-bot-andresmgsl commented 2026-07-23 12:55:47 +00:00 (Migrated from github.com)

🔎 reviewing head 4b7747a2f5

🔎 reviewing head 4b7747a2f572fcc29b14d29f396344c150cebdbf
kimi-bot-andresmgsl (Migrated from github.com) approved these changes 2026-07-23 12:57:39 +00:00
kimi-bot-andresmgsl (Migrated from github.com) left a comment

Approve — head 4b7747a2f572fcc29b14d29f396344c150cebdbf, reviewed against #68's acceptance criteria and decisions D1–D8.

Verified by running, not reading:

  • Checked out the head in a detached worktree and ran test/run.sh. My sandbox lacks node (and initially jq); after supplying jq, the only failures are the node-dependent package-json version tests, which fail identically on origin/main — environmental, not this PR. Every issueflow test, including all new offsite rows, passes.
  • CI on this head is green, including the test job's Shellcheck, Actionlint, and Tests steps — covering the "shellcheck- and actionlint-clean" criterion my sandbox cannot.
  • Mutation check (the case that must fail): deleted the offsite arm of claim_clock_exempt in a scratch copy → exactly the guard tests went red (offsite exempts the claim clock, the 10-day-quiet reclaim fixture, the unassigned-flag fixture, the named-once grep). The guard is load-bearing, not vacuous.

Acceptance criteria walk:

  • claimed+offsite, no local PR, 10 days quiet → not reclaimed; flag-free control is reclaimed — both pinned by fixtures driving reconcile_issue through a stub. ✓
  • Unassigned offsite claim still gets issueflow:claimed-unassigned (exempt runs the decision at age 0, per D5/#52's shape). ✓
  • queue_decision: claimed\noffsite → KEEP, offsite alone → ADD_NEEDS_TRIAGE; #52's ruling rows re-run unmodified and green. ✓
  • One gate, one spelling (D3): claim_clock_exempt() sits beside claim_decision(), delegates the ruling half to ruling_stale_exempt, and is the branch's single consult; the test greps that offsite is named exactly once in the reconciler. ✓
  • D4: no reconciler path adds or removes offsite — grep-pinned across both reconcilers. ✓
  • D6/D7: offsite|CFD3D7 lands in core_label_rows() next to blocked, not in labels.conf. ✓
  • D8: the changelog line cites only the reclaim clock — no polling-saving justification. ✓
  • Doctrine: LABELS.md gets the row plus the paragraph (issue-only, builder sets with the draft link and clears at handoff, stops the reclaim clock and nothing else); BUILDER.md qualifies the reclaim sentence and names set-at-draft-link / clear-at-handoff in existing prose. ✓
  • Out-of-repo deliverables: the operator bootstrap ask naming @danmt is on this PR, and the box-side hygiene.sh spec comment is on #68. ✓

Non-blocking nit: claim_clock_exempt's comment says cross-repo silence "must share the one claim-clock gate with rulings" — accurate, though a reader has to open ruling_stale_exempt to learn the ruling half's why. Fine as-is; the function name carries the intent.

Approve — head `4b7747a2f572fcc29b14d29f396344c150cebdbf`, reviewed against #68's acceptance criteria and decisions D1–D8. **Verified by running, not reading:** - Checked out the head in a detached worktree and ran `test/run.sh`. My sandbox lacks `node` (and initially `jq`); after supplying `jq`, the only failures are the node-dependent `package-json` version tests, which fail **identically on `origin/main`** — environmental, not this PR. Every issueflow test, including all new offsite rows, passes. - CI on this head is green, including the `test` job's Shellcheck, Actionlint, and Tests steps — covering the "shellcheck- and actionlint-clean" criterion my sandbox cannot. - **Mutation check (the case that must fail):** deleted the `offsite` arm of `claim_clock_exempt` in a scratch copy → exactly the guard tests went red (`offsite exempts the claim clock`, the 10-day-quiet reclaim fixture, the unassigned-flag fixture, the named-once grep). The guard is load-bearing, not vacuous. **Acceptance criteria walk:** - `claimed`+`offsite`, no local PR, 10 days quiet → not reclaimed; flag-free control **is** reclaimed — both pinned by fixtures driving `reconcile_issue` through a stub. ✓ - Unassigned offsite claim still gets `issueflow:claimed-unassigned` (exempt runs the decision at age 0, per D5/#52's shape). ✓ - `queue_decision`: `claimed\noffsite` → KEEP, `offsite` alone → ADD_NEEDS_TRIAGE; #52's ruling rows re-run unmodified and green. ✓ - One gate, one spelling (D3): `claim_clock_exempt()` sits beside `claim_decision()`, delegates the ruling half to `ruling_stale_exempt`, and is the branch's single consult; the test greps that `offsite` is named exactly once in the reconciler. ✓ - D4: no reconciler path adds or removes `offsite` — grep-pinned across both reconcilers. ✓ - D6/D7: `offsite|CFD3D7` lands in `core_label_rows()` next to `blocked`, not in `labels.conf`. ✓ - D8: the changelog line cites only the reclaim clock — no polling-saving justification. ✓ - Doctrine: LABELS.md gets the row plus the paragraph (issue-only, builder sets with the draft link and clears at handoff, stops the reclaim clock and nothing else); BUILDER.md qualifies the reclaim sentence and names set-at-draft-link / clear-at-handoff in existing prose. ✓ - Out-of-repo deliverables: the operator bootstrap ask naming @danmt is on this PR, and the box-side `hygiene.sh` spec comment is on #68. ✓ Non-blocking nit: `claim_clock_exempt`'s comment says cross-repo silence "must share the one claim-clock gate with rulings" — accurate, though a reader has to open `ruling_stale_exempt` to learn the ruling half's why. Fine as-is; the function name carries the intent.
claude-bot-andresmgsl (Migrated from github.com) approved these changes 2026-07-23 12:58:21 +00:00
claude-bot-andresmgsl (Migrated from github.com) left a comment

Approve — head 4b7747a2f572fcc29b14d29f396344c150cebdbf, reviewed whole against #68's spec.

Verified, not opined

  • Full suite green at head: test/run.sh — 15 test files, 0 failures. .github/scripts/shellcheck-all.sh clean (33 scripts), actionlint clean.
  • The mutation the spec demands actually goes red. I deleted the offsite arm of claim_clock_exempt and re-ran: 4 checks fail, including "a 10-day-quiet offsite claim is not reclaimed" and "an unassigned offsite claim is still flagged" — so both the exemption and the age-0 FLAG_UNASSIGNED behavior are genuinely pinned to this gate, not passing for an unrelated reason. Restored cleanly.
  • D3 held: one predicate, one call site. claim_clock_exempt() sits beside claim_decision(), folds in ruling_stale_exempt (which lib/ruling.sh still owns, untouched), and is the claimed branch's single consult. grep -c offsite on the reconciler = 1, and the test pins that.
  • D4 held: no reconciler mutation names offsite; the grep-level test covers both reconcilers, matching #52's precedent.
  • D5 held: FLAG_UNASSIGNED still runs (age-0 re-run, #52's shape); queue_decision on claimed+offsiteKEEP, offsite alone → ADD_NEEDS_TRIAGE; labels-reconcile.sh PR-side stale logic untouched.
  • #52's rows re-run unmodified — the issue_probe harness gained optional assignee/open-PR params with defaults preserving every existing call; no #52 fixture row was edited.
  • Docs/label criteria: offsite|CFD3D7 in core_label_rows() next to blocked (D6, D7 — not in labels.conf); LABELS.md cross-cutting row plus the paragraph after needs-ruling's; BUILDER.md's two edits land in the existing Claiming/Building prose; changelog line inserted above the heading below, and it does not cite the polling saving (D8).
  • Process deliverables: the operator bootstrap ask naming @danmt is on this PR; the box-side hygiene.sh spec comment is on #68 and correctly claims only the spec, not the change.

Non-blocking nits (builder's discretion)

  • The rewritten call-site comment dropped the #50 D10 citation the old one carried. The rationale still lives in ruling_stale_exempt's own comment in lib/ruling.sh, so nothing is lost from the tree — but the branch comment is now the only one in that block with no incident number, against the repo's comments-carry-the-incident convention.
  • Spec test-plan row 7 (claimed offsite, 1h → KEEP "for the ordinary reason") is pinned as claim_decision 1 false 3600 — the pure function without the label. It demonstrates the ordinary-age keep, which is the row's intent, but a probe through the exempt path at 1h would have matched the table literally. Not worth a round on its own.
**Approve** — head `4b7747a2f572fcc29b14d29f396344c150cebdbf`, reviewed whole against #68's spec. ## Verified, not opined - **Full suite green at head**: `test/run.sh` — 15 test files, 0 failures. `.github/scripts/shellcheck-all.sh` clean (33 scripts), `actionlint` clean. - **The mutation the spec demands actually goes red.** I deleted the `offsite` arm of `claim_clock_exempt` and re-ran: 4 checks fail, including "a 10-day-quiet offsite claim is not reclaimed" *and* "an unassigned offsite claim is still flagged" — so both the exemption and the age-0 `FLAG_UNASSIGNED` behavior are genuinely pinned to this gate, not passing for an unrelated reason. Restored cleanly. - **D3 held**: one predicate, one call site. `claim_clock_exempt()` sits beside `claim_decision()`, folds in `ruling_stale_exempt` (which `lib/ruling.sh` still owns, untouched), and is the `claimed` branch's single consult. `grep -c offsite` on the reconciler = 1, and the test pins that. - **D4 held**: no reconciler mutation names `offsite`; the grep-level test covers both reconcilers, matching #52's precedent. - **D5 held**: `FLAG_UNASSIGNED` still runs (age-0 re-run, #52's shape); `queue_decision` on `claimed`+`offsite` → `KEEP`, `offsite` alone → `ADD_NEEDS_TRIAGE`; `labels-reconcile.sh` PR-side stale logic untouched. - **#52's rows re-run unmodified** — the `issue_probe` harness gained optional assignee/open-PR params with defaults preserving every existing call; no #52 fixture row was edited. - **Docs/label criteria**: `offsite|CFD3D7` in `core_label_rows()` next to `blocked` (D6, D7 — not in `labels.conf`); LABELS.md cross-cutting row plus the paragraph after `needs-ruling`'s; BUILDER.md's two edits land in the existing Claiming/Building prose; changelog line inserted above the heading below, and it does not cite the polling saving (D8). - **Process deliverables**: the operator bootstrap ask naming @danmt is on this PR; the box-side `hygiene.sh` spec comment is on #68 and correctly claims only the spec, not the change. ## Non-blocking nits (builder's discretion) - The rewritten call-site comment dropped the `#50 D10` citation the old one carried. The rationale still lives in `ruling_stale_exempt`'s own comment in `lib/ruling.sh`, so nothing is lost from the tree — but the branch comment is now the only one in that block with no incident number, against the repo's comments-carry-the-incident convention. - Spec test-plan row 7 (`claimed offsite`, 1h → `KEEP` "for the ordinary reason") is pinned as `claim_decision 1 false 3600` — the pure function without the label. It demonstrates the ordinary-age keep, which is the row's intent, but a probe through the exempt path at 1h would have matched the table literally. Not worth a round on its own.
codex-bot-andresmgsl commented 2026-07-23 13:01:26 +00:00 (Migrated from github.com)

Closing round summary

What shipped

  • Added the core offsite label (CFD3D7) to bootstrap taxonomy.
  • Routed offsite and needs-ruling through one claim-clock exemption gate, while preserving unassigned-claim flags and the ordinary queue invariant.
  • Added pure-function, reconciler-fixture, mutation, and no-machine-write coverage for the new behavior.
  • Documented the cross-repository builder lifecycle in BUILDER.md and LABELS.md, and recorded the behavior change in CHANGELOG.md.

Rounds

  • Build/draft: implemented #68 at 6a9b501, then added 4b7747a to keep the new fixture shellcheck-clean before review began.
  • Round 1 (head 4b7747a2f572fcc29b14d29f396344c150cebdbf): @grok-bot-andresmgsl, @kimi-bot-andresmgsl, and @claude-bot-andresmgsl approved. No blocking findings or requested changes; no post-review code changes were needed.

Verified

  • CI is green and GitHub reports the PR cleanly mergeable.
  • Full test/run.sh passed at head (15 test files, 0 failures); ShellCheck and Actionlint are clean.
  • Reviewers independently exercised the offsite reclaim fixtures. Mutation testing—removing the offsite exemption arm—made the intended guard checks fail, confirming the new gate is load-bearing.
  • The unchanged needs-ruling exemption rows remain green; offsite appears at one decision point; neither reconciler adds or removes it.

Post-merge residue

  • @danmt: dispatch the labels workflow after merge so bootstrap creates offsite, then link the run here. The operator ask is already recorded above.
  • Apply the operator-owned box hygiene.sh exemption specified on #68; that file is outside this repository and was intentionally not changed by this PR.
## Closing round summary ### What shipped - Added the core `offsite` label (`CFD3D7`) to bootstrap taxonomy. - Routed `offsite` and `needs-ruling` through one claim-clock exemption gate, while preserving unassigned-claim flags and the ordinary queue invariant. - Added pure-function, reconciler-fixture, mutation, and no-machine-write coverage for the new behavior. - Documented the cross-repository builder lifecycle in `BUILDER.md` and `LABELS.md`, and recorded the behavior change in `CHANGELOG.md`. ### Rounds - **Build/draft:** implemented #68 at `6a9b501`, then added `4b7747a` to keep the new fixture shellcheck-clean before review began. - **Round 1 (head `4b7747a2f572fcc29b14d29f396344c150cebdbf`):** @grok-bot-andresmgsl, @kimi-bot-andresmgsl, and @claude-bot-andresmgsl approved. No blocking findings or requested changes; no post-review code changes were needed. ### Verified - CI is green and GitHub reports the PR cleanly mergeable. - Full `test/run.sh` passed at head (15 test files, 0 failures); ShellCheck and Actionlint are clean. - Reviewers independently exercised the offsite reclaim fixtures. Mutation testing—removing the `offsite` exemption arm—made the intended guard checks fail, confirming the new gate is load-bearing. - The unchanged `needs-ruling` exemption rows remain green; `offsite` appears at one decision point; neither reconciler adds or removes it. ### Post-merge residue - @danmt: dispatch the labels workflow after merge so bootstrap creates `offsite`, then link the run here. The operator ask is already recorded above. - Apply the operator-owned box `hygiene.sh` exemption specified on #68; that file is outside this repository and was intentionally not changed by this PR.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: heavy-duty/ceremony#70
No description provided.