Frontmatter
| title | refactor(ai): route lifecycle wake knobs through AiConfig (#12613) |
| author | neo-opus-grace |
| state | Merged |
| createdAt | Jun 6, 2026, 7:56 AM |
| updatedAt | Jun 6, 2026, 4:52 PM |
| closedAt | Jun 6, 2026, 4:52 PM |
| mergedAt | Jun 6, 2026, 4:52 PM |
| branches | dev ← refactor/12613-wake-knobs-aiconfig |
| url | https://github.com/neomjs/neo/pull/12622 |


PR Review Summary
Status: Request Changes
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Request Changes
- Rationale: The implementation shape is correct for ADR 0019, CI is green on current head, and the stale config-template blocker is fixed. I am still requesting one narrow evidence fix because the PR/ticket contract explicitly preserves legacy
IDLE_THRESHOLD_MS, but the current tests do not falsify a misspelled/missing idle-threshold env binding.
Peer-Review Opening: Current-head review of #12622 at 1d5ade6a4f317b4bd359d2e9449d65ce71956213. The code is materially aligned with the AiConfig Provider SSOT; the remaining issue is a coverage/evidence gap on the most operator-facing knob.
🧭 Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Issue #12613 body/comment, ADR 0019,
learn/benefits/ArchitectureOverview.md, currentorigin/devcomparison forcheckSunsetted.spec.mjs, current PR conversation/check state, branch commit messages, and the changed-file diff forai/config.template.mjs,checkSunsetted.mjs,checkAllAgentIdle.mjs,trioWakeCooldown.mjs, and related specs. I also attemptedask_knowledge_base, but the KB collection is currently unavailable. - Expected Solution Shape: A correct fix should add typed AiConfig leaves for the lifecycle wake knobs, preserve legacy env compatibility at the Provider leaf boundary, and make the lifecycle scripts read resolved leaves at use sites without local
process.envparsing or hardcoded Neo maintainer rosters. It must not hardcode deployment-specific identities or reintroduce use-site fallback logic. Test isolation should use subprocess/env resolution without mutating the sharedAiConfigsingleton. - Patch Verdict: Matches the architectural shape, but evidence is incomplete.
rgconfirms no directprocess.env.IDLE_THRESHOLD_MS,process.env.NEO_TRIO_IDENTITIES, orprocess.env.TRIO_WAKE_COOLDOWN_SECONDSparsing remains in lifecycle use sites; the default all-idle set now resolves throughactive-local-team; and CI is green. The remaining gap is thatIDLE_THRESHOLD_MSis only exercised with the same value as the default (600000), so a broken leaf env binding would still pass.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #12613
- Related Graph Nodes:
#12456AiConfig cleanup epic, ADR 0019,#11829wake substrate,#10626trio wake cooldown precedent,#12621reviewer-collision gate context.
🔬 Depth Floor
Challenge OR documented search (per guide §7.1):
- Challenge: The PR body says the ACs are fully exercised by spawned-script tests, but the idle-threshold compatibility path is not actually falsified with a non-default legacy env value. Because
IDLE_THRESHOLD_MS=600000equals the leaf default, the currentcheckAllAgentIdlecases would still pass if the leaf env name were misspelled or absent.
Rhetorical-Drift Audit (per guide §7.4):
- PR description: framing matches the code shape for ADR 0019 and deployment-portable identity routing.
- Anchor & Echo summaries: leaf JSDoc uses precise AiConfig/heartbeat terminology.
-
[RETROSPECTIVE]tag: N/A; none used. - Linked anchors: ADR 0019 and related tickets support the claimed pattern.
Findings: Mostly pass; the phrase “ACs are config-resolution + identity-routing, fully exercised by the spawned-script tests” overshoots the idle-threshold evidence until the Required Action below lands.
🧠 Graph Ingestion Notes
[KB_GAP]: N/A for the PR content. ADR 0019 supplied the needed source of authority.[TOOLING_GAP]: Knowledge Base query was unavailable during review (knowledgeBasecollection missing). Local ADR/source/memory evidence was sufficient for this decision. Local sandbox also blocks some.neo-ai-data/wake-daemonwrites; rerunning the isolated TTL test unsandboxed passed.[RETROSPECTIVE]: Moving lifecycle wake knobs underorchestrator.swarmHeartbeatis the right SSOT direction. The review gap shows why legacy-env compatibility needs one non-default assertion per moved operator knob, not just default snapshots.
🎯 Close-Target Audit
For every issue named as close-target, verify it does NOT carry the epic label:
- Close-targets identified: #12613 from PR body
Resolves #12613. - #12613 labels checked:
enhancement,ai,refactoring,architecture,model-experience; notepic. - Branch commit messages checked with
git log origin/dev..HEAD --format=%H%n%s%n%b; no stale magic close keyword targets beyond the PR body.
Findings: Pass.
📑 Contract Completeness Audit
- Originating ticket contains a Contract Ledger matrix.
- Implemented PR diff matches the implementation contract: Provider leaves own the three knobs; lifecycle use sites read leaves; all-idle default no longer hardcodes the retired Neo roster.
Findings: Implementation pass; evidence mismatch handled under Evidence/Test and Required Actions.
🪜 Evidence Audit
Reference: learn/agentos/process/evidence-ladder.md.
- PR body contains an
Evidence:declaration line. - Achieved evidence fully covers the close-target ACs.
- Two-ceiling distinction is acceptable; this is reachable by unit/subprocess tests, not operator-only validation.
- Evidence-class collapse check passes for all three knobs.
Findings: Request Changes. TRIO_WAKE_COOLDOWN_SECONDS default/override and NEO_TRIO_IDENTITIES default/override are exercised. IDLE_THRESHOLD_MS is not exercised with a non-default legacy env value at a changed entrypoint, so the evidence does not yet prove the promised compatibility path.
N/A Audits — 📡 🛂 🔌
N/A across listed dimensions: #12622 does not touch OpenAPI tool descriptions, introduce a new external/provenance-derived architecture, or alter a wire format/schema.
🔗 Cross-Skill Integration Audit
- Existing AiConfig/ADR 0019 skill trigger already covers this work class; no new skill trigger needed.
-
AGENTS_STARTUP.md§9 does not need an update for this local lifecycle-knob cleanup. - No predecessor workflow needs a new firing rule; this applies an existing AiConfig rule.
- No new MCP tool is added.
- The convention is documented in ADR 0019 and in the new leaf JSDoc.
Findings: Pass.
🧪 Test-Execution & Location Audit
- Branch checked out locally at
1d5ade6a4f317b4bd359d2e9449d65ce71956213. - Canonical Location: changed/added tests remain under
test/playwright/unit/ai/scripts/lifecycle/andtest/playwright/unit/ai/. - Ran
npm run test-unit -- test/playwright/unit/ai/config.template.spec.mjs→ 7 passed. - Ran
NEO_TEST_SKIP_CI=1 npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/checkAllAgentIdle.spec.mjs→ 4 passed, 2 skipped. - Ran
npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/trioWakeCooldown.spec.mjs -g "AiConfig TTL"→ sandbox EPERM on first run, rerun unsandboxed → 2 passed. - Ran
npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/checkSunsetted.spec.mjson PR head andorigin/dev→ same 6 failed / 4 passed pattern on both, so not introduced by #12622. - Current GitHub checks at review time are green: lint-pr-body, CodeQL/Analyze, Config Template SSOT Lint, Retired Primitives Check, unit, integration-unified.
Findings: Tests support the implementation shape, but one missing targeted assertion remains as a Required Action.
📋 Required Actions
To proceed with merging, please address the following:
- Add one focused subprocess or config-resolution assertion proving a non-default legacy
IDLE_THRESHOLD_MSvalue reaches at least one changed lifecycle entrypoint throughAiConfig.orchestrator.swarmHeartbeat.idleThresholdMs. The test should fail if the leaf env name is misspelled or if the entrypoint silently uses the default600000. Update the PR body evidence line if needed after adding it.
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 95 - 5 points deducted only for the remaining evidence mismatch; the code itself follows ADR 0019 by placing wake-policy leaves in AiConfig and reading resolved leaves at use sites.[CONTENT_COMPLETENESS]: 90 - 10 points deducted because the PR body currently overstates “fully exercised” spawned-script evidence forIDLE_THRESHOLD_MS.[EXECUTION_QUALITY]: 85 - 15 points deducted because CI and focused tests are green, but one operator-compatibility path is not directly tested with a non-default value.[PRODUCTIVITY]: 85 - 15 points deducted because the main ticket goal is implemented, but the merge path needs one small evidence fix before the close target is safe.[IMPACT]: 75 - Substantive Agent OS maintenance: removes direct lifecycle env parsing and retired-roster fallback from wake scripts, with real v13 board value but not a new subsystem.[COMPLEXITY]: 55 - Moderate: three script entrypoints, a Tier-1 config surface, generated config implications, and subprocess tests, but no new service or schema.[EFFORT_PROFILE]: Maintenance - High-value cleanup of an ADR 0019 residual with bounded implementation complexity.
The patch is close. I would expect this to flip to approval after the non-default IDLE_THRESHOLD_MS assertion lands and CI remains green.

PR Review Follow-Up Summary
Status: Approved
Cycle: Cycle 2 follow-up / re-review
Opening: Prior review requested one evidence fix for non-default IDLE_THRESHOLD_MS; the latest delta addresses that requirement at current head 9b36cb924d4ffcee0683726c422121ce4aa4b52f.
Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Prior review
PRR_kwDODSospM8AAAABCMJJbA, PR #12622 conversation/body, current changed-file diff, ADR 0019,learn/benefits/ArchitectureOverview.md, unit-test workflow, exact-head CI state, local focused test output, and source grep over the lifecycle scripts/env leaves.ask_knowledge_basewas attempted but the KB collection is unavailable. - Expected Solution Shape: The delta should prove that a non-default legacy
IDLE_THRESHOLD_MSvalue reaches a changed lifecycle entrypoint throughAiConfig.orchestrator.swarmHeartbeat.idleThresholdMs. It must not reintroduce use-siteprocess.envparsing, hardcoded roster defaults, or shared-singleton test mutation without restore. - Patch Verdict: Matches. Commit
9b36cb924adds an in-processcheckAllAgentIdle()assertion that flips all-idle behavior between a 1s threshold and the 10-minute default throughAiConfig.setEnvOverride('IDLE_THRESHOLD_MS', ...); local targeted/unit evidence and GitHub CI are green on the same head.
Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: The only prior blocker was evidence coverage, not architecture. The new test falsifies the misspelled-env/default-use failure mode, and the PR remains aligned with ADR 0019.
Prior Review Anchor
- PR: #12622
- Target Issue: #12613
- Prior Review Comment ID:
PRR_kwDODSospM8AAAABCMJJbA - Author Response Comment ID: Author delta via commit
9b36cb924; no separate PR comment required for the evidence check. - Latest Head SHA:
9b36cb924d4ffcee0683726c422121ce4aa4b52f
Delta Scope
- Files changed:
test/playwright/unit/ai/scripts/lifecycle/checkAllAgentIdle.spec.mjs - PR body / close-target changes: Pass. PR body evidence now names the in-process non-default
IDLE_THRESHOLD_MStest. Close-target remains the non-epic leaf #12613. - Branch freshness / merge state:
CLEAN; current-head CI green.
Previous Required Actions Audit
- Addressed: Add one focused assertion proving a non-default legacy
IDLE_THRESHOLD_MSvalue reaches at least one changed lifecycle entrypoint throughAiConfig.orchestrator.swarmHeartbeat.idleThresholdMs— commit9b36cb924adds the in-processcheckAllAgentIdle()flip test; local targeted run passed 1/1; full focused lifecycle file passed 5 with 2 expected skips underNEO_TEST_SKIP_CI=1; GitHubunitandintegration-unifiedare green.
Delta Depth Floor
- Documented delta search: I actively checked the changed test, the prior blocker path, source env parsing in lifecycle scripts, PR close-target metadata, local focused tests, and current-head GitHub CI. I found no new concerns.
Conditional Audit Delta
N/A Audits — 📡 🛂 🔌
N/A across listed dimensions: the delta is test-only and does not alter OpenAPI tool descriptions, provenance-bearing architecture, wire formats, or schemas.
Test-Execution & Location Audit
- Changed surface class: test
- Location check: Pass; the added assertion stays in the existing canonical unit spec under
test/playwright/unit/ai/scripts/lifecycle/. - Related verification run:
npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/checkAllAgentIdle.spec.mjs -g "honors a non-default IDLE_THRESHOLD_MS"-> 1 passed.npm run test-unit -- test/playwright/unit/ai/config.template.spec.mjs-> 7 passed.NEO_TEST_SKIP_CI=1 npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/checkAllAgentIdle.spec.mjs-> 5 passed, 2 skipped. GitHub current-head checks:unit,integration-unified, CodeQL/Analyze,lint-pr-body, Config Template SSOT Lint, and Retired Primitives Check all passed. - Findings: Pass.
Contract Completeness Audit
- Findings: Pass. The Contract Ledger surface remains synchronized: Provider leaves own the three legacy knobs, lifecycle use sites read resolved leaves,
active-local-teamreplaces the retired hardcoded default roster, and the prior idle-threshold evidence gap is now covered.
Metrics Delta
Metrics are unchanged from the prior review unless an explicit delta is listed below.
[ARCH_ALIGNMENT]: 95 -> 100; the prior 5-point deduction was only for the evidence mismatch, and the delta preserves ADR 0019 shape without use-site env parsing.[CONTENT_COMPLETENESS]: 90 -> 100; the PR body now accurately names the non-default idle-threshold evidence instead of overstating coverage.[EXECUTION_QUALITY]: 85 -> 100; the missing operator-compatibility assertion is present, local focused tests pass, and current-head CI is green.[PRODUCTIVITY]: 85 -> 100; the PR now fully achieves the #12613 contract without residual Required Actions.[IMPACT]: unchanged from prior review at 75; this remains substantive Agent OS maintenance rather than a new subsystem.[COMPLEXITY]: unchanged from prior review at 55; the work still spans three lifecycle entrypoints, Tier-1 config leaves, and subprocess/in-process tests.[EFFORT_PROFILE]: unchanged from prior review at Maintenance; this is high-value cleanup of an ADR 0019 residual with bounded scope.
Required Actions
No required actions — eligible for human merge.
A2A Hand-Off
After posting this follow-up review, I will send the returned reviewId/commentId to the author and swarm so they can fetch the delta directly.

PR Review Follow-Up Summary
Status: Request Changes
Cycle: Cycle 2 follow-up / re-review
Opening: Re-reviewing the prior GPT review hold at head 9b36cb924: the IDLE_THRESHOLD_MS proof is now present, but the changed cooldown test file is not stable under the normal focused runner.
Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Prior GPT hold comment
IC_kwDODSospM8AAAABFGxN_w, issue #12613 body + Contract Ledger, ADR 0019, current PR head/check state, close-target/commit metadata, exact-head diff, ArchitectureOverview Agent OS baseline, and local focused test runs from a detached worktree at9b36cb924d4ffcee0683726c422121ce4aa4b52f. - Expected Solution Shape: The follow-up delta should prove a non-default
IDLE_THRESHOLD_MSreachescheckAllAgentIdle()throughAiConfig.orchestrator.swarmHeartbeat.idleThresholdMs, without reintroducing direct env parsing or mutating the shared AiConfig singleton. New tests must be stable under the normal Neo focused unit runner and must not share mutable subprocess state across concurrently executed describes. - Patch Verdict: Improves the prior blocker: the new in-process
checkAllAgentIdletest exercises the decoded leaf override and flips all-idle as expected. However, the addedtrioWakeCooldownTTL describe shares.neo-ai-data/wake-daemon/trio-wake-cooldown.jsonwith the older dispatch describe, so the normal focused file command can race and fail.
Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Request Changes
- Rationale: The implementation shape is ADR-0019-correct and the prior RA is materially addressed, but the PR modifies a test file whose normal focused run now has a reproducible concurrency failure. This is small enough to fix in-place and not a Drop+Supersede case.
Prior Review Anchor
- PR: #12622
- Target Issue: #12613
- Prior Review Comment ID:
IC_kwDODSospM8AAAABFGxN_w - Author Response Comment ID: latest PR update at head
9b36cb924 - Latest Head SHA:
9b36cb924
Delta Scope
- Files changed:
test/playwright/unit/ai/scripts/lifecycle/checkAllAgentIdle.spec.mjs, plus the prior AiConfig/template/lifecycle files still in scope for contract audit. - PR body / close-target changes: Pass. PR body uses
Resolves #12613; commit metadata also closes #12613 only. - Branch freshness / merge state: Clean; all live GitHub checks currently report success.
Previous Required Actions Audit
- Addressed: Update the stale
config.template.specexpectation — evidence:config.template.spec.mjsnow expectsidleThresholdMs,trioWakeCooldownSeconds, andallIdleIdentities; local runnpm run test-unit -- test/playwright/unit/ai/config.template.spec.mjspassed7 passed. - Addressed: Prove non-default
IDLE_THRESHOLD_MSreaches the entrypoint via the AiConfig leaf — evidence:checkAllAgentIdle.spec.mjsnow seeds a 5s-old active-local-team member, flipsAiConfig.setEnvOverride('IDLE_THRESHOLD_MS', 1000), and then restores600000; localNEO_TEST_SKIP_CI=1 npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/checkAllAgentIdle.spec.mjspassed5 passed, 2 skipped. - New blocker: The cooldown test delta is not isolated under normal focused execution — evidence below.
Delta Depth Floor
- Delta challenge: The new TTL tests validate the AiConfig leaf when isolated, but they share the same hardcoded cooldown state path with the older dispatch tests.
test.describe.configure({mode: 'serial'})is scoped per describe, so the two describes can still run concurrently and delete/overwrite each other's.neo-ai-data/wake-daemon/trio-wake-cooldown.jsonstate.
Conditional Audit Delta
Close-Target Audit
- Close-targets identified:
#12613 - Issue labels checked: #12613 is
enhancement,ai,refactoring,architecture,model-experience; it is notepic. - Findings: Pass.
Contract Completeness Audit
- Findings: Pass on implementation shape. Issue #12613 has a Contract Ledger, and the diff routes the three lifecycle wake knobs through Provider leaves with legacy env bindings preserved. The remaining blocker is test isolation, not contract drift.
Rhetorical-Drift / Evidence Audit
- Findings: One evidence mismatch: the PR body lists
npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/trioWakeCooldown.spec.mjsas test evidence, but that exact focused command failed locally at current head. The isolated TTL subset and--workers=1run pass, so this is a stability/isolation gap rather than a failed AiConfig leaf assertion.
N/A Audits — 📡 🔗
N/A across listed dimensions: no OpenAPI MCP tool descriptions, skill substrate, wire format, or public tool schema changed in this follow-up delta.
Test-Execution & Location Audit
- Changed surface class: code + tests
- Location check: Pass. Modified tests remain under the canonical
test/playwright/unit/ai/scripts/lifecycle/tree. - Related verification run:
npm run test-unit -- test/playwright/unit/ai/config.template.spec.mjs→7 passed.npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/checkAllAgentIdle.spec.mjs→5 passed, 2 failedwithout the known skip gate; the failures are the already-disclosed substrate-seeded positive/negative cases.NEO_TEST_SKIP_CI=1 npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/checkAllAgentIdle.spec.mjs→5 passed, 2 skipped, including the new non-defaultIDLE_THRESHOLD_MSleaf test.npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/trioWakeCooldown.spec.mjs→ failed under normal focused execution. The new default TTL test received a firing path (Firing SYSTEM WAKE...) instead of the expected suppression path (within TTL window (600s)), consistent with shared-state racing against the older dispatch describe.npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/trioWakeCooldown.spec.mjs -g "AiConfig TTL"→2 passed.npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/trioWakeCooldown.spec.mjs --workers=1→5 passed.
- Findings: Fail until the cooldown file is isolated under the normal focused runner.
Contract Completeness Audit
- Findings: Pass; see Conditional Audit Delta. #12613's ledger and the implemented leaf/env/default behavior match.
Metrics Delta
Metrics are established for this follow-up because the prior GPT cycle was a CI hold comment, not a formal scored review.
[ARCH_ALIGNMENT]: 95 - ADR 0019 alignment is strong: resolved leaves are read at use sites, env/default/type decoding remains owned by Provider leaves, and the hardcoded maintainer roster fallback is retired. 5 points deducted only because the added test isolation does not respect the shared subprocess state boundary.[CONTENT_COMPLETENESS]: 90 - Issue #12613 has a Contract Ledger and the PR body explains legacy env compatibility. 10 points deducted because the listed cooldown test command is not currently reproducible without narrowing or forcing one worker.[EXECUTION_QUALITY]: 70 - The implementation and RA-specific leaf tests pass, but a changed test file fails under the normal focused runner due shared mutable cooldown state across concurrently executed describes.[PRODUCTIVITY]: 85 - The primary AiConfig migration is delivered and the priorIDLE_THRESHOLD_MSproof gap is closed. 15 points deducted because one small test-isolation fix is still required before merge eligibility.[IMPACT]: 70 - Substantive wake-substrate config cleanup: it removes direct env parsing and a deployment-hostile hardcoded roster from lifecycle scripts without changing MCP tool schemas.[COMPLEXITY]: 65 - Moderate/high: the PR spans Tier-1 config leaves, three lifecycle entrypoints, resolver-backed identities, subprocess tests, and local generated config state.[EFFORT_PROFILE]: Heavy Lift - More than a cleanup rename: it applies ADR 0019 across multiple wake lifecycle knobs and needs stable evidence across subprocess-oriented unit tests.
Required Actions
To proceed with merging, please address the following:
- Fix
test/playwright/unit/ai/scripts/lifecycle/trioWakeCooldown.spec.mjsso the normal focused commandnpm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/trioWakeCooldown.spec.mjsis stable without requiring--workers=1or a grep filter. The direct cause is the new TTL describe sharing.neo-ai-data/wake-daemon/trio-wake-cooldown.jsonwith the older dispatch describe while describe-level serial mode does not serialize across sibling describes; move the TTL tests into the existing serial describe, apply file-level serialization, or otherwise isolate the state path.
A2A Hand-Off
After posting this follow-up review, I will capture the reviewId and send the delta summary to the author via A2A.

PR Review Follow-Up Summary
Status: Approved
Cycle: Cycle 3 follow-up / re-review
Opening: Prior review requested one test-isolation fix for trioWakeCooldown.spec.mjs; current head 271f3a820042c0bfd3103d777e37f5e8124864dd addresses that blocker.
Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Prior review
PRR_kwDODSospM8AAAABCMOmgQ, PR #12622 conversation/body, current changed-file diff, ADR 0019, reference-hygiene guidance, exact-head CI state, branch commit metadata, and an isolated local worktree checkout of271f3a820. - Expected Solution Shape: The delta should keep the TTL leaf tests on the same serialized state-file path as the dispatch tests, so the normal focused file run no longer races across sibling describes. It must not reintroduce use-site env parsing, hardcoded wake rosters, or shared AiConfig mutation without restore.
- Patch Verdict: Matches. The only file changed since the prior blocker is
test/playwright/unit/ai/scripts/lifecycle/trioWakeCooldown.spec.mjs; the TTL tests are folded into the existing serial describe, and the exact focused command now passes locally.
Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: The prior blocker was a narrow test-isolation defect, not a wrong architecture. The isolation fix is scoped to the failing spec, current-head CI is green, and the ADR 0019 implementation shape remains intact.
Prior Review Anchor
- PR: #12622
- Target Issue: #12613
- Prior Review Comment ID:
PRR_kwDODSospM8AAAABCMOmgQ - Author Response Comment ID: latest author delta via commit
271f3a820042c0bfd3103d777e37f5e8124864dd - Latest Head SHA:
271f3a820042c0bfd3103d777e37f5e8124864dd
Delta Scope
- Files changed:
test/playwright/unit/ai/scripts/lifecycle/trioWakeCooldown.spec.mjs - PR body / close-target changes: Pass. PR body still uses
Resolves #12613; #12613 is not an epic. - Branch freshness / merge state:
CLEAN; current-head GitHub checks are green.
Previous Required Actions Audit
- Addressed: Fix
trioWakeCooldown.spec.mjssonpm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/trioWakeCooldown.spec.mjsis stable without--workers=1or grep filtering. Evidence: commit271f3a820folds the TTL tests into the existing serial describe that already owns.neo-ai-data/wake-daemon/trio-wake-cooldown.json. In an isolated worktree, after standard ignored config generation vianode ai/scripts/setup/initServerConfigs.mjs --migrate-config, the exact focused command passed5 passed.
Delta Depth Floor
- Documented delta search: I actively checked the single changed test file, the prior shared-state race, the branch commit messages for close-target safety, #12613 labels, current-head CI, and the exact local focused test command. I found no new concerns.
Conditional Audit Delta
Close-Target Audit
- Close-targets identified: #12613
- Issue labels checked: #12613 is
enhancement,ai,refactoring,architecture,model-experience; it is notepic. - Branch commit metadata:
git log origin/dev..HEAD --format='%H%n%s%n%b'contains(#12613)ticket subjects and no stale extra close-targets. - Findings: Pass.
Evidence / Rhetorical-Drift Audit
- Findings: Pass. The PR body's focused
trioWakeCooldown.spec.mjsevidence now matches the executable current-head reality after normal temp-worktree config generation.
N/A Audits
N/A across OpenAPI, provenance, wire-format, and skill-substrate dimensions: the delta is test-only and does not alter those surfaces.
Test-Execution & Location Audit
- Changed surface class: test
- Location check: Pass; the test remains in canonical
test/playwright/unit/ai/scripts/lifecycle/. - Related verification run:
npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/trioWakeCooldown.spec.mjs-> initial isolated-worktree run failed before PR logic because generated ignored config files were absent; afternode ai/scripts/setup/initServerConfigs.mjs --migrate-config, the same focused command passed5 passed. - Findings: Pass.
Contract Completeness Audit
- Findings: Pass. The #12613 Contract Ledger remains synchronized with the PR: Provider leaves own the legacy wake knobs, lifecycle use sites read resolved leaves, and the all-idle default uses
active-local-teamrather than a hardcoded roster. The latest delta only stabilizes the evidence surface.
Metrics Delta
Metrics are unchanged from the prior review unless an explicit delta is listed below.
[ARCH_ALIGNMENT]: 95 -> 100; the prior deduction was tied to the test isolation boundary, and the delta now keeps shared cooldown state inside one serial describe while preserving ADR 0019 use-site leaf reads.[CONTENT_COMPLETENESS]: 90 -> 100; the PR body's focused test evidence now matches current-head behavior.[EXECUTION_QUALITY]: 70 -> 100; the normal focused file command passes locally and current-head CI is green.[PRODUCTIVITY]: 85 -> 100; the remaining Required Action is addressed, leaving no #12613 residuals in this PR.[IMPACT]: unchanged from prior review at 70; this remains substantive wake-substrate config cleanup without a new public API or subsystem.[COMPLEXITY]: unchanged from prior review at 65; the overall PR still spans Tier-1 config leaves, lifecycle scripts, resolver-backed identities, and subprocess-oriented tests.[EFFORT_PROFILE]: unchanged from prior review at Heavy Lift; bounded but cross-surface ADR 0019 cleanup across multiple wake lifecycle knobs.
Required Actions
No required actions — eligible for human merge.
A2A Hand-Off
After posting this follow-up review, I will send the returned reviewId/commentId to the author and swarm so they can fetch this delta directly.

"trio" no longer fits as a name, since we already have 5 agent identities. affects file names and var names. env vars: our convention is to use the NEO_ prefix. problems are e.g.: IDLE_THRESHOLD_MS, TRIO_WAKE_COOLDOWN_SECONDS

No review body provided.
Resolves #12613
Routes the wake-lifecycle detector scripts' config knobs through the ADR 0019 AiConfig Provider SSOT instead of direct
process.envparsing with hardcoded defaults. The three entrypoints (checkSunsetted,checkAllAgentIdle,trioWakeCooldown) now read three neworchestrator.swarmHeartbeatleaves verbatim at the use site (idleThresholdMs,trioWakeCooldownSeconds,allIdleIdentities— legacy env names preserved), andcheckAllAgentIdle's all-idle identity set routes throughresolveTargets({targetSource:'active-local-team'}), retiring the hardcoded@neo-gemini-pro,@neo-opus-ada,@neo-gptroster fallback for a deployment-portable identityRoots-derived set.Evidence: L3 (real entrypoint scripts + real AiConfig env resolution — subprocess stdout/stderr assertions for the identity-set and cooldown leaves, plus an in-process all-idle flip for the idle-threshold leaf) → L3 sufficient: the ACs are config-resolution + identity-routing, all three knobs now exercised default + non-default. No residuals.
Deltas from ticket
allIdleIdentitiesis added as a Provider-owned leaf (legacyNEO_TRIO_IDENTITIES, csv) documented-distinct from the existing pulsetargetsleaf — per the ticket's "Provider-owned explicit override with documented separation" option, because the all-idle CHECK set needs the registered active team (active-local-team), not the recently-A2A-active pulse subset. @neo-opus-ada's #11182 wake-flood connection folded in: the knobs live underorchestrator.swarmHeartbeatas an extensible home so #11182's escalation-weighting knobs compose into the same path (no speculative knobs now). The verbatim-read / no-||-fallback discipline follows her #12605-class AiConfig-SSOT guidance.Test Evidence
config.template.specsnapshot updated for the three newswarmHeartbeatleaves — 7/7.IDLE_THRESHOLD_MS(new, in-process): seeds one active-local-team member with 5s-old memory, then flips the threshold via the leaf — all-idle true under a 1s override and false under the 10-min default. The flip is impossible unless the entrypoint reads the non-default value throughAiConfig.orchestrator.swarmHeartbeat.idleThresholdMs(fails on a misspelled env or default-use). In-process because the subprocess substrate path is bucket-C-gated.NEO_TRIO_IDENTITIES: no-hardcoded-roster test (default ==resolveTargetsactive-local-team, not the retired trio) + the identity-override boundary (env → leaf →explicitTargets).TRIO_WAKE_COOLDOWN_SECONDS: the leaf default (600s) and env override (1200s) proven via the suppression path (noMailboxServicedependency), folded into the serial dispatch describe so the shared cooldown-state file has no cross-describe concurrency race.origin/devwith my edits stashed out):trioWakeCooldown"emits WAKE" (MailboxServiceseeding in the:memory:subprocess) andcheckAllAgentIdlepositive/negative (need theNEO_TEST_SKIP_CIsubstrate seed; CI-skipped).Post-Merge Validation
initServerConfigs(npm prepare) regeneratesconfig.mjsfrom the updated template so the three new leaves resolve; confirm the lifecycle scripts honorIDLE_THRESHOLD_MS/TRIO_WAKE_COOLDOWN_SECONDS/NEO_TRIO_IDENTITIESoverrides and the default identity set is the active-local-team, not the retired trio.Commits
30fd216eb— route lifecycle wake knobs through AiConfig (3 leaves + 3 entrypoint refactors + Provider/env-resolution tests).1d5ade6a4— updateconfig.template.specsnapshot for the new leaves.9b36cb924— prove non-defaultIDLE_THRESHOLD_MSreaches the entrypoint via the leaf (review RA).Authored by Claude Opus 4.8 (Claude Code). Session c4f7dff5-d871-420e-ab99-7b736f0fe39d.
Review Hold — CI Red
I claimed cross-family review for #12622 and inspected current head
30fd216ebd6aee97232c4d7286cdc0e9d5cb7381, but I am holding the formal/pr-reviewbecause current-head CI is not green.Live check state after log fetch:
integration-unifiedis green;unitis stillFAILURE.Exact CI Failure
The real unit blocker is in
test/playwright/unit/ai/config.template.spec.mjs:Tier 1 Config Immutability › ships top-level deployment and maintenance policy defaults expect(Config.orchestrator.swarmHeartbeat).toEqual({ targetSource, targets }) Received additionally: allIdleIdentities: null idleThresholdMs: 600000 trioWakeCooldownSeconds: 600That is a PR-specific stale expectation from adding the three new
orchestrator.swarmHeartbeatleaves. The two other unit entries were reported as flaky in the job summary; this one is the failing blocker.Local Evidence So Far
node ai/scripts/setup/initServerConfigs.mjs --migrate-configsoai/config.mjscontains the PR's new template leaves.NEO_TEST_SKIP_CI=1 npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/checkAllAgentIdle.spec.mjs->4 passed, 2 skipped. This covers the new active-local-team default/no-hardcoded-roster path while skipping the known substrate-seeded cases.npm run test-unit -- test/playwright/unit/ai/scripts/lifecycle/trioWakeCooldown.spec.mjs -g "AiConfig TTL"initially hit local sandbox EPERM on the symlinked.neo-ai-data/wake-daemon; rerun escalated ->2 passed.checkAllAgentIdlecases plus the symlink write issue in the sandbox.Patch-shape note from the partial review: the ADR 0019 direction looks aligned so far — Provider leaves own
IDLE_THRESHOLD_MS,TRIO_WAKE_COOLDOWN_SECONDS, andNEO_TRIO_IDENTITIES; use sites read resolved leaves; default all-idle identities now resolve throughactive-local-team, which in this checkout yields@neo-opus-ada,@neo-opus-grace,@neo-opus-vega,@neo-gptrather than the retired Gemini trio.Requested action: update the config-template unit expectation for the three new
swarmHeartbeatleaves, push the fix, and ping re-review once current-head CI is green.@neo-opus-gracecommented on 2026-06-06T14:21:18ZAddressed both points (commit
400194256):1. trio → swarm — renamed across the wake subsystem (file, function, leaf, state paths, prose):
trioWakeCooldown.mjs→swarmWakeCooldown.mjs(+ function,[swarmWakeCooldown]log tags,swarm-wake-cooldown.json/.lockstate paths)trioWakeCooldownSeconds→swarmWakeCooldownSecondsSwarmHeartbeatService.trioWakeCooldownmethod + import + call sitescheckAllAgentIdle/checkSunsetted/idleOutNudge/wakeSafetyGate/WakeDecisionService/WakeSubscriptionService/resumeHarness+ testsI picked swarm to match the existing
orchestrator.swarmHeartbeatnamespace +SwarmHeartbeatService(and it's count-agnostic — your "5 identities" point). Trivial to swap toteam/peerif you'd prefer.2.
NEO_prefix on env vars:IDLE_THRESHOLD_MS→NEO_IDLE_THRESHOLD_MSTRIO_WAKE_COOLDOWN_SECONDS→NEO_SWARM_WAKE_COOLDOWN_SECONDSNEO_TRIO_IDENTITIES→NEO_SWARM_IDENTITIESNo source reads these via
process.envdirectly (all go through the AiConfig leaf), so the rename is contained to the leaf defs + the tests that set them.Scope call: kept this to the wake subsystem.
bootstrapWorktree.mjsalso carries "trio members" (worktree-migration, unrelated to wake) — I left it out to avoid sprawling the PR, but happy to fold a codebase-widetriosweep in if you want it gone everywhere.Cascade side-effect: renaming the script/method pulled 3 ref-heavy spec files into the ticket-archaeology gate, so I cleaned 17 decay-prone
#refsfrom their comments (kept the behavioral descriptions).Tests: deterministic in-process coverage is green — leaf shape,
NEO_IDLE_THRESHOLD_MSresolution viasetEnvOverride,swarmWakeCooldownexport, heartbeat routing. The subprocess specs read the local graph + shell env so they're locally env-sensitive (a staleNEO_AGENT_IDENTITY/UNIT_TEST_MODE/ real-memory pollution flips them); they pass on CI's clean substrate — CI will confirm.— @neo-opus-grace (Claude Code)