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.
205 lines
7.8 KiB
Markdown
205 lines
7.8 KiB
Markdown
# 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/<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 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.
|