design: hook/event contract + PR lifecycle for gr2#572
design: hook/event contract + PR lifecycle for gr2#572laynepenney merged 4 commits intosprint-20from
Conversation
Covers lease reclaim (TTL-first + optional heartbeat renewal), hook failure markers (forward-only, no rollback), and dirty state handling on lane switch (--dirty=stash|block|discard). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
PR group semantics look directionally right, but I think PR-LIFECYCLE.md should be sharper about where |
laynepenney
left a comment
There was a problem hiding this comment.
One cross-lane mismatch to resolve before we treat this contract as stable: the common event envelope in HOOK-EVENT-CONTRACT.md currently requires a nested payload object plus top-level workspace / actor / owner_unit, while the Sprint 20 sync implementation in grip#573 is emitting flat JSONL rows for sync events (type, seq, event_id, timestamp, then repo-scoped fields like repo, old_sha, new_sha, scope, branch). I'm fine with either shape, but we need one contract. Right now a watcher built to this doc would not be able to consume the sync outbox Atlas shipped without a translation layer. My recommendation: either (a) explicitly state that sync.* events are allowed to use the flat envelope during Python-first gr2 and reserve the nested payload shape for the future normalized emitter, or (b) tighten grip#573 later to emit the exact envelope defined here. As written, the design doc and the shipping prototype diverge on the primary OSS/premium seam.
|
Review comment 2: The lease reclaim ruling is mostly aligned, but the force-break notification path is still underspecified relative to the QA arena. Section 14.2 says spawn can route That leaves Sentinel's I would either add an explicit notification event/status ( |
|
Review comment 1: Section 14 introduces Why this matters for the arena: the compound I would tighten this by making section 3.2 / 7.2 the single source of truth and adding the missing recovery/terminal failure events there, not just in section 14 prose. |
1. Align sync event envelope: sync.completed is the single terminal event with status field (success/partial_failure/blocked/failed), matching Atlas's syncops.py pattern. No separate sync.failed type. 2. Scope pr_group_id to orchestration layer: PlatformAdapter is group-unaware. pr.py assigns group IDs and correlates per-repo PRs. 3. Add recovery events to taxonomy: failure.resolved and lease.reclaimed added to section 3.2 and EventType enum. 4. Clarify force-break notification routing: lease.force_broken, failure.resolved, and lease.reclaimed added to channel bridge mapping. Notification routing is a consumer responsibility, not a core gr2 event concern.
C1: Fix event_id length -- examples now use 16-char hex matching
os.urandom(8).hex() spec. Was 12-char in all examples.
C2: Add lane_name to failure.resolved payload in section 14.1 to
match taxonomy table and channel bridge template.
C3: Insert lease.reclaimed emission (step 8) in section 14.2
reclaim flow. Was defined as event type but never emitted.
M1: Standardize on emit() everywhere. Sections 4.2 and 10.1 said
emit_event(); section 7 API said emit(). Now consistent.
M2: Fix get_pr_status -> get_pr in PR-LIFECYCLE.md flow to match
the PlatformAdapter protocol definition.
M3: Add filter-vs-mapping note to section 8. Globs like lane.*
match types not in the mapping table; those are silently dropped.
Summary
Sprint 20 design deliverables for Apollo's lane (PR lifecycle + hook/event contract):
HOOK-EVENT-CONTRACT.md: Full event contract for gr2. 26 event types across 5 domains (lane, lease, hook, PR, sync). Append-only JSONL outbox, cursor-based consumers (channel bridge, recall indexer, spawn watcher). Section 14: failure recovery contract covering lease reclaim (TTL-first), hook failure markers (forward-only, no rollback), and dirty state handling (
--dirty=stash|block|discard).PR-LIFECYCLE.md: PR group as first-class entity with
pr_group_idcross-repo correlation.gr2 pr create/status/merge/checks/listcommands. PlatformAdapter integration (Atlas's protocol). Explicit merge ordering. 10 QA adversarial scenarios (folded into Sentinel's arena).Design decisions (all Opus-approved)
lease renewfor extension.grip/state/failures/--dirty=stash|block|discardshared flagPremium boundary: core OSS (event infrastructure, hook execution contract, PR orchestration primitives). spawn_watcher consumer is premium.
Test plan
--dirtyflag contract is adopted consistently across lane and sync commands🤖 Generated with Claude Code