Skip to content

feat: start sprint 21 sync engine and platform adapter lane#575

Merged
laynepenney merged 11 commits intosprint-21from
atlas/sprint-21-sync-engine
Apr 15, 2026
Merged

feat: start sprint 21 sync engine and platform adapter lane#575
laynepenney merged 11 commits intosprint-21from
atlas/sprint-21-sync-engine

Conversation

@laynepenney
Copy link
Copy Markdown
Collaborator

Summary

  • start Sprint 21 Sync Engine + PlatformAdapter lane on Python gr2
  • add TDD coverage for sync cache events, sync lock/dirty modes, and PR group lifecycle
  • implement first sync payload convergence and initial gr2 pr orchestration surface

Included slices

  • sync outbox payload convergence
    • sync.started now carries repos and strategy
    • sync.repo_updated now carries strategy and commits_pulled
    • sync.completed now carries repos_updated, repos_skipped, repos_failed, and duration_ms
    • sync.cache_seeded / sync.cache_refreshed events added
  • sync lock + dirty mode behavior
    • end-to-end tests for --dirty=block|stash|discard
    • lock contention now emits both sync.conflict and terminal sync.completed status=blocked
  • PlatformAdapter-backed PR orchestration
    • gr2 pr create|status|checks|merge
    • grouped PR state persisted under .grip/pr_groups/{pr_group_id}.json
    • pr status computes aggregated group_state
    • pr merge returns machine-readable partial_failure and preserves partially_merged state

Boundary

This stays within OSS workspace orchestration in grip.
Premium remains responsible for identity/org compilation; gr2 consumes compiled workspace/unit/lane state and coordinates repo + PR workflow locally.

Verification

  • pytest -q gr2/tests/test_sprint21_sync_platform.py
  • python3 -m py_compile gr2/python_cli/app.py gr2/python_cli/platform.py gr2/python_cli/syncops.py gr2/python_cli/gitops.py

Copy link
Copy Markdown
Collaborator Author

@laynepenney laynepenney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 repos and strategy per section 3.2
  • sync.completed carries repos_updated/repos_skipped/repos_failed/duration_ms per section 3.2
  • sync.conflict correctly emits conflicting_files and repo fields
  • failures.py is a solid implementation of the recovery domain (failure.resolved/lease.reclaimed)
  • Lock contention now emits both sync.conflict and terminal sync.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.

@laynepenney laynepenney force-pushed the atlas/sprint-21-sync-engine branch from 5cabe23 to e6ff502 Compare April 15, 2026 18:12
@laynepenney laynepenney merged commit e5e305b into sprint-21 Apr 15, 2026
1 check passed
@laynepenney laynepenney deleted the atlas/sprint-21-sync-engine branch April 15, 2026 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant