docs: define collections seam reuse strategy

This commit is contained in:
cyclez 2026-03-25 22:48:03 +01:00
parent ca70d5d9e4
commit 159a517744
2 changed files with 144 additions and 0 deletions

View File

@ -0,0 +1,143 @@
# Collections Seam Decision
## Decision
The emergency fork should **reuse the collections seam**, but **not import the whole upstream collections stack as-is**.
The right split is:
- **reuse in place**: manifest JSON files and their resource contract
- **reuse via adapter**: schema validation, tier resolution, and installed-status logic
- **do not reuse directly in v1**: controller, route, and update-service wiring that is tied to Adonis, Lucid, and the current server/admin runtime
In short:
> the collections seam is strong enough to preserve, but the current upstream implementation is too framework-coupled to become the emergency runtime boundary unchanged.
## Evidence from upstream
### What is strong and worth preserving
The upstream collections layer is already explicit, versioned, and content-oriented.
Relevant upstream files:
- `collections/kiwix-categories.json`
- `collections/maps.json`
- `collections/wikipedia.json`
- `admin/types/collections.ts`
- `admin/app/validators/curated_collections.ts`
Why this is a strong seam:
- manifests are versioned with `spec_version`
- resource entries are explicit: `id`, `version`, `title`, `description`, `url`, `size_mb`
- maps, curated ZIM content, and Wikipedia are all represented through the same family of contracts
- validators already define the acceptable schema cleanly
### What is reusable, but only behind a thin adapter
Relevant upstream files:
- `admin/app/services/collection_manifest_service.ts`
- `admin/app/models/collection_manifest.ts`
- `admin/database/migrations/1770849108030_create_create_collection_manifests_table.ts`
- `admin/app/models/installed_resource.ts`
- `admin/database/migrations/1770849119787_create_create_installed_resources_table.ts`
Useful parts:
- fetch and cache semantics for versioned specs
- pure tier resolution logic
- installed-status computation
- installed resource registry shape
Why it should sit behind an adapter:
- `CollectionManifestService` is coupled to Axios, Vine, Lucid, and hard-coded upstream URLs
- persistence is expressed through the current admin app models
- emergency runtime will likely want its own daemon-owned storage and sync state
### What should not be reused directly in v1
Relevant upstream files:
- `admin/app/controllers/easy_setup_controller.ts`
- `admin/app/controllers/collection_updates_controller.ts`
- `admin/start/routes.ts`
- `admin/app/services/collection_update_service.ts`
Why not:
- route/controller layer is tied to the admin UX and Adonis route tree
- update flow assumes current upstream API orchestration choices
- emergency runtime needs `ON` / `OFF` policy enforcement and armed one-shot semantics that do not exist here
## Practical reuse strategy
### Reuse in place
Keep these upstream assets as the canonical source-selection layer for now:
- `collections/*.json`
This preserves incremental compatibility and gives the emergency fork a stable seam with minimal divergence.
### Reuse through an emergency adapter
Create a future emergency-side adapter that owns this contract:
- load a manifest spec from local file or cached remote source
- validate against the upstream schema
- resolve tier inheritance
- compute installed status from local install state
- expose normalized results to the emergency daemon
This adapter should be framework-light and daemon-friendly.
### Keep emergency storage independent but mappable
The emergency runtime should not depend directly on Lucid models, but it should remain easy to map from upstream concepts:
- `collection_manifests` -> cached upstream specs
- `installed_resources` -> local package/install state
This gives you compatibility without inheriting the current runtime stack.
## Recommendation for v1
For the first technical implementation:
1. Treat `collections/*.json` as canonical upstream inputs.
2. Mirror the schema contract from `admin/types/collections.ts`.
3. Port or reimplement only the pure logic from `CollectionManifestService`:
- tier resolution
- installed-status computation
- filename parsing
4. Do not reuse `CollectionUpdateService` directly.
5. Put all remote fetch and one-shot policy logic behind the emergency daemon.
## Concrete next extraction target
The best next code seam is:
> a pure emergency collections adapter with no Adonis dependency
That adapter should accept:
- manifest type
- raw manifest JSON
- local installed resource state
And return:
- validated normalized manifest
- resolved tiers/collections
- install status
- candidate resources for one-shot sync
## Bottom line
The emergency fork should **stay aligned to upstream collections data** while **owning its own runtime behavior**.
That is the cleanest way to keep incremental compatibility without dragging the entire admin/server stack into the emergency core.

View File

@ -22,6 +22,7 @@ The profile is designed for a dedicated Android device running Ubuntu/Linux wher
- [Architecture](./ARCHITECTURE.md)
- [Local API](./LOCAL_API.md)
- [Seam Map](./SEAM_MAP.md)
- [Collections Seam](./COLLECTIONS_SEAM.md)
- [Bootstrap Prompt](./BOOTSTRAP_PROMPT.md)
## Intended use