This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user