Context
Live Lane Awareness (Epic #15100, graduated from Discussion #15090) composes four truth surfaces. Three now exist: the typed ComputedRouteResult route (#15087, merged), and the two historical Bird Views (#14435, #15088). The current-state landscape is in review (#15234 / PR #15264). The lifecycle frontier — ADR 0035 §2.3, the surface answering "what already requires MY response right now" — remains unbuilt, and it is the last producer the composition needs.
Its prerequisites are closed: #15106 (persist the winning assignee for broadcast A2A Tasks) and #15114 (durable GraphLog event identity for Task transitions). Without #15106 a lifecycle producer would have canonized a false owner; that gate is now clear.
The Problem
There is no source-backed answer to "what needs my action now?" — so every peer reconstructs it by hand, every session.
The empirical anchor is first-hand and specific: across ~50 stop-hook fires in one session, @neo-opus-vega recorded that the highest-value next actions were never cold backlog — they were lifecycle events (a gate-clear un-blocking a lane, fresh review-requests, a stale-assigned ticket, a peer correction clearing). Every fire required a manual survey of own-PR gate-state + the review queue + assigned tickets to find the real lane — precisely the work a lifecycle frontier exists to do. The Computed Golden Path answers "which direction serves the goal" (and is now typed, per #15087); it deliberately does not answer "what is already waiting on me". Those are different authorities (ADR 0035 §1.1) and conflating them was explicitly rejected.
This is upstream of presentation: the hook, the Fleet surface, and interactive peers are all consumers. Today they have nothing to consume.
The Architectural Reality
ADR 0035 §2.3 already specifies this leaf completely — this ticket implements a decided contract, it does not reopen one.
- Envelope:
lifecycle-frontier.v1 — {schemaVersion, scope: {agentId, harnessInstance}, status, capturedAt, sourceWatermark, expiresAt, coverage: {sources, degradedSources}, items[], notAuthority: true}.
- Ordering: stage first, then
actionableSince oldest-first, then stable source id.
- The five stages + their admission predicates (ADR §2.3 table): own-PR repair · own-PR reviewer routing · requested review · claimed A2A task · direct message. Each carries an exact
actionableSince clock and reset/removal rule; every PR-derived row resets on head change.
- Exclusions are as load-bearing as admissions (§2.3): pending/running CI without a failed required check; ordinary issue assignment without a claimed actionable Task envelope; an approved PR awaiting the human merge gate; draft PRs; unclaimed broadcasts; missing/inferred/conflicted/foreign identity; optional-check failure unless the repo marks it required.
- A "current-head closing review" is exactly an
APPROVED/CHANGES_REQUESTED decision whose reviewed commit is the current head; a review on an older head cannot close the current head.
- Sources are owned elsewhere and injected (§2.1): GitHub Workflow owns PR/review/check facts; Memory Core A2A owns claimed-task/direct-message facts (
MailboxService, and the Task assignee #15106 persisted). This producer normalizes; it never re-derives a source's truth and never converts lifecycle facts into Golden Path score inputs.
- Structural pre-flight: sibling-lift — the pure producer lands beside the shipped landscape/route modules in
ai/services/graph/ (precedent: laneLandscapeProjection.mjs, computedRouteResult.mjs, both pure + dependency-injected). No novel directory. Owning-folder cited per the Agent OS structure map.
The Fix
- A pure
lifecycle-frontier.v1 contract + producer: injected source reads → normalized items[] → one frozen notAuthority envelope. Fail-loud on contract violation (a malformed frontier is a producer bug); fail-closed to degraded with coverage.degradedSources when a source read fails — a partial frontier must never present as complete.
- Implement the five stages' admission predicates and their exclusions exactly per §2.3, including per-source
actionableSince clocks and the head-change reset.
- Enforce never-foreign lifecycle: a missing/inferred/conflicted identity omits the overlay with an explicit reason. Leakage of another peer's obligations is worse than absence (§2.4).
- Bind the impure edges (GitHub Workflow + Memory Core A2A reads) at the registration boundary — the producer itself stays hermetic and testable.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
New lifecycle-frontier.v1 envelope |
ADR 0035 §2.3 |
One agent-scoped, source-backed frontier: stage-ordered items[] + honest status/coverage |
Source failure → degraded + degradedSources; never partial-as-complete |
Module JSDoc |
Full admission/exclusion matrix specs |
| New lifecycle-frontier producer |
ADR 0035 §2.1 (lifecycle normalization owner) |
Normalizes injected source facts; never re-derives source truth, never feeds GP scoring |
Missing/conflicted identity → overlay omitted with reason |
Module JSDoc |
never-foreign-identity + no-GP-contamination specs |
| Existing GitHub Workflow PR/review/check reads |
ai/services/github-workflow/* |
Injected as source facts (PR state, head SHA, review decisions, required checks) |
Unavailable source degrades only its own coverage row |
Producer JSDoc |
per-source degradation spec |
| Existing Memory Core A2A reads |
MailboxService + the Task assignee persisted by #15106 |
Injected as claimed-task / direct-message facts |
Unclaimed broadcast is excluded by contract, not by heuristic |
Producer JSDoc |
claimed-vs-broadcast + owner-exactness specs |
Decision Record impact
aligned-with ADR 0035 §2.3 (the lifecycle-frontier contract) and §2.1 (lifecycle normalization ownership). No ADR amendment — this leaf implements the decided contract.
Decision Record
Required authority: ADR 0035 (graduated from Discussion #15090, Cycle-7). This leaf instantiates the lifecycle-frontier producer ADR §2.3 specifies.
Discussion Criteria Mapping
| Upstream criterion (D#15090 / ADR 0035) |
This ticket |
| Lifecycle facts stay a separate source-backed frontier, never GP-scored (§1.1, §2.3) |
AC: no lifecycle fact becomes a Golden Path score input |
| Exact admission/exclusion semantics; failed-vs-pending CI distinction (§2.3) |
AC: the full matrix + exclusions, spec-pinned |
actionableSince per-source clocks; head-change resets (§2.3) |
AC: reset-on-head-change + re-entry starts a new clock |
| Never-foreign lifecycle; leakage worse than absence (§2.4) |
AC: missing/conflicted identity omits the overlay with a reason |
| Honest empty/degraded, never normalized (§2.3) |
AC: degraded coverage names its degradedSources |
Acceptance Criteria
Out of Scope
- The projection writer / transport (ADR §2.6, the fenced Memory-Core lease) — a sibling #15100 leaf; this ticket produces the frontier, it does not publish it.
- Any hook rendering or reader cutover (§2.11 Phases 3–4) — hooks are pure bounded renderers of a published projection, not of this producer.
- Ranking, scoring, or lane selection — the Computed Golden Path's authority (#15087, merged). The frontier lists what awaits a response; it never orders lanes by importance.
- Fleet awareness reads (§2.9) —
fleet-awareness-read is a separate capability and is not Wave 1.
Avoided Traps
- Flattening lifecycle into the route: explicitly rejected by the D#15090 convergence — lifecycle actions are presented ahead of cold backlog but are NOT route authority. Conflating them recreates the second-scorer failure.
- Inferring identity: session ids correlate; they do not authorize. A confidently-wrong map leaks another peer's obligations — absence is the safe result (§2.4).
- Treating pending CI as actionable: the failed-vs-pending distinction is deliberate; "CI is running" is not a call to act, and blurring it manufactures busywork rows.
- Fabricating a non-empty frontier: the same pressure that produced the fixture-row failure on the route side. An empty frontier is an honest answer.
Related
Parent: #15100 (dependency edge; ADR 0035 §2.3 slot)
Prerequisites (both closed): #15106 (Task assignee persistence) · #15114 (Task GraphLog event identity)
Route sibling: #15087 / PR #15231 (merged) — the typed route; ranking authority lives there, not here
Current-state sibling: #15234 / PR #15264 (in review)
Transport sibling (out of scope here): ADR 0035 §2.6 projection writer — unfiled
Authority: ADR 0035 §2.1 / §2.3 / §2.4 · Discussion #15090 (Cycle-7)
First-hand anchor: @neo-opus-vega's ~50-fire manual-survey record on #15087
Live latest-open sweep: checked the latest 20 open issues + an ai:structure-map owning-folder check + a 30-message all-state A2A claim sweep at 2026-07-16T14:49Z; no equivalent ticket and no competing in-flight claim found (the lifecycle-frontier producer and the §2.6 projection writer are both unfiled).
Origin Session ID: f78647f0-583a-4054-95fb-1fae5d0f2551
Retrieval Hint: "lifecycle frontier producer response-required ADR 0035 §2.3 admission matrix actionableSince head-change reset never-foreign identity"
Retrieval Hint: "#15100 leaf lifecycle frontier sibling of computedRouteResult and laneLandscapeProjection"
Context
Live Lane Awareness (Epic #15100, graduated from Discussion #15090) composes four truth surfaces. Three now exist: the typed
ComputedRouteResultroute (#15087, merged), and the two historical Bird Views (#14435, #15088). The current-state landscape is in review (#15234 / PR #15264). The lifecycle frontier — ADR 0035 §2.3, the surface answering "what already requires MY response right now" — remains unbuilt, and it is the last producer the composition needs.Its prerequisites are closed: #15106 (persist the winning assignee for broadcast A2A Tasks) and #15114 (durable GraphLog event identity for Task transitions). Without #15106 a lifecycle producer would have canonized a false owner; that gate is now clear.
The Problem
There is no source-backed answer to "what needs my action now?" — so every peer reconstructs it by hand, every session.
The empirical anchor is first-hand and specific: across ~50 stop-hook fires in one session, @neo-opus-vega recorded that the highest-value next actions were never cold backlog — they were lifecycle events (a gate-clear un-blocking a lane, fresh review-requests, a stale-assigned ticket, a peer correction clearing). Every fire required a manual survey of own-PR gate-state + the review queue + assigned tickets to find the real lane — precisely the work a lifecycle frontier exists to do. The Computed Golden Path answers "which direction serves the goal" (and is now typed, per #15087); it deliberately does not answer "what is already waiting on me". Those are different authorities (ADR 0035 §1.1) and conflating them was explicitly rejected.
This is upstream of presentation: the hook, the Fleet surface, and interactive peers are all consumers. Today they have nothing to consume.
The Architectural Reality
ADR 0035 §2.3 already specifies this leaf completely — this ticket implements a decided contract, it does not reopen one.
lifecycle-frontier.v1—{schemaVersion, scope: {agentId, harnessInstance}, status, capturedAt, sourceWatermark, expiresAt, coverage: {sources, degradedSources}, items[], notAuthority: true}.actionableSinceoldest-first, then stable source id.actionableSinceclock and reset/removal rule; every PR-derived row resets on head change.APPROVED/CHANGES_REQUESTEDdecision whose reviewed commit is the current head; a review on an older head cannot close the current head.MailboxService, and the Task assignee #15106 persisted). This producer normalizes; it never re-derives a source's truth and never converts lifecycle facts into Golden Path score inputs.ai/services/graph/(precedent:laneLandscapeProjection.mjs,computedRouteResult.mjs, both pure + dependency-injected). No novel directory. Owning-folder cited per the Agent OS structure map.The Fix
lifecycle-frontier.v1contract + producer: injected source reads → normalizeditems[]→ one frozennotAuthorityenvelope. Fail-loud on contract violation (a malformed frontier is a producer bug); fail-closed todegradedwithcoverage.degradedSourceswhen a source read fails — a partial frontier must never present as complete.actionableSinceclocks and the head-change reset.Contract Ledger Matrix
lifecycle-frontier.v1envelopeitems[]+ honeststatus/coveragedegraded+degradedSources; never partial-as-completeai/services/github-workflow/*MailboxService+ the Task assignee persisted by #15106Decision Record impact
aligned-with ADR 0035 §2.3(the lifecycle-frontier contract) and§2.1(lifecycle normalization ownership). No ADR amendment — this leaf implements the decided contract.Decision Record
Required authority: ADR 0035 (graduated from Discussion #15090, Cycle-7). This leaf instantiates the lifecycle-frontier producer ADR §2.3 specifies.
Discussion Criteria Mapping
actionableSinceper-source clocks; head-change resets (§2.3)degradedSourcesAcceptance Criteria
lifecycle-frontier.v1for ONE explicitly attested agent: stage-ordered items, thenactionableSinceoldest-first, then stable source id.actionableSincefollows each stage's source clock; every PR-derived row resets on head change; clearing then re-entering a predicate starts a new clock.APPROVED/CHANGES_REQUESTEDon the current head; an older-head review does not close it.degradedSources); the frontier never presents partial-as-complete and never throws out of the pass.Out of Scope
fleet-awareness-readis a separate capability and is not Wave 1.Avoided Traps
Related
Parent: #15100 (dependency edge; ADR 0035 §2.3 slot) Prerequisites (both closed): #15106 (Task assignee persistence) · #15114 (Task GraphLog event identity) Route sibling: #15087 / PR #15231 (merged) — the typed route; ranking authority lives there, not here Current-state sibling: #15234 / PR #15264 (in review) Transport sibling (out of scope here): ADR 0035 §2.6 projection writer — unfiled Authority: ADR 0035 §2.1 / §2.3 / §2.4 · Discussion #15090 (Cycle-7) First-hand anchor: @neo-opus-vega's ~50-fire manual-survey record on #15087
Live latest-open sweep: checked the latest 20 open issues + an
ai:structure-mapowning-folder check + a 30-message all-state A2A claim sweep at 2026-07-16T14:49Z; no equivalent ticket and no competing in-flight claim found (the lifecycle-frontier producer and the §2.6 projection writer are both unfiled).Origin Session ID: f78647f0-583a-4054-95fb-1fae5d0f2551
Retrieval Hint: "lifecycle frontier producer response-required ADR 0035 §2.3 admission matrix actionableSince head-change reset never-foreign identity" Retrieval Hint: "#15100 leaf lifecycle frontier sibling of computedRouteResult and laneLandscapeProjection"