fix(docs): stop embedding internal engineering records; close the docs corpus - #1654
Merged
Conversation
…aries `DocsAssets` embedded all of `../docs` minus `book/` and hidden dirs, so every binary carried the ~39 working records under `docs/audit/` and `docs/audit-impl/` — audit briefs, findings registers, per-branch gate logs naming branches, worktree paths, benchmark run IDs, and contributors. They are not in `SUMMARY.md`, so mdBook never published them, but `fluree docs search` and the `docs_search` MCP tool returned them to any user. Exclude both trees; source comments that cite them by repo-relative path are unaffected. The leak was possible because nothing decided what the embedded set is. Make it a policy with a guardrail: an embedded page must be linked from `SUMMARY.md` or listed in `EMBEDDED_EXTRAS` with a reason, and only markdown embeds at all (the index skips everything else, so `book.toml` and the llms.txt preprocessor were dead weight). Tests fail in both directions — an unaccounted page, and an extras entry whose file is gone. Reconciling the existing corpus turned up three user-facing pages that were embedded but missing from the TOC, which also means mdBook never built them and the inbound links from published pages (`memory/guides/README.md`, `memory/cli/memory.md`, root `BENCHMARKING.md`) are broken on the site. Publish them. `operations/running-fluree.md` goes to `EMBEDDED_EXTRAS` with a TODO instead: it overlaps three published pages and whether to publish or fold it is an editorial call.
…docs Two things an agent driving this CLI has no way to discover from inside the binary: the packaging that installs the MCP wiring for it (fluree/claude-plugins, plus the forthcoming stack-first `fluree-companion` plugin), and the fact that a Fluree AI stack publishes a second, disjoint corpus at `https://<stack>/api/docs` describing the stack rather than the binary. Both as cross-links, in the page's existing style — the corpora stay separate, they just now know about each other.
…./ links Review-pass remediation. parse_summary was a line scan while mdBook parses CommonMark, so a SUMMARY entry commented out with a MULTI-LINE <!-- --> block — the natural way to temporarily unpublish a section — kept every guardrail green while mdBook dropped the page: embedded, searchable, deliberately unpublished, silently exempted from the closed-set policy (reproduced before fixing; the same-line form already failed closed). Comment spans are now stripped before the scan, newlines preserved so depth arithmetic is unaffected, unterminated comments run to end-of-input — and docs_tree stops listing commented-out chapters as a side effect. A ./ link prefix is normalized away too: mdBook accepts it, embedded paths never carry it, and unnormalized it produced a guardrail failure claiming a published page was unpublished. Also: ai/claude-code.md no longer overstates the fluree-cli plugin's wiring (it registers docs-only, not memory), and the index's redundant post-include filters are labeled belt-and-braces rather than load-bearing.
This was referenced Aug 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #1653 — the A1 corpus scoping plus the D3 cross-links. A6 (rev-stamping non-release builds) is deliberately not here; reasons at the bottom.
A1 — the embedded corpus is now a closed set
The rust-embed derive in
fluree-db-docs/src/embed.rsembedded all of../docsminusbook/*and hidden dirs — which shippeddocs/audit/anddocs/audit-impl/(39 internal engineering records: branch names, worktree paths, benchmark run IDs, contributor attribution) inside every released binary, retrievable by any user or agent throughfluree docs search/ the MCPdocs_searchtool. Verified at the binary surface before and after:fluree docs search "findings register"returned fouraudit/…paths onorigin/mainand returns none on this branch;"worktree"went from four hits to zero. Worth being precise about the exposure: mdBook only buildsSUMMARY.mdchapters, so these records were never on the docs site — the leak was exactly the binary/agent surface, i.e. content deliberately kept off the website was being served to anyone who asked the binary.The fix is a policy, not just an exclude: an embedded page must be linked from
SUMMARY.md, listed inEMBEDDED_EXTRASwith a reason, or excluded — and four new guardrail tests keep the set closed in both directions (embedded-but-unlisted fails naming offenders; an extras entry that stops existing fails too, so the allowlist can't rot).#[include = "*.md"]also dropsbook.tomlandscripts/llms_preproc.py, which were bytes in every binary no surface could return. The arithmetic closes exactly: 233 embedded = 231 SUMMARY-linked + 2 extras.Disclosure: which releases shipped this.
docs/audit/first appears at tag v4.1.2 (11 records) and the set grows to 39 by v4.1.5 — so released binaries v4.1.2 through v4.1.5 all embed internal engineering records (branch names, worktree paths, benchmark run IDs, contributor attribution), retrievable viafluree docs search/docs_getand the MCP docs tools. The records were never on the docs site (mdBook builds only SUMMARY chapters); the exposure is exactly the binary/agent surface. At the CLI's default limit of 10,"findings register"returned 9/10 audit hits and"worktree"returned 8/8 — the word existed nowhere else in the corpus. This PR is labeledbugso release notes file it where someone auditing an installed binary will look.The 44 previously-unlinked files (39 excluded + 3 promoted + 2 extras, one of which is
SUMMARY.mditself) sorted as:SUMMARY.md—contributing/benches.md,memory/cli/audit.md,memory/guides/hygiene-and-auditing.md. The two memory pages had inbound links from published pages that were dead on the site;contributing/benches.md's inbound links are repo-root files (BENCHMARKING.md,fluree-bench-support/README.md), so promoting it is an editorial call — the right one, but a call, not the mechanical no-judgment case.SUMMARY.mditself (the TOC;docs_treeparses it, it isn't a content page) andoperations/running-fluree.mdwith aTODO(review): 402 lines, zero inbound links, substantial overlap with three published pages. Publishing it or folding it in is an editorial call I didn't want to make silently inside a scoping PR, so it stays searchable with the open decision visible.Mutation-checked: a scratch page under
docs/fails the publish test naming it; removing the excludes fails three tests listing all 39 records; a bogus extras entry fails the exists test.D3 — the glue docs
docs/cli/server-integration.mdanddocs/cli/load.mdturned out to already be inSUMMARY.md(221d01a, which also added thedocs_coveragegate fordocs/cli/) — the anchor's premise was stale there, and the new corpus-wide test generalizes that same gate. What did change:docs/ai/claude-code.mdnow points at thefluree-cliClaude Code plugin (and the forthcoming stack-firstfluree-companion), and its remote section notes that a Fluree AI stack serves its own version-pinned docs at/api/docs— shape verified against the solo source rather than taken on faith.Why A6 isn't here
Rev-stamping would touch two different contracts and neither cheaply: this workspace has zero build scripts across 48 crates (adding one to the CLI puts a build-script dependency in every workspace compile), a baked SHA goes stale without rerun-if-changed on the resolved HEAD — and in a repo worked almost entirely through git worktrees, the obvious
../.git/HEADis wrong in exactly the environment we use daily; a confidently wrong rev is worse than none. And the docs-stamp half isn't a field addition —fluree_db_docs::VERSIONrides the wire shape ofdocs --jsonand the MCPdocs_*tools, which downstream consumers parse.fluree manifestalready carries thefeaturesarray as the main same-version-different-surface signal, and A1 makes the docs corpus deterministic per commit. If we still want build-identity in the field, it deserves its own issue with those constraints on the table.Tests
cargo fmt --checkclean;clippy -p fluree-db-docs --all-targetsclean;fluree-db-docs19/19 (4 new);docs_coverage5/5;fluree-db-mcp8/8;mdbook buildsucceeds and the llms preprocessor stages 231 pages, matching the SUMMARY count exactly.One pre-existing loose end left alone:
bench-baselines/README.mdlinksdocs/audit/2026-06-architecture-audit.md, which no longer exists onmain— unrelated to this change.Review-pass remediation (post-open):
parse_summarynow strips HTML comment spans before scanning — a SUMMARY entry unpublished with a multi-line<!-- -->block previously kept all guardrails green while mdBook dropped the page (reproduced, then fixed; the same-line form already failed closed), anddocs_treestops listing commented-out chapters as a side effect../-prefixed links are normalized so a published page can't fail the guardrail with a message claiming the opposite. Three new parse tests cover both comment forms, unterminated comments, and the prefix.ai/claude-code.mdno longer overstates the fluree-cli plugin's wiring (docs-only, not memory), and the index's post-#[include]filters are labeled belt-and-braces. Docs suite 22/22, coverage 5/5, mcp 8/8, fmt + clippy clean.Note on the clippy red at HEAD: it is main's breakage, not this branch's — #1580 trips
clippy::type_complexityon main itself, and every PR inherits it through the merge-ref checkout. Fix: #1658. This PR's own crates are clippy-clean under-D warningslocally.