docs(plan): re-sequence v0.2+ streams — defer consumer integration, add OKF inbox showcase as next build

Ground-truth pass over the named flagship consumer (portfolio-optimiser's
'OKF-upload-inbox') found it does not exist as a seam: both optimiser siblings
are frozen at release, carry their own OKF layer, receive no external bundles,
and take no dependency on this guard. Defer consumer integration (stream 2)
until the guard is mature; mature it here first, Node-port-friendly. Next
concrete build is the in-repo OKF inbox showcase (mode-b import_bundle as a
receive/quarantine gate), spec'd under 'The OKF inbox showcase'.
This commit is contained in:
Kjell Tore Guttormsen 2026-07-06 10:12:50 +02:00
commit ba7fc68c05

View file

@ -172,36 +172,82 @@ evasion (2504.11168), EchoLeak (CVE-2025-32711), RAGShield (2604.00387), CaMeL
(2503.18813), Dual-LLM (Willison), and the litellm supply-chain compromise (corroborates
the minimal-dependency thesis).
## v0.2+ stream sequencing (post-v0.1.0, decided 2026-07-06)
## v0.2+ stream sequencing (revised 2026-07-06)
v0.1.0 is tagged — the format-agnostic text core (modules 111, hardened at
`5397ba1`, released at `df30c7b`). Three forward streams, **all to be built**;
the order is dependency-driven, not preference:
v0.1.0 and v0.2.0 are tagged: the format-agnostic text core (modules 111,
`5397ba1` / released `df30c7b`) and the OKF adapter (stream 1, released
`542ac92`). The forward order was **re-sequenced on 2026-07-06** after a
ground-truth pass over the intended flagship consumer.
1. **OKF v0.2 hardening** — the OKF adapter + the 8 tasks in
`docs/OKF-INGESTION-BRIEF.md` §8 (internal order T8 → T1T4+T6 → T7 → T5).
2. **Wire consumers**`claude-code-llm-wiki`, `ms-ai-architect`,
`portfolio-optimiser` (its OKF-upload-inbox is the flagship).
3. **Node/polyglot port** — one polyglot repo over the shared JSON lexicon
(BRIEF §13.5/§8); driver = `ms-ai-architect` convergence.
**Finding that drove the change.** The named flagship — `portfolio-optimiser`'s
"OKF-upload-inbox" — does not exist as a seam. Both optimiser siblings are frozen
at their release milestone, carry their *own* OKF layer (navigate + materialize
from trusted manifests), receive no *external* bundles, and take no dependency on
this guard; the operator's own registered future work for them does not include
it. Wiring an immature guard into two mature, spec-frozen repos would complicate
them for a consumer that is not asking for it. **Consumer integration is therefore
deferred until the guard is mature**; consumers are informed at the operator's
timing, not pushed.
**Why this order (dependencies, not taste):**
Revised streams:
- The flagship consumer (`portfolio-optimiser`'s OKF-upload-inbox) *is* an OKF
surface. Wiring it before OKF hardening ships a knowingly-incomplete guard
into the exact case that needs it → **stream 2 depends on stream 1**.
- The Node port must port a *settled* public surface. OKF v0.2 adds the
OKF-adapter surface; porting before it = porting a moving target and exactly
the §13.3 split-drift the polyglot rule exists to forbid → **stream 3 after 1**.
- Within stream 1: **T8** (residual-risk docs, brief §7.2/§7.4) is the cheap,
decision-free first step — it lands independently and makes the live README
honest about uncovered OKF surfaces before anything else is built. **T3/T4/T5
are blocked on an OKF-spec confirmation pass** (brief §9 "operator premise":
concept-ID=path-minus-`.md`, reserved `index.md`/`log.md`, the `resource`
field, `description``index.md` were taken from the brief, not checked against
`SPEC.md`).
1. **OKF v0.2 hardening** — shipped (adapter + brief §8 tasks; T5b/B deferred to a
consumer that owns corpus storage).
2. **Mature the guard here, keeping it Node-port-friendly** — the near-term work.
The lexicon is already shared JSON (polyglot-ready); keep the `text -> findings`
surface clean and free of Python-only cleverness in the OKF layer, so stream 3
is a *translation*, not a redesign. The centrepiece is the **OKF inbox
showcase** (below): the guard demonstrating its own flagship use case
end-to-end, in-repo.
3. **Node/polyglot port** — the strategic enabler of painless integration (many
OKF consumers are Node/JS; the lexicon seed was `.mjs`). One polyglot repo over
the shared JSON lexicon; never split §13.3. Its API/lexicon contract should be
**scan-informed** (stream 4), not guessed.
4. **Pre-adaptation scan (operator-timed)** — at the operator's chosen point, scan
every repo and plugin that uses or plans Google OKF, then adapt the guard's
surface in advance so a later integration is painless. The scan is the input to
the "painless" guarantee: it grounds both the Node port's contract and any
consumer-specific seams before they are locked.
### The OKF inbox showcase (next concrete build, TDD)
The flagship artifact we hand a consumer later — an in-repo end-to-end
demonstration of the mode-b receive/quarantine gate, mirroring
`tests/test_showcase.py` but for a *received external OKF bundle*. It composes the
public `okf` surface exactly as an "upload inbox" consumer would, so it doubles as
the README's OKF worked example. Every test is authored by us — the point is to
prove intent, not to coincidentally pass.
- **Composition** (`tests/test_okf_showcase.py`): an `_inbox(bundle)` helper
calling `okf.import_bundle(bundle, origin=Origin.EXTERNAL, channel=Channel.AUTOMATIC)`
and mapping the aggregate disposition — `WARN` → ADMIT, `QUARANTINE_REVIEW`
HOLD, `FAIL_SECURE` → REJECT, any error → REJECT (fail-secure default).
- **One poisoned bundle** planting one attack per OKF surface at once, each with a
label proving it was caught/rejected:
- body injection (T1 scan) and frontmatter `description` injection (T1
whole-concept scan);
- a non-`https` `resource:` URL (T3 → FAIL_SECURE);
- a path-traversal concept key `../x.md` (T4 → FAIL_SECURE) and a reserved-name
shadow `index.md` / `log.md` (T4);
- a dangerous frontmatter value (anchor / alias / explicit tag, T2 → FAIL_SECURE);
- a dangerous-scheme cross-link `[x](javascript:…)` (T5a → `links.rejected`);
- a dangling cross-link to an absent concept (§7.2 dormant signal →
`links.dangling`);
- a carrier/obfuscation-hidden body injection (zero-width / homoglyph / rot13 /
whole-string base64) routed through `scan_concept`.
- **Assertions:** aggregate disposition is FAIL_SECURE; every planted OKF
vulnerability appears in the per-concept rejects / findings / link graph; a
**clean** bundle admits (WARN, no rejects, no dangling); `BundleResult.log()`
renders one line per concept with rejects marked. **Detach-proof:** neutering
`import_bundle` to always-admit makes the poison assertions fail.
- **Honest scope:** demonstrates the *structural + known-pattern* OKF surface only
— semantic/factual poisoning stays out (README honest-limits), consistent with
the core showcase.
**Deferred, unchanged:** T5b/B (the persisted cross-run link graph) waits for a
consumer that owns corpus storage; §7.2 dormant cross-run links remain a
documented residual until then.
**Splittable early win (optional):** text-only consumers can be wired at v0.1.0
today — for them the guard is already complete. Folded behind stream 1 by
default (editing other repos = context switch + weaker feedback than the
flagship). Pull forward only on explicit request.
today — for them the guard is already complete. Deferred with stream 2 by default;
pull forward only on explicit request.