# Proposed SPEC § 6.4: `assets/`, the bytes a concept points at Status: **a proposal, raised from a consumer**. Written in this repository because this repository implements the shape; the wording belongs upstream and `_okf-canonical` is not edited from here. Pinned commit read while writing: `ad30107` (OKF v0.2). ## Why it is needed OKF v0.2 is silent about non-markdown files. § 3 says "A bundle is a directory tree of markdown files"; § 11's conformance list scopes every clause to `.md` files; § 6.3 makes `references/` a convention for external material carried as concepts. So a picture is neither permitted nor forbidden — it is unaddressed, and a producer that carries one is guessing about where it goes and what a consumer may assume. The need is not hypothetical. Measured on R761 Prosesskoden:2025, a Norwegian road-construction process code published both as a 701-page PDF and as a NISO-STS XML delivery: the process text is carried in full, and 12 `Tabell N-N` and 9 `Figur N-N` captions stand over nothing, because the publisher ships those tables as raster images in **both** deliveries. Process 84 says "toleranseklasse ... er gitt i tabell 84-2" and table 84-2 is a JPEG. A bundle built from that document reads as complete and is not. ## The proposed wording > ### 6.4 The `assets/` convention > > A bundle MAY carry non-markdown files that its concepts point at — images > extracted from a source document, and anything else a concept embeds rather > than describes. An `assets/` directory at the bundle root conventionally > holds them. > > A concept points at an asset with a standard markdown image or link whose > target is a path-valued reference under § 6.2 — the bundle-relative form > (`/assets/`) is recommended, for the same reason § 6.1 recommends it > for links between concepts: it is stable when a concept moves within its > subdirectory. > > Asset file names are the producer's. A content-addressed name (for example a > prefix of the file's SHA-256 followed by a readable remnant of the source's > own name) is RECOMMENDED, because it makes the same bytes dropped twice one > file and makes a rebuild of one corpus produce one bundle. > > An asset is not a concept. It carries no frontmatter, it is not enumerated by > § 8's index files, and § 11's conformance clauses do not apply to it — they > are scoped to `.md` files, and this section does not widen them. > > Consumers MUST NOT reject a bundle because it carries files they do not > recognise, and MUST tolerate an asset pointer whose target is absent, for the > same reason § 6.1 requires them to tolerate a broken link: the pointer may > record that the source had a figure this bundle does not hold. ## What it does NOT propose - **No screening claim.** Whether the bytes of an asset were examined is outside this section and outside the format. This library states it per run in `log.md` because its own gate is text-only; a picture is not text and did not pass it. - **No required directory.** `assets/` is a convention, exactly as `references/` is. A producer that puts its images elsewhere and points at them correctly is conformant. - **No new frontmatter family.** This library writes a count (`images: N`) on its own profiles, and that is a local key, not a proposal. § 11 already tells consumers not to reject a concept over an unknown key. ## Conformance measured, not assumed The claim "existing consumers do not break" is § 11 item 1 scoping to `.md` files, plus the consumer-side MUST NOTs. Measured on a bundle WITH `assets/`, built by `okf build` from the fixture inbox: | Surface | Result | | --- | --- | | `okf check` (17 rules) | `conformant: 17 rules over 4 excerpts and 2 withheld entries, 0 findings`, rc 0 | | `okf skill` | rc 0 | | `okf consume` | rc 0, 4 excerpts; the pointers travel with the excerpt text | | `okf quality` | rc 3 — "nothing could be judged", because each file type has one document and the floor is five. No false `PASS`, no crash | | guard 1.4.0 `okf.import_bundle` | 6 of 6 concepts merged; the pointer blocks pass the gate as body text | The guard does not reject a bundle carrying binary files — it does not see them, because the importer walks `.md`. So no coordination message to `llm-ingestion-pipeline-security` is needed for this step. The measurement that did NOT pass first time is in the report: Door C merged the concepts and wrote no `assets/` at all, so every pointer in the imported bundle named a missing file. Fixed here, by the content-identity rule that door already owns. The run record is `docs/2026-09-17-bilder-i-bundlen-trinn1.md` § 5. ## Route Raised through `portfolio-optimiser-commons`, which owns the ingest-spec this library implements, and from there upstream. Not edited into `_okf-canonical` from here: that mirror is a read-only pin, and a spec change written by its implementer is not a spec change.