Skip to content

fix: ghost-commit recovery protocol and hardening sweep#16

Merged
Maelwalser merged 4 commits into
mainfrom
dev
Apr 24, 2026
Merged

fix: ghost-commit recovery protocol and hardening sweep#16
Maelwalser merged 4 commits into
mainfrom
dev

Conversation

@Maelwalser
Copy link
Copy Markdown
Owner

Summary

Two groups of changes:

1. Ghost-commit crash recovery (3ed9c8d) — closes the window where the materializer could crash after the trunk commit but before writing ChangesetMaterialized, leaving trunk ahead of the event log.

  • New EventKind::ChangesetMaterializationStarted { parent, path } fence event, written before any git write (crates/phantom-core/src/event.rs).
  • New phantom-orchestrator/src/recovery.rs reconciles orphan fences against HEAD's first-parent chain (bounded to 128 commits) using parent-OID + author matching. Idempotent by construction.
  • ph recover CLI (crates/phantom-cli/src/commands/recover.rs), surfaced in ph status, filterable in ph log.
  • Integration tests pin fence ordering and fault survival (tests/integration/tests/fence_emitted_in_order.rs, fence_survives_materialized_fault.rs).

2. Hardening sweep (4d95fd2) — correctness and security improvements, no new features:

  • Schema migrations: DDL + schema_version bump now run in one Transaction<Sqlite> so a crash between steps can't corrupt recorded version.
  • SQL LIKE metacharacters (%, _, \) now escaped in apply_event_filters; QueryBuilder fields made private; typed SortDir enum replaces raw strings.
  • mark_dropped UPDATE + snapshot DELETE now in one transaction.
  • Timestamps pinned to to_rfc3339_opts(Millis, true) for stable lexicographic sort.
  • OverlayLayer whiteout persistence errors now propagate — prevents silent data loss where a stale whiteout would hide a re-created file on restart.
  • phantom-git::fs_walk: added MAX_DEPTH = 64 and (dev, ino) symlink cycle tracking.
  • phantom-git::test_support now gated behind a test-helpers feature, kept out of the release binary.
  • ChangesetId / AgentId / PlanId validate on deserialize via #[serde(try_from = "String")]; restricted to ASCII alphanumerics + hyphen + underscore (anti-homograph).
  • Materializer event append: latest_event_for_changeset errors now propagate instead of silently using None causal parent, preserving the causal DAG used by rollback.
  • overflow-checks = true added to release profile.
  • release.yml: default contents: read; only publish job gets contents: write.
  • .github/dependabot.yml added (weekly cargo + github-actions updates, semver-major cargo updates excluded).
  • Many poisoned-RwLock recoveries use unwrap_or_else(PoisonError::into_inner).
  • New EventStoreError::SchemaCorrupted { key, value } replaces misleading SchemaMismatch on schema_meta parse failures.

3. Merge + cleanup (4b83ceb, 0797e2b) — merged main (picks up rand 0.8.6 Dependabot bump), applied cargo fmt, and corrected a stale docstring in validate_path_safe_id that claimed . was allowed (it isn't).

Test plan

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --workspace --all-features — 52 test binaries, 0 failures
  • RUSTDOCFLAGS="-Dwarnings" cargo doc --workspace --no-deps --all-features
  • cargo audit — no known vulnerabilities
  • cargo deny check — advisories / bans / licenses / sources all ok
  • CI passes on GitHub Actions

Compat notes

ChangesetId / AgentId / PlanId now reject non-ASCII characters on deserialize. All current internal generators (UUID v7, plan-YYYYMMDD-HHMMSS) fall inside the allowed set; any pre-existing .phantom/events.db with non-ASCII IDs would need regeneration. No impact expected in practice.

Fix formatting violations flagged by `cargo fmt --check` in five files touched
by the ghost-commit and hardening commits, and correct the
`validate_path_safe_id` doc comment which claimed the predicate accepts `.`
for UUID/timestamp IDs — it does not.
@Maelwalser Maelwalser merged commit be3dd04 into main Apr 24, 2026
8 checks passed
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