Files
DevRunbook-Public/docs/44-milestone-one-package-ingestion.md
DevRunbook release export cfd2804e27
Managed validation / full (push) Successful in 3m18s
Publish DevRunbook source
2026-09-03 04:09:17 +02:00

130 lines
6.6 KiB
Markdown

# 44 — Milestone 1 package-ingestion evidence
## Outcome
Milestone 1 passed on 2026-07-27 at commit
`b7dcb5d041f78027c9b6d3edf1d630098337befd`. The authoritative host was the
Unraid 7.2 `linux/amd64` server with Docker 27.5.1, Compose 2.40.3, the pinned
Node.js 24.18.0 image and PostgreSQL 17.9. The Windows Node.js 23 runtime was
not used as milestone evidence.
This milestone closes the canonical built-in content model and persistence
contracts. It does not claim the Library Explorer UI, private ZIP import,
Prompt Lab or package export; those remain assigned to later milestones.
## Content validation and catalog governance
The runtime loader validates package schemas, normalized UTF-8 content,
declared inventory, non-executable regular files, condition and template
semantics, lifecycle evidence and deterministic digests. Failures use
structured `{ path, code, message, remediation }` issues. A catalog load
aggregates errors across package directories rather than hiding later failures.
The separate seed-catalog loader validates all 72 roadmap entries and
cross-checks the 28 publishable P0 entries against runtime package identity,
title, category, type, risk tier, default mode and default autonomy. P1/P2
entries are never materialized as executable runtime packages.
Unit evidence includes malformed YAML, schema failure, semantic secret
exposure, unknown template variables, executable files, invalid UTF-8,
hardlinks, multi-package aggregation, catalog mismatch and duplicate identity.
The governed Python validator independently confirmed 28 P0 packages, six
normative examples, 72 catalog entries, nine schemas and 28 golden prompts.
## Import, storage and query contracts
The application layer owns an importer contract independent of web and worker
frameworks. The PostgreSQL adapter uses an advisory lock and one transaction to
create playbook identities and immutable semantic versions. Identical imports
are no-ops; a reused semantic version with another digest is rejected with
`playbook_version_conflict`. A database trigger independently prevents updates
to published `playbook_versions` rows.
The worker validates and cross-checks all built-ins before polling, imports
them through the shared adapter, and logs counts only. Both supported layouts
are covered: production `/content/{playbooks,catalog}` and development
`/app/content/playbooks` plus `/app/catalog`.
The PostgreSQL catalog chooses the highest eligible semantic version, including
correct numeric and prerelease ordering, and excludes draft or deprecated
versions from the current recommendation. Search uses the indexed search
projection and typed category, risk, lifecycle and source filters. Detail
queries return the current package plus complete version history; exact-version
queries return the immutable manifest, template and quality evidence.
The HTTP boundary exposes:
- `GET /api/v1/playbooks` with `{ items, nextCursor, facets }`;
- validated `q`, `category`, `riskTier`, `lifecycle` and `source` parameters;
- `GET /api/v1/playbooks/{slug}` for current detail and history;
- `GET /api/v1/playbooks/{slug}/versions/{version}` for exact content;
- stable `422` responses for invalid query values.
A public ZIP validation/import endpoint is intentionally not invented here.
The normative API assigns operator package import to the Prompt Lab milestone;
M1's invalid-input acceptance is proved at the canonical content boundary.
## Authoritative validation
The clean Git-bundle clone contained only committed files. The development
target performed a frozen pnpm 10.33.0 install under Node.js 24.18.0. Commands
and results:
| Command or check | Result |
| --- | --- |
| `pnpm verify` | PASS: formatting; 13 lint, typecheck and build workspaces; all unit tests; pack validation; reference composition. |
| `pnpm test:security` | PASS: 2 files, 11 tests. |
| `python3 scripts/validate_pack.py` through `pnpm verify` | PASS: 28 P0, 6 examples, 72 catalog entries, 9 schemas and 28 golden fixtures. |
| `python3 scripts/reference_compose.py --check` through `pnpm verify` | PASS: 28 byte-identical prompts. |
| `pnpm db:migrate` on an empty PostgreSQL 17 volume | PASS; replay after tests also exited zero. |
| `pnpm test:integration` with explicit database and artifact targets | PASS: 3 files, 7 tests. |
| Production `docker compose build` | PASS for web, worker and migrate; image digests recorded by Docker. |
| Production `docker compose up -d --wait` | PASS: PostgreSQL, web and worker healthy; migration exited successfully. |
An initial operator test invocation omitted the required temporary
`ARTIFACT_ROOT`; that invocation was rejected explicitly. Its named temporary
database and artifact volumes were removed, recreated empty and then used for
the passing migration and integration run above.
## Live production evidence
On the fresh Compose database, the worker reported 28 inserted playbooks and 28
inserted versions. After a controlled worker restart it reported zero inserts
and 28 unchanged versions and returned healthy. Direct PostgreSQL counts were
28 playbooks and 28 versions.
Live API checks returned 28 list items. The combined query `root cause` plus
`bugfixing`, `moderate`, `reviewed` and `built_in` returned only
`root-cause-bugfix`. Its detail response exposed current version `1.0.0` and one
history item. The exact-version response contained the manifest, 591-byte
template and quality record. An invalid risk tier returned `422`.
The PostgreSQL integration test attempted to mutate a published version and
observed the immutable trigger rejection. It also proved identical re-import,
digest-conflict rejection, indexed search, full detail and exact-version reads.
Web and worker ran as user `node` with read-only root filesystems and remained
healthy. A production log scan found none of the configured secret values and
no `Authorization:` or `Bearer ` markers.
## Browser evidence
The in-app Chromium browser exercised the live Unraid deployment:
- the home catalog rendered persisted built-ins without Gitea;
- the Root-Cause Bug Fix detail rendered identity, lifecycle, risk, version and
digest and stated the non-execution boundary;
- at 390 by 844 CSS pixels the detail article remained visible and document
width did not exceed viewport width;
- browser warnings and errors: zero.
Search controls, URL-preserved filters, favorites, dense view, enriched package
detail and their keyboard/accessibility gates remain Milestone 2 scope.
## Milestone decision
All Milestone 1 acceptance bullets in `IMPLEMENTATION_PLAN.md` have actual unit,
PostgreSQL, production-container and browser evidence. No project-wide release
artifact or final handoff is created at this intermediate gate. Milestone 2 may
begin.