LearnNewsExamplesServices
Frontmatter
id15267
titleProduce the lifecycle frontier — the response-required fact source
stateClosed
labels
enhancementaiarchitecturemodel-experience
assigneesneo-opus-ada
createdAtJul 16, 2026, 4:56 PM
updatedAt6:35 AM
githubUrlhttps://github.com/neomjs/neo/issues/15267
authorneo-opus-ada
commentsCount0
parentIssue15100
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[x] 15296 Publish hook projections through the fenced single-writer lease
closedAt6:35 AM

Produce the lifecycle frontier — the response-required fact source

Closed Backlog/active-chunk-6 enhancementaiarchitecturemodel-experience
neo-opus-ada
neo-opus-ada commented on Jul 16, 2026, 4:56 PM

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

  1. 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.
  2. Implement the five stages' admission predicates and their exclusions exactly per §2.3, including per-source actionableSince clocks and the head-change reset.
  3. 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).
  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

  • A pure producer emits lifecycle-frontier.v1 for ONE explicitly attested agent: stage-ordered items, then actionableSince oldest-first, then stable source id.
  • All five stages implemented with the ADR §2.3 admission predicates; every listed exclusion is pinned by spec (notably: pending/running CI without a failed required check is NOT actionable; an approved PR awaiting the human merge gate is NOT actionable; draft PRs and unclaimed broadcasts are excluded).
  • actionableSince follows each stage's source clock; every PR-derived row resets on head change; clearing then re-entering a predicate starts a new clock.
  • A current-head closing review is exactly an APPROVED/CHANGES_REQUESTED on the current head; an older-head review does not close it.
  • Never-foreign lifecycle: missing/inferred/conflicted/recipient-mismatched identity omits the overlay with an explicit unavailable/conflicted reason — never another peer's rows.
  • No lifecycle fact is converted into a Golden Path score input (static or runtime proof).
  • A source read failure degrades only its own coverage row (degradedSources); the frontier never presents partial-as-complete and never throws out of the pass.
  • Focused hermetic tests cover the full admission/exclusion matrix, head-change clocks, required-vs-optional checks, current-head review semantics, claimed-task ownership, direct-vs-broadcast, and never-foreign identity.
  • Cross-family review challenges the admission matrix + the exclusion completeness before merge.

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"