Skip to content

feat(scripts): hermes_parity — parity-sync CLI (status/start/gates/bisect/ack/finish/clean) - #265

Merged
Kyzcreig merged 3 commits into
mainfrom
feat/hermes-parity
Jul 10, 2026
Merged

Kyzcreig merged 3 commits into
mainfrom
feat/hermes-parity

Conversation

@Kyzcreig

Copy link
Copy Markdown
Collaborator

hermes_parity — parity-sync CLI

What

Stdlib-only internal CLI (scripts/hermes_parity/, python -m hermes_parity) that automates the upstream/fork parity-sync workflow: isolated worktree setup, conflict bucketing, a 6-stage verification gate ladder, merge-vs-baseline test classification, fork-feature survival enforcement, and PR handoff.

Distilled from the real 2026-07-10 sync (PR #255: 56 conflict files, 147 hunks, ~45 CI-surfaced reconciliation bugs across 4 CI rounds). Goal: next sync goes from a full day to ~1 hour of genuine decisions.

Command surface

command purpose
status [--fail-behind N] ahead/behind vs upstream, merge-base, conflict summary
start worktree + frozen target SHA + staged merge + conflict-bucket report + atomic state file
gates [--stage] [--fast] [--resume] [--strict] 6-stage ladder: markers → imports → unbound-name AST lint → manifest+forkdelta → full test suite → linux-only listing. Per-stage repro commands, gates.jsonl, tree-SHA invalidation
bisect classify failing tests vs cached fork baseline: MERGE REGRESSION / INHERITED / UPSTREAM TEST / ORDER-POLLUTION / FLAKY
ack --reason <why> <paths> first-class reviewed-and-intentional clearance for fork-delta hard-fails (so --force never becomes routine)
finish all-green check, 2-parent merge commit, push, generated PR body + gh pr create command
clean remove worktrees, echo rollback

Key mechanisms

  • Fork-feature manifest docs/sync/fork-features.json — the "must survive any merge" registry ({feature, tests, paths, why}); stage 4 runs exactly those tests. Seeded with 5 features from the 2026-07-10 postmortem.
  • Fork-delta cross-reference — fork-only files the merge deletes/renames (upstream DU/UD case) with no manifest coverage = hard fail. Honest scope: the delete/rename subset; upstream modifications are caught by manifest tests.
  • State .parity-state.json — atomic writes, tree-SHA gate invalidation, rollback SHAs, acks.
  • Landing rules printed by finish: --merge never squash; if BEHIND, merge fork/main in, never rebase.

Review provenance

  • 4-model mixture-of-agents PRD review → SPEC v2
  • Momus pass-1: BLOCK (4 header/body seams) → v2.1 body reconciliation
  • Momus pass-2: APPROVE-WITH-CHANGES, RC1–RC5 → v2.2 (folded into spec + code)
  • Built by Codex worker (2 rounds), certified by Apollo: 16 unit tests, live smoke against the real repo (real 3-conflict worktree vs upstream b9b463f3; markers gate exit 1; ack persisted; clean removed)

Spec: docs/sync/2026-07-10-hermes-parity-SPEC.md · Operator guide: docs/sync/README-hermes-parity.md

…sect/ack/finish/clean)

Automates the upstream/fork parity-sync workflow distilled from the
2026-07-10 sync (PR #255: 56 conflict files, 147 hunks, ~45 CI-surfaced
reconciliation bugs). Stdlib-only package at scripts/hermes_parity/,
run as 'python -m hermes_parity' via root shim.

Surface:
- status [--fail-behind N]: ahead/behind, merge-base, conflict summary
- start: isolated worktree + frozen target + staged merge + conflict-bucket
  report (docs/sync/review/conflict-buckets.md) + atomic state file
- gates [--stage|--fast|--resume|--strict]: 6-stage ladder (markers,
  imports, unbound-name AST lint, manifest+forkdelta, full tests,
  linux-only listing) with per-stage repro commands, gates.jsonl,
  tree-SHA invalidation, CI-owned reminder checklist (pinned-gitleaks
  version parse incl. fleet VER= form, hard-warns on parse failure)
- bisect: merge-vs-baseline classification (REGRESSION/INHERITED/
  UPSTREAM TEST/ORDER-POLLUTION/FLAKY), cached baseline worktree with
  SHA-mismatch re-pin, bounded parallelism, --from-file -, flake re-run
- ack --reason: first-class reviewed-and-intentional clearance for
  fork-delta hard-fails (distinct from finish --force)
- finish: all-green verification, 2-parent merge commit, push, generated
  PR body + gh command; --force requires --force-reason
- clean: worktree removal with rollback echo

Design reviewed: 4-model mixture-of-agents panel (v2), Momus pass-1
BLOCK (4 header/body seams, reconciled in v2.1), Momus pass-2
APPROVE-WITH-CHANGES (RC1-RC5, folded in v2.2 spec + this code):
fork-delta trigger pinned to the merge-touched delete/rename subset
with honest coverage split; ack path; gates signature reconciled;
baseline cache invalidation; module name pinned hermes_parity.

Manifest seeded with 5 fork features from the 2026-07-10 postmortem
(docs/sync/fork-features.json).

Verified: 16 unit tests green; live smoke against the real repo
(start created a real 3-conflict worktree vs upstream b9b463f, buckets
correct, markers gate exit 1 on real conflicts, ack persisted, clean
removed worktree); py_compile clean; all subcommand --help OK.
@Kyzcreig
Kyzcreig enabled auto-merge July 10, 2026 16:37
@Kyzcreig
Kyzcreig merged commit 7facfd3 into main Jul 10, 2026
34 checks passed
@Kyzcreig
Kyzcreig deleted the feat/hermes-parity branch July 10, 2026 17:06
Kyzcreig added a commit that referenced this pull request Jul 26, 2026
…00 summary-role pin) (#431)

* vendor(lcm): cherry-pick 9 upstream fixes from hermes-lcm (03b74f8 -> selected from 49e99a2)

Upstream hermes-lcm went MIT (LICENSE added 2026-06-26, f7ae61f) — vendoring
and cherry-picking now permitted with attribution. Tier-1 picks per
/tmp/lcm-refresh-out/CHERRY-PICK-LIST.md, code-only (their tests/docs/changelog
excluded; our vendored copy carries no tests dir — coverage rides
tests/context_engine/):

  #263 preserve source lineage after long sessions
  #264 perf: aggregate DAG status stats
  #265 harden externalized payload durability
  #269 preserve raw session ownership across compression rollover
  #278 avoid payload integrity false positives from log examples
  #280 pin summary role to user after system anchor (Anthropic HTTP 400) <- highest value
  #285 make context engine deepcopy clone-safe (subagent spawn safety)
  #282 strip injected context before compaction
  (+) discard reasoning-only summaries (unclosed <think> = quality bug + prompt leak)

All 9 verified clean-apply by the refresh-analysis worker on a simulated copy
of our tree; re-applied here onto fork/main.

* test(compaction): regenerate in-turn reconcile fixture for the vendored sanitizer

The 9 LCM cherry-picks (3c1d61c) add one line to
_sanitize_active_context_messages (upstream pick #282, strip injected
context before compaction), which moves the fixture's
sanitizer_source_sha1 provenance hash and reds
test_fixture_sanitizer_provenance_current.

Regenerated via the committed generator:
  python tests/agent/fixtures/gen_inturn_reconcile_fixture.py

Diff is the provenance hash ONLY -- messages, compressed,
true_kept_count and fresh_tail_count are byte-identical. The new line
routes through _preserved_objective_context_content, which returns ""
unless a row starts with the preserved-objective prefix, so it is a
strict no-op on all 632 fixture rows (verified: 0 rows mutated) and the
real sanitizer output is unchanged. Only one of the four hashed
functions changed; the other three are byte-identical.

Follow-up candidate (not this PR): this provenance test is a
change-detector, which AGENTS.md discourages -- it should assert the
sanitizer's behaviour (live sanitize(raw_tail) == committed comp tail)
rather than pinning its source SHA.

---------

Co-authored-by: Kyzcreig <9063726+Kyzcreig@users.noreply.github.com>
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