Skip to content

feat(plugin): synapse-coder-reporter learning-loop integration + companion plugins#1

Merged
Alter-Igor merged 4 commits into
devfrom
synapse-coder-reporter
Jul 19, 2026
Merged

feat(plugin): synapse-coder-reporter learning-loop integration + companion plugins#1
Alter-Igor merged 4 commits into
devfrom
synapse-coder-reporter

Conversation

@Alter-Igor

Copy link
Copy Markdown
Owner

What

Alterspective integration for the fork, all plugin/config-level (zero \src/\ changes — fork-local compliant, upstream merges stay clean):

  1. synapse-coder-reporter plugin (SYN-001) — detects LSP diagnostics after \�dit/\write/\�pply_patch, holds the failing edit as pending, and reports an \original\→\corrected\ pair to the Synapse Coder staging MCP (\coder_report_correction) when a follow-up same-file edit lands clean. Env-var opt-in gate (\SYNAPSE_CODER_REPORTER_ENABLED, default off) with first-use TUI toast; offline queue with retry; fire-and-forget hooks (no await on the report path).
  2. alterspective-rag-standards plugin — injects Alterspective standards awareness (rule-ID citation, RAG-first routing) into the chat system prompt via \�xperimental.chat.system.transform; opt-out env vars.
  3. health/version sidecar (.opencode/scripts/health-check.ts) — standalone /health\ + /version\ HTTP server (the fork-local fallback for operational visibility, since adding routes would touch high-churn upstream files).
  4. MCP wiring — .opencode/opencode.jsonc: synapse-coder (staging), alterspective-rag, keystone, timely, sharedo, vault-local, azure-devops. No plaintext secrets — {env:VAR}\ references only.

Key design constraint discovered (E2E)

The live \coder_report_correction\ schema requires \ ool, \model, and non-empty \original/\corrected\ (\�dditionalProperties: false) — one-sided reports are rejected (MCP -32602). The plugin therefore only reports paired corrections; unpaired detections are dropped after a 30-min window. No placeholder values are sent (learning-corpus pollution avoided). Full evidence: \docs/implementation/current/SYN-001-synapse-coder-reporter/evidence/phase4-e2e-verification.md.

Validation performed (observed, this session)

  • \�un typecheck\ from \packages/opencode: 0 errors
  • \�un test\ (3 new files): 39/39 pass (28 synapse + 6 rag-standards + 5 sidecar); 3+ consecutive clean runs. One environmental Windows test-runner flake investigated and documented (not a code bug; --only-failures\ absorbs it)
  • \mcp list: \synapse-coder\ connected (token from vault); 12 tools discovered incl. \coder_report_correction\
  • E2E against staging: paired correction accepted — visible in \coder_stats\ with exact payload
  • No visual/TUI verification performed (headless validation only — the toast path is unit-tested via mocked client)

Docs

  • Full plan + evidence + issues log: \docs/implementation/current/SYN-001-synapse-coder-reporter/\ (committed in this PR)
  • No user-doc impact: fork-internal tooling, not a shipped product surface.
  • Version governance: N/A — fork tracks upstream version in high-churn \package.json; plugins are machine-local .opencode/\ config, not shipped runtime. Deviation from APP-VERSIONING noted deliberately to keep upstream merges clean.
  • Tracker: no GitHub issue filed — tracked via in-repo SYN-001 plan docs (fork-local convention); deviation from WORK-TRACKING-STANDARDS Start Protocol noted.

Detects LSP diagnostics after edit/write/apply_patch, holds the failing
edit as pending, and reports an original->corrected pair to the Synapse
Coder staging MCP (coder_report_correction) only when a follow-up
same-file edit lands clean — the live schema requires non-empty
original/corrected, so one-sided detections are dropped after 30 min.

- Env-var opt-in gate (SYNAPSE_CODER_REPORTER_ENABLED, default off)
  with first-use TUI toast (once-per-project marker)
- Offline queue (.opencode/synapse-coder-queue.json) with retry on
  load + 5-min timer; fire-and-forget hooks (no await on report path)
- MCP wiring for synapse-coder + Alterspective servers in
  .opencode/opencode.jsonc (local entries fixed to schema shape)
- 28 tests covering detection, pairing rules, opt-in, queue, model
  tracking, fire-and-forget, first-use toast
- Plan/evidence docs under docs/implementation/current/SYN-001-*
Statically injects Alterspective standards awareness (rule-ID citation,
RAG-first routing via rag_search/rag_ask, standards index pointers) into
the chat system prompt via the experimental.chat.system.transform hook.
Opt-out via ALTERSPECTIVE_STANDARDS_INJECTION_DISABLED=true or
ALTERSPECTIVE_STANDARDS_INJECTION_ENABLED=false. 6 tests.
Standalone HTTP sidecar exposing /health and /version (upstream probe
optional via OPENCODE_SERVER_URL) — the fork-local fallback for
operational visibility, since adding routes would touch high-churn
upstream server files. 5 tests.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds fork-local Alterspective integrations to opencode via .opencode/ plugins/config and companion docs/tests, keeping core src/ untouched to minimize upstream merge churn.

Changes:

  • Introduces the synapse-coder-reporter learning-loop plugin (paired correction reporting, opt-in gating, offline queue/retry) and a comprehensive test suite.
  • Adds alterspective-rag-standards system-prompt injection plugin with opt-out env gates and tests.
  • Adds a standalone /health + /version sidecar script plus tests, and wires multiple MCP servers via .opencode/opencode.jsonc.

Reviewed changes

Copilot reviewed 31 out of 31 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
.opencode/plugin/synapse-coder-reporter.ts Implements paired correction detection/reporting + opt-in + queue/retry for Synapse Coder.
.opencode/plugin/alterspective-rag-standards.ts Injects Alterspective standards routing guidance into the system prompt.
.opencode/scripts/health-check.ts Adds a fork-local HTTP sidecar exposing /health and /version.
.opencode/opencode.jsonc Configures MCP servers (remote + local) for the fork environment.
.opencode/.gitignore Ignores local Synapse queue/marker files.
packages/opencode/test/plugin/synapse-coder-reporter/synapse-coder-reporter.test.ts Tests correction detection, pairing, opt-in gate, queueing, model tracking, and non-blocking behavior.
packages/opencode/test/plugin/synapse-coder-reporter/health-check.test.ts Integration tests for the health/version sidecar endpoints.
packages/opencode/test/plugin/alterspective-rag-standards/alterspective-rag-standards.test.ts Tests for standards system-prompt injection and env gating.
docs/implementation/current/SYN-001-synapse-coder-reporter/README.md Feature overview and scope documentation.
docs/implementation/current/SYN-001-synapse-coder-reporter/requirements.md Requirements and assumptions for SYN-001.
docs/implementation/current/SYN-001-synapse-coder-reporter/technical-design.md Architecture and hook-point design write-up.
docs/implementation/current/SYN-001-synapse-coder-reporter/acceptance-criteria.md Acceptance criteria and verification plan.
docs/implementation/current/SYN-001-synapse-coder-reporter/checklist.md Task checklist and wave plan.
docs/implementation/current/SYN-001-synapse-coder-reporter/status.md Current implementation/verification status.
docs/implementation/current/SYN-001-synapse-coder-reporter/issues.md Issue log and resolutions discovered during E2E.
docs/implementation/current/SYN-001-synapse-coder-reporter/impact-analysis.md Risk/impact analysis for fork-local approach.
docs/implementation/current/SYN-001-synapse-coder-reporter/module-register.md Module inventory and dependency mapping.
docs/implementation/current/SYN-001-synapse-coder-reporter/INDEX.md High-level index for the SYN-001 documentation set.
docs/implementation/current/SYN-001-synapse-coder-reporter/ai-memory.md Captures key decisions/gotchas for continuity.
docs/implementation/current/SYN-001-synapse-coder-reporter/ai-handover.md Handover notes for continuing the work.
docs/implementation/current/SYN-001-synapse-coder-reporter/evidence/phase1-mcp-verification.md Evidence for MCP wiring/tool discovery verification.
docs/implementation/current/SYN-001-synapse-coder-reporter/evidence/phase4-e2e-verification.md Evidence for E2E validation and schema mismatch discovery.
docs/implementation/current/SYN-001-synapse-coder-reporter/evidence/investigation-findings.md Investigation report for relevant hook points and constraints.
docs/implementation/current/SYN-001-synapse-coder-reporter/modules/synapse-coder-reporter/README.md Module-level overview for the plugin.
docs/implementation/current/SYN-001-synapse-coder-reporter/modules/synapse-coder-reporter/requirements.md Module-level requirements.
docs/implementation/current/SYN-001-synapse-coder-reporter/modules/synapse-coder-reporter/technical-design.md Module-level design sketch.
docs/implementation/current/SYN-001-synapse-coder-reporter/modules/synapse-coder-reporter/checklist.md Module-level checklist.
docs/implementation/current/SYN-001-synapse-coder-reporter/modules/synapse-coder-reporter/status.md Module-level status tracking.
docs/implementation/current/SYN-001-synapse-coder-reporter/modules/synapse-coder-reporter/INDEX.md Module document index.
docs/implementation/current/SYN-001-synapse-coder-reporter/modules/synapse-coder-reporter/ai-memory.md Module gotchas and decisions.
docs/implementation/current/SYN-001-synapse-coder-reporter/modules/synapse-coder-reporter/ai-handover.md Module-level continuity notes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +28 to +44
import { dirname, resolve as pathResolve, join as pathJoin } from "node:path"

const PORT = Number.parseInt(process.env.HEALTH_CHECK_PORT ?? "4040", 10) || 4040
const HOST = process.env.HEALTH_CHECK_HOST ?? "0.0.0.0"
const BUILD_SHA = process.env.BUILD_SHA ?? "unknown"
const BUILD_DATE = process.env.BUILD_DATE ?? "unknown"
const OPENCODE_SERVER_URL = process.env.OPENCODE_SERVER_URL ?? ""

const startedAt = Date.now()

function readOpencodeVersion(): string {
// Walk up from .opencode/scripts/ to repo root, then packages/opencode/package.json.
const here = dirname(fileURLToPath(import.meta.url))
const candidates = [
pathResolve(here, "..", "..", "packages", "opencode", "package.json"),
pathResolve(here, "..", "..", "package.json"),
]
Comment on lines +3 to +12
import { resolve as pathResolve } from "node:path"

const scriptPath = pathResolve(import.meta.dir, "..", "..", "..", "..", "..", ".opencode", "scripts", "health-check.ts")

function startSidecar(env: Record<string, string>): ChildProcessWithoutNullStreams {
return spawn(process.execPath, [scriptPath], {
env: { ...process.env, ...env },
stdio: ["pipe", "pipe", "pipe"],
})
}
Comment on lines +89 to +92
async function reportToSynapse(payload: ReportPayload): Promise<void> {
const token = process.env.SYNAPSE_CODER_STAGING_BEARER_TOKEN
if (!token) return

Comment on lines +107 to +117
const res = await fetch(SYNAPSE_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json, text/event-stream",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify(body),
signal: controller.signal,
})
if (!res.ok) throw new Error(`synapse-coder responded ${res.status}`)
Comment on lines +106 to +113
**Payload:**
- `original`: `input.args.newString` (edit), `input.args.content` (write), or `input.args.patchText` (apply_patch) — the LLM's proposed code
- `corrected`: `""` (one-sided — the next-turn fix is not available in this hook; Synapse may accept one-sided reports with `reason` containing the diagnostics)
- `category`: `"lsp-typecheck"`
- `language`: derived from file extension (`input.args.filePath` → extension → language map)
- `reason`: `"LSP diagnostics: <formatted errors from metadata.diagnostics>"`
- `reporterModel`: from the per-session model map (populated by `chat.message` hook)

# SYN-001: Synapse Coder Learning Loop Integration

**Feature ID:** SYN-001
**Status:** Planning
Comment on lines +3 to +6
**Status:** Planning — awaiting review
**Last updated:** 2026-07-18

No implementation started. See parent [status.md](../../status.md).
Comment on lines +5 to +16
| Task | Status |
|------|--------|
| Create plugin file with `chat.message` hook | PENDING |
| Implement `tool.execute.after` hook for LSP diagnostics | PENDING |
| Implement `event` hook for permission rejections | PENDING |
| Implement language derivation utility | PENDING |
| Implement reporter module (MCP call) | PENDING |
| Implement user opt-in gate | PENDING |
| Implement offline queue | PENDING |
| Implement async fire-and-forget | PENDING |
| Unit tests | PENDING |
| Integration tests | PENDING |
Comment on lines +74 to +76
function extractFilePath(args: any): string {
return args?.filePath ?? args?.path ?? ""
}
Comment on lines +218 to +221
const filePath = extractFilePath(hookInput.args)
const pendingKey = `${hookInput.sessionID}:${filePath}`
const reporterModel = sessionModels.get(hookInput.sessionID) ?? "unknown"

@Alter-Igor

Copy link
Copy Markdown
Owner Author

Reviewer configuration note (COP-06 gap): this is a personal fork outside the org — no CI checks run on the branch and Copilot review was requested but never attached (reviewRequests empty, no review posted after waiting). No automated review exists for this PR; treating "couldn't run" honestly, not as "passed".

Local verification evidence (observed 2026-07-19, worktree opencode---synapse-coder-reporter):

  • bun typecheck from packages/opencode: 0 errors
  • bun test (3 new files): 39/39 pass, 3+ consecutive clean runs
  • mcp list: synapse-coder connected; 12 tools discovered incl. coder_report_correction
  • E2E vs staging: paired correction accepted, visible in coder_stats
  • Fork-local: zero changes under packages/*/src/ (.opencode/, docs/, test/ only)

Review request: a human pass over .opencode/plugin/synapse-coder-reporter.ts (the pairing logic + opt-in gate) is the meaningful review surface here.

@Alter-Igor
Alter-Igor merged commit 0fbe82b into dev Jul 19, 2026
1 check passed
@Alter-Igor
Alter-Igor deleted the synapse-coder-reporter branch July 19, 2026 22:29
Alter-Igor added a commit that referenced this pull request Jul 20, 2026
#3)

AGENTS.md 'Fork-local notes' now lists the .opencode integration
(plugins, sidecar, MCP wiring incl. local-entry shape) so future
upstream syncs preserve it. SYN-001 status.md updated to final:
merged (PRs #1, #2), activated, learning loop verified end-to-end.
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.

2 participants