feat: add Go adapter and vibe-check analyze CLI command - #21
Conversation
Proposal, design, specs, and tasks for the vibe-check analyze command and Go language adapter. Includes extensions mechanism for go.interfaceWidth and go.interfaceProximity metrics. Refs: #2
- Add Extensions map[string]any to ModuleResult (omitempty) - Add extensions property to JSON schema, keep additionalProperties: false - Bump SchemaVersionCurrent from 1.0 to 1.1 - Update validate.go to accept both schema versions - Add validation that extensions must be JSON object when present Refs: #2
Go adapter implementing metrics.Adapter interface: - Package loading via go/packages with NeedTypes and NeedTypesInfo - Ca/Ce coupling metrics with stdlib/external filtering - AST-based type classification (interfaces = abstract) - LCOM4 via union-find connected components - Tarjan's SCC for circular dependency detection - go.interfaceWidth and go.interfaceProximity extensions - Typed extension accessors for JSON round-trip safety - Environment sanitization via metrics.SanitizeEnvironment - Comprehensive test suite (26 tests with race detection) Includes testdata fixtures for coupling, types, LCOM, extensions, partial builds, and empty directory scenarios. Refs: #2
Cobra-based CLI with testable RunAnalyze() entry point (AP-002/AP-003): - analyze subcommand invokes Go adapter - Threshold flags: --max-instability, --max-distance, --max-lcom, --no-circular-deps - --timeout flag for analysis time bounds - --version flag with ldflags-embedded build metadata - Signal handling (SIGINT/SIGTERM) with partial JSON suppression - Exit codes: 0=success, 1=policy violation, 2=tool error - Flag validation (range checks, type checks) - Comprehensive test suite (56 tests with race detection) Refs: #2
- Update Project Structure with cmd/vibe-check/ and internal/goadapter/ - Update Architecture section with three-layer design and phasing status - Add CHANGELOG.md with initial unreleased entries - Pin CI workflow actions to commit SHAs - Add concurrency group and descriptive workflow name Refs: #2
…ns, CI pinning - Fix CRITICAL: Ce now counts all imports (incl. stdlib) per Martin's definition - Fix HIGH: Add errors.Is assertions for context cancellation/deadline wrapping - Fix HIGH: Add Warning.Code/Module/Message assertions for partial builds - Fix HIGH: Pin golangci-lint to v2.12.2 (was 'latest') - Fix MEDIUM: Remove GOFLAGS from env allowlist (flag injection risk) - Fix MEDIUM: Replace os.Exit in RunE with exitCodeError type - Fix MEDIUM: Replace fragile RunE wrapper with cmd.Flags().Changed() - Fix MEDIUM: Use strings.HasPrefix instead of slice bounds check - Fix MEDIUM: Add testing.Short() guards on context tests Refs: #2
- Mark code-review passed in tasks.md - Store 4 retrospective learnings in Dewey knowledge base Assisted-by: claude-opus Generated with AI assistance (claude-opus)
jflowers
left a comment
There was a problem hiding this comment.
Note: Could not post as APPROVE — GitHub prohibits a PR author approving their own pull request (HTTP 422). Posted as COMMENT instead. Original council verdict: APPROVE.
Council Verdict: APPROVE
Reviewers: divisor-adversary, divisor-architect, divisor-curator, divisor-envoy, divisor-guard, divisor-herald, divisor-scribe, divisor-sre, divisor-testing (9 discovered, all invoked)
Iterations: 2 fix rounds — initial 9/9 REQUEST CHANGES → 8 APPROVE / 1 REQUEST CHANGES → 9/9 APPROVE
Resolved this cycle: 1 CRITICAL, 6 HIGH, 7 MEDIUM. No protected quality/governance gate was weakened (Guard: gatekeeping CLEARED). CI-parity green: go build/vet, go test -race -count=1, golangci-lint v2.12.2 (0 issues).
divisor-adversary (APPROVE)
Trust boundary now enforced (validate.go numeric ranges + external.go DisallowUnknownFields); GOFLAGS excluded + regression-locked. 3 LOW advisories: binaryPath validation in ExternalAdapter (not CLI-wired); recursive Tarjan lacks depth guard; public Validate() accepts non-integer for int count fields (boundary already int-decoded).
divisor-architect (APPROVE, Alignment 9/10)
canonicalizeCycle contract/GoDoc/impl aligned to sorted-set semantics + non-coincidental test; computeLCOM4 decomposed; 3-layer boundaries clean. 0 findings remaining.
divisor-guard (APPROVE — GATEKEEPING CLEARED)
All protected gates intact (CI flags, dep pins, 7 capability consts, schema strictness, severity defs, constitution MUSTs). Constitution VI legitimately PASS (LCOM4 defect fixed), III honestly PARTIAL. 1 LOW: CHANGELOG omits Spec: cross-ref.
divisor-testing (APPROVE)
Both prior HIGH now covered with deep non-coincidental assertions; all prior MEDIUM resolved. 2 LOW: testing.Short() guard consistency on loadTestPackage unit tests; a few CLI test names lack _Scenario suffix.
divisor-sre (APPROVE)
--version ReadBuildInfo fallback; README created; error remediation added; coverage-ratchet overclaim corrected. 3 LOW: quadratic countCa (P2); go 1.25.7 patch pin (protected — do not modify); coverage.out ungated/unretained.
divisor-scribe (APPROVE)
Type-classification precision + LCOM struct-field-only reconciled across doc.go/spec/design; schema enum+descriptions. 0 findings remaining.
divisor-curator (APPROVE)
README (128 lines) covers install/usage/flags/exit-codes/JSON+schema/limitations, FA-001 clean. 0 in-tree findings. 5 external pre-merge items (below).
divisor-herald (APPROVE)
CHANGELOG 0.1.0 finalized; Validate()/ExternalAdapter attribution corrected. 1 LOW (stylistic framing).
divisor-envoy (APPROVE)
Errors actionable; terminology/--version claims scoped; README + schema pointer added. 1 LOW: design.md:27 Goals says default ./... while CLI defaults to ..
Linked Issues
| Issue | Title | Notes |
|---|---|---|
| #2 | vibe-check analyze — Go-native package-level coupling metrics | Closed by this PR (P0 foundation). Intent: compute Ca/Ce/Instability/Abstractness/Distance/LCOM4 + cycle detection via go/packages. No explicit acceptance-criteria checkboxes in the issue body. |
External Pre-Merge Checklist (cannot action from tree — close before merge)
- Create+apply labels:
docs→#18,blog→#19,tutorial→#22 - Refresh/split stale #18 (predates CLI)
- File website-doc-sync issue
- File GoReleaser/release-automation issue
- Confirm v0.1.0 tag/release published
- File provenance follow-up issue (Constitution III PARTIAL)
This review was generated by /review-council (AI-assisted).
Address findings from /uf.review-council (2 iterations, final 9/9 APPROVE): - lcom: handle generic pointer receivers (*T[P]) via baseTypeName helper; add generic fixture + tests (previously dropped methods, corrupting LCOM4) - cycles: align Cycle contract/GoDoc/impl to sorted-set semantics + test - adapter: emit zeroed ModuleResult+warning for errored packages; add errTotalLoadFailure guard + anyPackageTypeChecked for total load failure - types: count type aliases (incl alias-to-interface) as concrete - extensions: add CapInterfaceWidth/CapInterfaceProximity consts + ExtensionCapabilities() accessor (DRY) - validate/external: enforce numeric ranges and DisallowUnknownFields at the ExternalAdapter trust boundary - cmd: extract run()/exitCode()/versionString() (ReadBuildInfo fallback); test analyzeCmd via Execute(); add actionable error remediation - refactor: decompose computeLCOM4; extract packageEnvAllowlist (GOFLAGS excluded) - docs: add README; finalize CHANGELOG 0.1.0; schema v1.1 enum+descriptions; reconcile design/spec/proposal/tasks with implementation
Summary
Implements the Go language adapter and
vibe-check analyzeCLI command — the first language adapter for Vibe-Check, making the toolkit usable for computing design quality metrics on Go codebases.Closes #2
What this adds
Go adapter (
internal/goadapter/) implementingmetrics.Adapterwith 7 metrics:go.interfaceWidthandgo.interfaceProximitygolang.org/x/tools/go/packagesfor type-aware dependency resolutionCLI command (
cmd/vibe-check/) with:vibe-check analyze [path]— JSON output conforming to ModuleGraph schema v1.1--max-instability,--max-distance,--max-lcom,--no-circular-deps--timeoutflag for analysis time boundsExtensions mechanism in
metrics/:Extensions map[string]anyfield onModuleResult(backward-compatible,omitempty)validate.goaccepts both versionsInterfaceWidths,InterfaceProximities) for JSON round-trip safetyCI workflow (
.github/workflows/ci.yml):-race -count=1), lint (golangci-lint v2.12.2)Architecture
Three-layer design per the RFC:
metrics/): Universal model — unchanged public API, additive Extensions fieldinternal/goadapter/): Go-specific analysis, implementsmetrics.Adaptercmd/vibe-check/): CLI entry point, delegates to adapter via testableRunAnalyze()How to Test
How to Demo
go build -o vibe-check ./cmd/vibe-check/./vibe-check analyze .— observe JSON output with metrics for each package./vibe-check analyze --max-instability 0.1 .— observe exit code 1 and violation messages on stderr./vibe-check analyze --no-circular-deps .— observe no circular deps in this repo./vibe-check --version— observe version output formatKey Files Changed
cmd/vibe-check/main.go,root.go,analyze.go,analyze_test.gointernal/goadapter/adapter.go,resolve.go,types.go,lcom.go,cycles.go,extensions.go,doc.gointernal/goadapter/adapter_test.go,types_test.go,lcom_test.go,cycles_test.go,extensions_test.gointernal/goadapter/testdata/metrics/graph.go,modulegraph.schema.json,validate.go,validate_test.go.github/workflows/ci.ymlopenspec/changes/go-analyze/proposal.md,design.md, specs,tasks.mdAGENTS.md,CHANGELOG.md,go.mod,go.sum52 files changed, 4751 insertions, 24 deletions
Known Issues
The following findings from the review council were acknowledged but not resolved:
# v4) instead of exact minor/patch versionsci.ymldeviates from CI-010ci_prefix conventionSpec:path references for traceabilityThis PR was generated by /uf.finale (AI-assisted).