This restores the product shape that was accepted but never filed under Epic #12679.
On 2026-07-02, the operator separated two Bird Views: Memory Core sessions/memories by week/month, and pull-request conversation bodies by 3-day/week/month/quarter windows. Epic #12679 recorded the second source as Leaf D — GitHub-conversation temporal windows and the season owner accepted it as a distinct fourth leaf because its ingestion mechanics differ from Memory Core. On 2026-07-12, a fresh authority audit found that Leaf D was never created, while later work shipped a static Markdown handoff retrospective and a static HTML mock instead.
The operator has now restated the requirement at P0: Bird View is a runtime exploration tool, never a Markdown blob in sandman_handoff.md, and resolved pull-request history must remain separate from the Memory/session view.
Source record:
Epic #12679 — accepted Leaf-D comments IC_kwDODSospM8AAAABIezvDw and IC_kwDODSospM8AAAABIe0zJA.
Builds on merged #14435 / PR #15096 — the query-time temporal runner, honest envelope, and Memory Core model-bound runtime entry.
Strategic parent Discussion #11375 — explicitly rejects dashboard/presentation-first work as a substitute for queryable synthesis.
Graduated history Discussion #11376 and ADR 0028 — L3–L5 are synthesized on demand, never durably materialized.
The Problem
There is no runtime operation that answers: “What happened across the resolved pull-request conversations in this window?”
The existing surfaces are insufficient:
list_pull_requests returns a bounded metadata list. It does not read review/comment reasoning or synthesize a window.
get_conversation({pr_number}) gives excellent one-PR drill-down, but reconstructing a week requires first discovering every resolved PR and then walking them N+1, with no coverage manifest or cross-PR synthesis.
The generated Handoff Retrospective is a parallel direct-read renderer, not the temporal pyramid. Its exact 2026-07-09 09:11Z → 2026-07-12 09:11Z window rendered 50 merged / 10 opened / 50 closed issues / 50 opened issues; bounded GitHub search returns 86 / 99 / 97 / 85. The readers hard-cap several classes at 50, and “opened PRs” means only PRs still open when synthesis runs.
The handoff session rows are metadata labels such as “session recorded”; no conversation or memory content is synthesized.
The missing capability is not another display. It is a source-complete, window-parameterized, cite-backed runtime query over resolved PR conversation bodies, with exact drill-down handles.
#11375 intentionally remains open as a parent ontology rather than graduating as one epic. Filing is nevertheless valid because: (1) the operator made the runtime/separate-view call directly at P0; (2) graduated Discussion #11376 plus Epic #12679 already accepted Leaf D as an implementation leaf; and (3) the divergence matrix below preempts the remaining parent-level consumer ambiguity. If later #11375 children alter the broader current-state or future-planning dimensions, this ticket’s output vocabulary and consumer list may need amendment; the historical query-time/no-durable-write boundary remains governed by ADR 0028.
Option
Evidence / falsifier
Disposition
Static handoff or dashboard
#11375 rejects presentation over unsynthesized data; current handoff totals are empirically capped/wrong
No exact window coverage, no synthesis, N+1 archaeology, bounded list semantics
Rejected
One mixed PR + Memory/session digest tool
Different source completeness, privacy, citation, and drill-down contracts; operator explicitly requires separate views
Rejected
Separate runtime PR-history tool over the shared dynamic-synthesis path
Matches the accepted Leaf-D disposition and preserves source-specific truth
Selected
The Architectural Reality
Current contract alignment (2026-07-13 intake)
Facade / model owner: Memory Core registers explore_pull_request_history and owns the temporal runner + chat-model binding shipped by PR #15096.
Source owner: GitHub Workflow owns repository binding, active/archive corpus reads, resolution semantics, freshness, completeness, and PR/comment/review drill-down through PullRequestHistoryService.
Dependency inversion: Memory Core injects the generic runner/generate seam into the GitHub-owned service. GitHub Workflow never imports ai/services/memory-core/helpers/*.
Inference contract: PR conversation content, not titles alone, must reach synthesis. A PR-specific input adapter is required; generic title-only reuse is a blocking falsifier.
Coverage layers:coverage.totalResolved counts terminal PRs. Comment/review counts and exhaustion are child-evidence coverage and may not be conflated with the PR census.
Manifest identity: provenance includes content revision/digest, not PR IDs alone, so a post-close conversation edit changes the manifest.
Release preset: GitHub Workflow resolves cut-to-cut boundaries, then passes one explicit half-open window to the generic temporal runner.
Drill-down truth: every citation preserves a PR number/URL. Exact comment/review IDs are emitted only when the source artifact actually preserves them; get_conversation is the PR/comment drill-down, not a false review-ID reader.
GitHub Workflow owns PR ingestion and one-PR drill-down. PullRequestSyncer.mjs writes active and release-bucketed archived PR Markdown containing body/reviews/conversation content; resources/content/_index.json addresses the repo corpus.
The corpus currently spans both resources/content/pulls/ and resources/content/archive/pulls/; a window reader that scans only the active directory is incomplete by construction.
PullRequestService.getConversation() is the existing surgical drill-down authority. The new overview must cite PR numbers/comment or review IDs so callers can continue through that tool rather than embedding every conversation in one response.
#14435 / PR #15096 ship the reusable dynamic runner and model binding in Memory Core. This leaf adds GitHub-owned PullRequestHistoryService and a distinct explore_pull_request_history operation registered by Memory Core. Dependency direction is Memory Core toolService → injected GitHub source service; GitHub Workflow MUST NOT import Memory Core private helpers. Co-location at the MCP facade does not mix source records or response envelopes.
ADR 0028 §2.2 forbids durable L3–L5 output. Every Bird View is generated on demand from source artifacts and L1/L2 facts.
PR sync completeness is part of the truth boundary. Current sync artifacts cap comments/reviews, persist neither connection totalCount/pageInfo nor node IDs/exhaustion, and the content index is a regeneratable projection rather than proof of corpus completeness. The source adapter must prove a live resolved-PR census plus child-evidence exhaustion, or return an incomplete/degraded envelope; cap equality, stale paths, and silent truncation are forbidden.
Structural pre-flight
Future ai/services/github-workflow/PullRequestHistoryService.mjs is a structural fast-path sibling of PullRequestService.mjs in ai/services/github-workflow/: same GitHub-corpus service role, no novel directory. The temporal engine stays in the landed #14435 Memory Core lane. The separate operation is added to the existing Memory Core OpenAPI/dispatch; GitHub-specific source code stays under ai/services/github-workflow/. No ArchitectureOverview map update is required.
The Fix
One coherent PR:
Add a GitHub PR-history source service that selects all resolved PRs in a half-open [windowStart, windowEnd) interval across active + archived synced content. Resolution semantics are explicit: merged, closed_unmerged, or all_resolved; ordering uses mergedAt/closedAt, never creation time.
Prove source completeness. Exhaust PR review/comment connections during sync or persist a structured incompleteness signal; the reader fails closed/degraded when any selected conversation is legacy-unknown or truncated.
Feed a PR-specific conversation evidence projection into the landed temporal runner from #14435 / PR #15096 by dependency injection. Do not pass title-only sources; no higher-tier document is persisted.
Register the distinct read-only explore_pull_request_history operation in the Memory Core OpenAPI/dispatch, with arbitrary (windowStart, windowEnd) plus presets daily, 3-day, weekly, monthly, quarterly, and release (cut-to-cut resolved by GitHub Workflow). The operation remains separate from explore_memory_history; its source records and response never mix with Memory/session history.
Return a structured Bird View: window semantics, exact coverage/exhaustion, source-manifest hash, narrative/themes/decisions/friction/outcomes, cite-backed notable events, and PR/comment/review drill-down handles. Stamp notAuthority: true and generated-at/source provenance.
Bound response density without hiding coverage: the narrative may be concise, but coverage.totalResolved, inclusion/exclusion counts, truncation state, and citations remain explicit.
{window, resolution, coverage, sourceManifestHash, generatedAt, citations, notAuthority:true} accompanies every answer
No confident narrative without complete coverage
Schema/OpenAPI
schema + partial-source falsifiers
Decision Record impact
aligned-with ADR 0028; composes-with ADR 0035; builds on merged #14435 / PR #15096; implements the accepted Leaf-D disposition under #12679. It does not amend the durable/dynamic tier boundary.
Decision Record
Required authority: ADR 0028 + Epic #12679. Strategic parent #11375 remains open by design.
Discussion Criteria Mapping
Upstream criterion
This ticket
Queryable synthesis, not dashboard polish (#11375)
New runtime MCP operation; Markdown/UI excluded
Historical L3–L5 dynamic, no photocopy cascade (#11376 / ADR 0028)
Query-time synthesis; explicit no-write AC
GitHub conversations as distinct source (Epic #12679 Leaf D)
Source-specific PR adapter + separate operation
Arbitrary windows and PR conversation content (operator July-2026 seeds)
Parameterized windows/presets + full conversation reasoning
A read-only runtime tool explores resolved PR conversations separately from Memory/session history; Memory Core owns the operation/model binding, GitHub Workflow owns the injected source adapter, and no GitHub module imports Memory Core private helpers.
Arbitrary (windowStart, windowEnd) and daily / 3-day / weekly / monthly / quarterly / release presets resolve through one path.
Window inclusion is half-open and resolution-event based; merged, closed-unmerged, and all-resolved filters are explicit.
Active and archived PR corpora are both covered; >50 selected PRs neither truncate nor masquerade as a complete answer.
Conversation review/comment exhaustion is proven; unknown/incomplete artifacts return a degraded envelope, never numeric zero or partial-as-complete synthesis.
Output includes exact PR-census coverage, separate child-evidence exhaustion, a content-revision-sensitive source manifest/hash, generated timestamp, concise narrative/themes/decisions/friction/outcomes, and drill-down citations.
Every mutable/derived claim is cite-backed and stamped notAuthority:true.
Every citation preserves a PR number/URL consumable by get_conversation({pr_number}); exact comment/review IDs are emitted only when retained by the source, and review citations never pretend the comment-only drill-down resolves review nodes.
No L3–L5 result is written to Chroma, SQLite, Markdown, handoff, or another cache.
Inference failure preserves deterministic source/coverage evidence and clearly marks narrative synthesis unavailable.
Focused tests include >50 PRs, active+archive union, exact boundaries, closed-unmerged semantics, release windows, incomplete conversations, no-write behavior, and citation drill-down.
Cross-family review challenges the exact tool contract and source-completeness proof before merge.
Out of Scope
Memory/session Bird View (owned separately by #14435).
Handoff Markdown, Fleet Manager cockpit, dashboard, HTML mock, or other presentation surfaces.
Issues/Discussion conversation Bird Views; this P0 slice is resolved pull requests. They may extend the source family later without changing this tool’s PR-specific semantics.
Current-state strategy, future counterfactual planning, ranking, or automatic lane selection.
Live duplicate sweep: latest 20 open issues, targeted open-title searches, Knowledge Base tickets, active+archived local issues/Discussions, and last 30 all-state A2A messages checked at 2026-07-12T09:59:43.552Z; no equivalent ticket or competing in-flight claim found. #14620 is a Fleet UI consumer, and #14435 is the separate Memory/session source.
tobiu referenced in commit be4aa02 - "refactor(graph): remove the static Handoff Retrospective from the Golden Path (#15089) (#15091) on Jul 12, 2026, 2:36 PM
tobiu referenced in commit 9b4b80f - "feat(agentos): add resolved-PR history Bird View (#15088) (#15131)" on 5:19 PM
Context
This restores the product shape that was accepted but never filed under Epic #12679.
On 2026-07-02, the operator separated two Bird Views: Memory Core sessions/memories by week/month, and pull-request conversation bodies by 3-day/week/month/quarter windows. Epic
#12679recorded the second source as Leaf D — GitHub-conversation temporal windows and the season owner accepted it as a distinct fourth leaf because its ingestion mechanics differ from Memory Core. On 2026-07-12, a fresh authority audit found that Leaf D was never created, while later work shipped a static Markdown handoff retrospective and a static HTML mock instead.The operator has now restated the requirement at P0: Bird View is a runtime exploration tool, never a Markdown blob in
sandman_handoff.md, and resolved pull-request history must remain separate from the Memory/session view.Source record:
IC_kwDODSospM8AAAABIezvDwandIC_kwDODSospM8AAAABIe0zJA.#11375— explicitly rejects dashboard/presentation-first work as a substitute for queryable synthesis.#11376and ADR 0028 — L3–L5 are synthesized on demand, never durably materialized.The Problem
There is no runtime operation that answers: “What happened across the resolved pull-request conversations in this window?”
The existing surfaces are insufficient:
list_pull_requestsreturns a bounded metadata list. It does not read review/comment reasoning or synthesize a window.get_conversation({pr_number})gives excellent one-PR drill-down, but reconstructing a week requires first discovering every resolved PR and then walking them N+1, with no coverage manifest or cross-PR synthesis.50 merged / 10 opened / 50 closed issues / 50 opened issues; bounded GitHub search returns86 / 99 / 97 / 85. The readers hard-cap several classes at 50, and “opened PRs” means only PRs still open when synthesis runs.The missing capability is not another display. It is a source-complete, window-parameterized, cite-backed runtime query over resolved PR conversation bodies, with exact drill-down handles.
Architectural Step-Back / ungraduated-parent exception
#11375intentionally remains open as a parent ontology rather than graduating as one epic. Filing is nevertheless valid because: (1) the operator made the runtime/separate-view call directly at P0; (2) graduated Discussion#11376plus Epic #12679 already accepted Leaf D as an implementation leaf; and (3) the divergence matrix below preempts the remaining parent-level consumer ambiguity. If later#11375children alter the broader current-state or future-planning dimensions, this ticket’s output vocabulary and consumer list may need amendment; the historical query-time/no-durable-write boundary remains governed by ADR 0028.#11375rejects presentation over unsynthesized data; current handoff totals are empirically capped/wronglist_pull_requests+ N×get_conversationmanuallyThe Architectural Reality
Current contract alignment (2026-07-13 intake)
Facade / model owner: Memory Core registers
explore_pull_request_historyand owns the temporal runner + chat-model binding shipped by PR #15096.Source owner: GitHub Workflow owns repository binding, active/archive corpus reads, resolution semantics, freshness, completeness, and PR/comment/review drill-down through
PullRequestHistoryService.Dependency inversion: Memory Core injects the generic runner/generate seam into the GitHub-owned service. GitHub Workflow never imports
ai/services/memory-core/helpers/*.Inference contract: PR conversation content, not titles alone, must reach synthesis. A PR-specific input adapter is required; generic title-only reuse is a blocking falsifier.
Coverage layers:
coverage.totalResolvedcounts terminal PRs. Comment/review counts and exhaustion are child-evidence coverage and may not be conflated with the PR census.Manifest identity: provenance includes content revision/digest, not PR IDs alone, so a post-close conversation edit changes the manifest.
Release preset: GitHub Workflow resolves cut-to-cut boundaries, then passes one explicit half-open window to the generic temporal runner.
Drill-down truth: every citation preserves a PR number/URL. Exact comment/review IDs are emitted only when the source artifact actually preserves them;
get_conversationis the PR/comment drill-down, not a false review-ID reader.GitHub Workflow owns PR ingestion and one-PR drill-down.
PullRequestSyncer.mjswrites active and release-bucketed archived PR Markdown containing body/reviews/conversation content;resources/content/_index.jsonaddresses the repo corpus.The corpus currently spans both
resources/content/pulls/andresources/content/archive/pulls/; a window reader that scans only the active directory is incomplete by construction.PullRequestService.getConversation()is the existing surgical drill-down authority. The new overview must cite PR numbers/comment or review IDs so callers can continue through that tool rather than embedding every conversation in one response.#14435 / PR #15096 ship the reusable dynamic runner and model binding in Memory Core. This leaf adds GitHub-owned
PullRequestHistoryServiceand a distinctexplore_pull_request_historyoperation registered by Memory Core. Dependency direction is Memory CoretoolService→ injected GitHub source service; GitHub Workflow MUST NOT import Memory Core private helpers. Co-location at the MCP facade does not mix source records or response envelopes.ADR 0028 §2.2 forbids durable L3–L5 output. Every Bird View is generated on demand from source artifacts and L1/L2 facts.
PR sync completeness is part of the truth boundary. Current sync artifacts cap comments/reviews, persist neither connection
totalCount/pageInfonor node IDs/exhaustion, and the content index is a regeneratable projection rather than proof of corpus completeness. The source adapter must prove a live resolved-PR census plus child-evidence exhaustion, or return an incomplete/degraded envelope; cap equality, stale paths, and silent truncation are forbidden.Structural pre-flight
Future
ai/services/github-workflow/PullRequestHistoryService.mjsis a structural fast-path sibling ofPullRequestService.mjsinai/services/github-workflow/: same GitHub-corpus service role, no novel directory. The temporal engine stays in the landed #14435 Memory Core lane. The separate operation is added to the existing Memory Core OpenAPI/dispatch; GitHub-specific source code stays underai/services/github-workflow/. No ArchitectureOverview map update is required.The Fix
One coherent PR:
[windowStart, windowEnd)interval across active + archived synced content. Resolution semantics are explicit:merged,closed_unmerged, orall_resolved; ordering usesmergedAt/closedAt, never creation time.explore_pull_request_historyoperation in the Memory Core OpenAPI/dispatch, with arbitrary(windowStart, windowEnd)plus presetsdaily,3-day,weekly,monthly,quarterly, andrelease(cut-to-cut resolved by GitHub Workflow). The operation remains separate fromexplore_memory_history; its source records and response never mix with Memory/session history.notAuthority: trueand generated-at/source provenance.coverage.totalResolved, inclusion/exclusion counts, truncation state, and citations remain explicit.Contract Ledger Matrix
explore_pull_request_historyMCP operationPullRequestHistoryServicesource adapterPullRequestSyncercorpus ownership + ADR 0028 §2.2PullRequestService.getConversation()drill-downai/services/github-workflow/PullRequestService.mjs+ GitHub Workflow OpenAPI#11375DerivedSignalContract + ADR 0035 + operator truthfulness correction{window, resolution, coverage, sourceManifestHash, generatedAt, citations, notAuthority:true}accompanies every answerDecision Record impact
aligned-with ADR 0028;composes-with ADR 0035; builds on merged #14435 / PR #15096; implements the accepted Leaf-D disposition under #12679. It does not amend the durable/dynamic tier boundary.Decision Record
Required authority: ADR 0028 + Epic #12679. Strategic parent
#11375remains open by design.Discussion Criteria Mapping
#11375)#11376/ ADR 0028)notAuthority:trueAcceptance Criteria
(windowStart, windowEnd)and daily / 3-day / weekly / monthly / quarterly / release presets resolve through one path.notAuthority:true.get_conversation({pr_number}); exact comment/review IDs are emitted only when retained by the source, and review citations never pretend the comment-only drill-down resolves review nodes.Out of Scope
Avoided Traps
Related
Parent: #12679
Builds on: #14435 / PR #15096
Strategic parent: #11375
Graduated history source: #11376
Wrong-shape artifacts:
#14603,#14706,#14680, PR#15085Existing drill-down:
get_conversation({pr_number})Live duplicate sweep: latest 20 open issues, targeted open-title searches, Knowledge Base tickets, active+archived local issues/Discussions, and last 30 all-state A2A messages checked at 2026-07-12T09:59:43.552Z; no equivalent ticket or competing in-flight claim found.
#14620is a Fleet UI consumer, and#14435is the separate Memory/session source.Origin Session ID: 837ad74b-c2d2-413d-9aab-b7165a93a82a
Retrieval Hint: "P0 Bird View resolved PR conversation runtime tool Leaf D #12679 #14435 static handoff authority correction"