zudo-circuit-doc

Type to search...

to open search from anywhere

Publication

The three gates a value must clear to reach a built page, the selection lock, the assets allowlist, and why assetViewerExclude is not privacy.

Adding evidence to a bundle never publishes it. Publication is default-zero and opt-in: a value reaches a built page only if it clears three independent gates, enforced structurally rather than by convention.

The three gates

GateWhat it checksEnforced by
INSTANCEThe record's ID (and, for a source, its source ID) appears in the project's committed InstanceSelection (circuit/publication/selection.json)An ID not listed is simply never read; an ID listed but absent from the evidence is a fatal STALE_SELECTION
FIELDThe value's FieldKey is PUBLISH in the publication matrixPublicationMatrix is Record<FieldKey, FieldDecision> — adding a field to the view model without recording a decision is a compile error, not a runtime gap
VALUEThe value survives text-safety and URL-classification checks at render timeApplied uniformly, regardless of the first two gates

Repository visibility is irrelevant to all three: a field that is readable in the evidence bundle you have checked out is still unpublished until it clears INSTANCE, FIELD and VALUE. The default matrix denies a handful of fields outright regardless of selection — for example source.sha256, source.evidenceExtract, pinMap.reviewedBy and the routing prompt lists — so that hashes, raw extract text, reviewer names and search-avoidance prompts never reach a built page even for a fully selected record.

The selection lock

circuit/publication/selection.json is the reviewed publication lock:

{
  "schema_version": 1,
  "recordIds": [],
  "sourceIds": [],
  "linkableSourceIds": [],
  "documentSelections": [],
  "expect": { "records": 0, "sources": 0, "integrationRules": 0, "packages": 0 }
}
  • recordIds / sourceIds — which records and sources clear the INSTANCE gate.

  • linkableSourceIds — selecting a source publishes its metadata; an outbound link is published only for source IDs also listed here.

  • documentSelections — one document choice per record (documentKind: datasheet, specification or drawing), decided after inspecting the content.

  • expect — a reviewed count lock (records, sources, integrationRules, packages), each of which may be 0. It gates generate/check/build and is never serialized into the preflight report. cad.enabled is a separate capability flag — a selected PCB record while CAD is disabled is an explicit error, never a silent skip, except the one declared-zero exception described in CAD fidelity.

Selection and assets-allowlist edits happen in the same task as the evidence change they publish, and the diff is the review — no separate per-part conversational permission prompt is expected.

The assets allowlist

Raw evidence and CAD files never belong under a built site's public directory by accident. The public-scope check fails on any such file under doc/public/, with exactly two exceptions:

  • generator-owned previews under assets/component-previews/** (footprint SVGs, published WRL models), and

  • files listed in circuit/publication/assets.json, the deliberate-publication allowlist:

{
  "schema_version": 1,
  "assets": [
    { "path": "favicon.svg", "reason": "Site favicon shipped by the zudo-doc scaffold; not component evidence or CAD." }
  ]
}

Each entry names a path relative to publicRoot, a human reason, and an optional source_id. A file placed under doc/public/ for any other reason fails the scan.

The check only restricts file types that are plausible raw evidence or CAD/manufacturing exports — it doesn't scan every file under doc/public/. A restricted extension outside the exempt preview root always needs either the allowlist entry above or to not be there at all:

.pdf .step .stp                                          datasheets, drawings, mechanical exports
.kicad_mod .kicad_sym .kicad_pcb .kicad_sch               KiCad library/board/schematic files
.kicad_pro .kicad_prl                                     KiCad project files
.zip .7z .json .wrl .svg                                  archives, raw evidence bundles, preview formats
.stl .3mf .obj .glb .gltf                                 3D meshes
.gbr .gtl .gbl .gto .gbo .gts .gbs .gtp .gbp .gko .gm1     Gerber fabrication layers
.drl .xln                                                 drill files
.csv                                                       BOM exports

.svg and .wrl are also the preview generator's own output formats, which is why they're on this list and exempted under assets/component-previews/** specifically — anywhere else on the public root they're exactly as unreviewed as any other restricted type.

assetViewerExclude is not privacy

zudo-doc's generated asset viewer can hide a file from its own index with assetViewerExclude. That setting changes visibility in one navigation surface — it does not make the file private, does not remove it from the built output, and does not exempt it from the public-scope check above. A file under doc/public/ is public the moment it is built, whether or not the asset viewer lists it. If a file should not be public, it should not be under publicRoot at all — or it needs a genuine entry (with a genuine reason) in assets.json, not an exclusion flag.

Revision History

CreatedUpdated