docs(11.1): record gap-closure code review
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -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_
|
||||||
|
|||||||
Reference in New Issue
Block a user