feat: machine-owned, versioned sidecars and harness migrate #306
No reviewers
Labels
No labels
bug
enhancement
needs-triage
ready-for-agent
ready-for-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/deckle!306
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "afk/302"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Sidecars are now machine-owned and versioned per file, and the harness migrates them forward. The schema can change after sites are in production without pinning the harness.
What changed
internal/sidecardir):Versionschain (today{Oldest: 1, Current: 1}, no steps) and a key order.Canonicalis the one serializer. It emits the two-line machine-owned header, block style and one spelling per value, and checks itself by decoding its output again.Plancomputes every file's canonical bytes at the current version.Loadapplies the same chain in memory, so the loader andharness migrateshare one transform.RequireVersion1, soversion: 2is a load error naming the file.harness migrate [--site] [--json](internal/migratecmd):--jsonshape (formatVersion: 1).harness checkwarns, per file, about a sidecar or language file that is outdated or not canonical, and namesharness migrateas the fix.scaffold/canonical_test.go) keeps them so.harness addwrites bundle sidecars canonical,--dirbundles included, and hashes the bytes it writes.childrenedit (add/remove) now decodes the file, edits it and writes it back canonical, replacing about 500 lines of textual editing. It refuses an outdated sidecar.harness sidecardrafts canonical YAML and prints its review hints instead of# TODOcomments.internal/sidecarsetis the one owner of which site directory holds which family.## Migrate,### harness migrate --json, the two check warnings and the receipt rule.Behaviour to note
version: "1"orversion: 1.0still loads, as it did before; migrate writes it as1.harness addorharness removeon a site's page type rewrites that file in canonical form. Its comments are dropped, as the issue specifies.harness.yamlleniently, so it needs no change. Runningmigrateon upgrade is its own issue.Verification
go vet ./...,gofmtandgo test ./...are all green;npm testinweb/passes 3317 tests.migratereportunchanged.add newsand a comment added tocards.yaml,checkgives one warning;migraterewrites that one file and no receipt;checkis then clean andremove newssucceeds.version: 99sidecar givesstatus: errorand exit 1.news-list.yamlis still reported customised byremove newsaftermigrate.Closes #302
🤖 Generated with Claude Code
[autoland] verdict: pass
PASS — validated by the lander.
Signal relied on:
labctl pr checks 306aggregate success (ci / build-and-test green; release skipped as usual on a PR). Head60b2fe6sits directly on current main (merge-base = main tip2ce93a7), so there is nothing to resolve.Conventions: the Conventional Commits title is fine and
Closes #302is present. The diff matches the issue's brief: the version chain and canonical serializer in sidecardir, Load and Plan sharing one chain, element sidecars on RequireVersion1,harness migratewith the documented --json shape and exit codes, the receipt matched-before rule, the check warnings, and canonical writers in init/add/sidecar plus the children edit. The ADR, AGENTS.md, docs/harness.md, docs/features.md, architecture, the docs map, one README line and every listed skill are updated.Spot checks: I probed whether canonicalizing unquoted scalars (1.50, 01, 0x1F, 1_000, yes, 1e3, dates) changes a loaded Schema. It doesn't, because goccy's typed decode already normalizes them, so a select option or label loads the same before and after migrate. deckle-hosted reads only feature/version from receipts and no sidecar, so migrate's receipt rewrites are safe for it.
Nit, non-blocking:
sidecarset.ForPathhas no non-test caller yet.