[deckle-hosted] Per-site features: add at creation, add later, remove, driven by the harness #145
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#145
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Summary
Let people switch deckle feature bundles (today: news) on and off per site — at site creation, at any later point, and off again — by driving the harness's
features,addandremovecommands. Hosted renders its Features UI entirely from what the configured harness reports, so it knows nothing about any specific feature.Current behavior
harness init, commit, verificationhugo --minify, push (gitservescaffolder). No feature is ever added, and the new-site dialog has no Features group.hugo.tomlafter creation. The editor's publish only carriescontent/andassets/media/tomain, so feature changes can never come from the editor.mainonly on a cold start and only when it is completely clean; any unpublished draft blocks the refresh (instancesworktree handling).Any hardcoded handling of
newsthat exists on a branch (feature names, labels, an edit ofeditor/pagetypes/home.yaml) is replaced by this work.Desired behavior
Catalogue
At startup hosted runs the configured harness once with
features --jsonand keeps the answer: each feature's name, label, description and version. If the command is unknown or fails (an older harness), hosted logs it once, shows no Features UI anywhere, and otherwise works as before.At site creation
The new-site dialog shows a Features group — one checkbox per catalogue entry with its label and description — when "a working deckle site" is selected. The scaffold runs
harness add <feature> --jsonfor each ticked feature afterharness initand before the initial commit, so the first commit already contains them and the verification build covers them. A failed add fails the scaffold like any other step, with its own step name and the harness's diagnostics.On an existing site
A Features section on the site shows every catalogue entry and whether it is installed on the site's
main(fromharness features --site … --json, i.e. the receipts undereditor/features/).Adding runs in a clean temporary clone of
main, exactly like the scaffold:harness add, commit as the platform identity, verification build, push. Nothing is pushed if the build fails. The push goes through the normal build pipeline. Outcomes shown to the user: added; already installed; conflict ("this site has its own files where the feature would go", with the paths); and a note when the harness reports that it could not allow the section on the home page type.Removing (normal path)
harness remove <feature> --jsonwithout--purgeon a clean clone ofmain. This is a read-only preview.main), the remove is refused: the owner is asked to publish or discard those drafts first, with the pages named.harness remove <feature> --purge --jsonin the clean clone, commit, verification build, push.Removing (forced, operators only) — for when the operator must take a feature away regardless of the customer's work in progress:
mainas in the normal path.harness remove <feature> --purgeruns directly on the editor working copy, which deletes draft pages of the feature's types and strips the feature's elements out of other drafts while keeping their other edits.mainwith all remaining drafts intact.Keeping the editor in step
After any feature commit lands on
main, the site's editor working copy is fast-forwarded to it even when it holds drafts, whenever the incoming commits and the drafts touch different files. An add only touches sidecars, layouts and config, so it always goes through; the owner who just enabled News finds it in the editor regardless of unrelated drafts. Drafts are never altered by this.Decisions
mainis always changed in a clean temporary clone, verified by a build before the push — same guarantee the scaffold gives:mainnever receives a tree that does not build.Key interfaces
The harness contract (Cloonar/deckle#144). With
--jsoneach command prints exactly one JSON object on stdout carrying a format version. Exit0: the change happened or was already in place. Exit1: it did not, and the JSON says why. Exit2: usage error, no JSON. Read the status first; treat the exit code as a cross-check.features: name, label, description, version per feature; with--sitealso installed and installed version.add: status added / already installed / conflict (with paths) / error; plus whether the page-type allowance was applied, already present, or skipped (with the reason).removewithout--purge: changes nothing when the feature is in use and reports status blocked with the usage: pages of the feature's types, elements on other pages, customised vendored files, pages linking to pages that would go. Guaranteed read-only on any tree, including one with uncommitted changes.remove --purge: status removed, with what was purged and which config settings were kept because the owner had changed them. Works identically on a clean clone and on a working copy with uncommitted changes.editor/features/and are committed with the site.Starting hints in hosted: the
gitservescaffolder (clone / init / commit / build / push steps andScaffoldError), theinstancesworktree handling (ensureWorktree,refreshWorktree), the config'sharness_pathandoperators, and the new-site dialog.Acceptance criteria
features --json, the new-site dialog lists every reported feature with its label and description; with one that does not, the dialog and site pages show no Features UI and nothing else breaks.harness addduring scaffold fails the creation with a named step and leaves the bare repository empty.main.mainby the platform identity, only after a successful verification build, and triggers the normal site build.mainand a successful build.main, and leaves the editor working copy on the newmainwith unrelated drafts intact and no page or element of the feature left.mainmoved in the meantime (e.g. an editor publish) is retried from a fresh clone or reported; it never leaves a half-applied state.How to verify
DECKLE_HOSTED_TEST_HARNESS,DECKLE_HOSTED_TEST_HUGO).Assumptions to check
hugo.tomlchanges without a restart (the harness reads sidecars per request;hugo serverconfig reload is the part nobody verified).mainleaves exactly the remaining drafts as differences.Decisions not yet made
Out of scope
Blocked by
Parked here for transfer: this brief is for the deckle-hosted repository and is not to be implemented in deckle. It is labelled ready-for-human so no agent picks it up here. The body is written to be copied over as-is; it depends on #144. Close this issue once it has been copied.