coulomb-social/docs/architecture/spike-checklist.md
tegwick a79a9e6e77 Add ArchitectureBlueprint and content-plane spike checklist
Document coulomb layering (NetKingdom, Railiance, PageOps, markitect-tool),
compare thin store vs shard-wiki vs kontextual-engine, and outline asset-store
extraction from kontextual BlobStorage. Include executable spike checklist.
2026-08-12 18:38:27 +02:00

205 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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 ≤23 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 01
- [ ] Layout: `spaces/<slug>/pages/<page>.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 36 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 01
- [ ] 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 16 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 (15, 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.