ZDDC/zddc/internal/zddc/worm.go
ZDDC 1e0e403f1e feat(zddc): retire defaults.zddc.yaml; .zddc.zip is the policy carrier (phase 6)
Completes the migration. The embedded per-depth tree (internal/zddc/defaults/)
is now the sole source of the shipped baseline; defaults.zddc.yaml is deleted.

  - EmbeddedDefaults() assembles the tree (no yaml). show-defaults now emits a
    .zddc.zip (per-depth, "*" wildcard members) via EmbeddedDefaultsZip() —
    operators redirect it to <ROOT>/.zddc.zip (or any directory) and edit/add/
    delete individual members.
  - Dropped EmbeddedDefaultsBytes; reworked the dumpable test to validate the
    emitted zip; removed the now-redundant tree-vs-yaml oracle (the Layer-2
    matrix is the ongoing behavioral guarantee, and it stays green).
  - Swept stale "defaults.zddc.yaml" comment references to the embedded tree.
  - GRAMMAR.md §1/§6 updated: .zddc.zip is a policy bundle mountable at ANY
    directory (subtree mount; inherit:false + acl.inherit:false = island); the
    shipped baseline is the embedded bundle at the root.

Net of the 6-phase migration: policy is per-depth .zddc files in a .zddc.zip
that an operator can drop at any level to override the cascade; the engine
(Assemble + the unchanged walker) enforces it. Full Go suite + matrix green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 11:35:21 -05:00

60 lines
2.2 KiB
Go

package zddc
// WORM (write-once-read-many) zones are declared in the cascade via
// the `worm:` key on a ZddcFile (see file.go). This file resolves the
// effective WORM grant for a principal walking a policy chain.
//
// Replaces the hardcoded IsWormPath / WormFolderLevelIndex / WormMask
// machinery (which keyed off the literal folder names "received" and
// "issued"). The convention now lives in internal/zddc/defaults/ — those
// two folders carry `worm: {}` — and any operator can mark another
// directory WORM by adding `worm:` to its .zddc.
// WormZoneGrant inspects the policy chain for email. If any level in
// the chain (including paths-derived contributions) declares a `worm:`
// map, the path is inside a WORM zone: inWorm is true and grant is the
// UNION of the principal's verb grants across every Worm map in the
// chain, masked to {r, c}. When no level declares worm:, inWorm is
// false and grant is meaningless (returned as 0).
//
// Caller (the policy evaluator) combines this with the normal cascade
// read grant:
//
// if g, inWorm := WormZoneGrant(chain, email, mode); inWorm {
// effective = (normalCascadeVerbs(chain, email, mode) & VerbR) |
// (g & VerbsRC)
// return effective.Has(requestedVerb)
// }
//
// i.e. inside a WORM zone, w/d/a are always stripped; c survives only
// via the worm: grant; r survives via the normal ACL or the worm:
// grant. Admins are excluded upstream (handler's IsAdmin bypass).
func WormZoneGrant(chain PolicyChain, email string) (grant VerbSet, inWorm bool) {
for i := 0; i < len(chain.Levels); i++ {
wl := chain.Levels[i].Worm
if wl == nil {
continue
}
inWorm = true
for _, principal := range wl {
if MatchesPrincipal(principal, email, chain, i) {
grant |= VerbsRC // listed controllers get read + write-once-create
}
}
}
// The embedded baseline could in principle carry a top-level
// worm: too (it doesn't today — it's declared via paths:), so
// fold it in for completeness.
if chain.Embedded.Worm != nil {
inWorm = true
for _, principal := range chain.Embedded.Worm {
if MatchesPattern(principal, email) {
grant |= VerbsRC
}
}
}
if !inWorm {
return 0, false
}
return grant, true
}