You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[finding] The half-state patrol's anchor is not exempt from the stale bot — it survives only while the patrol is alive, so a dead patrol has its own gravestone auto-closed #15002
Observation-level, unassigned, filed from the #14881 measurement flight (the hotcrm patrol install). ⛔ Not the subject of that card. Fleet-wide, and it is this repo's own anchor #9857 too — not a hotcrm-only hazard.
The patrol anchor #9857 carries exactly one label, tracking, and no assignee. tracking is not in that exempt list. The anchor is therefore protected by nothing but its own updated_at, which the patrol refreshes four times a day when it PATCHes the body.
That protection is exactly co-extensive with the patrol being alive — which inverts it. half-state-patrol.yml's header states the property the anchor exists to carry:
The Swept timestamp in that body is the patrol's heartbeat and is deliberately refreshed even when the findings are unchanged: a timestamp that stops advancing is how a reader learns the standing caller died.
So: patrol dies, the heartbeat stops, updated_at freezes — and 60 days later the stale bot labels the gravestone stale, then closes it 14 days after that. The one artifact whose job is to make the death visible is removed because of the death. And remove-stale-when-updated: true means a patrol that recovers silently clears the stale label, so the near-miss leaves no trace either.
The sweeper keeps writing into a closed issue afterwards — issues.update succeeds on a closed issue — which is the "runs, finds, and tells nobody" shape the same header calls out by name.
Severity, stated honestly
It needs the patrol dead ~74 days first, and a patrol that cannot run fails its job red on every scheduled fire, so this is a second-order failure behind a loud first-order one, not a live defect today. What makes it worth a row anyway is the direction: it degrades the alarm precisely in the scenario the alarm is for, and the repair is one word in a list.
It is tighter in the repos being onboarded
hotcrm (clone at 18444c8, .github/workflows/stale.yml) runs the same action with days-before-issue-close: 7 and exempt-issue-labels: 'pinned,security,bug,enhancement' — also no tracking. Whatever is decided here should be decided for the install recipe #14881 hands the repo:hotcrm seat, or every adopter inherits it.
What would close it
Add tracking to exempt-issue-labels in stale.yml (and mirror it in each adopter's copy), or give the anchor a label already in the list. ⛔ Not fixed in #14881's PR: stale.yml is outside that card's declared file surface, and this deserves its own judgement rather than a rider.
Triage — skills seat (session session_019RfFHiRCSs3JXLK4cwcfox, os-steve), 2026-09-03T17:12Z. Graded priority:p3 (the window is 60 + 14 days; nothing is at risk this month), finding cleared, domain:skills kept (the patrol and its anchor are this lane's tooling), tooling, state pm:queue, type Task. Applied and read back after this comment.
Scope as queued (XS, .github/workflows/stale.yml only): add the anchor's label to exempt-issue-labels so the gravestone outlives a dead patrol, with the reason recorded in the file. The hotcrm copy is the seam card's business, not this card's. ⛔ No change to the patrol workflow or the sweeper.
Claim: PM loop round 2
Session: session_019RfFHiRCSs3JXLK4cwcfox
Branch: claude/issue-15002-stale-exempt-anchor
Worktree: objectstack-issue-15002
Domain: domain:skills
File surface: .github/workflows/stale.yml (the exempt-issue-labels value at :48 at origin/main33681eae, plus one comment line above it) (stop on breach; explain in the report). ⛔ Not exempt-pr-labels, not the patrol workflow, not the anchor issue.
Container & model: XS mechanical (one list value + one comment line in a workflow), mode:subagent, model: sonnet (tier: node scripts/pm/dispatch-gates.mjs --tier .github/workflows/stale.yml at origin/main33681eae, 17:17Z: "no path-derived mandate … floor sonnet · default opus · ceiling fable"; PM's call: sonnet floor, the review runs at the contract tier in-seat)
Clause-②: no
Serial constraints cleared: .github/workflows/stale.yml is free on the seat post's hot-file queue; no in-flight claim names it; no open PR touches it (last merge 736980c9 08-31). Not a governed surface (check-governed-merges --test: 0 of 1 hit), no .md ⇒ pure-code landing: in-seat review → ready → auto-merge.
Decision re-read (17:17Z): no maintainer ruling; triaged by this seat 17:12Z (comment 5529324386) with the scope "add the anchor's label to exempt-issue-labels so the gravestone outlives a dead patrol, with the reason recorded in the file". Of the finding's two remedies, exempting tracking is the one that keeps the anchor's single-label shape the sweeper and the adopt recipe both depend on; giving the anchor pinned would be a second label with a second meaning. The hotcrm copy's stale workflow is the seam card's business (#15009), not this card's.
{
"issue": 15002,
"status": "done",
"branch": "claude/issue-15002-stale-exempt-anchor",
"pr": "https://github.com/objectstack-ai/objectstack/pull/15016",
"premise_still_valid": true,
"summary": "Added `tracking` to `exempt-issue-labels` in `.github/workflows/stale.yml` (the value at line 48 on origin/main 33681eae) with a one-line comment above it explaining why, leaving `exempt-pr-labels` and every other key/file untouched. Verified against origin/main that the patrol's anchor issue #9857 is designed to carry exactly this one label (half-state-patrol.yml lines 166-167: 'The anchor deliberately carries tracking and NO domain:* label') and that the pinned actions/stale@v11.0.0 action.yml documents exempt-issue-labels as a comma-separated list. Opened as draft PR #15016 with skip-changeset applied via an additive REST POST and read back (present alongside the pre-existing size/xs label, nothing stripped).",
"tests": "python3 -c 'import yaml,sys; yaml.safe_load(open(\".github/workflows/stale.yml\"))' parses clean after the edit. node scripts/pm/check-governed-merges.mjs --test .github/workflows/stale.yml -> NOT governed (0 of 1 path hits the register). Own control-byte self-scan (grep -naP '[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]') clean on the edited file and on the PR body draft. Ran the pinned 26-command gate list at head 06e82410e4141b425b4cc3cdb5893de0fc2eed6c; node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands .github/workflows/stale.yml re-derived the identical 26 commands at that head (no additions). First attempt (before I ran pnpm install in the fresh worktree, my own setup miss) surfaced 8 gates' own PREREQUISITE NOT MET declarations (exit 3, e.g. check-aggregator-roster.mjs, check-required-contexts.mjs, check-shard-attestation.mjs, check-step-collectors.mjs, check-pnpm-acquisition, check-required-contexts, check-shard-attestation, check-stall-guard-budget, check-stall-guard-headroom, check-workflow-status-functions) plus one raw ERR_MODULE_NOT_FOUND on check-comment-mask-corpus.mjs (exit 1, missing @typescript-eslint/parser) -- none were red gates, all NOT MEASURED per their own text, not scored. After pnpm install, re-ran all 26 with exit captured before any pipe: all 26/26 exited 0, each gate's own printed verdict line quoted in the PR body's gate table (e.g. 'check-nul-bytes: OK (scanned 8168 text file(s) ... no raw ASCII control bytes)', 'check-shard-attestation: 2 aggregate gate(s) count 3 declared leg(s) across 3 attesting job(s)', 'dispatch-gates self-test: 1288 cases pass'). No package build/typecheck applies -- this diff touches only a workflow YAML file, no TS/JS source and no packages/spec artifact.",
"mcp_calls": "2 (create_pull_request, add_issue_comment for this report -- the skip-changeset label add and both read-backs used direct REST calls with GITHUB_TOKEN, not MCP)",
"open_questions": [],
"out_of_scope_findings": []
}
ACCEPT — skills seat (session session_019RfFHiRCSs3JXLK4cwcfox), reviewer of record, 2026-09-03T17:41Z, verified against GitHub and the PR head over git, not against the report.
PR #15016 @ 06e82410 — draft, base main, first line Fixes #15002, one file .github/workflows/stale.yml+2/-1, skip-changeset (nothing published), no other closing keyword, no model name in the body, one footer. check-governed-merges --test: not governed, no .md ⇒ pure-config landing by the seat.
Content against the triage scope (comment 5529324386): exempt-issue-labels gains tracking (read back from the parsed workflow at the head: pinned,security,roadmap,tracking), exempt-pr-labels unchanged, one comment line above it stating the reason in the file's register; the dev confirmed the anchor's single-label design against the patrol workflow's own header and the pinned action's documented input format. The hotcrm copy is untouched, as scoped (seam card #15009).
Deviations: none. Report mcp_calls: 2 — within contract.
CI at 17:39Z on 06e82410: 28 check runs, 12 success + 12 skipped, four in_progress (Lint & Repo Gates, three Type Check legs); nothing red.
Landing: the seat flips ready and arms auto-merge once every check is green (next read at the 17:58Z patrol or the next boundary before it); card closes on merge.
Activity
claude commentedon Sep 3, 2026
Triage — skills seat (session
session_019RfFHiRCSs3JXLK4cwcfox, os-steve), 2026-09-03T17:12Z. Gradedpriority:p3(the window is 60 + 14 days; nothing is at risk this month),findingcleared,domain:skillskept (the patrol and its anchor are this lane's tooling),tooling, statepm:queue, type Task. Applied and read back after this comment.Scope as queued (XS,
.github/workflows/stale.ymlonly): add the anchor's label toexempt-issue-labelsso the gravestone outlives a dead patrol, with the reason recorded in the file. The hotcrm copy is the seam card's business, not this card's. ⛔ No change to the patrol workflow or the sweeper.Generated by Claude Code
os-steve commentedon Sep 3, 2026
Claim: PM loop round 2
Session:
session_019RfFHiRCSs3JXLK4cwcfoxBranch:
claude/issue-15002-stale-exempt-anchorWorktree:
objectstack-issue-15002Domain:
domain:skillsFile surface:
.github/workflows/stale.yml(theexempt-issue-labelsvalue at:48atorigin/main33681eae, plus one comment line above it) (stop on breach; explain in the report). ⛔ Notexempt-pr-labels, not the patrol workflow, not the anchor issue.Container & model: XS mechanical (one list value + one comment line in a workflow),
mode:subagent,model: sonnet(tier:node scripts/pm/dispatch-gates.mjs --tier .github/workflows/stale.ymlatorigin/main33681eae, 17:17Z: "no path-derived mandate … floor sonnet · default opus · ceiling fable"; PM's call: sonnet floor, the review runs at the contract tier in-seat)Clause-②: no
Serial constraints cleared:
.github/workflows/stale.ymlis free on the seat post's hot-file queue; no in-flight claim names it; no open PR touches it (last merge736980c908-31). Not a governed surface (check-governed-merges --test: 0 of 1 hit), no.md⇒ pure-code landing: in-seat review → ready → auto-merge.Decision re-read (17:17Z): no maintainer ruling; triaged by this seat 17:12Z (comment 5529324386) with the scope "add the anchor's label to
exempt-issue-labelsso the gravestone outlives a dead patrol, with the reason recorded in the file". Of the finding's two remedies, exemptingtrackingis the one that keeps the anchor's single-label shape the sweeper and the adopt recipe both depend on; giving the anchorpinnedwould be a second label with a second meaning. The hotcrm copy's stale workflow is the seam card's business (#15009), not this card's.Generated by Claude Code
os-steve commentedon Sep 3, 2026
os-dev-report
{ "issue": 15002, "status": "done", "branch": "claude/issue-15002-stale-exempt-anchor", "pr": "https://github.com/objectstack-ai/objectstack/pull/15016", "premise_still_valid": true, "summary": "Added `tracking` to `exempt-issue-labels` in `.github/workflows/stale.yml` (the value at line 48 on origin/main 33681eae) with a one-line comment above it explaining why, leaving `exempt-pr-labels` and every other key/file untouched. Verified against origin/main that the patrol's anchor issue #9857 is designed to carry exactly this one label (half-state-patrol.yml lines 166-167: 'The anchor deliberately carries tracking and NO domain:* label') and that the pinned actions/stale@v11.0.0 action.yml documents exempt-issue-labels as a comma-separated list. Opened as draft PR #15016 with skip-changeset applied via an additive REST POST and read back (present alongside the pre-existing size/xs label, nothing stripped).", "tests": "python3 -c 'import yaml,sys; yaml.safe_load(open(\".github/workflows/stale.yml\"))' parses clean after the edit. node scripts/pm/check-governed-merges.mjs --test .github/workflows/stale.yml -> NOT governed (0 of 1 path hits the register). Own control-byte self-scan (grep -naP '[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]') clean on the edited file and on the PR body draft. Ran the pinned 26-command gate list at head 06e82410e4141b425b4cc3cdb5893de0fc2eed6c; node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands .github/workflows/stale.yml re-derived the identical 26 commands at that head (no additions). First attempt (before I ran pnpm install in the fresh worktree, my own setup miss) surfaced 8 gates' own PREREQUISITE NOT MET declarations (exit 3, e.g. check-aggregator-roster.mjs, check-required-contexts.mjs, check-shard-attestation.mjs, check-step-collectors.mjs, check-pnpm-acquisition, check-required-contexts, check-shard-attestation, check-stall-guard-budget, check-stall-guard-headroom, check-workflow-status-functions) plus one raw ERR_MODULE_NOT_FOUND on check-comment-mask-corpus.mjs (exit 1, missing @typescript-eslint/parser) -- none were red gates, all NOT MEASURED per their own text, not scored. After pnpm install, re-ran all 26 with exit captured before any pipe: all 26/26 exited 0, each gate's own printed verdict line quoted in the PR body's gate table (e.g. 'check-nul-bytes: OK (scanned 8168 text file(s) ... no raw ASCII control bytes)', 'check-shard-attestation: 2 aggregate gate(s) count 3 declared leg(s) across 3 attesting job(s)', 'dispatch-gates self-test: 1288 cases pass'). No package build/typecheck applies -- this diff touches only a workflow YAML file, no TS/JS source and no packages/spec artifact.", "mcp_calls": "2 (create_pull_request, add_issue_comment for this report -- the skip-changeset label add and both read-backs used direct REST calls with GITHUB_TOKEN, not MCP)", "open_questions": [], "out_of_scope_findings": [] }Generated by Claude Code
Generated by Claude Code
os-steve commentedon Sep 3, 2026
ACCEPT — skills seat (session
session_019RfFHiRCSs3JXLK4cwcfox), reviewer of record, 2026-09-03T17:41Z, verified against GitHub and the PR head over git, not against the report.PR #15016 @
06e82410— draft, basemain, first lineFixes #15002, one file.github/workflows/stale.yml+2/-1,skip-changeset(nothing published), no other closing keyword, no model name in the body, one footer.check-governed-merges --test: not governed, no.md⇒ pure-config landing by the seat.Content against the triage scope (comment 5529324386):
exempt-issue-labelsgainstracking(read back from the parsed workflow at the head:pinned,security,roadmap,tracking),exempt-pr-labelsunchanged, one comment line above it stating the reason in the file's register; the dev confirmed the anchor's single-label design against the patrol workflow's own header and the pinned action's documented input format. The hotcrm copy is untouched, as scoped (seam card #15009).Deviations: none. Report
mcp_calls: 2 — within contract.CI at 17:39Z on
06e82410: 28 check runs, 12success+ 12skipped, fourin_progress(Lint & Repo Gates, threeType Checklegs); nothing red.Landing: the seat flips ready and arms auto-merge once every check is green (next read at the 17:58Z patrol or the next boundary before it); card closes on merge.
Generated by Claude Code