Skip to content

Commit 8cba338

Browse files
committed
fix: reconcile Go linter with Kit factory
1 parent 8dd744d commit 8cba338

6 files changed

Lines changed: 69 additions & 35 deletions

File tree

.github/workflows/guide-draft.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
- name: Setup Go
2929
uses: actions/setup-go@v5
3030
with:
31-
go-version: '1.22'
31+
go-version-file: tools/lint-guide/go.mod
3232

3333
- name: Build guide linter
3434
working-directory: tools/lint-guide

docs/superpowers/plans/2026-08-27-go-guide-linter-port-implementation.md

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,28 @@
44
55
**Goal:** Replace PR #171's TypeScript guide-lint semantics with one parity-tested Go checker in an isolated tools module while preserving current CLI, workflow, doctrine, and guide behavior.
66

7-
**Architecture:** `tools/lint-guide/internal/guidecheck` owns all validation and a goldmark-based rendered-URL classifier; `tools/lint-guide/cmd/lint-guide` preserves the current grouped human/JSON CLI contract. Remaining TypeScript workflow code calls the Go command through a semantics-free asynchronous process client until the rest of the pipeline is migrated.
7+
**Architecture:** `tools/lint-guide/internal/guidecheck` owns all validation and a goldmark-based rendered-URL classifier; `tools/lint-guide/cmd/lint-guide` preserves the grouped human/JSON CLI and adds the required `--meta-only` compatibility mode. The live Kit factory builds and consumes this nested command directly through `LINT_GUIDE_BIN`; no TypeScript workflow client remains.
88

9-
**Tech Stack:** Go 1.22+, goldmark 1.8.5, yaml.v3 3.0.1, jsonschema/v5 5.3.1, Node.js 24, TypeScript 7, `node:test`, and GitHub Actions.
9+
**Tech Stack:** Go 1.22+, goldmark 1.8.5, yaml.v3 3.0.1, jsonschema/v5 5.3.1, the Kit factory, Node.js 24 for remaining repository JavaScript tooling, and GitHub Actions.
1010

1111
**Spec:** `docs/superpowers/specs/2026-08-27-markdown-url-placement-go-port-design.md`
1212

13+
## Post-Prerequisite Reconciliation
14+
15+
The factory prerequisite series through PR #178 merged before final review. The original task sequence below remains the historical record of the parity-first TypeScript-to-Go cutover, but steps that invoke `pipeline`, its temporary process client, npm tests, or TypeScript typecheck are superseded and are not commands for the final tree.
16+
17+
The authoritative final integration is the Kit factory: production and Factory CI use `go-version-file: tools/lint-guide/go.mod`, build `tools/lint-guide/cmd/lint-guide` once, and pass the runner-temp executable as `LINT_GUIDE_BIN`; the factory image builds the same nested module. `factory/scripts/validate.sh` uses the supplied binary or a local nested-module fallback. The public `go` module contains no duplicate checker.
18+
19+
`--meta-only` is now required for partial factory exports and is covered by checker, CLI, and host-validator regression tests. It preserves grouped human/JSON output and `0`/`1`/`2` exits. Current user invocations are:
20+
21+
```bash
22+
mise run lint-guide -- asana
23+
mise run lint-guide -- --json guides/asana
24+
mise run lint-guide -- --meta-only guides/asana
25+
```
26+
27+
The resolved-tree acceptance matrix is: tools-module fmt/test/vet/tidy drift; focused CLI and `--meta-only` contracts; all 21 guides; the complete factory suite with `LINT_GUIDE_BIN`; `actionlint` and structural workflow assertions; shellcheck; public Go tests and `go/check.sh`; linux/amd64 factory-image build; deletion/duplication searches; and Git diff/status hygiene.
28+
1329
## Global Constraints
1430

1531
- Keep all linter dependencies in the nested `tools/lint-guide` module; do not modify the published `go/go.mod` for authoring-tool dependencies.
@@ -19,21 +35,23 @@
1935
- Exclude real link/image/reference destinations, autolinks, resolved reference syntax, definition labels/destinations, and fenced code; scan prose, labels/alt text, titles, inline/indented code, raw HTML, and unresolved references.
2036
- Do not add URL suppression, network validation, GFM, or linkify behavior.
2137
- Never run two authoritative linters in production; TypeScript remains only as a temporary oracle during parity work.
22-
- Retain Node 24, TypeScript 7, doctrine changes, six migrated guide sources, and generated Go copies already in PR #171.
38+
- Retain Node 24 for repository JavaScript tooling, doctrine changes, six migrated guide sources, and generated Go copies already in PR #171. The merged prerequisite removed the obsolete TypeScript 7 drafting pipeline; do not reintroduce it.
2339

24-
## File Structure
40+
## Final Reconciled File Structure
2541

26-
- `tools/lint-guide/go.mod`, `go.sum`: isolated authoring dependencies.
27-
- `tools/lint-guide/internal/guidecheck/check.go`: file orchestration and all non-URL guide rules.
42+
- `tools/lint-guide/go.mod`, `go.sum`: isolated authoring dependencies and Go version authority.
43+
- `tools/lint-guide/internal/guidecheck/check.go`: file orchestration, metadata-only compatibility, and all non-URL guide rules.
2844
- `tools/lint-guide/internal/guidecheck/markdown.go`: goldmark parsing, source recovery, projection, and URL findings.
29-
- `tools/lint-guide/internal/guidecheck/*_test.go`: rule and Markdown parity tables.
30-
- `tools/lint-guide/internal/guidecheck/testdata/`: valid/malformed guide directories and golden findings.
31-
- `tools/lint-guide/cmd/lint-guide/main.go`: target resolution, output formatting, and exits.
32-
- `tools/lint-guide/cmd/lint-guide/main_test.go`: CLI contract tests.
33-
- `pipeline/src/lint-guide-client.ts`: asynchronous Go-process adapter only.
34-
- `pipeline/src/lint-guide-client.test.ts`: process and JSON/error contract tests.
35-
- `pipeline/src/workflow.ts`: await the Go client.
36-
- `pipeline/package.json`, lockfile, `mise.toml`, and Pipeline CI: build/invoke the Go tool and remove linter-only npm dependencies.
45+
- `tools/lint-guide/internal/guidecheck/*_test.go` and `testdata/`: rule, metadata-only, Markdown parity, and golden finding tests.
46+
- `tools/lint-guide/cmd/lint-guide/main.go` and `main_test.go`: Mise-facing usage, target resolution, grouped output, `--meta-only`, and exit contracts.
47+
- `.github/workflows/guide-draft.yml` and `factory-ci.yml`: version-file setup, build-once, and `LINT_GUIDE_BIN` wiring.
48+
- `factory/scripts/validate.sh`, `factory/Dockerfile`, and factory tests: live host, image, fallback, and compatibility consumers.
49+
- `mise.toml`: `mise run lint-guide -- ...` developer entry point.
50+
- `go/cmd/lint-guide` and `go/internal/guidecheck`: absent after duplicate prerequisite implementations were reconciled into the nested tool.
51+
52+
### Historical Pre-Prerequisite Files (Superseded)
53+
54+
The original plan temporarily used `pipeline/src/lint-guide-client.ts`, its process tests, `pipeline/src/workflow.ts`, pipeline package files, and Pipeline CI to bridge TypeScript orchestration to Go. The merged Kit factory deleted that pipeline before final reconciliation; these paths remain in the task history below only to document the parity-first cutover.
3755

3856
---
3957

@@ -642,6 +660,9 @@ Do not delete the historical rationale or falsely rewrite completed history.
642660
643661
- [ ] **Step 2: Run final acceptance verification**
644662
663+
> Historical pre-prerequisite command block: the `pipeline` npm command and its
664+
> expected typecheck are superseded by the post-prerequisite matrix above.
665+
645666
```bash
646667
(cd tools/lint-guide && go test ./... && go vet ./...)
647668
(cd go && go test ./...)
@@ -657,7 +678,7 @@ git diff --check
657678
test -z "$(git status --porcelain)"
658679
```
659680
660-
Expected: tools/public Go tests pass, 21 guides and zero findings, pipeline tests/typecheck pass, and the worktree is clean after the documentation commit.
681+
Historical expectation at the time of the original plan: tools/public Go tests, 21 guides with zero findings, and pipeline tests/typecheck. In the reconciled tree, the complete Kit factory suite and workflow checks supersede the deleted pipeline checks; the worktree must still be clean after the documentation commit.
661682
662683
- [ ] **Step 3: Commit documentation**
663684
@@ -670,7 +691,7 @@ Rerun `git status --short`; expected output is empty.
670691
671692
- [ ] **Step 4: Update the draft PR**
672693
673-
Update PR #171 without changing its draft state. The title should describe deterministic Go guide linting. The body must summarize the nested module, parity-preserved CLI/workflow cutover, doctrine/guide migration, Node 24/TypeScript 7 baseline retained for remaining pipeline code, and exact final verification counts. Keep the prerequisite merge-order note.
694+
Update PR #171 without changing its draft state. The title should describe deterministic Go guide linting. The body must summarize the nested module, parity-preserved CLI, live Kit-factory integration, doctrine/guide migration, retained Node 24 tooling pin, superseded TypeScript pipeline, and exact final factory verification count. Keep the prerequisite merge-order history and record that reconciliation completed.
674695
675696
- [ ] **Step 5: Request broad whole-branch review**
676697
@@ -685,8 +706,8 @@ Review the complete PR range, not only the last task. Require explicit checks fo
685706
- [ ] Go and the former TypeScript oracle matched on every committed guide and malformed fixture before deletion.
686707
- [ ] URL behavior includes rendered entities/escapes/formatting, destination exclusions, unresolved references, non-ASCII byte columns, and linear traversal.
687708
- [ ] Human/JSON output, target order/resolution, and `0/1/2` exits match the current CLI.
688-
- [ ] Workflow uses only the semantics-free TypeScript process client.
689-
- [ ] TypeScript semantic files and linter-only npm dependencies are absent.
709+
- [ ] Workflow and factory image consume only the nested Go command; no TypeScript process client remains.
710+
- [ ] TypeScript semantic files, the deleted pipeline, duplicate public-module checker, and linter-only npm dependencies are absent.
690711
- [ ] Doctrine and all six guide migrations remain intact; generated copies match.
691-
- [ ] Tools Go tests, public Go checks, pipeline tests/typecheck, all-guide lint, and diff hygiene pass.
712+
- [ ] Tools Go tests/vet/tidy/fmt, public Go checks, complete factory tests, workflow checks, all-guide lint, Docker build, and diff hygiene pass.
692713
- [ ] PR #171 remains a draft and documents prerequisite merge ordering.

docs/superpowers/specs/2026-08-27-markdown-url-placement-go-port-design.md

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -185,11 +185,23 @@ Exit codes remain:
185185
- `1`: one or more findings;
186186
- `2`: usage, help, or unresolved target.
187187

188-
Unknown options continue to be interpreted according to the current argument behavior rather than silently adopting Go's standard `flag` semantics. Factory-specific flat JSON, `--meta-only`, or alternate exit conventions are outside this PR and must be introduced later as explicit modes or separate thin commands.
188+
Unknown options continue to be interpreted according to the current argument behavior rather than silently adopting Go's standard `flag` semantics. `--meta-only` is now a required compatibility surface for partial Kit-factory exports: it validates `meta.yaml` against the repository schema without requiring published Markdown files, retains grouped human/JSON output, and uses the same `0`/`1`/`2` exit contract. Focused checker, CLI, and host-validator tests cover this mode.
189189

190-
## TypeScript Workflow Adapter
190+
The supported human entry point and usage text are exactly:
191191

192-
The existing TypeScript drafting workflow currently imports the checker in-process. During this broader repository migration, it calls the Go command through a thin process/JSON adapter with no lint semantics.
192+
```text
193+
Usage: mise run lint-guide -- [--json] [--meta-only] <slug|guides/<slug>|path>…
194+
```
195+
196+
For example, `mise run lint-guide -- asana` checks one guide and `mise run lint-guide -- --json guides/asana` requests grouped JSON.
197+
198+
## TypeScript Workflow Adapter (Historical, Superseded)
199+
200+
> This section records the approved pre-prerequisite cutover. The merged Kit
201+
> factory removed the TypeScript drafting pipeline and client before final
202+
> reconciliation; no TypeScript adapter or pipeline check exists in the final tree.
203+
204+
The pre-prerequisite TypeScript drafting workflow imported the checker in-process. During that migration stage, it called the Go command through a thin process/JSON adapter with no lint semantics.
193205

194206
Binary resolution is:
195207

@@ -224,9 +236,9 @@ After cutover, delete:
224236
- `pipeline/src/markdown-url-placement.ts`;
225237
- `pipeline/src/markdown-url-placement.test.ts`.
226238

227-
Add one small TypeScript process adapter under a name that does not imply semantic ownership, such as `pipeline/src/lint-guide-client.ts`, only while TypeScript workflow orchestration remains.
239+
The pre-prerequisite plan allowed one small semantics-free TypeScript process adapter only while TypeScript workflow orchestration remained. The merged Kit prerequisite removed that orchestration, so the final reconciled tree contains no adapter or pipeline package.
228240

229-
Remove npm dependencies only after a repository-wide import search proves they are unused. Node 24 and TypeScript 7 standardization remains in PR #171 as previously requested; unrelated TypeScript pipeline tools continue to use that baseline.
241+
The historical cutover removed linter-only npm dependencies after a repository-wide import search. Node 24 remains pinned for repository JavaScript tooling; the prerequisite removed the obsolete TypeScript 7 drafting pipeline rather than this port reintroducing it.
230242

231243
## Existing Content Migration
232244

@@ -247,7 +259,7 @@ Add focused tools-module checks:
247259
cd tools/lint-guide && go test ./...
248260
```
249261

250-
The pipeline workflow builds the command once before TypeScript tests and exports `LINT_GUIDE_BIN`. Mise's `lint-guide` task invokes the built Go command while preserving current examples. CI continues to run Node/TypeScript checks for remaining pipeline code and Go checks for both the public module and nested linter module.
262+
The live Kit integration builds the nested command once. `guide-draft.yml` uses `actions/setup-go@v5` with `go-version-file: tools/lint-guide/go.mod`, writes the executable to `${{ runner.temp }}/lint-guide`, and supplies it to export validation through `LINT_GUIDE_BIN`. Factory CI uses the same module version file, tests and builds the command, and supplies the binary to the complete factory suite. The factory image builds the nested module into `/usr/local/bin/lint-guide`; local validation falls back to building that same command. Mise invokes `go run ./cmd/lint-guide` from `tools/lint-guide`.
251263

252264
The command must not require network access at runtime. Dependencies are resolved only during module download/build.
253265

@@ -257,7 +269,7 @@ The command must not require network access at runtime. Dependencies are resolve
257269
- Operational file/process/configuration failures are returned errors and produce usage/runtime failure rather than partial findings.
258270
- JSON output is never mixed with human diagnostics on stdout.
259271
- Human diagnostics and usage text go to stderr where the current contract requires it.
260-
- The TypeScript adapter includes stderr in operational errors but does not expose environment contents or credentials.
272+
- Factory consumers validate grouped JSON and preserve stderr for operational errors without exposing environment contents or credentials.
261273
- No ignore or suppression mechanism is added for URL placement.
262274

263275
## Verification and Acceptance
@@ -269,18 +281,19 @@ The port is accepted only when all of the following pass:
269281
- Go CLI contract and exit-code tests;
270282
- temporary TypeScript-to-Go parity fixtures;
271283
- all committed guides with zero findings;
272-
- existing pipeline tests and TypeScript typecheck;
273-
- `go test ./...` in `tools/lint-guide`;
284+
- the complete Kit factory regression suite with the prebuilt `LINT_GUIDE_BIN`;
285+
- workflow structural checks, `actionlint`, and changed-script `shellcheck`;
286+
- `go test ./...` and `go vet ./...` in `tools/lint-guide`;
274287
- `go test ./...` in `go`;
275288
- `go/check.sh` generation, formatting, vet, and tests;
276289
- source/generated guide parity;
277290
- `git diff --check`;
278291
- final whole-branch review.
279292

280-
The final PR tree contains one authoritative Go semantic checker, one temporary semantics-free TypeScript client for the remaining workflow, and no TypeScript guide-lint rules.
293+
The final reconciled PR tree contains one authoritative Go semantic checker, direct Kit-factory consumers, and no TypeScript client, pipeline package, duplicate public-module checker, or TypeScript guide-lint rules.
281294

282295
## Rollout and Compatibility
283296

284-
PR #171 remains a draft until prerequisite work identified by the author has merged. This port is implemented directly on PR #171 rather than stacked on the local `feat/kit-guide-factory` branch. After any prerequisite merge, rebase or merge conflict resolution must rerun the full parity and acceptance matrix.
297+
The prerequisite factory series through PR #178 has merged. PR #171 remains draft while its rebased reconciliation and checks complete. Every prerequisite merge and rebase reruns the resolved-tree acceptance matrix.
285298

286-
If a later factory migration introduces a different Go CLI protocol, preserve both consumer contracts through explicit modes or thin adapters first. Protocol consolidation is a separate design and must not silently change this PR's human/Mise contract.
299+
The live factory protocol preserves the human/Mise contract and adds the explicit `--meta-only` compatibility mode. Any later protocol consolidation must preserve both surfaces or introduce a tested thin adapter rather than silently changing either consumer.

factory/tests/test-coordinator.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ for phrase in \
123123
'group: guide-draft-issue-${{ github.event.issue.number }}' \
124124
'cancel-in-progress: false' 'TMPDIR=%s\n' \
125125
'uses: actions/setup-go@v5' \
126-
"go-version: '1.22'" \
126+
'go-version-file: tools/lint-guide/go.mod' \
127127
'go build -o "$RUNNER_TEMP/lint-guide" ./cmd/lint-guide' \
128128
'LINT_GUIDE_BIN: ${{ runner.temp }}/lint-guide' \
129129
'contents: write' 'issues: write' 'pull-requests: write' \

tools/lint-guide/cmd/lint-guide/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"github.com/speakeasy-api/mcp-setup-docs/tools/lint-guide/internal/guidecheck"
1111
)
1212

13-
const usageText = "Usage: npm run lint-guide -- [--json] [--meta-only] <slug|guides/<slug>|path>…"
13+
const usageText = "Usage: mise run lint-guide -- [--json] [--meta-only] <slug|guides/<slug>|path>…"
1414

1515
type guideResult struct {
1616
Guide string `json:"guide"`

tools/lint-guide/cmd/lint-guide/main_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func TestUsageAndHelp(t *testing.T) {
4242
if got.stdout != "" {
4343
t.Fatalf("stdout = %q, want empty", got.stdout)
4444
}
45-
if got.stderr != "Usage: npm run lint-guide -- [--json] [--meta-only] <slug|guides/<slug>|path>…\n" {
45+
if got.stderr != "Usage: mise run lint-guide -- [--json] [--meta-only] <slug|guides/<slug>|path>…\n" {
4646
t.Fatalf("stderr = %q", got.stderr)
4747
}
4848
})

0 commit comments

Comments
 (0)