fix(wake): #964 re-verdict — record-only polarity, both-forms deny, absent-ledger refusal
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
Answers the NOT CLEAR verdict on #964 (B2 cases C+D, B11), new commit per the re-verdict terms. - B2-D (polarity): extras are RECORD-ONLY by default; byte capture for an extra requires WAKE_PREIMAGE_CAPTURE opt-in. Core set (adapter, watch-list) stays capture-eligible. Case D is safe by polarity alone — verified with the content shape list stubbed to always-allow. - B2-C (both forms): path deny evaluates raw AND realpath-resolved candidate forms against unresolved AND resolved mosaic-home anchors; deny runs first in the gate chain, so an allowlisted symlink cannot smuggle a denied target. - Content deny is defense-in-depth on the opt-in path only: six scrub shapes + named-assignment probe; probe errors fail TOWARD refusal (grep rc>=2 is a deny, not a fall-through). - B11: absent/empty ledger over non-empty objects/ is a loud non-zero refusal to re-baseline — that state cannot be a first install. - Suite: P2 moved to the core adapter; P4/P5/P10 exercise the opt-in path; new needles P13-P17 mirror every verdict probe (symlinked store, outside-store copy, live secret no-opt-in/opt-in, record-only tracking, ledger deletion, allowlist-symlink both halves). Red-first: pre-fix code fails exactly P13/P14/P15/P16 (14 assertions); fixed 17/17. P17's deny half is green pre-fix (basename rule) — kept as a guard needle, disclosed in the PR body. All 10 wake suites green. Written-by: pepper (sb-it-1-dt) Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01NsKce8iZuSuRnu3gVMCBKB
This commit is contained in:
co-authored by
Claude Fable 5
parent
e07943d742
commit
8aff7d8b47
@@ -390,15 +390,33 @@
|
||||
# (acceptance a). A git-repo-in-operator-dir design was REJECTED:
|
||||
# its who/why claim is false under shared-author fleets, and
|
||||
# .gitignore is pattern-based where acceptance (b) demands
|
||||
# fail-closed. (2) CREDENTIAL HARD GATE (acceptance b): byte
|
||||
# capture is REFUSED — never redacted — for (i) credential-store
|
||||
# PATHS (mosaic-home credentials.json, tools/_lib/credentials.json,
|
||||
# credentials/**, any basename credentials.json), (ii)
|
||||
# secret-SHAPED content (digest.sh's six scrub shapes reused as a
|
||||
# content-deny grep), (iii) files over WAKE_PREIMAGE_MAX_BYTES
|
||||
# (default 1 MiB). A refused file still gets its hash/size/mtime
|
||||
# row (captured:false + refused reason) so change TIME survives
|
||||
# even when content must not. (3) FIRST-CLASS CAUSE LINE
|
||||
# fail-closed. (2) CREDENTIAL HARD GATE (acceptance b), FOUR
|
||||
# LAYERS (#964 re-verdict: B2 cases C+D): (i) POLARITY — extras
|
||||
# (WAKE_PREIMAGE_EXTRA) are RECORD-ONLY by default (ledger row +
|
||||
# cause line, NO bytes); byte capture for an extra requires the
|
||||
# path listed in WAKE_PREIMAGE_CAPTURE (colon-separated opt-in);
|
||||
# only the core set (adapter, watch-list) is capture-eligible by
|
||||
# default — a shape list can only refuse the secrets someone
|
||||
# already enumerated, so safety may not rest on one (#964-D).
|
||||
# (ii) PATH DENY evaluated on BOTH the raw and realpath-resolved
|
||||
# candidate forms against BOTH unresolved and resolved
|
||||
# mosaic-home anchors (credentials.json,
|
||||
# tools/_lib/credentials.json, credentials/**, any basename
|
||||
# credentials.json) — a deny list written in unresolved paths
|
||||
# cannot match a path resolved before it arrived (#964-C), and a
|
||||
# symlinked opt-in entry cannot smuggle a denied target (deny
|
||||
# runs FIRST, independent of what the opt-in matched). (iii)
|
||||
# CONTENT DENY on the opt-in path only, defense-in-depth NOT the
|
||||
# safety mechanism: digest.sh's six scrub shapes + a
|
||||
# named-assignment probe (key/token/secret/passw/hmac/credential/
|
||||
# bearer = unbroken value >=16 chars); probe ERROR fails TOWARD
|
||||
# refusal (an error exit is not a negative result); false
|
||||
# positives are acceptable — a false match only withholds byte
|
||||
# capture, never tracking. (iv) size cap WAKE_PREIMAGE_MAX_BYTES
|
||||
# (default 1 MiB). Deny ALWAYS wins over the opt-in. A refused
|
||||
# file still gets its hash/size/mtime row (captured:false +
|
||||
# refused reason) so change TIME survives even when content must
|
||||
# not. (3) FIRST-CLASS CAUSE LINE
|
||||
# (acceptance c): on a change (or deletion — ABSENT is a state,
|
||||
# not an error), one class=actionable entry is enqueued via the
|
||||
# store allocator with locators {kind:preimage, path (§2.1 hard
|
||||
@@ -414,13 +432,20 @@
|
||||
# object/ledger write, or failed enqueue is a loud non-zero —
|
||||
# never read as "no change"; in both integrations the pass exits
|
||||
# non-zero but source observation still proceeds (no starvation).
|
||||
# First-seen is a SILENT baseline (detector first-poll idiom).
|
||||
# An ABSENT/EMPTY ledger with objects/ NON-empty is a loud
|
||||
# non-zero REFUSAL to re-baseline (#964-B11: objects with no
|
||||
# ledger cannot be a first install — history was deleted; the
|
||||
# first-install path must not silently absorb it). First-seen on
|
||||
# a genuinely clean state dir is a SILENT baseline (detector
|
||||
# first-poll idiom).
|
||||
# The installer is UNCHANGED — Gate A auto-enumerates the new
|
||||
# file from the filesystem; the recording site is the runtime
|
||||
# tick, which is where the env-derived preimage set exists.
|
||||
# store.sh/digest.sh/beacon.sh UNCHANGED; watch-list schema
|
||||
# UNTOUCHED ([1,1]). Changed: preimage.sh (new), detector.sh,
|
||||
# reconcile.sh (+ test-wake-preimage.sh P1-P12).
|
||||
# reconcile.sh (+ test-wake-preimage.sh P1-P17; P13-P17 are the
|
||||
# #964 re-verdict regression needles: symlinked store, live
|
||||
# secret value, polarity, ledger deletion, allowlist-symlink).
|
||||
component=wake
|
||||
version=0.7.0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user