Skip to content

fix: index command reports empty output for generated index files#8

Merged
akeemjenkins merged 3 commits into
mainfrom
fix/index-reserved-loading
Jul 8, 2026
Merged

fix: index command reports empty output for generated index files#8
akeemjenkins merged 3 commits into
mainfrom
fix/index-reserved-loading

Conversation

@akeemjenkins

Copy link
Copy Markdown
Contributor

Problem

The okf index command generates index.md files into every directory, but JSON output reports count: 0, indexes_written: null.

Root Cause

bundle.Load() calls concept.Parse() for reserved files (index.md). Generated index.md files have no YAML frontmatter, so concept.Parse returns ErrNoFrontmatter. The file is silently skipped because bundle.go only appends to Reserved when perr == nil.

Fix

When concept.Parse returns ErrNoFrontmatter for a reserved file, load it as a Concept with empty Frontmatter and Body set to raw file content. This ensures generated index.md files are tracked in Reserved.

@akeemjenkins

Copy link
Copy Markdown
Contributor Author

Review — reviewed against current main (d641562), test-merged locally

Verified: merges cleanly, and go build / go vet / go test ./... all pass on the merged result. The root-cause fix is correct — reserved index.md/log.md files with no frontmatter were being silently dropped from b.Reserved, which is exactly the slice runIndex scans, so generated index files never appeared in the output. Loading them at the source is the right call, and the fallback Concept's ID/Path match what concept.Parse produces on the success path. Good regression test in bundle_test.go.

🔴 Blocker (fails CI now that lint is enforced): the redundant read is also a gosec finding

Since the CI go-version fix + golangci-lint-action v9 bump landed on main, golangci-lint runs for real, and this branch fails it:

internal/bundle/bundle.go:74:29: G122: Filesystem operation in filepath.Walk/WalkDir callback
uses race-prone path; consider root-scoped APIs (e.g. os.Root) ... (gosec)

concept.Parse(path, relPath) at bundle.go:67 already reads the whole file (it only returns ErrNoFrontmatter after a successful read). The new os.ReadFile(path) at bundle.go:74 reads the same file a second time, and because that literal read sits inside the WalkDir callback, gosec flags it. Fixing the double-read clears the lint failure too.

Suggested fix: surface the raw body from the concept package instead of re-reading in the walk — e.g. have concept.Parse return the raw bytes alongside ErrNoFrontmatter, or add a concept.LoadReserved(path, relPath) helper that does the no-frontmatter fallback internally, so no literal os.ReadFile remains in the callback.

Nits

  • bundle.go:70 — only ErrNoFrontmatter is rescued. A reserved file with malformed frontmatter still hits neither branch and vanishes with no diagnostic (the same silent-drop class this PR fixes). Consider surfacing other parse errors.
  • Missing an end-to-end test asserting runIndex's indexes_written/count is non-empty after generation (the user-visible symptom). The current test covers the loader layer well.

Recommendation: small change requested — resolve the double-read (which also clears the gosec/CI failure), then good to merge.

🤖 Automated review via Claude Code, verified locally against current main.

akeemjenkins and others added 2 commits July 8, 2026 10:47
Resolve the gosec G122 CI-lint blocker: reserved files without
frontmatter were read a second time via a literal os.ReadFile inside the
filepath.WalkDir callback. Move the no-frontmatter fallback into the
concept package as ParseReserved, which reads the file exactly once and
returns a *Concept with empty Frontmatter and the raw content as Body.
No literal os.ReadFile remains in the walk callback.

Also stop silently swallowing malformed-frontmatter errors on reserved
files: ParseReserved only rescues ErrNoFrontmatter and surfaces every
other parse error, so a reserved file with broken frontmatter no longer
vanishes without a diagnostic.

Add an end-to-end regression test that generates index.md files via
index.Generate and asserts they appear in b.Reserved (the slice runIndex
scans), covering the user-visible empty-output symptom.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@akeemjenkins akeemjenkins merged commit 3513efd into main Jul 8, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant