docs(11.1): record gap-closure code review

This commit is contained in:
Jakub Zych
2026-10-01 09:25:15 +02:00
parent 16be02c6f1
commit 571a2e56a0
2 changed files with 166 additions and 5 deletions

View File

@@ -67,9 +67,29 @@ findings:
severity: info severity: info
disposition: open disposition: open
title: "The identifier checker cannot see several span forms" title: "The identifier checker cannot see several span forms"
open: 16 - id: WR-08
total: 16 severity: warning
recorded: 2026-09-30T22:34:40.155Z disposition: open
title: "Shell fences in any language other than the exact words sh, shell, bash and console are not command-checked"
- id: WR-09
severity: warning
disposition: open
title: "checkBuiltGo still accepts Go files go test ./... does not build"
- id: WR-10
severity: warning
disposition: open
title: "A trailing shell continuation is reported as the command name, and the real command on the next line is never checked"
- id: WR-11
severity: warning
disposition: open
title: "The acceptance scanner misses a list-item fence on the marker line, and it marks a normal indented fence as nested"
- id: IN-09
severity: info
disposition: open
title: "The identifier index still counts files the default build ignores"
open: 21
total: 21
recorded: 2026-10-01T07:25:00.000Z
--- ---
# Phase 11.1: Code Review Disposition # Phase 11.1: Code Review Disposition
@@ -92,6 +112,11 @@ recorded: 2026-09-30T22:34:40.155Z
| IN-06 | info | open | - | | IN-06 | info | open | - |
| IN-07 | info | open | - | | IN-07 | info | open | - |
| IN-08 | info | open | - | | IN-08 | info | open | - |
| WR-08 | warning | open | - |
| WR-09 | warning | open | - |
| WR-10 | warning | open | - |
| WR-11 | warning | open | - |
| IN-09 | info | open | - |
Dispositions: `open` (recorded, not yet triaged), `fixed`, `skipped`, `deferred`. Dispositions: `open` (recorded, not yet triaged), `fixed`, `skipped`, `deferred`.
Set `deferred` by hand and put the reason in the Source cell; both are preserved. A `|` in the reason is kept as prose and escaped on the next run. Set `deferred` by hand and put the reason in the Source cell; both are preserved. A `|` in the reason is kept as prose and escaped on the next run.

View File

@@ -1,8 +1,8 @@
--- ---
phase: 11.1-summercms-documentation-for-humans-and-ai-agents phase: 11.1-summercms-documentation-for-humans-and-ai-agents
reviewed: 2026-09-30T22:32:58Z reviewed: 2026-10-01T07:20:12Z
depth: standard depth: standard
files_reviewed: 93 files_reviewed: 95
files_reviewed_list: files_reviewed_list:
- cmd/summer/docs.go - cmd/summer/docs.go
- cmd/summer/docs_test.go - cmd/summer/docs_test.go
@@ -97,6 +97,8 @@ files_reviewed_list:
- modules/wire/example_test.go - modules/wire/example_test.go
- modules/wristband/example_test.go - modules/wristband/example_test.go
- scripts/check-phase11.1.sh - scripts/check-phase11.1.sh
- internal/docsite/fences.go
- internal/docsite/fences_test.go
findings: findings:
critical: 1 critical: 1
warning: 7 warning: 7
@@ -373,3 +375,137 @@ forbidden_hits() {
_Reviewed: 2026-09-30T22:32:58Z_ _Reviewed: 2026-09-30T22:32:58Z_
_Reviewer: Claude (gsd-code-reviewer)_ _Reviewer: Claude (gsd-code-reviewer)_
_Depth: standard_ _Depth: standard_
## Gap closure 11.1-07
Reviewed the gap-closure diff `d9f187ae..HEAD` (standard depth) on 2026-10-01T07:20:12Z. Scope was the fence AST, snippet execution check, command-word parser, `go doc -c`, the acceptance scanner, and the phase-gate plants. The sections above are the 2026-09-30 review and are unchanged.
This pass: critical 0, warning 4, info 1, total 5.
### Prior findings touched by this diff
- **CR-01 fixed in the product.** `collectFences` walks goldmark's `*ast.FencedCodeBlock` nodes, so callouts, blockquotes and list items are visible. A nested `src=` fence is a snippet problem and is not rewritten by `docs:sync`. `fenceAnnotator` captions only a top-level `src=` fence of a docs page, so a module README or a nested fence no longer renders a verified-source caption. The acceptance scanner strips `>` markers. One list form is still invisible to that scanner (WR-11); `docs:build --check` already refuses it.
- **WR-01 fixed for Examples.** `loadTestGraph` roots an Example only when `doc.Examples` reports `Output` or `EmptyOutput`. A helper or region reached only from an Example with no output is refused. The original note about an unconditional `t.Skip` is unchanged; this diff does not address it.
- **WR-02 fixed for the cases it reproduced.** `//go:build ignore`, a mismatched `_GOOS` file, and a lexical `testdata` or `_`-prefixed segment are refused. A directory symlink into `testdata`, and a package under `vendor/`, still pass (WR-09).
- **WR-03 fixed.** `goDoc` runs `go doc -c`.
- **WR-04 fixed.** `goLang` uses the chroma lexer, so `golang`, `GO` and `main.go` need `src=`.
- **WR-05 fixed for the forms it named** (leading `VAR=value`, a flag before the command word, `go run ./cmd/summer`, `bin/{app}` without `./`). Shell language case and aliases, and a continuation backslash, are still open (WR-08, WR-10).
- **WR-06, WR-07, IN-01 through IN-08** are not changed by this diff.
### Warnings
### WR-08: Shell fences in any language other than the exact words `sh`, `shell`, `bash` and `console` are not command-checked
**File:** `internal/docsite/check_commands.go:31` (`shellLangs`), used at `internal/docsite/check_commands.go:89`
**Issue:** Go fences were moved onto chroma's lexer registry so `golang` and `GO` cannot skip the policy. Shell fences were not. `slices.Contains(shellLangs, f.lang)` is a case-sensitive compare against four lowercase words. chroma classifies `Bash`, `SH`, `Shell` and `zsh` as the Bash lexer and `sh-session` as Bash Session, and `highlight` will colour them as shell, but `checkCommands` skips the fence. Reproduced: a docs page whose only shell sample was a `Bash` fence containing `summer no:such` produced no command problem from `Check`. The same page's `sh` fence was checked. An unknown command written the way the Go aliases used to be written still ships.
**Fix:** Treat a fence as shell when its language is in `shellLangs` or when `lexerFor` reports the Bash or Bash Session lexer, and keep `console` in that set:
```go
func shellFence(lang string) bool {
if slices.Contains(shellLangs, lang) {
return true
}
l := lexerFor(lang)
if l == nil {
return false
}
switch l.Config().Name {
case "Bash", "Bash Session":
return true
default:
return false
}
}
```
Use `shellFence(f.lang)` in place of the `shellLangs` contains check. Add a `Bash` and a `zsh` fence to `TestCommandTokenForms`.
### WR-09: `checkBuiltGo` still accepts Go files `go test ./...` does not build
**File:** `internal/docsite/snippet.go:112` (the `ref.Path` passed in), `internal/docsite/snippet.go:174-178` (the segment test), `internal/docsite/snippet.go:179` (`build.ImportDir` on the resolved directory)
**Issue:** The new skip list looks only at the lexical `src=` path, and only for `testdata` and a `_` prefix. Two layouts that `go test ./...` never builds still pass `Extract`:
- A directory symlink whose name is ordinary. `p/extra` → `p/testdata`, with `hidden.go` calling an undefined function and a test beside it: `Extract(p/extra/hidden.go#Hidden)` returned nil. On that same tree `go list ./...` listed `p` and did not list `p/extra` or `p/testdata`, and `go test ./...` did not run the hidden test. `filepath.WalkDir` does not follow a symlink to a directory, which is why `./...` misses it. The lexical segments of `p/extra/hidden.go` are not `testdata`, and `build.ImportDir` is then pointed at the resolved `testdata` directory, whose own tests make the file look built.
- A package underneath a `vendor` directory. `vendor/leaf/leaf.go` with a test returned nil from `Extract`, and `go list ./...` did not list it. A package whose own directory is named `vendor` is included by `go test` and must stay allowed; only a `vendor` segment that is not the last directory is skipped.
A direct `p/testdata/hidden.go` is refused. The hole is the resolved location and `vendor`.
**Fix:** Decide skip rules from the path `./...` walks, and do not let `EvalSymlinks` move the package check into a directory the walk never enters:
```go
func skippedByGoTest(rel string) bool {
segs := strings.Split(rel, "/")
dirs := segs[:len(segs)-1]
for i, seg := range dirs {
if seg == "testdata" || strings.HasPrefix(seg, "_") {
return true
}
if seg == "vendor" && i != len(dirs)-1 {
return true
}
}
return false
}
```
Before that, `Lstat` each directory prefix of the lexical path and refuse a symlink (`./...` will not descend into it). Call `build.ImportDir` on the lexical directory, not on `filepath.Dir(real)`, so a file symlink is judged as the file the go tool compiles. Add the `p/extra` and `vendor/leaf` cases next to `TestSnippetRootsAndBuild`.
### WR-10: A trailing shell continuation is reported as the command name, and the real command on the next line is never checked
**File:** `internal/docsite/check_commands.go:146-147`, called once per physical fence line at `internal/docsite/check_commands.go:92-94`
**Issue:** `commandWord` returns the first non-flag token after the program. A line `summer \` is therefore the command `\`. Reproduced: an `sh` fence
```sh
summer \
no:such
```
was reported as `command: "\\" is not a summer or application command` and not as `no:such`. The unknown command sits on the continuation line, which is checked alone and is not a summer invocation, so it passes. The same parse rejects a valid wrap (`summer \` / `docs:build --check`) for the token `\`. `highlightShell` already treats a trailing `\` as a continuation; the checker does not.
**Fix:** Join continued lines before `commandWord`, and do not treat `\` as a command word:
```go
var pending string
for _, line := range f.code {
text := strings.TrimRight(line.text, " \t")
if pending != "" {
text = strings.TrimRight(pending, `\`) + " " + strings.TrimSpace(text)
pending = ""
}
if strings.HasSuffix(text, `\`) {
pending = text
continue
}
check(d, d.line+line.line, text)
}
```
### WR-11: The acceptance scanner misses a list-item fence on the marker line, and it marks a normal indented fence as nested
**File:** `cmd/summer/phase11_1_acceptance_test.go:490-507` (`stripMarkers`), `cmd/summer/phase11_1_acceptance_test.go:518-520`
**Issue:** `stripMarkers` only removes leading spaces and `>` markers. A CommonMark list fence whose opener is on the marker line, `- ```go src=p/p.go#Ok`, does not start with a space or `>`, so `scanDocFences` never records it. The comment on `scanDocFences` says a fence inside a list is visible. It is not, for this form. `Check` does refuse it (reproduced: `snippet: ... src= code block must be a top-level block`), so today's SC4 still fails closed through `docsite.Check`. The independent half of SC4, the nested-`src=` walk and the figcaption count, cannot see it. That is the same blind spot CR-01 had, narrowed to one list shape.
The other direction disagrees with the product. Any leading space sets `nested`. Goldmark and `openFence` treat one to three spaces as a top-level fence, caption it, and verify it. SC4 would then fail a page `docs:build --check` accepts, either as a nested `src=` or as a figcaption-count mismatch.
**Fix:** Strip a list marker (`- `, `* `, `+ `, or `N. `) as well as `>`, and set `nested` only when a marker was removed or the indent is greater than three spaces. Leave a one-to-three-space opener as top-level, matching `openFence`. Extend `TestAcceptanceFenceScanner` with `- ```go src=...` and with a three-space top-level fence.
### Info
### IN-09: The identifier index still counts files the default build ignores
**File:** `internal/docsite/check_identifiers.go:85-90`
**Issue:** `buildIdentIndex` parses every non-test `.go` file under `modules/`. It does not apply build tags, so a declaration that exists only in a `//go:build ignore` file (or a mismatched `_GOOS` file) is `pkg.has` and the span passes without reaching `go doc -c`. The new snippet check refuses that file as a `src=` target; a code span naming the same API does not. This diff does not change the index, and the gap notes it as deferred. It is the identifier-shaped remainder of WR-02.
**Fix:** When indexing a directory, keep only the files `build.ImportDir(dir, 0)` lists in `GoFiles` and `CgoFiles`.
---
_Reviewed: 2026-10-01T07:20:12Z_
_Reviewer: the agent (gsd-code-reviewer)_
_Depth: standard_