Opens the two designed seams (roadmap §8.4): _artifactResolve accepts type:"app" (slug validated, the installed-app gate skipped — presence is the collision policy's call), and payload.kind:"bundle" gets its own APPLY flow. The download core (sha256 pin vs the signed index + minisig + refuse-unsigned) is factored into _artifactDownloadVerified, shared by ops and bundle payloads. A bundle add: fetch → quarantine-validate → place in the definition tree (staging + one rename, manager funnel) → lpRegenWebui → verify the app surfaced in apps.json → applied-record with a precise undo → History. The validator is fail-closed (traversal/absolute paths, links/devices, single top-level dir == slug, charset, size/entry caps, set-id strip, config TITLE+CATEGORY + compose present, bash -n every .sh) because the definition tree is live-sourced on every CLI start — nothing lands there before trust + quarantine pass. Collision policy: installed-live refused, local definitions win, registry-owned re-add = reversible definition update (prior tree packed into the undo). Revert removes/restores the definition (refused while installed) and regens. Apps never auto-apply (type filter kept + publisher forces auto:false). New verb: libreportal app add <slug|artifact-id> (app_add task; resolves by slug via appAddFromRegistry, ambiguity refused). Also fixes the second half of the sigstate-propagation bug class: artifactApply captured $(_artifactResolve) in a subshell, stranding _ART_INDEX/_ART_APP/_ART_SCOPE AND the LP_INDEX_SIGSTATE the apply gate enforces — on a signed box every apply would have refused as unsigned. Resolve now assigns globals (_ART_JSON) and is called directly. Source-and-mock harness: 46/46 (resolve gates, 14 validator refusals, happy add, collision matrix, definition-update round-trip, revert semantics, postcheck + record-failure rollbacks, apply-auto exclusion, app add verb). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
25 lines
1.2 KiB
Bash
25 lines
1.2 KiB
Bash
#!/bin/bash
|
|
|
|
# Artifact (distribution primitive) Commands Header
|
|
# Shows available `libreportal artifact` subcommands.
|
|
|
|
cliShowArtifactHelp()
|
|
{
|
|
echo ""
|
|
echo "Available Artifact Commands:"
|
|
echo ""
|
|
echo " libreportal artifact index - Fetch + verify the signed index; list what's available"
|
|
echo " libreportal artifact applied - List the artifacts currently applied to this install"
|
|
echo " libreportal artifact apply <id> - Apply an artifact (reversible; hotfix ops or app bundle)"
|
|
echo " libreportal artifact revert <id> - Revert a previously-applied artifact (replays its undo log)"
|
|
echo ""
|
|
echo "An 'artifact' is anything LibrePortal pulls from the outside and applies"
|
|
echo "reversibly — a hotfix (bounded declarative ops, no scripts) or an app"
|
|
echo "definition bundle from the registry catalog (themes / components later)."
|
|
echo "They share one team-signed catalog (index.json) on the same channel as the"
|
|
echo "version check, verified against the root-owned signing key. apply/revert run"
|
|
echo "through the task system (never a mutating API), record a precise undo, and"
|
|
echo "auto-roll-back on failure. See docs/roadmap/updates-and-distribution.md."
|
|
echo ""
|
|
}
|