v0.4.1 — Instruction Reach: Context Injection Across Every IDE

The Broader Goal at the End of the Previous PR

After v0.4.0 (PR #39) shipped the dispatch plane — agent discovery, synlynk dispatch, job store, workgroup identity — the roadmap pointed toward the Capability Engine (v0.5.0): routing tasks to the right agent based on a performance ledger rather than sending every task to every agent. That work required AGENT_CAPABILITY_BASELINES to become data-driven and a SQLite capability registry to land.

But a gap surfaced in the audit between v0.4.0 and v0.5.0: synlynk's context injection pipeline only reached Claude Code (CLAUDE.md), OpenAI Codex (AGENTS.md), and AntiGravity CLI (GEMINI.md). Cursor, GitHub Copilot, Windsurf, and every other IDE had no synlynk presence. Developers using any of those tools were flying blind — no context.md injection, no worktree directive, no sentinel awareness. This PR patches that gap before the capability ledger work begins.

Strategic Shifts in This PR

v0.4.1 is a focused minor release inserted between v0.4.0 and v0.5.0. The decision was: don't let the capability work start on a foundation where half of modern AI IDEs have no visibility into synlynk context. Instruction reach is low-blast-radius, high-value, and can land in a single PR.

Two strategic clarifications sharpened during design:

1. Gemini CLI is EOL'd — replaced by AntiGravity (AGY). The AGY CLI (agy) replaced Gemini as synlynk's third trio member. This required removing "gemini" from AGENT_CAPABILITY_BASELINES, AGENT_DISCOVERY_DEFAULTS, and _probe_model_version probe commands. GEMINI.md was updated to reference the AGY engine and dropped the transition-window hedge. This was the right moment to make the cut — before v0.5.0 locks in the capability ledger schema.

2. Drift detection is more valuable than silent overwrites. The initial instinct was to have synlynk exec re-regenerate instruction files on every run. Code review pushed back: users may intentionally edit instruction files and don't want their changes silently clobbered. The right model is to detect drift (SHA mismatch against a manifest), fire an INSTRUCTION_DRIFT sentinel, and let the user decide — synlynk instructions update to regenerate, or synlynk instructions ack to acknowledge the divergence.

What This PR Shipped

AGY Cleanup

Removed all "gemini" references from agent baselines, discovery defaults, probe patterns, and argparse help strings. GEMINI.md template now uses agy-2.x engine and contains AGY-specific instructions without any Gemini transition context. agent_slots default changed from "agy": "gemini" to "agy": "agy".

Section Marker System

Three marker styles encode synlynk ownership in instruction files:

  • html<!-- synlynk:start version="0.4.1" tool="claude" --> / <!-- synlynk:end --> — used for CLAUDE.md, GEMINI.md, AGENTS.md, Copilot, AI_INSTRUCTIONS.md
  • hash# synlynk:start / # synlynk:end — used for .windsurfrules (no HTML comments in Windsurf rules format)
  • none — synlynk owns the whole file, no markers — used for .cursor/rules/synlynk.mdc (Cursor's MDC format has frontmatter that must be the first thing in the file)

_extract_synlynk_section(content, marker_style) extracts only the synlynk-owned region, excluding surrounding user content. This is the key primitive: SHAs are computed on the section only, so user edits outside markers never trigger false drift events.

_write_instruction_file() — Three-Case Write Logic

Every instruction target goes through one function:

  1. Create — file doesn't exist: write the full content with markers
  2. Append — file exists but no markers: append the synlynk section as a new block, preserving user content
  3. Replace-section — markers found: swap the block between existing markers, user content outside is untouched

marker_style='none' always overwrites — Cursor's .mdc file is synlynk-owned entirely.

Instruction Reach — 7 IDE/Agent Targets

Tool-Native Templates

Three new content builders for extended targets:

  • _build_cursor_mdc() — MDC frontmatter with alwaysApply: true, Session Start, Git Worktree sections. Cursor loads this as a persistent context rule.
  • _build_copilot_instructions() — Plain markdown, no frontmatter. GitHub Copilot reads .github/copilot-instructions.md directly.
  • _build_windsurf_rules() — Terse 6 lines with hash markers. Windsurf rules are more opinionated about format.

Instruction Manifest — .synlynk/instructions.json

Every synlynk init now writes a SHA manifest tracking the synlynk-owned section of each instruction file:

{
  "schema_version": 1,
  "generated_at": "2026-06-17T14:00:00",
  "synlynk_version": "0.4.1",
  "files": {
    "CLAUDE.md": {"tool": "claude", "sha": "a3f8c2e1", "last_checked": "..."},
    ".cursor/rules/synlynk.mdc": {"tool": "cursor", "sha": "b7d91f44", "last_checked": "..."}
  }
}

SHAs are the first 16 hex chars of SHA-256 of the synlynk section content. The manifest merges on update — user-managed entries outside _INSTRUCTION_TARGETS are preserved.

_check_instruction_drift() — Runtime Sentinel

Hooked into exec_command() after check_sentinel_patterns(). On every agent invocation:

  1. Load manifest
  2. For each tracked file in the manifest, extract current section and compute SHA
  3. If SHA differs from manifest entry → fire INSTRUCTION_DRIFT in sentinel.md + update manifest to current SHA (deduplication: next run sees matching SHA, won't re-fire)
  4. Return list of drifted paths for logging

Deduplication is the key design decision: the sentinel fires once per change, not once per exec invocation.

synlynk instructions CLI

Four subcommands:

synlynk instructions status          # Columnar table: 7 tracked files × status (ok/missing/drifted/untracked/no-markers)
synlynk instructions diff [<file>]   # Shows user content outside synlynk markers
synlynk instructions update [<file>] # Re-generates synlynk section, refreshes manifest SHA
synlynk instructions ack <file>      # Removes INSTRUCTION_DRIFT lines from sentinel.md

status uses _YELLOW for missing and drifted states (not error-level red — these are informational alerts, not failures).

init() Refactored for All 7 Targets

Previously init() wrote 3 template files. Now it writes up to 7:

  • Trio (always): CLAUDE.md, GEMINI.md, AGENTS.md — gated by agent_set (discovered agents)
  • Extended (environment-gated): .cursor/rules/synlynk.mdc only if .cursor/ exists; .github/copilot-instructions.md only if .github/ exists; .windsurfrules and AI_INSTRUCTIONS.md always

Detection guards are sourced from _INSTRUCTION_TARGETS[i][3] (the detection_fn field) — single source of truth, no duplicate gate dict.

Test Approach

34 new tests in tests/test_instruction_reach.py, covering every layer:

  • _extract_synlynk_section: all three marker styles, missing markers, nested content
  • _write_instruction_file: create/append/replace-section for html + hash + none styles
  • Template builders: cursor MDC frontmatter, copilot no-frontmatter, windsurf terse format
  • Manifest: write/load/merge, missing file, corrupt JSON
  • Drift detection: clean run (no fire), drifted file (fires once), deduplication (no re-fire)
  • cmd_instructions_status: all five status values rendered correctly
  • cmd_instructions_diff/update/ack: section extraction, re-generation, sentinel cleanup
  • CLI subparser: instructions verb wired with all four sub-subcommands

Existing tests updated: AGY baseline replaces gemini, version test bumped to "0.4.1", init test renamed to test_init_appends_to_existing_without_force (behavior is now append-not-skip), .cursorrules removed from template keys test.

Brainstorm Visuals Used

No dedicated brainstorm HTML was produced for v0.4.1. The design originated from the gap analysis in the four-imperatives brainstorm session (post #10) and was formalized in docs/superpowers/specs/2026-06-17-instruction-reach-design.md.

What This Achieved on the Path to Autonomy

Before this PR, synlynk's instruction injection stopped at the three CLI agents. After this PR:

  • Every IDE with an instruction file convention now has a synlynk block with project context and the worktree directive
  • The SHA manifest gives synlynk observability over all 7 instruction files — it knows if a human edited them
  • Runtime drift detection means agents calling synlynk exec get alerted when their instruction files diverge from what synlynk last generated
  • synlynk instructions update closes the loop: when context changes (new milestone, new teammates, new capability), one command refreshes all instruction files

This PR extends synlynk's reach from 3 CLI targets to 7 tracked files across all major AI development environments.

Strategic Note: The Goal at the End of This PR

v0.4.1 closes the instruction reach gap. The roadmap picks back up at v0.5.0 (Capability Ledger): SQLite-backed capability.json, AGENT_CAPABILITY_BASELINES becoming a data-driven registry, and synlynk score for recording post-run ratings. That work can now proceed on a foundation where every AI tool in the workspace has synlynk context injected — routing decisions will be visible to Cursor, Copilot, and Windsurf, not just the CLI trio.