chore: gardener housekeeping 2026-04-09
- Update AGENTS.md watermark to HEAD (31b55ff)
- Update gardener/AGENTS.md watermark to HEAD
- Close #419 (vision: all sprint sub-issues done)
- Close #494 (resolved by #502+#503)
- Close #477 (obsolete: #379 deployed, env.sh guard is correct)
- Add AC + affected files to #471, #498, #499; promote to backlog
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
31b55ff594
commit
39031de2e4
4 changed files with 49 additions and 10 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
<!-- last-reviewed: b79484d5810abfcac48fb5eb0259242cdd250060 -->
|
<!-- last-reviewed: 31b55ff5945157b28a9f265a25d60d7b0151d968 -->
|
||||||
# Disinto — Agent Instructions
|
# Disinto — Agent Instructions
|
||||||
|
|
||||||
## What this repo is
|
## What this repo is
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<!-- last-reviewed: b79484d5810abfcac48fb5eb0259242cdd250060 -->
|
<!-- last-reviewed: 31b55ff5945157b28a9f265a25d60d7b0151d968 -->
|
||||||
# Gardener Agent
|
# Gardener Agent
|
||||||
|
|
||||||
**Role**: Backlog grooming — detect duplicate issues, missing acceptance
|
**Role**: Backlog grooming — detect duplicate issues, missing acceptance
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,47 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"action": "comment",
|
"action": "close",
|
||||||
"issue": 446,
|
"issue": 419,
|
||||||
"body": "Closing as resolved: sub-issues #442, #443, #444, #445 are all closed. The gardener formula now includes an `agents-update` step that checks watermarks and keeps AGENTS.md files current. The last gardener run (commit faaaeb0) confirmed the step is working — all per-directory AGENTS.md files were updated."
|
"reason": "All sprint sub-issues #437\u2013#454 are closed and merged. The blast-radius approval tiers vision goal is complete."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"action": "close",
|
"action": "close",
|
||||||
"issue": 446,
|
"issue": 494,
|
||||||
"reason": "resolved: sub-issues fixed and gardener agents-update step is operational"
|
"reason": "Resolved by merged sub-issues: #502 (load-project.sh derives container repo paths) and #503 (entrypoint.sh workaround removed). Both PRs merged."
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"action": "remove_label",
|
"action": "close",
|
||||||
"issue": 419,
|
"issue": 477,
|
||||||
"label": "blocked"
|
"reason": "Obsolete: issue assumed #379 (while-true loop) was not yet deployed, but #379 was merged and closed on 2026-04-08. The DISINTO_CONTAINER guard in lib/env.sh is now correct \u2014 compose env vars flow through the while-true loop process tree, so .env should NOT be sourced inside containers."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "edit_body",
|
||||||
|
"issue": 498,
|
||||||
|
"body": "## Problem\n\n`has_responses_to_process` is only set to `true` inside the `open_arch_prs >= 3` gate in `architect/architect-run.sh` (line 521). When fewer than 3 architect PRs are open, ACCEPT/REJECT responses on existing PRs are never processed \u2014 the response-processing block at line 688 defaults to `false` and is skipped entirely.\n\nThis means that if a user ACCEPTs or REJECTs a pitch while the open PR count is below 3, the architect agent will never handle the response.\n\n## Fix\n\nMove the ACCEPT/REJECT response scan outside the `open_arch_prs >= 3` gate. Set `has_responses_to_process=true` unconditionally whenever any open architect PRs have ACCEPT/REJECT comments \u2014 not only when the 3-PR cap is hit.\n\n## Affected files\n\n- `architect/architect-run.sh` (lines 521\u2013541: the `>= 3` PR gate and response scan block; line 688: the response-processing block)\n\n## Acceptance criteria\n\n- [ ] ACCEPT/REJECT comments on architect PRs are processed regardless of how many PRs are open\n- [ ] The `>= 3` early-exit guard still works for the \"no responses, too many PRs\" case (skip pitching)\n- [ ] A test with 1 open architect PR that has an ACCEPT comment results in the architect processing it\n- [ ] Existing architect formula step ordering is preserved\n\n---\n*Flagged by AI reviewer in PR #496*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "add_label",
|
||||||
|
"issue": 498,
|
||||||
|
"label": "backlog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "edit_body",
|
||||||
|
"issue": 499,
|
||||||
|
"body": "## Problem\n\nIn `architect/architect-run.sh` line 203, the `has_open_subissues` function compares `.number` (a JSON integer) against `$vid` (a bash string via `--arg`). In jq, `42 != \"42\"` evaluates to `true` (different types are never equal), so the self-exclusion filter never fires. The self-exclusion logic is silently broken \u2014 though low-risk in practice since vision issues don't contain 'Decomposed from #N' in their own bodies.\n\n## Fix\n\nCast the string to a number in jq:\n\n```jq\nselect(.number != ($vid | tonumber))\n```\n\n## Affected files\n\n- `architect/architect-run.sh` (line 203: `select(.number != $vid)` in the `has_open_subissues` function)\n\n## Acceptance criteria\n\n- [ ] `select(.number != ($vid | tonumber))` replaces `select(.number != $vid)` at line 203\n- [ ] ShellCheck passes (the jq expression is in a heredoc/string, not inline shell)\n- [ ] `has_open_subissues` correctly excludes the vision issue itself when checking for open sub-issues\n\n---\n*Flagged by AI reviewer in PR #496*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "add_label",
|
||||||
|
"issue": 499,
|
||||||
|
"label": "backlog"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "edit_body",
|
||||||
|
"issue": 471,
|
||||||
|
"body": "## Bug description\n\nWhen dev-bot picks a backlog issue and launches dev-agent.sh, a second dev-poll instance (dev-qwen) can race ahead and mark the issue as stale/blocked before dev-agent.sh finishes claiming it.\n\n## Reproduction\n\nObserved on issues #443 and #445 (2026-04-08):\n\n**#443 timeline:**\n- `20:39:03` \u2014 dev-bot removes `backlog`, adds `in-progress` (via dev-poll backlog pickup)\n- `20:39:04` \u2014 dev-qwen removes `in-progress`, adds `blocked` with reason `no_assignee_no_open_pr_no_lock`\n- `20:40:11` \u2014 dev-bot pushes commit (dev-agent was actually working the whole time)\n- `20:44:02` \u2014 PR merged, issue closed\n\n**#445 timeline:**\n- `20:54:03` \u2014 dev-bot adds `in-progress`\n- `20:54:06` \u2014 dev-qwen marks `blocked` (3 seconds later)\n- `20:55:13` \u2014 dev-bot pushes commit\n- `21:09:03` \u2014 PR merged, issue closed\n\nIn both cases, the work completed successfully despite being labeled blocked.\n\n## Root cause\n\n`issue_claim()` in `lib/issue-lifecycle.sh` performs three sequential API calls:\n1. PATCH assignee\n2. POST in-progress label\n3. DELETE backlog label\n\nMeanwhile, dev-poll on another agent (dev-qwen) runs its orphan scan, sees the issue labeled `in-progress` but with no assignee set yet (assign PATCH hasn't landed or was read stale), no open PR, and no lock file. It concludes the issue is stale and relabels to `blocked`.\n\nThe race window is ~1-3 seconds between in-progress being set and the assignee being visible to other pollers.\n\n## Affected files\n\n- `lib/issue-lifecycle.sh` \u2014 `issue_claim()` function: reorder API calls to set assignee before adding in-progress label\n- `dev/dev-poll.sh` \u2014 orphan/stale detection: add grace period (e.g. skip issues whose in-progress label was added < 30s ago via label event timestamp)\n\n## Acceptance criteria\n\n- [ ] `issue_claim()` sets assignee before adding `in-progress` label, OR writes lock file before any label changes\n- [ ] Stale detection in dev-poll skips issues where in-progress was added less than 30 seconds ago\n- [ ] No spurious `blocked` labels appear on freshly claimed issues in integration test scenario\n- [ ] Existing `issue_claim()` behavior is preserved for the happy path (single dev-poll instance)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"action": "add_label",
|
||||||
|
"issue": 471,
|
||||||
|
"label": "backlog"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
9
gardener/pending-actions.jsonl
Normal file
9
gardener/pending-actions.jsonl
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
{"action":"close","issue":419,"reason":"All sprint sub-issues #437–#454 are closed and merged. The blast-radius approval tiers vision goal is complete."}
|
||||||
|
{"action":"close","issue":494,"reason":"Resolved by merged sub-issues: #502 (load-project.sh derives container repo paths) and #503 (entrypoint.sh workaround removed). Both PRs merged."}
|
||||||
|
{"action":"close","issue":477,"reason":"Obsolete: issue assumed #379 (while-true loop) was not yet deployed, but #379 was merged and closed on 2026-04-08. The DISINTO_CONTAINER guard in lib/env.sh is now correct — compose env vars flow through the while-true loop process tree, so .env should NOT be sourced inside containers."}
|
||||||
|
{"action":"edit_body","issue":498,"body":"## Problem\n\n`has_responses_to_process` is only set to `true` inside the `open_arch_prs >= 3` gate in `architect/architect-run.sh` (line 521). When fewer than 3 architect PRs are open, ACCEPT/REJECT responses on existing PRs are never processed — the response-processing block at line 688 defaults to `false` and is skipped entirely.\n\nThis means that if a user ACCEPTs or REJECTs a pitch while the open PR count is below 3, the architect agent will never handle the response.\n\n## Fix\n\nMove the ACCEPT/REJECT response scan outside the `open_arch_prs >= 3` gate. Set `has_responses_to_process=true` unconditionally whenever any open architect PRs have ACCEPT/REJECT comments — not only when the 3-PR cap is hit.\n\n## Affected files\n\n- `architect/architect-run.sh` (lines 521–541: the `>= 3` PR gate and response scan block; line 688: the response-processing block)\n\n## Acceptance criteria\n\n- [ ] ACCEPT/REJECT comments on architect PRs are processed regardless of how many PRs are open\n- [ ] The `>= 3` early-exit guard still works for the \"no responses, too many PRs\" case (skip pitching)\n- [ ] A test with 1 open architect PR that has an ACCEPT comment results in the architect processing it\n- [ ] Existing architect formula step ordering is preserved\n\n---\n*Flagged by AI reviewer in PR #496*"}
|
||||||
|
{"action":"add_label","issue":498,"label":"backlog"}
|
||||||
|
{"action":"edit_body","issue":499,"body":"## Problem\n\nIn `architect/architect-run.sh` line 203, the `has_open_subissues` function compares `.number` (a JSON integer) against `$vid` (a bash string via `--arg`). In jq, `42 != \"42\"` evaluates to `true` (different types are never equal), so the self-exclusion filter never fires. The self-exclusion logic is silently broken — though low-risk in practice since vision issues don't contain 'Decomposed from #N' in their own bodies.\n\n## Fix\n\nCast the string to a number in jq:\n\n```jq\nselect(.number != ($vid | tonumber))\n```\n\n## Affected files\n\n- `architect/architect-run.sh` (line 203: `select(.number != $vid)` in the `has_open_subissues` function)\n\n## Acceptance criteria\n\n- [ ] `select(.number != ($vid | tonumber))` replaces `select(.number != $vid)` at line 203\n- [ ] ShellCheck passes (the jq expression is in a heredoc/string, not inline shell)\n- [ ] `has_open_subissues` correctly excludes the vision issue itself when checking for open sub-issues\n\n---\n*Flagged by AI reviewer in PR #496*"}
|
||||||
|
{"action":"add_label","issue":499,"label":"backlog"}
|
||||||
|
{"action":"edit_body","issue":471,"body":"## Bug description\n\nWhen dev-bot picks a backlog issue and launches dev-agent.sh, a second dev-poll instance (dev-qwen) can race ahead and mark the issue as stale/blocked before dev-agent.sh finishes claiming it.\n\n## Reproduction\n\nObserved on issues #443 and #445 (2026-04-08):\n\n**#443 timeline:**\n- `20:39:03` — dev-bot removes `backlog`, adds `in-progress` (via dev-poll backlog pickup)\n- `20:39:04` — dev-qwen removes `in-progress`, adds `blocked` with reason `no_assignee_no_open_pr_no_lock`\n- `20:40:11` — dev-bot pushes commit (dev-agent was actually working the whole time)\n- `20:44:02` — PR merged, issue closed\n\n**#445 timeline:**\n- `20:54:03` — dev-bot adds `in-progress`\n- `20:54:06` — dev-qwen marks `blocked` (3 seconds later)\n- `20:55:13` — dev-bot pushes commit\n- `21:09:03` — PR merged, issue closed\n\nIn both cases, the work completed successfully despite being labeled blocked.\n\n## Root cause\n\n`issue_claim()` in `lib/issue-lifecycle.sh` performs three sequential API calls:\n1. PATCH assignee\n2. POST in-progress label\n3. DELETE backlog label\n\nMeanwhile, dev-poll on another agent (dev-qwen) runs its orphan scan, sees the issue labeled `in-progress` but with no assignee set yet (assign PATCH hasn't landed or was read stale), no open PR, and no lock file. It concludes the issue is stale and relabels to `blocked`.\n\nThe race window is ~1-3 seconds between in-progress being set and the assignee being visible to other pollers.\n\n## Affected files\n\n- `lib/issue-lifecycle.sh` — `issue_claim()` function: reorder API calls to set assignee before adding in-progress label\n- `dev/dev-poll.sh` — orphan/stale detection: add grace period (e.g. skip issues whose in-progress label was added < 30s ago via label event timestamp)\n\n## Acceptance criteria\n\n- [ ] `issue_claim()` sets assignee before adding `in-progress` label, OR writes lock file before any label changes\n- [ ] Stale detection in dev-poll skips issues where in-progress was added less than 30 seconds ago\n- [ ] No spurious `blocked` labels appear on freshly claimed issues in integration test scenario\n- [ ] Existing `issue_claim()` behavior is preserved for the happy path (single dev-poll instance)"}
|
||||||
|
{"action":"add_label","issue":471,"label":"backlog"}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue