docs(linkedin-studio): OKF-runde trinn C — bundle-inventar + taksonomi-innsigelse

Legger det varige innholdet fra adopsjonsrunden i eiende repo (postkassens
regel 2: beslutninger bor i eiende repos docs, kopien i _okf-interim er
varselet).

Nytt par. 6: bundle-inventar + plassering. Vi har EN OKF-bundle (brain/),
og alt bruker-eid ligger allerede utenfor repo-treet via data-dir-seamen
(M0/v0.6.0) - beslutningen krever ingen migrasjon hos oss.

Innsigelse mot taksonomien: beslutningstabellen diskriminerer paa hvem som
skriver. Vaar brain/ skrives av pluginen og ville derfor klassifisert som
plugin-eid og hoert hjemme i repoet - som er akkurat feil for det mest
personlige vi har, i et offentlig distribuert repo. Riktig akse er hvilken
livssyklus innholdet foelger. Maskinskrevet + bruker-eid er ikke et hjoerne,
det er hva ethvert laerende system produserer.

Par. 7-9 renummerert.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019uzhvLjCm39mNQXVFwG7w2
This commit is contained in:
Kjell Tore Guttormsen 2026-07-20 08:51:20 +02:00
commit c4cd974e9c

View file

@ -16,7 +16,7 @@
>
> **Separate, do not merge:** `docs/ingestion-guard/plan.md` (`planned`) is this repo's *security* wiring
> plan. It shares persist points with this document by necessity, but is a distinct decision with a
> distinct dependency. §6 states the boundary.
> distinct dependency. §7 states the boundary.
## 1. Executive answer
@ -161,7 +161,47 @@ declare themselves generic by architecture. Note we carry the data-root resolver
*path convention* is plugin-local even where the *idiom* is not; a shared library should take the idiom and
leave the path.
## 6. Boundary against the guard plan
## 6. Bundle inventory and placement
Operator decision, 2026-07-20: **user-owned OKF bundles live outside the plugin/repo tree and are only
referenced from it.** Plugin-generated bundles that are part of the plugin's own delivery stay.
**We already comply — the migration happened in M0 (v0.6.0), before the decision existed.** Every
user-owned artifact resolves through `${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/`
(`references/data-path-convention.md`), with an idempotent session-start migration. Nothing user-owned has
lived in the repo tree since.
| Artifact | Path | OKF bundle? | Class |
|---|---|---|---|
| **Brain** | `<data-dir>/brain/` | **Yes** — the repo's only OKF bundle (`type` + per-level `index.md` + root `okf_version: 0.1`; `okf-check.mjs` exit 0, 2026-06-26) | **User-owned** — see boundary case below |
| Published-post tributary | `<data-dir>/ingest/{inbox,published}/` | No — deliberately excluded (§5) | User-owned |
| Trend store | `<data-dir>/trends/trends.json` | No — a single JSON file, not a markdown bundle | User-owned |
| Morning briefs | `<data-dir>/trends/morning-brief/<date>.md` | No — dated briefs with frontmatter, no `index.md`, not concept files | User-owned |
| Specifics-bank | `<data-dir>/specifics-bank/specifics-bank.json` | No | User-owned |
| Analytics batches | `<analytics-root>/posts/*.json` | No | User-owned |
| Reference docs (28) | `references/*.md` **in repo** | No — no `type`, no `index.md` | **Plugin-owned**, ships with the plugin, correctly in-tree |
**Nothing breaks on migration, because there is nothing left to migrate.** The one caveat is historical:
pre-M0 installs kept data in-tree, and the session-start migration already handles that path. A second
caveat worth naming: `assets/drafts/queue.json` and `assets/analytics/` remain in-tree as gitignored
scratch — they are not bundles, but they are the last in-tree paths that hold user bytes, and they should
be revisited if the decision is ever tightened to "no user bytes in-tree at all."
### The boundary case — and it says the taxonomy's axis is wrong
The decision's table discriminates on **who writes**: plugin writes → plugin-owned → lives in the repo.
Our brain is **written by the plugin** (`consolidate`/fold, operator-gated at `--apply --confirm`) and
never hand-authored. By that table it is plugin-owned and belongs in the repo. **That conclusion is
exactly wrong** — it is the single most personal artifact we hold, it must survive plugin upgrade and
uninstall, and the repo is publicly distributed.
The discriminator that gives the right answer everywhere in our inventory is **whose lifecycle the content
follows**, not whose hand writes the bytes. Our brain is machine-written and user-owned, and that
combination is not a rare corner — it is what any learning system produces. We suggest the axis be
lifecycle/ownership, with authorship as a non-determinative attribute. Otherwise every plugin that
*derives* user knowledge lands on the wrong side of a table it read correctly.
## 7. Boundary against the guard plan
`docs/ingestion-guard/plan.md` identifies four persist gates: trends `capture`, brain
`writePublished`/`scanInbox`, newsletter→`ekstern` bindings, analytics `saveBatch`. Two of those (trends
@ -173,7 +213,7 @@ and in what shape.** They share a dependency in one place only — R1's seam is
land — and that is noted as a seam requirement, not a security decision. Neither plan is a prerequisite for
the other's approval. The guard plan's own interop blocker (Python↔Node) is tracked there.
## 7. Open questions for the library owners
## 8. Open questions for the library owners
1. Does R1 (model-mediated payload door) belong to door B, or is it a fourth door? It is neither an inbox
scan nor an external bundle import.
@ -182,7 +222,7 @@ the other's approval. The guard plan's own interop blocker (Python↔Node) is tr
3. For phase 4: is the Node half expected to reach parity with door A only, or with whatever doors exist
when it starts? Our adoption depends on R1, which is not door A.
## 8. References
## 9. References
- Library: `https://git.fromaitochitta.com/open/llm-ingestion-okf`
- Guard: `https://git.fromaitochitta.com/open/llm-ingestion-pipeline-security`