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
Sub of #10214. See parent epic for architectural rationale. This ticket focuses on the implementation delta for Sub 5 - extending the DreamService / sandman substrate with an active stale-assignment detector + recent-open-PRs listing in the sandman_handoff.md output.
Historical blocker note: the original ticket treated the entire #10030 concept-ontology epic as the prerequisite. Current source reality narrows that prerequisite to reliable Sandman handoff generation through GoldenPathSynthesizer.synthesizeGoldenPath(), which exists today and must be re-verified during intake.
The Problem
Sub 1 of #10214 (ticket-intake 7-day rule) is the passive reassignment substrate - it fires when an agent attempts pickup. It doesn't surface stale assignments proactively. Agents on boot have no visibility into reassignment opportunities OR into recent PRs needing review.
Sandman is the existing architectural pattern for boot-time "here's what changed while you were asleep" signal. Adding two detector passes to the DreamService output extends this capability without new substrate.
The Architectural Reality
DreamService writes sandman_handoff.md (per AGENTS_STARTUP.md §6 Memory Core check). Currently contains REM-derived strategic priorities + topological alerts. Adding two sections:
## Stale Assignment Candidates
Tickets with an assignee and no qualifying activity in >=7 days:
- #N - <title> - assignee @X - last activity <timestamp> (N days ago)
- ...
## Recent Open PRs
5 most recent open PRs:
- #N - <title> - author @X - opened <timestamp> - cross-family reviewed: yes/no
- ...
Detector logic:
Stale assignments: iterate resources/content/issues/*.md where frontmatter has non-empty assignees and state === 'OPEN'. For each, compute lastQualifyingActivity (per Sub 1's definition - assignee comment OR maintainer ack). If now - lastQualifyingActivity >= 7 days, flag.
Recent PRs: list top 5 PRs by createdAt desc where state === 'OPEN'. Include cross-family review status (per #10208 mandate) as signal.
Current source-anchor update (2026-05-28): the handoff is currently generated by GoldenPathSynthesizer.synthesizeGoldenPath(), with DreamService.synthesizeGoldenPath() delegating to it. aiConfig.handoffFilePath defaults to resources/content/sandman_handoff.md. Existing repo-specific enrichment already includes ## Active PR Cycle State via fetchOpenPRs() and ## Latest Priority Backlog via local issue/graph state; #10219 should extend or reuse those enrichment paths rather than introduce a second handoff writer.
The Fix
Extend the GoldenPathSynthesizer handoff render path with two detector passes:
Stale-assignment pass iterates local synced issue state, applies the 7-day qualifying-activity rule from Sub 1
Recent-PRs pass either reuses/extends Active PR Cycle State or emits a deterministic capped recent-open-PR section with cross-family review status
Output both signals into sandman_handoff.md alongside existing repo-enrichment content.
Surface-Anchor V-B-A used for this ledger (2026-05-28):
ai/services/graph/GoldenPathSynthesizer.mjs owns fetchOpenPRs(), synthesizeGoldenPath(), ## Active PR Cycle State, ## Latest Priority Backlog, and the final write to aiConfig.handoffFilePath.
ai/daemons/orchestrator/services/DreamService.mjs delegates its Golden Path phase to GoldenPathSynthesizer.synthesizeGoldenPath().
ai/mcp/server/memory-core/config.template.mjs sets handoffFilePath to resources/content/sandman_handoff.md.
learn/agentos/decisions/0014-cloud-deployment-topology-and-scheduler-task-taxonomy.md classifies the Active PR Cycle State and Latest Priority Backlog enrichments as Neo-maintainer-repo-specific and graceful-degrade, so this ticket must preserve that deployment boundary.
Target Surface
Source of Authority
Proposed Behavior
Fallback / Edge Case
Docs
Evidence
resources/content/sandman_handoff.md stale-assignment signal
Add a deterministic ## Stale Assignment Candidates section when repo enrichment is enabled; list assigned open issues whose last qualifying activity is >=7 days old, sorted by oldest qualifying activity first, with an explicit empty-state when no candidates exist.
If issue-state input cannot be read, log a warning and continue handoff generation without failing the Golden Path render; malformed issue records are skipped with defensive logging.
Update learn/agentos/DreamPipeline.md or the handoff consumer doc that owns the Sandman output schema.
Focused GoldenPathSynthesizer unit coverage with injected issue fixtures for stale, fresh, unassigned, closed, malformed, and empty-state cases.
Stale-assignment detector input
ticket-intake 7-day rule + local synced issue substrate
Use local synced issue/graph state, not live GitHub network calls, for open issue state, assignees, labels, and qualifying activity evidence. The qualifying-activity definition must match the ticket-intake rule: assignee comment OR maintainer in-progress acknowledgement.
Missing assignee, missing open state, missing qualifying-activity evidence, or needs-re-triage should not produce a candidate. Do not mutate assignments.
JSDoc on the detector helper plus the same operator doc as the output section.
Unit test proving the 7-day threshold and maintainer/assignee activity semantics, including boundary timestamps.
Prefer extending/reusing the existing ## Active PR Cycle State section rather than adding duplicate PR-cycle output. If a distinct recent-open-PR list is still chosen, fetchOpenPRs() must include createdAt and the render must cap to the top 5 open PRs by createdAt desc with cross-family-review status.
fetchOpenPRs() failure remains graceful-degrade: log warning and omit repo enrichment, with no hard dependency on GitHub during unit tests. Non-agent PRs may be included only if the implementation explicitly documents that broader consumer choice.
Update handoff schema docs if a new heading is introduced; otherwise document the extension in GoldenPathSynthesizer JSDoc/test names.
Unit test with mocked fetchOpenPRs() proving ordering, cap, cross-family review flag, and graceful failure.
Keep stale-assignment and recent-PR sections behind the existing repo-enrichment boundary or an equivalent explicit config gate; tenant/cloud deployments should not emit Neo-maintainer-repo-specific noise when repo enrichment is disabled.
repoEnrichmentEnabled: false omits both new signals and preserves the core Golden Path output.
ADR 0014 already owns the deployment taxonomy; add only a small doc note if a new config is introduced.
Unit test for repoEnrichmentEnabled: false proving no new repo-specific sections are emitted.
No label mutation in the first implementation. If pursued later, require an explicit opt-in config and label existence verification before mutation.
Default behavior is visibility-only. If the label is missing or config disabled, no mutation occurs.
Future ticket only; no first-pass docs requirement beyond out-of-scope note.
Not part of #10219 first-pass evidence; future mutation ticket must provide integration-level proof.
Acceptance Criteria
DreamService/GoldenPathSynthesizer iterates open issues and flags stale-assignment candidates in sandman_handoff.md
Stale-assignment definition matches Sub 1's qualifying-activity rule (reuse the definition; do not diverge)
Top 5 open PRs are listed or the existing Active PR Cycle State is extended with equivalent recent-open-PR/cross-family-review visibility
Repo-specific sections respect the existing repo-enrichment/deployment boundary and degrade gracefully when local issue or GitHub PR input is unavailable
Unit tests cover stale/fresh assignment detection, recent-PR ordering/capping or Active PR Cycle State extension, and enrichment-disabled behavior
(Optional/future) auto-label status: needs-reassignment remains out of scope unless a separate opt-in mutation ticket is filed
Out of Scope
Auto-reassignment (mutating assignments without agent action) - out of scope; too aggressive
Notification push (email, slack) - the sandman substrate is boot-time polling; push is separate substrate
PR age filtering beyond "top 5 most recent" - could extend to "all PRs whose author is an agent identity" but that's feature-creep; keep initial simple
Integration with notificationPreview from Sub 4 - different data paths; could consolidate later
Blocked By
Narrowed prerequisite: reliable Sandman handoff generation through GoldenPathSynthesizer.synthesizeGoldenPath(). The original broad #10030 dependency should not be read as requiring the entire concept-ontology epic to close before this ticket can proceed; intake should verify current source reality before implementation.
Related
Parent epic:#10214
Passive counterpart: Sub 1 of #10214 (codified 7-day rule in ticket-intake) - this ticket is the active surfacer
Context
Sub of
#10214. See parent epic for architectural rationale. This ticket focuses on the implementation delta for Sub 5 - extending the DreamService / sandman substrate with an active stale-assignment detector + recent-open-PRs listing in thesandman_handoff.mdoutput.Historical blocker note: the original ticket treated the entire
#10030concept-ontology epic as the prerequisite. Current source reality narrows that prerequisite to reliable Sandman handoff generation throughGoldenPathSynthesizer.synthesizeGoldenPath(), which exists today and must be re-verified during intake.The Problem
Sub 1 of
#10214(ticket-intake 7-day rule) is the passive reassignment substrate - it fires when an agent attempts pickup. It doesn't surface stale assignments proactively. Agents on boot have no visibility into reassignment opportunities OR into recent PRs needing review.Sandman is the existing architectural pattern for boot-time "here's what changed while you were asleep" signal. Adding two detector passes to the DreamService output extends this capability without new substrate.
The Architectural Reality
DreamService writes
sandman_handoff.md(perAGENTS_STARTUP.md §6 Memory Core check). Currently contains REM-derived strategic priorities + topological alerts. Adding two sections:Detector logic:
resources/content/issues/*.mdwhere frontmatter has non-emptyassigneesandstate === 'OPEN'. For each, computelastQualifyingActivity(per Sub 1's definition - assignee comment OR maintainer ack). Ifnow - lastQualifyingActivity >= 7 days, flag.createdAtdesc wherestate === 'OPEN'. Include cross-family review status (per#10208mandate) as signal.Current source-anchor update (2026-05-28): the handoff is currently generated by
GoldenPathSynthesizer.synthesizeGoldenPath(), withDreamService.synthesizeGoldenPath()delegating to it.aiConfig.handoffFilePathdefaults toresources/content/sandman_handoff.md. Existing repo-specific enrichment already includes## Active PR Cycle StateviafetchOpenPRs()and## Latest Priority Backlogvia local issue/graph state; #10219 should extend or reuse those enrichment paths rather than introduce a second handoff writer.The Fix
Active PR Cycle Stateor emits a deterministic capped recent-open-PR section with cross-family review statussandman_handoff.mdalongside existing repo-enrichment content.status: needs-reassignmentlabel on detected stale assignments only if a later opt-in config/ticket proves that mutation path is safe. First-pass Sandman active detector: stale assignments + recent open PRs #10219 remains visibility-only.Contract Ledger
Surface-Anchor V-B-A used for this ledger (2026-05-28):
ai/services/graph/GoldenPathSynthesizer.mjsownsfetchOpenPRs(),synthesizeGoldenPath(),## Active PR Cycle State,## Latest Priority Backlog, and the final write toaiConfig.handoffFilePath.ai/daemons/orchestrator/services/DreamService.mjsdelegates its Golden Path phase toGoldenPathSynthesizer.synthesizeGoldenPath().ai/mcp/server/memory-core/config.template.mjssetshandoffFilePathtoresources/content/sandman_handoff.md.learn/agentos/decisions/0014-cloud-deployment-topology-and-scheduler-task-taxonomy.mdclassifies the Active PR Cycle State and Latest Priority Backlog enrichments as Neo-maintainer-repo-specific and graceful-degrade, so this ticket must preserve that deployment boundary.resources/content/sandman_handoff.mdstale-assignment signal## Stale Assignment Candidatessection when repo enrichment is enabled; list assigned open issues whose last qualifying activity is >=7 days old, sorted by oldest qualifying activity first, with an explicit empty-state when no candidates exist.learn/agentos/DreamPipeline.mdor the handoff consumer doc that owns the Sandman output schema.GoldenPathSynthesizerunit coverage with injected issue fixtures for stale, fresh, unassigned, closed, malformed, and empty-state cases.ticket-intake7-day rule + local synced issue substrateneeds-re-triageshould not produce a candidate. Do not mutate assignments.Active PR Cycle StateGoldenPathSynthesizer.fetchOpenPRs()+ #10208 cross-family review mandate## Active PR Cycle Statesection rather than adding duplicate PR-cycle output. If a distinct recent-open-PR list is still chosen,fetchOpenPRs()must includecreatedAtand the render must cap to the top 5 open PRs bycreatedAtdesc with cross-family-review status.fetchOpenPRs()failure remains graceful-degrade: log warning and omit repo enrichment, with no hard dependency on GitHub during unit tests. Non-agent PRs may be included only if the implementation explicitly documents that broader consumer choice.GoldenPathSynthesizerJSDoc/test names.fetchOpenPRs()proving ordering, cap, cross-family review flag, and graceful failure.synthesizeGoldenPath({ repoEnrichmentEnabled = true })parameterrepoEnrichmentEnabled: falseomits both new signals and preserves the core Golden Path output.repoEnrichmentEnabled: falseproving no new repo-specific sections are emitted.Acceptance Criteria
sandman_handoff.mdActive PR Cycle Stateis extended with equivalent recent-open-PR/cross-family-review visibilitystatus: needs-reassignmentremains out of scope unless a separate opt-in mutation ticket is filedOut of Scope
notificationPreviewfrom Sub 4 - different data paths; could consolidate laterBlocked By
GoldenPathSynthesizer.synthesizeGoldenPath(). The original broad#10030dependency should not be read as requiring the entire concept-ontology epic to close before this ticket can proceed; intake should verify current source reality before implementation.Related
#10214#10214(codified 7-day rule in ticket-intake) - this ticket is the active surfacer#10208(cross-family mandate - Recent-PRs pass can surface unreviewed-by-cross-family as signal)Handoff Retrieval Hints
query_raw_memories(query="sandman active detector stale assignment recent open PRs")query_raw_memories(query="sandman_handoff.md DreamService extension 7-day rule")query_summaries(query="agent operational hygiene active detector sandman")Known contributing sessions:
ae546a40-2133-482f-85a6-779fdf6757b2(epic authoring session)