VibeVM
Contents
On this page
en
Publisher
org.vibevm.ai-native
Version
1.0.0latest
Audiences
Reading time
7 min
Rendered
Read aloud
never

TCG-ORACLE-GO v0.1 — the gopls oracle process model

01Status: v0.1 — authored with GO-AI-NATIVE-PLAN v0.1 (Phase 3), implemented by its Phase 7.

02The component brief is tools/vibe-agentic-tcg-go.xml; the message grammar is TCG-PROTOCOL-GO-v0.1.

03This document owns the oracle PROCESS: resolution, LSP lifecycle, configuration, overlays, quiescence, the fidelity posture, and latency.

04Where the sibling Rust mechanism cites measured spike facts, this one names the same quantities as campaign-measured — the bench harness (go-ai-native-tcg bench) is the instrument; no Go corpus or baseline has yet been taken, so the figures below are posted targets rather than measured ones. Creating the Go test codebase to measure against is deliberately far-future work (the corpus could be LLM-generated or fuzzer-generated); it is not being built now — a target moves only with a committed REPORT reason.

1. The process and its resolution

05req r1

06The oracle process is the CONSUMER's own gopls binary — the stack never bundles, links, or vendors an analyzer.

07Resolution order, run from the project root so go.work/module context is honoured, each failure recipe-carrying and never silently skipped:

  1. 08the GO_AI_NATIVE_GOPLS env override when set (a set-but-not-a-file value refuses with the recipe, without probing further), then gopls on PATH;
  2. $GOBIN/gopls, then $(go env GOBIN)/gopls;
  3. $(go env GOPATH)/bin/gopls;
  4. hard failure: the bridge's gopls-missing error with the recipe go install golang.org/x/tools/gopls@latest.

09Installing this stack OBLIGES the machine to carry go ≥ 1.24 and gopls (the same posture as rust-analyzer for the Rust stack and node ≥ 22.6 for the TS one): inside the stack's own test suite an absent tool is a recipe-carrying FAILURE, never a skip; outside the stack no obligation exists.

10The resolved path and the server's reported version land in the init result. Specified, not built — half of it. The version half ships: init_result emits gopls_version (crates/go-ai-native-tcg/src/serve.rs:74-84), beside position_encoding, pull_diagnostics and ready. The path half does not: the path IS resolved — resolve_gopls (crates/go-ai-native-tcg-bridge/src/lib.rs:145) returns it — but it is never put into the result. The Rust stack states the same fact and fails it the same way.

2. LSP session and capabilities

11req r1

12The bridge speaks LSP 3.17 over the child's stdio (Content-Length framing).

13The initialize request declares:

  • 14utf-8 in general.positionEncodings (fallback: utf-16 positions converted through the line's text, unit-tested on non-ASCII content),
  • pull diagnostics (textDocument.diagnostic),
  • publish-diagnostics handling,
  • and window.workDoneProgress.

15Every downstream feature keys off the GRANTED set — a capability the server does not grant degrades per §6 into a well-formed error or a documented fallback, never a crash.

16The bridge answers the server's own requests: workspace/configuration (with §3's config object), window/workDoneProgress/create and client/registerCapability (null results).

17Diagnostics channel, stated honestly. gopls has historically PUSHED diagnostics (textDocument/publishDiagnostics) and gained pull support later than rust-analyzer; which channel the shipped gopls grants is pinned by the Phase-7 live chain and recorded in the differential corpus. Specified, not built — the history is true, the recording is not. The channel IS negotiated at run time and carried on the capabilities (pull_diagnostics, crates/go-ai-native-tcg-bridge/src/client.rs:33), but nothing records which one the shipped gopls granted: research/tcg-bench/ holds a TypeScript corpus (corpus/) and a Rust one (corpus-rust/) and no Go corpus at all, so there is no differential corpus for this to be recorded in.

18The bridge supports BOTH: prefer the pull channel when granted; otherwise collect pushed diagnostics for the target document with a bounded settle window after didOpen/didChange.

19Either way validate answers one document's diagnostics — never a whole-workspace sweep.

3. Configuration

20req r1

21The bridge ships one configuration object, passed as initializationOptions and repeated in every workspace/configuration answer.

22v0.1 keeps it minimal and DOCUMENTED — gopls's defaults are production-grade (its diagnostics are not gated behind experimental flags the way rust-analyzer's E0308-class ones are; the Rust bridge's config lesson transfers as a posture, not as content):

  • 23staticcheck integration stays OFF (the floor runs staticcheck itself; one tool, one truth),
  • analyses stay at gopls defaults,
  • and any future knob (build tags, env) extends this one object in one place.

4. Overlays and versions

24req r1

25An overlay is an LSP-owned text document:

  • 26didOpen {uri, version: 1, text} claims the document (the server stops reading disk for it),
  • didChange with full-text sync and a MONOTONICALLY increasing per-document version replaces it,
  • didClose releases it back to disk.

27The rules the TS and Rust campaigns proved are law here and the bridge enforces them structurally:

  • 28versions never repeat within an overlay's lifetime (a monotonic counter per open document, never derived from content); clearing an overlay (update {content: null}) closes the document and a later reopen starts again at 1 — crates/go-ai-native-tcg-bridge/src/oracle.rs, and the bridge's own overlay_versions_are_monotonic_and_close_resets test;
  • validate WITHOUT inline content reads the disk file and opens it with that text, so version bookkeeping has exactly one owner (the bridge) and a later disk edit is picked up by the next validate's didChange;
  • an overlaid file need not exist on disk — a hypothetical new file in an existing package participates via didOpen alone;
  • update {content: null} maps to didClose.

5. The fidelity posture (gopls is go/types, not the compiler)

29req r1

30The three stacks now span a fidelity spectrum, and this oracle's place on it is spec, not fine print:

  • 31The TS oracle IS the compiler (the LanguageService is tsc's engine — agreement by construction).
  • rust-analyzer is NOT rustc (an independent, deliberately partial analysis).
  • gopls stands on go/types — the reference library implementation of the Go specification, the same framework go vet builds on — while the gc compiler type-checks with types2, go/types' deliberately-synchronized port. The delta is a maintained-identical pair whose divergences are treated as bugs upstream: far tighter than rust-analyzer↔rustc, still not identity.

32Consequences, all normative:

  • 33A clean validate does NOT certify a clean floor. The floor (go-ai-native floor → gofmt/vet/build/test) remains the truth; consumer-facing docs repeat it.
  • The differential corpus curates diagnostic classes and pins each to the floor's own verdict (go build / go vet exit + message class) through a committed mapping table: type mismatch, undeclared name, wrong argument count, unknown field, missing return, unused import/variable. Specified, not built: there is no Go corpus and no mapping table. The corpora that exist are research/tcg-bench/corpus/ (TypeScript, 7 cases) and research/tcg-bench/corpus-rust/ (Rust, 9 cases); no corpus-go exists anywhere in the tree. The six classes named above are a curation nobody has performed yet.
  • Known asymmetries are DOCUMENTED-GAP corpus cases, not omissions — the standing candidates to probe in Phase 7: diagnostics gated on saved-vs-overlay state, go.mod-dependent resolution under a pure overlay, and vet-only findings (printf shapes) that the floor reports and the oracle may not. Each observed asymmetry becomes a corpus case asserting exactly that shape, so the gap list never rots.

6. Quiescence, degradation, never crashes

34req r1

35After initialized, the server loads the workspace (go.mod parsing, package metadata, cache priming).

36The bridge bounds its readiness wait by a deadline keyed on workDoneProgress end events for the initial load; a deadline pass degrades: answers carry degraded: true, so callers can distinguish warm truth from cold best-effort.

37The Rust campaign's falsified progress-drain heuristic is inherited as a WARNING, not a mechanism: no wait strategy is trusted until the Phase-7 live chain pins gopls's actual signalling, and a replay test pins whatever is chosen.

38B5 extends to the whole session:

  • 39an op the relay does not know answers a protocol error naming the known set;
  • an analyzer crash surfaces oracle-crashed op-grain and ends the session (the product registry owns respawn-once);
  • no input may poison the session.

7. Process lifecycle and Windows discipline

40req r1

41One long-lived child per (root, session).

42Graceful exit is the LSP dance — shutdown request, exit notification — with kill-on-drop as the backstop; the no-zombie property is test-asserted.

43Paths become URIs only after verbatim-prefix stripping (\\?\ breaks child argv and URI builders — the standing house lesson).

44stdout carries LSP frames only; gopls's own stderr chatter is drained and discarded by the reader (surfaced only in bridge debug logging), so protocol streams stay clean.

8. Latency posture

45req r1

46Targets are POSTED and MEASURED, never CI-gated (the standing split: gate what cannot flake, record what can).

47Posted targets for demo-class trees:

  • 48warm validate p50 < 500 ms,
  • complete p50 < 300 ms — posted, not yet measured: the bench harness (crates/go-ai-native-tcg/src/bench.rs) records per-case warm_ms for validate only and computes no percentile of any kind; the measurement corpus is deliberately far-future work (BACKLOG.md B-042),
  • cold init-to-ready < 15 s.

49The bench harness (go-ai-native-tcg bench) records distributions per run; the Phase-7 ledger entry carries the first measured set on research/go-demo, and a target that moves, moves in a committed REPORT with a reason. Specified, not built — the harness, not the ledger entry. The harness ships and does record a per-case distribution: run_bench (crates/go-ai-native-tcg/src/bench.rs:106) collects warm_ms over three warm passes per case. What does not exist is the measured set: research/tcg-bench/reports/ holds bench-2026-07-07-baseline.json (TypeScript) and bench-rust-2026-07-07-baseline.json (Rust) and no Go run at all, so nothing has ever been measured on research/go-demo and there is no committed REPORT for a target to move against.

50Large-workspace consumers are warned about the product's 60 s first-request ceiling; the relay's eager init at serve start spends the cold cost as early as possible. Specified, not built — the eager init is real, the 60 s ceiling is not a number this stack has anywhere. The relay does spend the cold cost up front: serve boots gopls before the first host frame (crates/go-ai-native-tcg/src/serve.rs:235). A large-workspace warning also exists, one document over — the tcg brief's ##RISK-COLD-INIT-ON-LARGE-WORKSPACES — but it is a spec-layer risk record, not anything the product emits to a consumer at run time. And the 60 s figure is supported by nothing: the shipped readiness budget is READINESS_BUDGET = 45 s (crates/go-ai-native-tcg/src/lib.rs:32) and this document's own ##TARGET-COLD-INIT posts < 15 s. Three numbers, and 60 is not one of them.

For an agent

This page has a machine mirror. The citation carries the version rather than latest, so what an agent quotes does not move under it.

spec://org.vibevm.ai-native/go-ai-native-lang@1.0.0/go/mechanisms/TCG-ORACLE-GO-v0.1

.md.xmlllms.txt