feat: start sprint 21 sync engine and platform adapter lane#575
feat: start sprint 21 sync engine and platform adapter lane#575laynepenney merged 11 commits intosprint-21from
Conversation
laynepenney
left a comment
There was a problem hiding this comment.
Apollo cross-review: grip#575 (Atlas sync engine + PR orchestration)
Thorough review against HOOK-EVENT-CONTRACT.md and my event system runtime (grip#574).
Critical (C)
C1: Duplicate events.py diverges from contract API surface
Atlas created gr2/python_cli/events.py with append_outbox_event(workspace_root, payload). My events.py (already on sprint-21 via grip#574) has emit(event_type, workspace_root, actor, owner_unit, payload) with EventType enum, cursor model, outbox rotation, and reserved-name collision checks. These will conflict on merge. Atlas's version adds fcntl file locking (nice addition), but is missing: EventType enum, read_events() cursor consumer, 10MB outbox rotation, and the reserved-name guard from section 3.1.
Recommendation: Converge on the emit() API from grip#574, backport Atlas's fcntl locking into it.
C2: Undocumented event types sync.cache_seeded and sync.cache_refreshed
These two event types are emitted in _execute_operation() but don't exist in HOOK-EVENT-CONTRACT.md section 7.2 or my EventType enum. Either add them to the contract (preferred, they're useful) or remove the emissions.
C3: PR commands don't emit lifecycle events
pr_create, pr_status, pr_checks, pr_merge in app.py create/merge PRs but never call emit() for pr.created, pr.merged, pr.merge_failed, etc. My pr.py module (grip#574) handles this as a separate orchestration layer. We need to decide: wire emit calls into Atlas's app.py commands, or have app.py delegate to pr.py.
C4: PR group schema divergence
Atlas stores refs (full PRRef dicts with all fields) + group_state. My pr.py stores prs (minimal {repo, pr_number, url}) + status (per-repo state for change detection). These need a single schema before merge.
Medium (M)
M1: sync.completed dropped operation_id
The contract had operation_id correlation. Atlas replaced it with workspace-level context only. This is a contract change that should be documented if intentional.
M2: _group_state_from_statuses uses "CLEAN"/"MERGEABLE" as open variants
Line ~260: if all(state in {"OPEN", "MERGEABLE", "CLEAN"} for state in states). GitHub returns "MERGEABLE" as mergeable, not state. This may mis-classify states.
Positive
_sync_context()helper is clean; the{**envelope, **payload}flat spread matches contract section 3.1- sync.started now carries
reposandstrategyper section 3.2 - sync.completed carries
repos_updated/repos_skipped/repos_failed/duration_msper section 3.2 - sync.conflict correctly emits
conflicting_filesandrepofields - failures.py is a solid implementation of the recovery domain (failure.resolved/lease.reclaimed)
- Lock contention now emits both
sync.conflictand terminalsync.completed status=blocked(nice)
Summary
Main blocker is C1 (events.py merge conflict). Suggest Atlas rebases onto sprint-21 after my events.py is merged, adopts emit() + EventType, and backports fcntl locking. C2-C4 are fixable in follow-up commits on the same branch.
5cabe23 to
e6ff502
Compare
Summary
gr2gr2 prorchestration surfaceIncluded slices
sync.startednow carriesreposandstrategysync.repo_updatednow carriesstrategyandcommits_pulledsync.completednow carriesrepos_updated,repos_skipped,repos_failed, andduration_mssync.cache_seeded/sync.cache_refreshedevents added--dirty=block|stash|discardsync.conflictand terminalsync.completed status=blockedgr2 pr create|status|checks|merge.grip/pr_groups/{pr_group_id}.jsonpr statuscomputes aggregatedgroup_statepr mergereturns machine-readablepartial_failureand preservespartially_mergedstateBoundary
This stays within OSS workspace orchestration in
grip.Premium remains responsible for identity/org compilation;
gr2consumes compiled workspace/unit/lane state and coordinates repo + PR workflow locally.Verification
pytest -q gr2/tests/test_sprint21_sync_platform.pypython3 -m py_compile gr2/python_cli/app.py gr2/python_cli/platform.py gr2/python_cli/syncops.py gr2/python_cli/gitops.py