# Spike checklist — content plane & assets | Field | Value | |-------|--------| | Blueprint | [ArchitectureBlueprint.md](./ArchitectureBlueprint.md) | | Goal | Falsify or confirm options A/B/C and asset extraction before ADR-0003/0004 | | Time box | Prefer ≤2–3 working days per major spike; stop when decision quality is enough | Scoring legend for each spike: **Pass** / **Partial** / **Fail** / **Skip** with one-line evidence. --- ## Spike 0 — Shared page document fixture **Owner:** coulomb-social **Depends on:** none - [ ] Define one **stage-1 page** markdown fixture: - frontmatter: `id`, `type`, `title`, `abstract`, `visual`, `space` - body: short markdown - backmatter: e.g. `relations` or provenance stub - [ ] Define one **space** container convention (page-type vs directory). - [ ] Define **export package** layout (`pages/**`, `assets/**`, `MANIFEST.json`). - [ ] Commit fixtures under `docs/space-fixtures/` or `docs/architecture/fixtures/`. **Pass when:** fixture is stable enough that all later spikes use the same bytes. --- ## Spike 1 — markitect-tool as structure lib **Owner:** coulomb-social (+ markitect-tool if API gaps) **Depends on:** Spike 0 - [ ] From Python in coulomb (or throwaway script): parse fixture with markitect-tool public API. - [ ] Round-trip serialize without losing title/abstract/visual fields. - [ ] Validate required frontmatter fields (even minimal schema). - [ ] Note missing APIs (backmatter support, field maps) as markitect-tool gaps. **Pass when:** coulomb can treat markitect-tool as dependency for read/write structure without shelling out to `mkt` for the happy path. **Fail when:** only CLI works or public API cannot preserve frontmatter stably. --- ## Spike 2 — Thin folder/git store (Option A) **Owner:** coulomb-social **Depends on:** Spike 0–1 - [ ] Layout: `spaces//pages/.md` + `assets/`. - [ ] Implement throwaway PageOps: list, get, put, copy, transfer (filesystem). - [ ] Reindex card projection into SQLite/Postgres (title, abstract, visual path, space). - [ ] Export = tar/zip of tree; reimport without DB. - [ ] Measure: copy/transfer LOC and failure modes (broken links, name collision). **Pass when:** stage-1 verbs work on files alone; export/import demonstrated. **Decision input:** Is A enough for 3–6 months without federation? --- ## Spike 3 — shard-wiki thin slice (Option B) **Owner:** coulomb-social + shard-wiki **Depends on:** Spike 0 - [ ] Boot one InformationSpace with **single** FolderAdapter or native engine shard. - [ ] Ingest/edit stage-1 page; read via headless API (no UI). - [ ] Implement or map: list, get, put; prototype copy/transfer (engine op or app-level). - [ ] Attach **fake Actor** from static OIDC-like subject; confirm authz hooks exist or gap list. - [ ] Document API surface coulomb would depend on (count endpoints/concepts). - [ ] Stress “structure tax”: can card UI ignore federation/overlays entirely? **Pass when:** thin slice delivers page CRUD without coulomb importing federation UX concepts. **Fail when:** product code must understand multi-shard resolution for basic CRUD. **Decision input:** structure surface area vs future multi-shard value. --- ## Spike 4 — kontextual-engine page + markdown SoR (Option C) **Owner:** coulomb-social + kontextual-engine **Depends on:** Spike 0–1 - [ ] Create `KnowledgeAsset` for stage-1 page; store **source** representation as markdown bytes (BlobStorage). - [ ] Put title/abstract/visual in metadata and/or inside markdown frontmatter (document which is authoritative for export). - [ ] Get content stream; reconstruct `.md` file bit-identical (or document lossiness). - [ ] Run markitect-tool adapter on stored markdown (existing boundary tests as reference). - [ ] Prototype copy = new asset + blob refs; transfer = metadata/relationship change to space context entity. - [ ] Export package: write assets + markdown to filesystem from engine API. **Pass when:** user-visible export is clean markdown+assets; engine IDs are additive not mandatory for reuse. **Fail when:** content is only queryable as opaque registry rows without faithful markdown export. **Decision input:** governance/lineage value vs stage-1 complexity. --- ## Spike 5 — NetKingdom / PolicyGateway wiring **Owner:** coulomb + kontextual (and/or flex-auth) **Depends on:** Spike 3 or 4 - [ ] Map live or mocked OIDC claims → `Actor(external_ref=issuer|sub, groups=...)`. - [ ] Implement **deny-by-default** PolicyGateway stub that allows only same-tenant resource metadata. - [ ] Optional: call flex-auth `check` with coulomb vocabulary (if service available). - [ ] Prove fail-closed: missing policy → no content bytes. - [ ] Document gap list for production adapter ownership. **Pass when:** written design + failing/passing test for cross-tenant deny. **Fail when:** only AllowAll can run the stack. --- ## Spike 6 — Asset / Visual path **Owner:** coulomb (+ kontextual or extracted store) **Depends on:** Spike 2 or 4 - [ ] Store a cover image via content-addressed put; reference from page frontmatter `visual: sha256:…` or `asset:…`. - [ ] Serve image for card UI (signed URL, app proxy, or static mount — pick one). - [ ] GC/unreferenced dry-run once. - [ ] Compare effort: in-process kontextual BlobStorage vs copy port to shared package. **Pass when:** card shows visual without storing image bytes in Postgres. **Decision input for extraction:** is a second consumer ready? If no → keep in kontextual for now. --- ## Spike 7 — Asset-store extraction feasibility **Owner:** platform / kontextual **Depends on:** Spike 6 - [ ] Inventory kontextual `BlobStorage` + adapters (fs/s3/memory) public surface. - [ ] Inventory markitect-main `markitect/assets/` for **ideas only** (dedupe, packaging); do not port wholesale. - [ ] Draft package name + repo boundary: bytes only vs registry. - [ ] Estimate extraction PR: move port+adapters, leave KnowledgeAsset in kontextual. - [ ] List consumers: coulomb, kontextual, shard-wiki (optional). **Pass when:** one-page extraction proposal with “extract now / later / never” recommendation. **Default bias:** **later** until two consumers need it. --- ## Spike 8 — Cross-option decision workshop **Owner:** founder + implementers **Depends on:** Spikes 1–6 results - [ ] Fill scorecard (below). - [ ] Choose primary content plane for stage 1 + migration path. - [ ] Choose asset strategy (in-kontextual vs extract vs folder-only). - [ ] File ADR-0003 (page model + SoR) and ADR-0004 (content plane). - [ ] Update `docs/capability/model-v0.yaml` feature wording if PageOps replaces Forgejo-centric features. ### Scorecard (1–5, higher better) | Criterion | A thin store | B shard-wiki | C kontextual | |-----------|:------------:|:------------:|:------------:| | Markdown export fidelity | | | | | Stage-1 speed | | | | | Structure tax (inverse) | | | | | Copy/transfer naturalness | | | | | Visual/blob readiness | | | | | NetKingdom/authz fit | | | | | Multi-shard / federation later | | | | | Multi-format / ECM later | | | | | Railiance operability | | | | | Aligns with fleet layers | | | | | **Total** | | | | --- ## Suggested order ```text 0 fixture → 1 markitect → 2 thin store (always, baseline) ├→ 3 shard-wiki thin └→ 4 kontextual page+blob → 5 authz on winner(s) → 6 visual → 7 extraction feasibility → 8 decision / ADRs ``` Spike 2 is the **control experiment**: even if B or C wins, A defines the export contract users feel. --- ## Exit criteria for this checklist Stop spiking when: 1. One primary content plane is chosen for stage 1 with explicit residuals, and 2. Asset strategy is chosen (where Visual bytes live), and 3. NetKingdom policy gap is owned (who implements PolicyGateway adapter), and 4. ADR-0003/0004 drafts exist or are scheduled.