ci/woodpecker/pr/ci Pipeline was canceled
Ships fleet/bin/mosaic in the framework so the T106 shipped-first launcher contract survives split-home layouts. The shipped npm mosaic resolves from the passwd real home instead of $HOME: under a seat home (HOME=seat dir) the operator's npm prefix is still found, so 'HOME=<seat-home> fleet/bin/mosaic --version' returns the shipped version. The $HOME/.npm-global candidate is consulted only when the passwd lookup fails, and then every path component must be a non-symlink (secure descriptor traversal; a planted descriptor is refused without execution). T106 behavior preserved verbatim: worktree builds are MOSAIC_CLI_WORKTREE opt-in only, health-checked, shipped fallback on doubt; MOSAIC_FLEET_CLI_OFF forces pure pass-through; no runnable candidate exits 127 with the documented stderr line; stale worktree candidates never regain default precedence (without the opt-in env the worktree path is never read). Manifest: fleet/bin/** added to the [framework] section so the updater and installer both own the subtree (manifest-parity 17/17 green). Hermetic suite test-mosaic-launcher.sh covers the split-home positive, typed failure, stale-worktree non-precedence, opt-in healthy/unhealthy, OFF pass-through, and descriptor-refusal arms. Marker T110-DISPATCH-TOPHER-1N2O.
92 lines
3.4 KiB
Plaintext
92 lines
3.4 KiB
Plaintext
# Mosaic framework path-ownership manifest — SSOT for the updater.
|
|
#
|
|
# This single file is the source of truth consumed by BOTH the bash installer
|
|
# (packages/mosaic/framework/install.sh) and the TypeScript config adapter
|
|
# (packages/mosaic/src/config/file-adapter.ts). A parity test asserts both
|
|
# paths resolve the same ownership from this file, so the two can never drift
|
|
# (the failure mode that #631 patched by hand in two places).
|
|
#
|
|
# Format: one glob per line, relative to the mosaic home (~/.config/mosaic).
|
|
# - Lines starting with '#' and blank lines are ignored.
|
|
# - '[framework]' / '[operator]' switch the active section.
|
|
# - '**' matches any depth; '*' matches within a single path segment.
|
|
#
|
|
# Ownership resolution for a path P (deny-wins / fail-safe):
|
|
# 1. P matches an [operator] glob -> operator-owned.
|
|
# 2. else P matches a [framework] glob -> framework-owned.
|
|
# 3. else (matches neither) -> OPERATOR-OWNED BY DEFAULT.
|
|
#
|
|
# Rule 3 is the root-cause fix for #791: a path the manifest authors never
|
|
# anticipated is protected because UNKNOWN defaults to operator. The updater
|
|
# may only ever create/overwrite framework-owned paths, and may only prune a
|
|
# framework-owned path that lives inside a shipped framework subtree and is
|
|
# absent from the current framework source (a genuinely retired file).
|
|
# Operator-owned and unknown paths are structurally unreachable by pruning.
|
|
|
|
[framework]
|
|
# Top-level framework contract files (also reconciled from defaults/ on upgrade).
|
|
CONSTITUTION.md
|
|
AGENTS.md
|
|
STANDARDS.md
|
|
# Shipped framework subtrees — pruning is scoped to these roots.
|
|
adapters/**
|
|
constitution/**
|
|
CONTRIBUTING.md
|
|
defaults/**
|
|
examples/**
|
|
guides/**
|
|
# Shipped framework subtree — canonical skills are upgrade-reconciled.
|
|
skills/**
|
|
install.sh
|
|
install.ps1
|
|
LICENSE
|
|
profiles/**
|
|
runtime/**
|
|
systemd/**
|
|
templates/**
|
|
tools/**
|
|
# Fleet: only the framework-seeded fleet subtrees are framework-owned.
|
|
fleet/README.md
|
|
fleet/bin/**
|
|
fleet/examples/**
|
|
fleet/profiles/**
|
|
fleet/roles/**
|
|
fleet/roster.schema.json
|
|
fleet/services/**
|
|
# The manifest itself is framework-owned.
|
|
framework-manifest.txt
|
|
|
|
[operator]
|
|
# Identity / user-seeded contract files — generated by the wizard or seeded
|
|
# once from defaults/, then owned by the operator. Never overwritten on upgrade.
|
|
SOUL.md
|
|
USER.md
|
|
TOOLS.md
|
|
# Local overlays (tighten-only) authored by the operator.
|
|
*.local.md
|
|
# Operator-owned trees the updater must never write over or prune.
|
|
agents/**
|
|
policy/**
|
|
memory/**
|
|
sources/**
|
|
credentials/**
|
|
# Operator-authored/customized skills live separately from canonical skills/ and
|
|
# must remain structurally unprunable even as skills/** is framework-owned.
|
|
skills-local/**
|
|
# Secret-bearing operator file INSIDE the framework-owned tools/ subtree.
|
|
# Listed explicitly so the deny-wins rule carves it out of tools/**.
|
|
tools/_lib/credentials.json
|
|
# Operator-owned fleet state (roster SSOT, per-agent env, heartbeats, backlog,
|
|
# persona overrides). Losing these silently downgrades a running fleet (#791).
|
|
fleet/roster.yaml
|
|
fleet/roster.json
|
|
fleet/agents/**
|
|
# Runtime state, incl. the #797 Runtime Session Ledger at fleet/run/sessions/
|
|
# (events.ndjson journal + ledger.json projection). This carve-out is the
|
|
# mechanism that makes the ledger upgrade-safe: an upgrade that wiped it would
|
|
# defeat its reason to exist. The HARD GATE (test-upgrade-manifest-guard.sh)
|
|
# proves a populated ledger survives byte-identical + mtime-unchanged.
|
|
fleet/run/**
|
|
fleet/backlog/**
|
|
fleet/roles.local/**
|