Contextfulv0.23.0

Docs / Specification

A-disclosure — Visibility, disclosure and accountability decisions

Status: accepted

mirrored-authorization-carries — Mirrored authorization carries a freshness budget and refuses past it

Cited bydisclosure.sweep.coverage-watermarkdisclosure.sweep.ungapped-streamdisclosure.sweep.sweep-epochdisclosure.reach.degraded-uncacheddisclosure.reach.cache-epochsdisclosure.bound-staleness.budget-grammardisclosure.bound-staleness.access-staledisclosure.bound-staleness.budget-below-cadence

A mirrored grant is only as current as the oldest resource its sweep observed. The narrowing posture on_stale = public_only serves only swept public rows, marked degraded.

OptionLost onCost
Coverage watermark, per-table budget, typed refusal (chosen)—A limping sweep takes a source offline; the public-status sweep is a second shape to operate.
Serve past the budget with an advisory fieldDetectabilityA revoked grant keeps answering, marked by a field nobody reads.
Zero rows past the budget, or a truncated closureDetectabilityA shortened set reads as a quiet corpus.
A time-to-live on the reachable-set cacheInvalidation by constructionA revoked grant answers for an undeclared second staleness window.

Revisit: a source offers sequenced delivery with gap reconciliation.

fidelity-bounded-what — Fidelity is bounded by what the source enforces

Cited bydisclosure.declare-fidelity.family-bounddisclosure.declare-fidelity.family-undeclareddisclosure.declare-fidelity.federated-registereddisclosure.pack.mapping-absentdisclosure.pack.asserts-accessdisclosure.pack.unsupported-coarse

The family is the one judgment per source. A source that computes access answers live under the reader’s delegated credential; a source with no permission data lands with no fidelity claim.

OptionLost onCost
Per-table level bounded by a declared family (chosen)—Federated legs pay live latency and go dark with the source.
One deployment-level permission-aware claimFalsifiabilityThe weakest source sets the real guarantee undetected.
Mirror a sharing engine’s inputs and reproduce its rulesDriftA second evaluator disagrees in exactly the restricting constructs.
An audience field in the packEnforceabilityNo read-path step consults it.

grants-rows-under — Grants are rows under _visibility, and the closure is a rebuilt projection

Cited bydisclosure.mirror.grants-tabledisclosure.mirror.unmirrorable-openingdisclosure.reach.closure-overflowdisclosure.template.read-envelope

Authorization has one source, the join over observed rows, and a replica answers offline.

OptionLost onCost
Grant rows via the land path, closure in derived.sqlite (chosen)—A replica rebuilds the closure after each pull.
A separate grant store beside the catalogOne write pathA second commit protocol, lock and erasure path.
A closure synced as filesOne authorization sourceClosure bytes on a replica drift from their rows.
Openings as manifest policyEnforceabilityA key no sweep observes answers without expiry or record.

aggregate-disclosure-enforced — Aggregate disclosure is enforced at build with noisy thresholding and an up-front budget reservation

Cited bydisclosure.release.budget-reservationdisclosure.release.release-envelopedisclosure.release.duplicate-graindisclosure.release.group-keydisclosure.release.contributor-keydisclosure.release.forbidden-columndisclosure.suppress.min-group-sizedisclosure.suppress.contributor-sharedisclosure.suppress.dominance-unverifiabledisclosure.suppress.empty-policydisclosure.suppress.grouping-allowlistdisclosure.suppress.sentinel-rowdisclosure.bound-cohort.singleton-cohortdisclosure.bound-cohort.exact-figures

Every read path inherits the guarantee from the staged bytes.

OptionLost onCost
Build-time enforcement, reservation up front (chosen)—A policy edit is a rebuild; an exhausted unit blocks every release naming it.
Suppress on exact counts, or a switch to exact figuresPrivacy guaranteeCell presence discloses a threshold crossing; a policy edit removes the protection.
Debit spend after the releaseConcurrencyTwo concurrent releases each spend budget the other observes.
A query-time aggregate evaluatorSurvival across read pathsReimplemented per surface; a rollup loses per-contributor mass.

Revisit: lookalike segment release settles its audience floor, readback rule and cross-party consent.

exact-integer-noise — Exact integer noise spends the declared budget across released statistics

Cited bydisclosure.release.noise-mechanismdisclosure.release.metric-boundsdisclosure.release.lookalike-refusal

An auditable privacy spend needs finite sensitivity and a sampler with no floating-point tails.

OptionLost onCost
Exact geometric noise, bounded metrics, no lookalike release (chosen)—Every noised sum needs bounds; an activation product has no release path.
Floating-point Laplace noise over raw sumsAuditable sensitivityThe privacy spend is unverifiable.
Exact grouped figures behind a noisy thresholdFigure privacyA published sum reveals contributors even with the key hidden.
Lookalike release beside aggregate figuresConsentAn activation handle reaches a party under no consent rule.

Revisit: a consent and readback contract admits activation handles.

model-declares-spend — The model declares the spend, the project the cap, and the ledger stays on the machine

Cited bydisclosure.release.model-policydisclosure.release.release-verbdisclosure.release.spend-declarationdisclosure.release.lifetime-capdisclosure.release.budget-ledger

One cap per unit decided it. No spend is undeclared, and no contributor key rests outside the store.

OptionLost onCost
Spend on the model, cap on the project, local ledger (chosen)—Two machines releasing one project each hold a full cap.
A cap per modelOne cap per unitA unit named by two models spends two lifetimes.
A default spend when none is declaredAuthor intentEvery unit pays a budget nobody chose.
The ledger inside the store rootReplica safetyA push carries per-contributor balances to every replica.

Revisit: a project releases from more than one machine.

cross-owner-release — A cross-owner release runs only when the boundary is enforced below the engine

Cited bydisclosure.set-mode.check-verbdisclosure.set-mode.aggregate-shapedisclosure.set-mode.policy-absentdisclosure.set-mode.opt-out-recorddisclosure.set-mode.model-unreadabledisclosure.set-mode.clean-room-preconditionsdisclosure.set-mode.hashed-joindisclosure.set-mode.pepper-version

A protection the engine only documents fails silently, as corrupted data or a forged grant.

OptionLost onCost
Store-enforced preconditions, per-pair pepper (chosen)—Stores without per-prefix write policy are ruled out; pepper escrow is operational work.
Protections as operator responsibilitiesDetectabilityFailure arrives silently.
Two of three preconditionsCoverageThe third path stands open.
A static pepper shared across joinsPepper compromiseOne recovered pepper reverses every join.

Revisit: private set intersection replaces the pepper; an attested enclave join serves very-high-risk pairings.

hash-chain-attestable — The hash chain is the attestable record

Cited bydisclosure.record.unpersisted-entrydisclosure.record.read-chaindisclosure.attest.root-replication

Audit storage becomes an availability dependency of reads. A compromised node cannot truncate history its replicated roots cover; telemetry is a projection with no durability obligation.

OptionLost onCost
Linked chain under group commit, signed segment roots (chosen)—A read fails when its entry cannot persist.
Telemetry spans as the recordDetectabilityA dropped span reads as a quiet period.
Fail open with a gap marker, or buffer and retryEvidential completenessRows leave before their entry exists.
An external transparency log as primaryAir-gapped operabilitySome deployments cannot reach a third party.

Revisit: audit writes replicate to a second store; group commit sustains less than the reference read rate.

append-group-pays — An append group pays one sync, and the tip signs at segment close

Cited bydisclosure.record.group-commitdisclosure.record.segment-opendisclosure.record.tip-signing

A per-append sync of segment, tip and directory, plus a signature, costs three full syncs (F_FULLFSYNC on macOS) per read. Syncs per read decided it; throughput then scales with concurrency.

OptionLost onCost
One sync per group, tip at close, idle and export (chosen)—One failed sync refuses the whole group; the unsigned tail truncates undetected.
Three syncs and a signature per appendSyncs per readLatency grows with every durable write the tip needs.
Sync and sign the tip per groupSyncs per readThree syncs protect a tail no replicated root covers yet.

audit-format-v1 — Audit format v1 is versioned, whole-entry canonical and Merkle-rooted

Cited bydisclosure.record.chain-headerdisclosure.record.entry-formatdisclosure.record.v0-chaindisclosure.attest.broken-chaindisclosure.attest.merkle-rootdisclosure.attest.root-tagdisclosure.attest.inclusion-proofdisclosure.attest.proof-invalid

A v0 entry proves membership only with its whole segment, and its header fields sit outside the digest. Offline per-entry evidence decided it; every released format verifies forever.

OptionLost onCost
Versioned whole-entry digest, Merkle root (chosen)—Two verifier paths kept forever; attribute integers within ±(2^53 − 1).
Keep v0Per-entry evidenceMembership needs the whole segment.
One digest for every chainEmbedder fitA verifier pinned to the other digest cannot read the chain.
Sign every entrySyncs per readOne signature per read, which group commit amortizes away.

audit-log-opens — An audit log opens under the key custody its caller holds

Cited bydisclosure.record.read-signerdisclosure.record.audit-key-lossdisclosure.record.unanchored-over-signeddisclosure.record.unsigned-tipdisclosure.erase.signer-binding

A read path holding no issuer key still appends, and a verifier needs no writer lock. Tamper evidence decided it: a signed chain.held marks a chain held for good.

OptionLost onCost
Held, unanchored or read-only, explicit anchoring (chosen)—An unanchored chain carries no signature until its owner anchors it.
A key for every appendAvailabilityA read path without issuer custody cannot serve.
Anchor silently at the first held openTamper evidenceA stripped, rewritten chain reads as unanchored and the next open signs it.

append-group-holds — One append group holds the log at a time

Cited bydisclosure.record.read-entrydisclosure.record.single-writerdisclosure.record.audit-keydisclosure.record.foreign-taildisclosure.record.read-only

serve --http and mcp run as separate processes on one project, and both append to its one linear chain.

OptionLost onCost
Directory lock per append group (chosen)—Groups across processes serialize at one sync at a time.
Directory lock for a process’s lifetimeConcurrent read processesA second read process cannot start.
One chain per processTruncation detectabilityA deleted chain leaves no gap in any other.
A daemon owning the logScopeA third long-lived process and its transport to operate.

audit-reads-view — audit_reads is a view over the chain, and a refused read appends

Cited bydisclosure.record.reads-viewdisclosure.record.erasures-viewdisclosure.record.refused-read

One record decided it, and a refusal is typed and recorded (P2). A lookup over 24 h answers within 1 s.

OptionLost onCost
A view computed per query from the segments (chosen)—Query cost scales with the chain’s length; probes grow the chain.
A reserved table beside the chainOne recordA second state model drifts and needs its own erasure.
A projection rebuilt on appendOne recordA crash between two writes leaves them disagreeing.
A refused read leaves no entryTyped refusalsA probe of ungranted tables stays invisible.

explanation-reads-exchange — An explanation reads the exchange policy and the chain, and keeps no store

Cited bydisclosure.explain.decisiondisclosure.explain.pathdisclosure.explain.replaydisclosure.explain.coveragedisclosure.explain.audience

An explanation carries no row (P5) and qualifies every negative (P2).

OptionLost onCost
Current grants decide, the chain replays (chosen)—A decision states the grants in force at the call, not those a past read held.
A store snapshotting grants per readOne recordA second state drifts from the chain.
Replay the read itself to decideNo rowsEvaluating the relation touches rows.

erasure-forced-rewrite — Erasure is a forced rewrite, a bounded cascade and a measured receipt

Cited bystore.declare.erasure-metadatadisclosure.erase.recoverydisclosure.erase.unsigned-recoverydisclosure.erase.retirement-inventorydisclosure.erase.canonical-audit-key

One authenticated frontier spans every affected table, and readers and writers fence against it so an erased row never returns through an older batch. A failed audit publication leaves the original frontier selected.

OptionLost onCost
One authenticated publication record with release fencing (chosen)—Every reader and writer validates the frontier; collection rewrites retained artifacts.
Independent table pointer commitsAtomicityA reader observes partial cross-table erasure.
Response-time tombstone filters alonePhysical removalRetained files and sidecars preserve erased bytes.

forced-rewrite-measured — Forced rewrite and measured receipt

Cited bydisclosure.erase.subject-columndisclosure.erase.key-setdisclosure.erase.surviving-citationsdisclosure.erase.survivor-namesdisclosure.erase.cascadedisclosure.erase.cascade-unboundeddisclosure.erase.tenant-column-typedisclosure.erase.tenant-undeclareddisclosure.erase.owner-onlydisclosure.erase.tenant-rewritedisclosure.receipt.pseudonymdisclosure.receipt.widened-claimdisclosure.receipt.replayeddisclosure.receipt.chain-record

A purge deletes no bucket object, so the receipt claims rewrite-and-exclude over the canonical store. Replicas and the replication bucket sit outside the claim.

OptionLost onCost
Forced rewrite, bounded closure, measured receipt (chosen)—Cost scales with the table; fact reads go down until re-synthesis.
A one-hop cascadeCompletenessA fact derived from a derived fact outlives its evidence.
An unbounded transitive walkTerminationProvenance is never proved acyclic.
Crypto-shredding a per-subject keyFit with the substrateEvery write path holds a per-subject key forever.
A broad “data destroyed” receiptAssertabilityThe claim is false when signed.

Revisit: a purge deletes bucket objects; 72 h request-to-last-replica erasure becomes an engine bound.

re-synthesis-after — Re-synthesis after erasure replays the extraction cache

Cited bydisclosure.erase.atomic-publicationdisclosure.erase.reader-frontierdisclosure.erase.shared-referencesdisclosure.erase.subject-pseudonymdisclosure.erase.row-free-auditdisclosure.erase.store-bindingdisclosure.erase.working-publicationdisclosure.erase.recovery-verbdisclosure.erase.physical-removal

An erased row reaches derived state through its claims, its batch’s extraction-cache entry and any dead-letter row. A batch with no erased row replays without a model call only at its original boundaries under an unchanged template, model and cutoffs.

OptionLost onCost
Collect affected entries; replay untouched batches (chosen)—Replay needs each batch’s recorded membership, else restaging re-extracts.
Flush the whole cache on any erasureCostEvery restaging re-extracts the full table.
Leave entries to their own retentionPhysical removalA response quoting the erased row outlives the deadline.
Restage under the erasing credentialAttributionRestored claims carry the forget grant.

drive-permission-coverage — Drive permission coverage includes every selected file

Cited bydisclosure.drive-sweep.permission-pagesdisclosure.drive-sweep.unreadable-resource

A refused permission page does not prove that a file’s prior grants remain complete.

OptionLost onCost
Complete per-file permission reads (chosen)—A refused file stalls coverage and can close reads past the budget.
Treat a refused file as grantlessTruthfulnessEmpty grants conceal an unread resource.
Advance after the first permission pageRevocation coverageLater pages can hold the revoked principal.