Skip to content

Fix template-echo escalation loop + auto-close linked issues on PR merge#343

Merged
kai-linux merged 1 commit intomainfrom
fix/template-echo-and-issue-autoclose
Apr 24, 2026
Merged

Fix template-echo escalation loop + auto-close linked issues on PR merge#343
kai-linux merged 1 commit intomainfrom
fix/template-echo-and-issue-autoclose

Conversation

@kai-linux
Copy link
Copy Markdown
Owner

Summary

The 2026-04-23 blocked-task escalation on eigendark-website#77 was caused by three cascading bugs. Fixing all three.

Context

Telegram alert:

🛑 Blocked task escalation — eigendark-website#77 — Attempts: 3, Blocked age: 1 day. Blocker codes: `One line. Required when STATUS is partial or blocked...`

The blocker "code" was the literal prompt template text. Root causes:

1. Prose placeholders in the .agent_result.md template

Agents (codex in this case) copied the template verbatim. The old template had "One line. Required when STATUS..." and "- bullet / - bullet" which look plausibly like content.
Fix: replace with `<...>` markers, explicit "never copy the placeholders" rule.

2. Snapshot extractor didn't validate BLOCKER_CODE

`_extract_task_result_snapshot` read the raw log text after `BLOCKER_CODE:` without checking `VALID_BLOCKER_CODES`. That's why the echoed prose flowed into the Telegram and into the error-pattern aggregator.
Fix: new `_sanitize_snapshot_blocker_code` maps unknown values to `invalid_result_contract` so aggregation stays useful.

3. Agent PRs didn't auto-close their linked issue

Both `_create_prs_for_orphan_branches` (pr_monitor) and github_sync wrote "Automated changes for issue #N" as the PR body — not a GitHub closing keyword. Merging the PR left the issue open with `in-progress`, which kept the blocked-task poller firing on work that was long done.
Fix: both paths now lead with `Closes #N`.

Also

Closed eigendark-website#77 manually (the page has been rendering correctly since PR #88 merged yesterday).

Test plan

  • `pytest tests/test_blocker_code_template_echo.py` — 7 new tests (sanitizer enum, placeholder stripping, template-text pin, Closes-keyword pin)
  • Updated `tests/test_gh_project.py::test_create_prs_for_orphan_branches_audits_opened_pr` to match new PR body
  • `pytest tests/` excluding the slow queue suite — 584 passed

The 2026-04-23 blocked-task escalation on eigendark-website#77 cascaded
through three distinct bugs; this change fixes all three.

1. Agents (especially codex) sometimes copied the .agent_result.md
   prompt template verbatim — including the literal instruction text
   "One line. Required when STATUS is partial or blocked..." as the
   BLOCKER_CODE value and "- bullet\n- bullet" as DONE. The prose
   placeholders looked plausibly like content. Replace with
   unambiguous `<...>` markers and add an explicit
   "never copy the <...> placeholders" rule.

2. The escalation snapshot (`_extract_task_result_snapshot` in
   github_dispatcher) read the raw log text after `BLOCKER_CODE:`
   without validating it against `VALID_BLOCKER_CODES`. That is why
   the Telegram escalation displayed the entire echoed instruction
   prose as the blocker code. New `_sanitize_snapshot_blocker_code`
   maps anything unknown to `invalid_result_contract` so error-pattern
   aggregation stays useful.

3. Agent PRs opened via `_create_prs_for_orphan_branches` (pr_monitor)
   and via github_sync used "Automated changes for issue #N" as the PR
   body. That is NOT a GitHub closing keyword, so merging the PR left
   its linked issue open with the `in-progress` label, which kept the
   blocked-task poller firing on long-completed work. Both paths now
   lead with `Closes #N`.

Together these ensure a prompt-echo incident (a) produces a crisp
`invalid_result_contract` signature the operator can act on, and (b)
cannot cascade into a day-long escalation on a PR that already merged.
@kai-linux kai-linux merged commit ac42e7a into main Apr 24, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant