synlynk Changelog
Stay up to date with new features, improvements, and fixes to the multi-agent coordination kernel.
All notable changes to synlynk are documented here.
Format follows Keep a Changelog. Versioning follows Semantic Versioning.
Unreleased
Added
synlynk agent add <name>to retroactively onboard a newly available CLI agent on$PATH, generating its directive file, writing its role fence, wiringworkgroup_agents/agent_slots/roles, and seeding a capability baseline. Fixes #277.- Lazy daily housekeeping on the first
synlynk execof a new calendar day, detecting new PATH agents, re-probing onboarded agents for drift, repairing directive fences, and recordinglast_housekeeping_date. Fixes #277.
Fixed
synlynk migratefalse-positiveMigrationImportErroron idempotent re-runs (#276): the loud-fail check treatedINSERT OR IGNOREwithrowcount == 0as a hard failure whenever a non-empty source landed zero new rows. On a project that had already been migrated, natural-key collisions (especiallyroadmap_arcs.versionUNIQUE) correctly no-op the insert, so re-import /--recoverraisedMigrationImportError: 0 rows inserted … roadmap_arcs (N parsed/attempted, 0 inserted)even when every expected row was already present._migrate_import()now checks natural keys before insert (memory_entries.section,roadmap_arcs.version,roadmap_phases(arc_version, phase_title), cost fingerprint,devlogauthor+date+title,todogh_issuealready set) and only fails loud when zero rows were inserted and not all attempted rows were already present. Genuine 0-of-N write failures still raise with the same error message prefix.- Dispatch auto-PR branch detection (#280):
_finalize_completed_worktree_job()re-derives the worktree's actual current branch viagit branch --show-currentinstead of trusting the pre-recordeddispatch/<agent>/<job_id>name. When an agent commits on a custom branch (the encouraged human-readable pattern), push andgh pr create --headnow target that branch; the job record is updated sosynlynk jobsreports the real name. Detached HEAD falls back to the recorded branch without erroring. synlynk probenow clearsHARNESS_VERSION_DRIFTalerts for the specific agent it just re-probed, so the warning disappears once the recordedinstalled_versionmatches the live binary again. Fixes #281.
Release pitch: the operational backbone gets provably reliable and provably accounted for — dispatched jobs finish their own git steps, a 5th zero-cost local agent joins the fleet, story routing gets real capability+quota+cost scoring with a fleet batch scheduler, and every dollar synlynk reports is now either structurally sourced or visibly flagged as an estimate.
Added
Measurement Ledger Hardening — Phase 1 + Phase 2 + display layer (epic #210, PRs #236/#241/#242/#244/#245/#246/#252/#256/#257/#264/#266/#267)
Phase 1 — provenance-tagged cost tracking (PR #236):
cost_entriesgained explicit provenance columns:cost_source TEXT NOT NULL(actual|estimated_token_rate|estimated_tshirt|estimated_manual|legacy_unknown, no default — everyINSERTmust pass it explicitly) andestimate_basis TEXT. Migration rebuilds the table and backfills historical rows aslegacy_unknown._insert_cost_row()(synlynk/db.py) is now the sole sanctioned writer tocost_entries, replacing four independently-drifting direct-SQL write sites indispatch.py,jobs.py(×2), andsupport_engineer.py. Upserts byjob_idwhen present. Enforced by a call-site audit test that fails the suite if any other file writes tocost_entriesdirectly.extract_tokens()now tags a.basis(regex_pair|total_split|none) distinguishing a real per-field token extraction from an 80/20 heuristic guess..synlynk/model_rates.json(scaffolded bysynlynk init) is now the source of truth for per-model rates andbilling_mode, replacing a hardcoded table; falls back to hardcoded rates on missing/invalid file.- New 3-tier t-shirt-size token fallback (
_estimate_tshirt_tokens()) for surfaces with no real token count: story'sestimated_tokenscolumn → historical average fromcost_entries(same discipline+phase, ≥3 samples) → fixed conservative default. synlynk cost log— manually log a cost row for native/unwrapped PM or brainstorming sessions with no CLI token data, taggedestimated_manual.- Cost coverage closed across every surface identified in the design spec's audit:
dispatch_agent()'s exec wrapper (no longer gated onin_tokens > 0),jobs.py's reconcile and daemon-reconcile paths,cmd_launch(), andsupport_engineer.py's investigation runs.synlynk release,synlynk probe, andsynlynk doctoraudited and confirmed correctly out of ledger scope. check_budgets()gained a dedicated sub-line surfacing failed-job placeholder estimates separately from the headline spend total.costs.mdand budget parsers now tolerate[est]/[legacy]/~prefixes.- New "Cost Capture Protocol" section in
CLAUDE.md. [failed job]marker fix:dispatch.py's zero-token-failure cost label now prepends (not appends) the marker so it survivesupdate_costs()'s 20-character command truncation, restoringcheck_budgets()'s failed-job sub-line to live code.
Phase 2 — structured-output token adapters, one per dispatch CLI (PRs #244, #252, #256, #257): replaces the 80/20 heuristic split with a real per-field structured-JSON extraction path for each vendor CLI — Codex, Claude, Agy (Gemini), and Grok all shipped, closing epic #210's adapter scope.
Display layer (PRs #264, #266): Vizor's Effort & Cost tab now visually flags estimated-vs-measured cost rows; synlynk status gained a RATES line (and JSON rates_updated_at key) showing when the model rate table was last updated, warning ⚠ never updated when no rate file exists.
Design spec: docs/superpowers/specs/2026-07-13-measurement-ledger-hardening-design.md. Roadmap arc + epic #210 marked shipped (PR #267). Deferred follow-ups filed as issues, out of scope for this release: #260 (Savings Ledger), #261 (dispatch-path unification), #262 (surface consolidation), #263 (stage constants staleness).
Local Agent — 5th dispatch agent, zero-cost on-device inference (PRs #200/#204/#205/#207/#208/#209)
localjoins claude/codex/agy/grok as a dispatchable agent, running as anaiderCLI subprocess against an on-device oMLX OpenAI-compatible endpoint — zero per-token cost.- Capability envelope seeding + concurrency guard so
localstarts with a conservative starter whitelist that self-widens with verified results. - Real-hardware opt-in pytest tier (
tests/test_local_agent_hardware.py) exercises actual Aider+oMLX end-to-end, correctly skipped when no local hardware is running. - Capability-matrix taxonomy worked example + blog post documenting the integration.
Capability Matrix Hardening — 3-stage routing engine + fleet batch scheduler (epic #137, PRs #139/#140/#141/#147/#148/#150/#151/#152/#154/#156)
_best_agent_for_story()now scores candidates across three real stages: weighted capability score (VERIFIER tier, dead-signal handling,pr_review_cycles/verified_by_cisignals), a hard quota-headroom gate (agent_quotastable across 5h/hourly/daily/weekly/monthly windows, degraded-mode fallback when quota signal is missing), and a cost tie-break (cheaper model wins when top scores are within 0.15).- New
synlynk/scheduler.py:stories.priority/readinesscolumns,synlynk story ready/draftgate, fleet-level in-batch headroom accounting (story N in a batch sees story 1..N-1's projected spend), retry/reassignment capped at 2 attempts,synlynk schedule [--execute] [--max-stories N]CLI. - GOVERNS seven-stage vocabulary rollout replaces the old CYCLES/CYCLE_COLOURS naming across the capability taxonomy and HUD.
- Capability tag enum enforcement + taxonomy reference doc;
cycle_capabilityrow dedup migration fix. - Deferred v2 (reset-timing-aware bin-packing, persistent quota-blocking history, GOVERNS-aware readiness gate) tracked as a goal, gated on 30 days of v1 production data (deadline 2026-08-10) rather than scoped into stories now.
Job Lifecycle Ground-Truth Verification (#126, #127, #128, #129, PRs #130/#131/#132/#133/#135)
dispatch_agent()creates a dedicatedgit worktreeper dispatched job (worktrees/<job_id>, branchdispatch/<agent>/<job_id>) instead of sharing the invoking shell'scwd— concurrent dispatches no longer collide._reconcile_jobs()cross-checks git state when a job's exit sentinel is missing, instead of treating an ambiguous exit as automatic failure; new"failed_unverified"status flags "inspect before discarding."files_touchedis real (viagit diff --name-only <merge-base> HEAD+git status --short --porcelain), no longer hardcoded to[].cmd_migrate()prints the resolvedDB_PATHand fails loud withMigrationImportErroron a 0-row import from a non-empty source, instead of a silent green banner.
Vizor
- Architect Map v2 (PR #167): replaces the static tube-map SVG with a live force-directed graph of workspace repos and typed cross-repo edges, a side drawer (path/stack/GitHub/dispatch/Gantt-jump/active-dream-count), and an IDE-style file-tree sub-view.
- Business Goals Panel (PR #153): surfaces
goals/storiesrollups in the HUD. __init__.pyre-modularized a second pass — 11 focused modules extracted (synlynk/db.py,jobs.py,dispatch.py,context.py,sentinel.py,scheduler.py, etc.), no more single-file monolith (PR #180).
Fixed
Dispatch git-finalization reliability chain (#182/#184/#185/#189/#190/#191/#196/#198, PRs #186/#187/#192/#193/#194/#195/#199/#201)
- Dispatched agents (Codex/Agy) frequently completed real, tested work but didn't reliably finish their own git steps (commit/push/PR). synlynk now performs git finalization itself once, gated on a job's
running→terminal transition (idempotent by construction) — stages everything except a hard-exclusion list, commits, pushes, opens a PR viagh pr createif none exists. - Borrowed-worktree completions attributed via
origin/<branch>state instead of being misread as zero-work. HARNESS_INTERNAL_TIMEOUTjobs now auto-retry (cap 2) instead of landing as a dead failure.- A job that raced its own disk writes and landed
failedwith0 touchedis re-inspected once and reclassifiedfailed_unverifiedrather than staying permanently stale. - Cost accounting no longer bypasses the per-model rate table in 3 places (including a hardcoded
gemini-2.5-pro$0 bug);localgets an explicit $0.0 override regardless of model version. - Capability router now filters on canonical
discipline, not the legacyengg_domaincolumn. - Daemon queue launch unified through
dispatch_agent()so worktree/preflight/permission-flags/concurrency-guard logic isn't duplicated across two divergent paths. - Harness no longer misreports completed jobs as
FAILEDwith fabricated token counts.
Misc dispatch/CI hardening (PRs #163/#164/#165/#171/#173/#238/#240)
- Codex sandbox gets
--add-dir <git-common-dir>so it can write git refs inside a worktree. dispatch --help's agent list now derives fromAGENT_CAPABILITY_BASELINESinstead of a stale hardcoded list.- Stall-killer generalized to detect harness-internal timeouts and checks remote branch activity before hard-failing a silent job.
- 3 baseline CI flakes isolated from runner environment state; Python 3.8 compat fix for a
tuple[str, str]annotation. dispatch --context-mode fullnow warns when used on a task that's already self-contained.
Release pitch: synlynk v0.11.0 is the Agent Ecosystem Operational Layer — every dispatch now carries permissions and recovery paths, your terminal shows a live fleet of agents in real time, and the full workflow discipline is baked into every agent directive file at init.
Added
Agent Autonomy Bridge (BS-12, PR #119)
synlynk dispatch --grant <perm> --revoke <perm>— per-task permission overrides; role defaults in.synlynk/config.jsonmap 12 roles (pm, review, implement, test, css, infra, etc.) to capability tiers. Resolved set translates to--allowedTools(Claude),--approval-policy(Codex), or a## Permissionscontext header (Agy).synlynk configure agent <name> [--flag k=v] [--env K=V] [--network-dep host:port]— write per-project harness overrides to.agents/<agent>.json;dispatch_agent()merges at call time: baseline → per-project overrides → per-task grant/revoke.synlynk jobs --stalled— list jobs withHANDOFF_PENDINGsentinel (set when a job accumulates STALL_NO_OUTPUT, FLATLINE, or QUOTA_EXHAUSTED). Shows job ID, agent, failure sentinel, elapsed time, and recommended next agent.synlynk jobs handoff <job_id> [--to <agent>]— transfer a stalled job to a new agent; appends## Handoff Noteto the job context file, incrementshandoff_count, updatesprevious_agents(JSON array), launches new dispatch with full context, clearsHANDOFF_PENDING.synlynk doctorTC-5 — scans each directive file for all 6 required SOP section headers; warns (non-blocking) if any are absent. Interactive fix wizard runs after each TC failure with structured fix paths (TC-1–5) and an "I'm stuck" escape that assembles failure context and dispatches Claude for conversational diagnosis.synlynk sync --repair-sops— re-injects missing SOP sections into directive files without touching existing harness fence content. Idempotent.- 6 SOP blocks written into CLAUDE.md, GEMINI.md, AGENTS.md, and GROK.md at
synlynk initandsynlynk synctime: PR Review Discipline · Brainstorm-First Policy · Design → Plan → Build Sequence · Capability-Based Task Allocation · Cost Visibility · Repo Hygiene. daemon_jobsschema additions:handoff_count INTEGER DEFAULT 0,previous_agents TEXT(JSON array). Migration applied automatically on first access.
Live Job Observatory (BS-13, PR #117)
synlynk watch --live— fullscreen live job board: all running/recent jobs with agent, status, elapsed time, cost, and output tail; auto-refreshes every 3s; Ctrl-C to exit.- Vizor Observatory tab — fifth tab in
synlynk vizbrowser dashboard: real-time job fleet table (JS polling), per-agent status badges, cost rollup, job output drawer.
Vizor Efficiency Enrichment (BS-22, PRs #113, #118)
- R/W/T budget bars — per-agent card shows Read, Write, Test utilisation as percentage of TIER1_CAPACITY.
- Cycle × Agent capability matrix —
6 × 4table (dream/plan/work/ship/maintain/engage × Claude/Agy/Codex/Grok) with full/partial/none badges (cap-full,cap-partial,cap-noneCSS classes). - Per-agent radar hexagon SVGs — 80×80px SVG radar on each agent card; 6-axis polygon filled at 30% opacity with agent theme colour; axis score maps
full→1.0,partial→0.5,none→0.0.
Ecosystem Status + Capacity (BS-16, PR #110)
synlynk status— terminal platform health: harness compliance table, agent availability, budget pulse (R/W/T capacity bars per agent), 6-cycle capability matrix.synlynk status --json— machine-readable ecosystem snapshot consumed by Vizor as its live data contract.- Three dispatch modes:
eco(respects R/W/T budget gates),daily-grind(default),perf(no budget gates). - Three new
_preflight_dispatch()gates:CAPACITY_EXCEEDED_INPUT,CAPACITY_EXCEEDED_OUTPUT,TOOL_PRESSURE. - New
state.dbtables:harness_status,cycle_capability;probecommand extended to seed Tier 1 capacity baselines. synlynk/status.pynew module;HarnessSnapshotdataclass inhud.py.
Modularisation (chore, PRs #103–#109)
- Extracted
synlynk/__init__.py(11,268L) into five focused modules:synlynk/probe.py,synlynk/sentinel.py,synlynk/upgrade.py,synlynk/dispatch.py,synlynk/_constants.py.__init__.pyreduced to ~1,500L of orchestration and CLI surface.
Fixed
TC-2 dispatch fix arc (PRs #114–#116)
- Fixed false-positive TC-2 failures caused by Agy
dispatch_flagsbaseline including--non-interactive(valid for Agy but flagged as invalid by harness validator). Corrected per-agent flag baseline maps. - Fixed
_run_tc2seeding invalid flags into the passed list on first scan, blocking all subsequent Agy dispatches. synlynk logsnow shows exit summary + TC-2 preflight gate result per dispatch.
BS-12 review fixes
--repair-sopsnow merges missing SOP blocks into existing harness fence body instead of replacing the entire fence.- TC-5 result wired into
all_passedincmd_doctor; doctor now exits non-zero when SOPs are missing. - Handoff note included in
handoff_tasksent to new agent (was reading context before append). - TC-5 fix menu scoped to agents with missing sections only (was firing for all agents in loop).
--flag KEY(boolean flag without=) inconfigure agentnow usespartitioninstead of crashing withValueError.
BS-22 review fixes
- Removed
is_placeholdershort-circuit in SVG circles matrix that contradicted the new text capability matrix. - CSS class
cap-{support}now normalised to lowercase; prevents unstyled cells from mixed-case DB values. - Removed unreachable dead-code fallback block in
get_capability_level().
Changed
- `synlynk doctor` interactive fix wizard replaces silent print-and-exit after TC failures. - `_check_job_stall()` now also writes `HANDOFF_PENDING` sentinel on STALL_NO_OUTPUT / FLATLINE / QUOTA_EXHAUSTED. - `dispatch_agent()` merge layer: baseline → `.agents/Release pitch: synlynk v0.10.0 is the Developer Preview — install it via pipx, set up your workspace in 60 seconds with the terminal wizard, and get a live browser dashboard that shows exactly what your agent team is doing.
Added
FTUE + Onboarding
synlynk init --wizard— FTUE typeform-style TUI wizard (6 screens: home harness detection, workspace topology, skills scan, agent fleet, role assignment, launch cheat sheet). Mandatory Phase 0 silent scan; writes workspace config, state.db, and role blocks into each agent's directive file. Ctrl-C before completion leaves no state.synlynk scan— re-runnable repo analysis: detects topology (single/mono/multi), fingerprints stack per repo/package via 14 file-presence heuristics, parses CLAUDE.md/GEMINI.md/AGENTS.md, maps to workspace in state.db, regenerates structured context.md. Flags:--refresh,--add <path>,--remove <path>,--dry-run.synlynk launch— FTUE task picker TUI with 6-cycle SDLC view (Dream · Plan · Work · Ship · Maintain · Engage); 12 scan-triggered launch templates (3 core + 9 stack-aware); dispatch preview screen;synlynk openreplaces oldsynlynk launch <agent>for direct agent open. (BS-19, PR #94)synlynk roles— print current agent role table from.synlynk/config.json;synlynk initandsynlynk doctornow generate per-agent directive role blocks (## Your Rolein CLAUDE.md, GEMINI.md, AGENTS.md). (BS-12a, PR #95)
State + Migration
synlynk migrate— one-shot atomic import ofproject-docs/markdown into state.db (8 steps: import → copy to.synlynk/project-docs/→git rm→.gitignore→ sentinel → commit). After migration, every DB write immediately mirrors to.synlynk/project-docs/as a local backup (write-through). Flags:--dry-run,--recover(re-import from backup after DB loss),--setup-dr(configure cloud-synced DR folder).synlynk memory add/synlynk devlog append— write memory entries and devlog sessions to state.db with immediate flat-file write-through.- 5 new state.db tables:
memory_entries,roadmap_arcs,roadmap_phases,cost_entries,devlog_entries;gh_issuecolumn onstories. - DR sync — configurable
dr_sync_pathin.synlynk/config.json; every write-through copy is also synced to a cloud-synced local folder (iCloud/GDrive/OneDrive). No OAuth, no new deps.
Deep Scan
synlynk scan(deep mode) — 6-stage pipeline: repo fingerprint, dependency graph, test coverage ratio, doc coverage, CI health, churn density. Stage Cards TUI with progress indicators; scan fences written to state.db;synlynk launchtemplates upgrade automatically from scan signal data. 6 new scan fields:test_ratio,readme_word_count,has_ci,has_docs,has_type_hints,has_orm. (BS-20, PR #96)
Daily-Driver Commands
synlynk jobs --summary <id>— after every job closes, print structured summary: files touched, exit status, cost, tokens, duration; append to.synlynk/logs/<job_id>.summary; readable viasynlynk jobs --summary <id>. (PR #97)synlynk release— Ship cycle stub: bump VERSION, generate CHANGELOG entry from merged stories since last tag, write blog post stub indocs/blog/;--dry-runpreviews without writing. (PR #98)synlynk status --platform— infrastructure health view: harness compliance (last probe, any DRIFT sentinels), agent availability table (installed/version/TC status), budget pulse (daily/weekly burn rate). (PR #99)
Browser Dashboard
synlynk viz— 5-view local browser dashboard generated fromstate.db, served athttp://localhost:8721. Views: Gantt (accordion drill-down, stage bars, pencil notes), User Journeys (split-pane,docs/journeys/*.md), Architect Map (tube map SVG fromvizor-tube.json), Effort & Cost (SVG bar charts), Efficiency (agent report cards + sentinel timeline). Sticky note system:POST /note→viz-notes.json→ injected intogenerate_context()(visual annotation → AI context loop). Live JS polling + browser notifications. Zero new deps. (BS-21, PR #101)
Packaging
- pipx packaging —
pyproject.tomlwith[project.scripts]entry point; VERSION is the single source of truth insynlynk/__init__.py(pyproject.toml reads it via dynamic attr). Install viapipx install git+https://github.com/nikhilsoman/synlynk. _detect_install_type()— detects pipx vs pip vs script install;synlynk upgraderoutes topipx upgrade synlynkwhen installed via pipx.
Changed
- **`generate_context()`** routes to `_generate_context_from_db()` when `.synlynk/.synlynk_migrated` sentinel is present; reads from state.db (top story, recent devlog entries, recent memory sections). - **`install.sh`** derives VERSION dynamically from `synlynk/__init__.py` instead of hardcoding. - **Python requirement** raised from 3.8+ to 3.9+. - **Refactor:** `main()` extracted to `synlynk/cli.py`; data-layer functions extracted to `synlynk/db.py`. Single-file `bin/synlynk.py` is now a thin dispatcher. - README fully overhauled: pipx install, badge strip, wizard-first 60-second quickstart, state.db architecture, all new commands documented.Tests
- 747 tests (up from 588 at v0.9.8); 28 new migrate tests, 28 launch/FTUE tests, 21 Vizor tests, 7 packaging tests, 40 deep-scan tests, full E2E round-trips.
Added
- **`synlynk exit`** — reverse all synlynk onboarding: strips managed sections from tracked instruction files (CLAUDE.md, GEMINI.md, etc.), removes `.agents/` profiles and `.synlynk/` directory, writes `SYNLYNK_HANDOFF.md` with re-init instructions. Dry-run by default; `--confirm` to execute. `--remove-docs` optionally removes `project-docs/`. - **`synlynk repair`** — exit + immediate re-init from captured config (agents, mode, org, repo, docs-dir). Dry-run by default; `--confirm` to execute. - **`synlynk sync`** — propagate updated synlynk artifacts (instruction file sections, missing `.agents/` profiles) to an existing repo without full re-init. Dry-run by default; `--confirm` to execute. - **`_strip_synlynk_section(path, marker_style)`** internal helper — removes synlynk-managed block from any instruction file; handles html/hash/none marker styles; leaves surrounding user content intact.Changed
- VERSION bumped `0.9.7 → 0.9.8`Added
- **Grok as a first-class fourth agent peer** alongside claude/agy/codex across all synlynk subsystems - `AGENT_CAPABILITY_BASELINES["grok"]` — cli, non_interactive_flags (`-p`), prompt_via_arg, dispatch_flags (`--always-approve`), roles (builder/architect), strengths - `AGENT_DISCOVERY_DEFAULTS["grok"]` — discovery path `~/.grok` - `_probe_model_version` — `grok -v` probe + `grok-[\w.-]+` version pattern - `GROK.md` template — identity (`Co-Authored-By: GrokFixed
- Stale time-sensitive fixture in `test_collect_capability_drop_returns_finding` — hardcoded 2026-06-21 timestamps replaced with `datetime.now(timezone.utc)`-relative valuesAdded
- `SynlynkDaemon` class — subclasses `WatchDaemon` to add an embedded HTTP server thread on `localhost:27471` and persistent job dispatch on every poll tick; double-fork daemonization inherited from `WatchDaemon`; separate pidfile `.synlynk/daemon.pid` and log `.synlynk/daemon.log` - `daemon_jobs` table in `state.db` — persistent job queue with `priority` (1–10), `depends_on` (JSON array of job IDs), and full status lifecycle `queued → running → done | failed` - `_reconcile_daemon_jobs()` — reaps finished child processes using `os.waitpid(WNOHANG)` (zombie-safe), reads `.exit` files for exit codes, updates `status`/`exit_code`/`completed_at` in state.db - `_dispatch_ready_jobs(max_parallel)` — launches queued jobs respecting concurrency cap and dependency chains; propagates `failed` status to downstream dependents immediately; commits per-job for crash-safe restart semantics - HTTP API on `localhost:27471` — 10 endpoints: `GET /context`, `GET /status`, `GET /jobs`, `GET /jobs/Fixed
- Daemon zombie process detection: replaced `os.kill(pid, 0)` with `os.waitpid(WNOHANG)` so exited child processes are properly reaped rather than staying `running` indefinitely - Dependency deadlock: queued jobs whose dependency fails are immediately marked `failed` rather than staying queued forever - Transaction isolation in dispatch: each launched job is committed individually so a crash mid-loop cannot produce duplicate spawns on restartAdded
- `synlynk join` — new member onboarding: seeds a devlog stub for the joining user, regenerates AI context files (CLAUDE.md, GEMINI.md, AGENTS.md) with the joining member's identity, and prints a team digest showing all active members and their recent focus areas - `synlynk team status` — team digest view: lists all members with devlog presence, current story assignments, token budget consumption, and last-active timestamp; reads `project-docs/devlogs/Fixed
- None in this releaseAdded
- `--docs-dirFixed
- Installed binary (`~/.synlynk/bin/synlynk`) crashed with `ModuleNotFoundError: No module named 'synlynk'` when invoked outside the source repo after the v0.9.0 package split. Fixed by embedding the package `synlynk/` directory in `~/.synlynk/lib/synlynk/` at install time and prepending `$HOME/.synlynk/lib` to `sys.path` in the installed shim. - `synlynk init` in a repo with existing `project-docs/` overwrote the existing docs with blank templates. Fixed by detecting existing files via `_find_existing_doc()` and migrating their content to the new location (or skipping write if no relocation is needed).Added
- Scoped dispatch context: `exec` now injects a per-task section (`## Current Task`) with only the relevant plan block instead of the full devlog, reducing context window usage - `## Relevant Files` injected per dispatch from the source map — derived from the task description matched against `source-map.md` symbols - `## How to Verify` contract injected per dispatch — specifies acceptance criteria the agent should validate before declaring the task done - Per-agent prompt framing: Claude, AGY, and Codex each receive a tailored preamble that matches their CLI interaction model (conversational vs. task-oriented vs. non-interactive) - Ed25519 capability rating signing: every `capability_ratings` row is signed with the project key so ratings cannot be forged across project boundaries - Anti-gaming quality cap: `test_count < 3` stories are capped at quality score 5.0 regardless of other signals, preventing artificially inflated ratings for untested work - `synlynk/` package split: all ~5000 lines of application logic moved from `bin/synlynk.py` into `synlynk/__init__.py`; `bin/synlynk.py` becomes a 5-line import shimFixed
- `capability_ratings` entries were not being attributed to the correct project when multiple synlynk-managed repos shared the same `~/.synlynk/` directory — Ed25519 project key now scopes all ratings correctlyAdded
- `synlynk agent run` — foreground support engineer investigation: collects signals, formats a structured report, and offers to file a GitHub issue or draft a fix PR - Five signal collectors for the support engineer archetype: failing tests, flaky tests, coverage gaps, stale dependencies, open GitHub issues exceeding age threshold - 7-day and 30-day deduplication: signals already filed within the window are suppressed so the agent doesn't file duplicate issues on repeated runs - `synlynk agent --install-cron` — registers a launchd plist (macOS) or systemd timer (Linux) that runs the support engineer agent on a configurable schedule - `.agents/` config directory: `support-engineer.json` defines signal weights, age thresholds, and notification channels per project; read by `synlynk agent run` at startup - GitHub issue filing via `gh issue create` with structured body including signal summary, affected files, and suggested fix skeleton - Draft fix PR creation via `gh pr create` for issues with high-confidence fix candidatesAdded
- `synlynk scan` / `synlynk scan --deep` — language-agnostic source scanner: reads file tree, extracts top-level symbols from Python/JS/TS/Go/Rust/Ruby/Java/C/C++ source, writes `source-map.md` and populates `source_symbols` table in `state.db` - `## Source Architecture` section injected into every `exec` context from the cached scan result, giving agents a structural overview without reading individual files - Passive git-HEAD cache: scan results are keyed to the current git HEAD SHA; a re-scan is only triggered when HEAD changes, not on every `exec` call - `synlynk scan --status` — shows last scan timestamp, HEAD SHA, and symbol count without re-scanning - Dual storage: symbols written to both SQLite `source_symbols` table (queryable) and `source-map.md` (human-readable, injected into agent context) - Language detection by file extension with fallback to content heuristicsFixed
- `synlynk scan` no longer traverses `.git/`, `node_modules/`, or `.synlynk/` directoriesAdded
- Instruction reach to seven additional IDE/editor targets: Cursor (`.cursor/rules/`), GitHub Copilot (`.github/copilot-instructions.md`), Windsurf (`.windsurfrules`), Cline (`.clinerules`), Aider (`.aider.conf.yml`), Continue (`.continue/config.json`), and Sourcegraph (`.sourcegraph/memory.md`) - SHA manifest (`instructions.json`) tracking the synlynk-managed section hash for each generated file; used for drift detection - Runtime drift detection: `exec` warns if any tracked instruction file's section has been externally modified since last generation - `synlynk instructions status / diff / update / ack` — manage instruction file state - Task status model: 5 states (`active`, `done`, `deferred`, `superseded`, `absorbed`); deferred tasks are included in context with reduced weight; `checkpoint` archives resolved states to a separate section - AGY CLI replaces Gemini CLI throughout: all references to `gemini` updated to `agy` - VERSION synced to GitHub releases (was incorrectly stuck at 0.4.x) - `DB_PATH` centralised to `~/.synlynk/projects/Added
- Model version tier-2 probe: `discover_agents()` now probes for Opus/Sonnet/Pro variants in addition to the base model, annotates capability entries with `model_tier` - `synlynk pr check` — validates that the current branch's diff satisfies the story's acceptance criteria before opening a PR; exits non-zero if criteria unmet - `synlynk score attest` — manually attest a story's quality score with a signed reason; appended to `capability_ratings` with `attestation=true` flag - Verifier pipeline output capture: `run --trio` now captures and surfaces the Verifier agent's structured review comment - Tokq `org_domain_tags` capability dimension: stories can be tagged with domain taxonomy labels (`backend/api`, `frontend/ui`, etc.) for cross-project capability aggregation - Constraint propagation: blocking story constraints propagate to child tasks; dispatching a child task for a blocked story emits a warning and requires `--force`Added
- SQLite WAL state database (`~/.synlynk/projects/Added
- Task status model (`active` / `done` / `deferred` / `superseded` / `absorbed`) added to the context schema; deferred tasks included in `context.md` with a `[deferred]` prefix - `checkpoint` archives all resolved-state tasks to a `## Resolved Tasks` section rather than deleting them — preserves decision history while keeping the active list clean - Agent instruction templates updated to explain the 5-state model and checkpoint archivalAdded
- Section marker system: synlynk-managed blocks in instruction files delimited by `` / `` markers so user customisations outside those markers are preserved on regeneration - SHA manifest (`instructions.json`): tracks content hash of the synlynk section in each generated file; used for drift detection - `synlynk instructions status / diff / update / ack` — full CLI for managing instruction file drift - `DB_PATH` centralised: all state now written to `~/.synlynk/projects/Fixed
- `init` no longer regenerates files that already contain a synlynk section — protects user customisations from accidental overwriteAdded
- `AGENT_CAPABILITY_BASELINES` — hardcoded capability dict for claude/gemini/codex/agy with `cli`, `non_interactive_flags`, `roles`, and `strengths` per agent - `discover_agents(config)` — probes each known agent CLI with `--version`, returns functional agents with their roles and capabilities; supports per-project path overrides via config - `_static_scan(root)` — reads git log, README, and file tree to produce a structured project context dict (project name, commit count, languages, recent topics) - `_write_informed_skeleton(scan)` — writes project-docs/ first draft using scan results instead of blank placeholders - `_llm_enrich(agent_name, agent_cli, scan)` — opt-in step that calls the best available agent non-interactively to synthesise an informed `roadmap.md` from scan results - `init()` refactored to a 6-step wizard: scan → **Magic Moment 1** (workgroup discovery table showing all detected agents with roles) → doc bootstrap → LLM enrichment offer → cloud nudge → finalise config - `dispatch_agent(agent, task, story_id)` — launches agent CLI in background using `subprocess.Popen(start_new_session=True)`, captures stdout to `.synlynk/logs/Fixed
- `_reconcile_jobs()`: `PermissionError` from `os.kill(pid, 0)` means the process exists (owned by another user) — no longer crashes the CLI; job correctly stays `running` - `_reconcile_jobs()`: empty `log_file` no longer accidentally reads/deletes an unrelated `.exit` file in the current working directory - `_llm_enrich()`: baselines now indexed by canonical agent name (not CLI binary path), so custom CLI paths still resolve the correct non-interactive flagsInfrastructure
- 5 new reconcile/enrich tests; 4 new E2E tests (dispatch, jobs, logs, reconcile startup)
- 188 tests total (up from 140)
Added
- Enriched agent instruction templates: CLAUDE.md, GEMINI.md, AI_INSTRUCTIONS.md now include Live Issues SOP (Sev1/Sev2/Sev3 with RCA doc path pattern), Git Worktree-First Policy, per-agent branch naming and commit trailers, Mid-Session Anti-Amnesia Protocol (Phase 1/2 cadence), Mandatory 4-Doc Discipline, and GitHub Projects v2 GraphQL integration block with parameterizable `PROJECT_ID` - `AGENTS.md` — new Codex agent instruction file, generated at repo root on `synlynk init` - `synlynk init --agentsChanged
- `synlynk init` now writes `project-docs/.synlynk_config.json` directly (previously missing from init, requiring manual creation)Fixed
- `exec_command()` now returns the child process exit code and `main()` calls `sys.exit()` with it — previously a wrapped command exiting non-zero would cause `synlynk exec` to exit 0, silently swallowing failures - `parse_costs_md()` was reading the wrong column (`parts[6]` = Summary instead of `parts[5]` = Estimated Cost USD), causing `status` and budget checks to always report $0.00 - `install.sh` version corrected from `1.2.0-lite` to `0.2.0` - `conftest.py` fixture schema aligned with real `costs.md` format (6-column) so budget tests exercise the correct parser behaviorRemoved
- Dead functions
log_telemetry(),extract_tokens(), andupdate_costs()— superseded bylog_telemetry_event()and manual cost tracking; removed to prevent confusion
Infrastructure
.gitignoreexpanded to cover.synlynk/,__pycache__/,*.pyc,.DS_Store,test_archive/,test_context_output/,.venv/project-docs/roadmap.mdupdated to reflect v0.2.x reality (was stale with v1.2/v1.3/v1.4 references)- Test added for exit code propagation (47 tests total)
Added
- `synlynk watch start/stop/status` — background daemon that polls `project-docs/` and regenerates `context.md` on any file change, with configurable interval and debounce - `synlynk checkpoint` — archives completed `[x]` tasks from `todo.md` into the user devlog, refreshes context, and emits a structured telemetry event - `synlynk status` — project state dashboard showing active tasks, last checkpoint, sentinel alerts, budget, and watcher state; `--json` flag for machine-readable output - `synlynk init --force` — overwrite existing template files - `set_state()` — writes `.synlynk/state` and updates terminal title with state icon (`●` watching / `⚡` active / `○` stopped) - Helper functions: `get_username()`, `get_mode()`, `load_config()`, `parse_costs_md()` - `log_telemetry_event()` — structured event logging with `schema_version` and `type` fields - `_check_costs_freshness()` — warns when `costs.md` has not been updated within the current session - Devlog archiving: entries older than 30 days moved to `devlogs/archive/YYYY-MM.md`Changed
- `generate_context()` — now compacts output: excludes completed `[x]` tasks, includes only "In Progress" roadmap rows, injects sentinel alerts at top when present, scoped to last 7 days of devlog - `check_budgets()` — now reads cumulative spend from `costs.md` instead of telemetry; request count sourced from telemetry `type=exec` events - `check_flatline()` — now writes alerts to `.synlynk/sentinel.md` in addition to stdout - `exec_command()` — uses `subprocess.Popen` (no stdout capture) for full TTY interactivity with Claude Code and Gemini CLI - `CLAUDE.md` / `GEMINI.md` templates — include full session protocol: startup checklist, during-session rules, session-end steps - `VERSION` bumped to `0.2.0`Fixed
- Type hint `str | None` replaced with `Optional[str]` for Python 3.8 compatibility (union syntax requires 3.10+)Infrastructure
- Added pytest test suite (
tests/conftest.py+tests/test_synlynk.py) with 46 tests andproject_dirfixture - Added GitHub Actions CI workflow (runs pytest on Python 3.8, 3.10, 3.12 on push and PRs)
- Added
LICENSE(MIT),CONTRIBUTING.md, PR template, issue templates
Initial public release.