fix(framework): track anchor presence separately from value (T51 WP0b rework)
ci/woodpecker/pr/ci Pipeline was successful

${VAR:-} collapsed exported-empty into genuinely-unset, mis-filing
both-empty and the two mixed empty/unset states as informational where
the charter requires WARNs. Presence now tracked via [[ -v VAR ]]
alongside value: NOTES only when both variables are genuinely absent;
any present-but-empty or single-present state emits a loud WARN per
missing/empty anchor, each naming the launchers as authority (unset and
empty get distinct wording). Suite: the wrong both-empty note arm
replaced by three warn arms (both-empty, host-empty+brain-unset,
host-unset+brain-empty); warn arms accept >=1 warn with zero notes
(single-present states warn once, both-present-empty warns twice — per
anchor, by design); red control now mutates presence tracking back to
the nonemptiness collapse (the reviewed defect shape) and must emit
NOTEs for both-empty. 10 arms green; gates green.
This commit is contained in:
2026-08-24 07:32:35 -05:00
parent 023540b151
commit 7ad47152c2
2 changed files with 40 additions and 18 deletions
@@ -392,19 +392,34 @@ check_structure_anchor_provisioning() {
# Severity follows the doctor's existing conventions: pass/note are quiet
# (note unless --verbose), warn counts toward --fail-on-warn.
local host_root="${MOSAIC_HOST_ROOT:-}" brain_home="${MOSAIC_BRAIN_HOME:-}"
if [[ -n "$host_root" && -n "$brain_home" ]]; then
# T51P2WP0BRW B1: presence is tracked SEPARATELY from value — `${VAR:-}`
# collapses exported-empty into genuinely-unset, which mis-filed both-empty
# and the mixed empty/unset states as informational. Only BOTH-genuinely-
# absent may be informational (charter state 3); any present-but-empty or
# single-present state warns.
local host_set=0 brain_set=0
[[ -v MOSAIC_HOST_ROOT ]] && host_set=1
[[ -v MOSAIC_BRAIN_HOME ]] && brain_set=1
if [[ "$host_set" -eq 1 && "$brain_set" -eq 1 && -n "$host_root" && -n "$brain_home" ]]; then
pass "Structure anchors provisioned: MOSAIC_HOST_ROOT=$host_root MOSAIC_BRAIN_HOME=$brain_home (paths reported only; not expanded, not consumed)"
return
fi
if [[ -z "$host_root" && -z "$brain_home" ]]; then
if [[ "$host_set" -eq 0 && "$brain_set" -eq 0 ]]; then
note "Structure anchors not provisioned in this environment. Launcher-equivalent derivation (INFORMATIONAL, NON-AUTHORITATIVE — seats receive the authoritative values from the launchers): MOSAIC_HOST_ROOT would default to the operator home; MOSAIC_BRAIN_HOME would default to the brain tree resolved at launch. Doctor does not guess values for consumption; it audits provisioning."
note "Provision both anchors via the seat launchers (launch-seat.sh / launch-seat-claude.sh export them; see T51 spec §1.2a)."
return
fi
if [[ -z "$host_root" ]]; then
warn "MOSAIC_HOST_ROOT is missing or empty in this environment while MOSAIC_BRAIN_HOME is set — declaration consumers fail closed without it (spec §1.2a). The seat launchers are the authoritative source."
else
warn "MOSAIC_BRAIN_HOME is missing or empty in this environment while MOSAIC_HOST_ROOT is set — the projects/ mirror and brain declaration resolve from it (spec §1.2a). The seat launchers are the authoritative source."
# At least one variable is present (possibly empty), or exactly one exists:
# every missing/empty anchor gets its own loud WARN naming the launchers.
if [[ "$host_set" -eq 0 ]]; then
warn "MOSAIC_HOST_ROOT is not set in this environment while MOSAIC_BRAIN_HOME is — declaration consumers fail closed without it (spec §1.2a). The seat launchers are the authoritative source."
elif [[ -z "$host_root" ]]; then
warn "MOSAIC_HOST_ROOT is present but EMPTY in this environment — declaration consumers fail closed without a usable value (spec §1.2a). The seat launchers are the authoritative source."
fi
if [[ "$brain_set" -eq 0 ]]; then
warn "MOSAIC_BRAIN_HOME is not set in this environment while MOSAIC_HOST_ROOT is — the projects/ mirror and brain declaration resolve from it (spec §1.2a). The seat launchers are the authoritative source."
elif [[ -z "$brain_home" ]]; then
warn "MOSAIC_BRAIN_HOME is present but EMPTY in this environment — the projects/ mirror and brain declaration resolve from it (spec §1.2a). The seat launchers are the authoritative source."
fi
}