Parent Epic
#11829 — Sub 2 of 5.
Premise
Current heartbeat label is opaque: "[heartbeat] idle-out nudge". Per Epic AC3: replace with content-rich prompt that gives the receiving agent immediate-actionable next-lifecycle directives — milestone-agnostic (no hardcoded "Project 12" / "v13"; resolve current-release Project from substrate).
Prescription
Replace opaque heartbeat label with:
[heartbeat] idle-out — if not on active lifecycle event, query unassigned current-release Project backlog: gh issue list --search 'project:<owner>/<current> no:assignee'. Snapshot: <N> open PRs total; <M> unassigned in current-release Project. Halt only at zero-candidate state.
Where:
<current> resolved dynamically from substrate (config / identityRoots / Project metadata) — NOT hardcoded
<N> / <M> fetched via dispatcher-side query at wake-emit time
Resolver function for current-release Project must be deployment-portable (Neo team profile / repo-fork / cloud-tenant / npx neo-app workspace).
Acceptance Criteria
Avoided Traps (per Epic)
- ❌ Hardcoding "v13" / "Project 12" — operator-explicit: "we will pass that milestone"
- ❌ Snapshot counts at config-time vs wake-emit-time (stale data)
Depends on
Sub 1 #11905 (Layer 2 heartbeat target resolver) — wake-emit dispatch infrastructure
Related
- Epic #11829 (parent)
- AC3 (Epic)
ai/scripts/idleOutNudge.mjs (per-identity sender — content payload destination)
Authored by: Claude Opus 4.7 (Claude Code)
Contract Ledger
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
Heartbeat A2A subject |
#11829 AC3 + this ticket |
Replace the opaque idle-out nudge subject with a concise lifecycle-specific heartbeat subject that identifies idle-out handling without hardcoding a release board |
If resolver data is unavailable, keep the subject generic and put failure detail in the body |
PR body + updated tests |
Unit coverage for emitted subject and no stale hardcoded Project 12/v13 wording |
Heartbeat A2A body / prompt template |
#11829 AC3 + post-review-pickup halt discipline |
Include immediate next-lifecycle directives: query current-release unassigned backlog, include wake-time counts, and halt only at zero-candidate state |
If GitHub/project lookup fails, body must state lookup failure and avoid claiming zero candidates |
PR body + wake substrate docs if user-facing wording changes |
Snapshot test for body content under success and failure cases |
| Current-release Project resolver |
Epic avoided trap: no hardcoded Project 12 / v13 |
Resolve current-release Project from deployment config or discoverable repository/project metadata at wake-emit time |
Fail closed with explicit missing-current-release-project reason; do not silently fall back to Project 12 |
JSDoc on resolver/source-of-truth |
Tests for Neo team profile, repo fork, cloud tenant, and npx workspace shapes |
| Open PR count query |
This ticket AC3 |
Count open PRs at wake-emit time from GitHub repository state |
Report unknown when GitHub API is unavailable; do not reuse cached config-time values |
PR evidence |
Test covers successful count and API failure payload |
| Unassigned current-release issue count query |
This ticket AC3 + heartbeat no-idle contract |
Count open no-assignee issues in the resolved current-release Project at wake-emit time |
Report unknown on ProjectV2/API failure and keep the agent in discovery mode, not halt mode |
PR evidence |
Test covers nonzero, zero, and failure states |
| GitHub API / ProjectV2 failure semantics |
V-B-A + no false zero-candidate states |
Surface failure as degraded telemetry inside the heartbeat body; never convert lookup failure into a zero-candidate halt state |
If authenticated project access is absent, use repository issue search only with explicit reduced-confidence wording |
JSDoc / PR body |
Failure tests assert no false zero-candidate message |
| Test matrix |
This ticket AC5 |
Cover Neo team profile, fork, cloud tenant, and npx workspace without hardcoded owner/project constants |
If a shape lacks project metadata, assert the explicit failure body path |
Test file comments only where needed |
Unit/integration tests document fixture inputs and emitted heartbeat payloads |
Parent Epic
#11829 — Sub 2 of 5.
Premise
Current heartbeat label is opaque:
"[heartbeat] idle-out nudge". Per Epic AC3: replace with content-rich prompt that gives the receiving agent immediate-actionable next-lifecycle directives — milestone-agnostic (no hardcoded "Project 12" / "v13"; resolve current-release Project from substrate).Prescription
Replace opaque heartbeat label with:
Where:
<current>resolved dynamically from substrate (config / identityRoots / Project metadata) — NOT hardcoded<N>/<M>fetched via dispatcher-side query at wake-emit timeResolver function for current-release Project must be deployment-portable (Neo team profile / repo-fork / cloud-tenant /
npx neo-appworkspace).Acceptance Criteria
<N>open PRs total;<M>unassigned in current-release Project) fetched at wake-emit timeAvoided Traps (per Epic)
Depends on
Sub 1 #11905 (Layer 2 heartbeat target resolver) — wake-emit dispatch infrastructure
Related
ai/scripts/idleOutNudge.mjs(per-identity sender — content payload destination)Authored by: Claude Opus 4.7 (Claude Code)
Contract Ledger
subjectbody/ prompt templatepost-review-pickuphalt discipline