refactor(sync): put every Skill Sync verb under hermes sync; drop HSP naming

Encapsulates the feature behind one command for launch, and adopts the
official product name.

One command:
- `propose` moves from `hermes skills propose` to `hermes sync propose`, so
  the whole feature is one command to learn and one to document. Its handler
  moves from cmd_skills to cmd_sync accordingly.
- The `hermes sync` parser now documents both halves plainly: personal sync
  across your devices, and sharing with your organisation. Added an examples
  epilog; rewrote the verb help in user language ("Include a skill in your
  sync" rather than "Opt a skill into sync").
- Every user-facing string that pointed at `hermes skills propose` now points
  at `hermes sync propose` (8 sites, including the agent-visible guidance
  returned by skill_manage and the org provenance header).

This also clears the way for #39343, which adds its own top-level `sync` for
git-repo profile backup — that feature nests under `skills`, this one owns
`sync`.

Naming:
- HSP / "Hermes Sync Protocol" is gone from prose, docstrings, and comments.
  The feature is "Skill Sync".
- Public identifiers renamed: HSPClient -> SyncClient, HSPError -> SyncError,
  HSPConflict -> SyncConflict, hsp_address -> wire_address, HSP_VERSION ->
  WIRE_VERSION.
- The WIRE names are deliberately NOT renamed: the `hsp_version` capability
  field and the `x-hsp-object-type` response header are set by the deployed
  gateway-gateway sync plane (verified in src/sync/syncRouter.ts), so
  renaming them client-side would break sync against a live server. A comment
  at the version constant records why they differ from the product name.
- The version-mismatch error is now actionable ("this server speaks sync
  version X, but this Hermes speaks Y — update Hermes to sync with it")
  instead of leaking the protocol acronym.

Also fixes a wiring gap found on the way: the gateway housekeeping tick
pulled personal skills but never org skills — the same defect already fixed
for the CLI. Org pull now runs there too, gated on real org membership.

Tests: the jargon guard now also fails on a bare "HSP". The two tests that
asserted the old cross-command structure are replaced by three asserting the
new one (propose IS under sync, propose is NOT under skills, sync usage
lists it). 2294 passed / 0 failed across all 51 suites that import the
changed modules, via scripts/run_tests.sh.

Verified by running the real CLI: `hermes sync --help` lists all eight verbs,
`hermes skills --help` no longer mentions propose, `hermes sync propose
--help` parses, and `hermes sync status` still reports live org state.
This commit is contained in:
Ben Barclay 2026-07-29 07:47:06 +10:00
parent 981feb6730
commit 4f990ec09e
10 changed files with 240 additions and 230 deletions

View file

@ -680,7 +680,7 @@ def set_pinned(skill_name: str, pinned: bool) -> None:
def set_sync(skill_name: str, sync: bool) -> None:
"""Set the HSP-sync opt-in flag on a skill's usage record (M1-D).
"""Set the sync opt-in flag on a skill's usage record.
Sync is OPT-IN: nothing propagates to the sync plane unless the user marks
a skill with ``sync: true`` here. Sits alongside ``pinned``/``created_by``
@ -695,7 +695,7 @@ def set_sync(skill_name: str, sync: bool) -> None:
def is_sync_enabled(skill_name: str) -> bool:
"""Whether a skill is opted into HSP sync (``sync: true`` in its record)."""
"""Whether a skill is opted into sync (``sync: true`` in its record)."""
return get_record(skill_name).get("sync") is True