diff --git a/CHANGELOG.md b/CHANGELOG.md index aad5367..417be35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,51 @@ skip versions are the composition of each intervening adjacent release's steps in order — no A-to-B path is pre-computed beyond that. +## 0.50.0 — 2026-06-07 + +**Minor — single-entry metadata edit + sidecar-aware writes (§22.4a SLICE-4).** +An authorized user can now edit one entry's schema-defined metadata directly from +its detail view. A new endpoint +`POST /api/projects/{id}/collections/{cid}/rfcs/{slug}/meta` takes `{values:{…}}`, +validates them against the collection's `fields:` schema at the write boundary +(INV-4), writes them to the entry's `.meta.yaml` **sidecar** with a **direct +commit** (D7 — no PR for authorized roles), and re-ingests. A legacy entry is +**lazy-migrated** to a clean body-only `.md` + sidecar on its first metadata edit. +The detail view renders one control per declared field (enum→select, tags→chips, +text→input), read-only without contribute access; `GET` on an entry now returns +its `meta` mapping and a `can_edit_meta` capability. This completes PUC-1 of the +[Configurable Collection Metadata](./docs/design/2026-06-06-configurable-collection-metadata.md) +design (§7.2); bulk edit (SLICE-5) follows. + +Carried from SLICE-1: **every entry write path is now sidecar-aware.** Graduation, +ownership claim, retire/un-retire, mark-reviewed, the body-edit accept/flush +wrappers, and the PR-replay wrappers all dual-read an entry (so a migrated +body-only `.md` no longer crashes `entry.parse`) and write metadata changes to the +sidecar, keeping the `.md` body pure (INV-2) and never re-growing frontmatter; a +legacy entry lazy-migrates on its first metadata-bearing write. With the write +paths safe, the **Owner-gated collection-migration endpoint** +`POST /api/projects/{id}/collections/{cid}/migrate` now ships (PUC-5): it converts +a collection's legacy-frontmatter entries to clean body-only `.md` + sidecars in +one commit, idempotently. + +Non-breaking and opt-in (INV-5): a collection with **no `fields:`** exposes no +edit panel and the edit endpoint returns 422 ("no editable fields"); the §22.13 +default `document` collection declares none — so **N=1 deployments see no change**. + +**Upgrade steps** + +- No schema migration. The edit and migrate endpoints are additive; the sidecar + storage layer (mig 033) and `meta_json` index (mig 034) shipped in 0.47.0/0.49.0. +- A deployment adopts single-entry editing by declaring an `enum`/`tags`/`text` + `fields:` block in a collection's `.collection.yaml` (SLICE-2). Contributors+ + on that collection (§22 Part B / S3 scope roles) may then edit from the detail + view; the change is a direct commit to the entry's sidecar. +- Operators MAY run `POST …/collections/{cid}/migrate` (collection Owner only) to + convert a collection's existing entries to clean body-only docs + sidecars up + front. It is idempotent and safe to re-run; dual-read means an un-migrated + collection keeps working, and entries lazy-migrate on their first metadata edit + regardless. **No data migration is required.** + ## 0.49.0 — 2026-06-07 **Minor — faceted left-pane filtering (§22.4a SLICE-3).** A collection that diff --git a/SPEC.md b/SPEC.md index b437464..7d145aa 100644 --- a/SPEC.md +++ b/SPEC.md @@ -5152,6 +5152,16 @@ never used for routing or lookup. New entries are never assigned one. > across collections. What `type` still selects is the **terminology** (item 2, > the entry noun, shipped v0.45.0) and the **default `initial_state` / review > posture** (§22.4b–c). +> +> **Shipped status.** The design lands incrementally: sidecar storage + +> dual-read (SLICE-1, v0.47.0), the collection `fields:` schema + central +> validation (SLICE-2, v0.48.0), faceted left-pane filtering (SLICE-3, v0.49.0), +> and **single-entry metadata edit (SLICE-4, v0.50.0)** — the direct-commit +> `POST …/rfcs/{slug}/meta` editor (contributor+, validated at the write +> boundary), the schema-driven detail panel, all entry **write paths made +> sidecar-aware** (a migrated body-only `.md` never re-grows frontmatter), and +> the Owner-gated `POST …/collections/{cid}/migrate` endpoint. Bulk edit +> (SLICE-5) follows. See §9.5 for the edit-metadata write-through this reuses. Every collection declares a `type` in its `.collection.yaml` manifest (§22.2), chosen at creation and **immutable**: one of `document`, diff --git a/VERSION b/VERSION index 5c4503b..564edf8 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.49.0 +0.50.0 diff --git a/frontend/package.json b/frontend/package.json index 42127af..1be35a6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,7 +1,7 @@ { "name": "rfc-app-frontend", "private": true, - "version": "0.49.0", + "version": "0.50.0", "type": "module", "scripts": { "dev": "vite",