Skip to content

den: declare value-conditional policy codomains (binds, suppresses) - #178

Merged
sini merged 1 commit into
mainfrom
den-codomain-declares
Aug 1, 2026
Merged

den: declare value-conditional policy codomains (binds, suppresses)#178
sini merged 1 commit into
mainfrom
den-codomain-declares

Conversation

@sini

@sini sini commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Two den policies emit their codomain from value-conditional bodies, so any analysis that discovers a policy's codomain by firing it at a value-less probe takes the false branch and observes nothing. This declares the codomain as data on the policy record instead:

  • env-to-hosts becomes a policy record carrying binds = [ "accessGroups" ] — its member emission binds accessGroups, gated on the host's environment matching, which a probe entry never does.
  • drop-user-to-host-on-droid becomes a policy record carrying suppresses = [ "user-to-host" ] — its exclusion fires only where host is bound to a droid target.

Both were bare lambdas; a lambda has no field to carry a declaration, so each becomes the { __isPolicy = true; …; fn } record form. den's policy type checks __isPolicy and its merge preserves extra fields, dispatch reads only .fn — verified inert under the current den pin:

  • Full multi-surface eval capture (users/groups/config-name lists/syncthing folders per host) is byte-identical before and after.
  • Sensitivity control: neutralizing the binding under test moves 13 of those surfaces, so the identity is not instrument blindness.
  • Liveness: replacing a record's fn with a throw propagates — the record form registers, type-checks, and dispatches.
  • The droid exclusion still fires with the declaration in place (verified via the error-fingerprint contrast that flips when the exclusion is disabled).

The declarations become load-bearing at the den v2 pin bump, where the compile layer consumes a declared codomain directly instead of probing the body.

Both records emit their codomain from a value-conditional body, so a body
fired at a value-less sentinel takes the false branch and the codomain cannot
be observed by firing. env-to-hosts declares the accessGroups member binding
it carries into host scope; drop-user-to-host-on-droid declares the policy its
exclusion suppresses. Stratification is decided from the declared graph, so an
edge known only at runtime is one the check never sees.

Both are authored as policy records rather than bare functions because a bare
closure has no field to declare a codomain on. The extra fields are inert under
the current den pin: the fleet surfaces are byte-identical across the change.
@sini
sini merged commit 89db884 into main Aug 1, 2026
1 check passed
@sini
sini deleted the den-codomain-declares branch August 1, 2026 13:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant