Post 28 — PR #70 — v0.9.8: Health Pulse + Lifecycle Commands
Date: 2026-06-27
Branch: feat/v0.9.8-health-lifecycle
Version: 0.9.7 → 0.9.8
Where we left off
v0.9.7 added Grok as the fourth first-class agent peer. The CLI could now discover, inject, and dispatch to all four harnesses (Claude, Agy, Codex, Grok). The synlynk doctor command and HealthCheck registry were already in place from an earlier cycle — but the lifecycle was incomplete: once synlynk was running in a repo, there was no clean way to step back out or push updated artifacts forward.
What moved the goalpost
The BS-5 website redesign design phase completed this session, and BS-7 (Skill Pack Interoperability + Benchmarks) is queued for next session. Both require synlynk to be easy to install, evaluate, and remove cleanly — especially for benchmarking where a "before synlynk" vs "after synlynk" comparison requires running the suite with synlynk fully stripped from the repo.
That gap — no clean exit path — was OB-13 through OB-17 from the Onboarding epic. v0.9.8 closes it.
What shipped
synlynk exit (OB-13/14/15)
Reverses onboarding. Steps:
- Reads
.synlynk/instructions.jsonmanifest to find every tracked instruction file - Strips the
<!-- synlynk:start -->…<!-- synlynk:end -->block from each file, preserving surrounding user content - Removes
.agents/profiles and the.synlynk/directory - Optionally removes
project-docs/with--remove-docs - Writes
SYNLYNK_HANDOFF.mdsummarising what was configured, including a ready-to-pastesynlynk initcommand to reinstate
Dry-run by default. Pass --confirm to execute.
synlynk exit # preview what would be removed
synlynk exit --confirm # execute
synlynk exit --confirm --remove-docs # also delete project-docs/
The key implementation decision: strip synlynk sections rather than delete instruction files. A developer's CLAUDE.md typically has both synlynk-managed content and their own. Deleting the file would destroy their custom instructions — so _strip_synlynk_section() removes only the managed block using the existing marker regex, leaving everything else intact.
synlynk repair (OB-13)
Exit + re-init in one command. Reads config before exiting (agents, mode, org, repo, docs-dir), then calls init() with the same parameters. Useful when synlynk state has drifted or .synlynk/ has been manually edited into an inconsistent state.
synlynk repair # preview
synlynk repair --confirm # execute
synlynk sync (OB-16/17)
Propagates updated artifacts to an existing repo without destroying and rebuilding:
- Re-writes the synlynk-managed sections in all tracked instruction files with current templates
- Creates any missing
.agents/<name>.jsonprofiles for slots in config - Updates
.synlynk/instructions.jsonmanifest SHAs
Does NOT touch project-docs/. Safe to run on any repo that's already initialised.
synlynk sync # preview
synlynk sync --confirm # execute
_strip_synlynk_section() helper
Internal function that removes synlynk blocks from instruction files:
htmlmarker style: removes<!-- synlynk:start … -->through<!-- synlynk:end -->hashmarker style: removes# synlynk:startthrough# synlynk:endnonemarker style: deletes the file entirely (synlynk owns 100% of it, e.g..cursorrules)
Returns True if a section was found and removed, False if no markers present (file left unchanged).
Tests
13 new tests covering all three commands and the helper:
test_cmd_exit_dry_run_prints_plan— dry-run output, no files removedtest_cmd_exit_confirm_removes_synlynk_dir— .synlynk/ gone, SYNLYNK_HANDOFF.md writtentest_cmd_exit_strips_instruction_sections— CLAUDE.md markers removed, user content preservedtest_cmd_exit_remove_docs_flag— project-docs/ deleted with--remove-docstest_strip_synlynk_section_html— html markers removed, surrounding content preservedtest_strip_synlynk_section_none_removes_file— full-file ownership deletes the filetest_strip_synlynk_section_no_markers— no-op when no markers presenttest_cmd_repair_dry_run— .synlynk still present after dry runtest_cmd_repair_confirm_reinits— init() called with captured config, .synlynk reappearstest_cmd_sync_dry_run— prints plan, no writestest_cmd_sync_confirm_updates_instruction_files— sections rewritten, manifest updatedtest_cmd_sync_no_manifest— advisory printed, returns 0
Suite: 513 → 524 passing (+11 net, 1 skipped for brainstorm HTML not present on this branch).
Where we are now
Lifecycle is complete: init → join → exit → repair → sync. synlynk can be cleanly installed, evaluated, stripped for benchmarking, and re-installed with one command. This unblocks the BS-7 benchmark session (skill pack interoperability) which requires a clean before/after comparison.
Next: BS-7 brainstorm (2026-06-28/29), then v0.10.0 developer preview (packaging, pipx install, first-run polish, synlynk viz).