# Enterprise Fact Authority 0.1.0 — semantic contract This document describes the reference implementation, not every capability proposed by the researchers. Terms are original design proposals unless `research.md` explicitly links an observed source. The closed JSON Schema and companion are normative for this bounded reference. Research assurance is reviewable-draft. ## Structure, responsibility and graph boundary | Bundle | Layer | Objects / findings | Artifacts and quality | Allowed actions | |---|---|---|---|---| | Governance | Scope and accountable term | FactAuthority; definition/value separation | Authority revision and exact scope; no default owner | Scoped governor records/corrects/retracts appointment | | Governance | Operational appointments | StewardshipAssignment | Stable part identity, evidence, bounded duties and term | Governor changes appointment; steward may receive a route, not acquire powers | | Source policy | Selection | MastershipRule | Source × priority × valid term; explicit overlap conflict | Governor revises preference; evaluator reads | | Source policy | Submission | WriteGrant | Source × writers × current term; no priority field | Host authorizes authenticated writer; governor changes grant | | Observation | Assertions and corrections | FactObservation | Stable source/subject anchor; per-revision writer and digest; retained evidence | Authorized writer asserts/corrects/retracts its source’s record under the current explicit grant | | Reliance | Historical query and projection | Derived Evaluation; AuthorityRegister | Full input slice and policy digests, separate clocks, full-reader permission | Read; report unknown/contested/preferred; propose follow-up | Instance references can be cyclic in the external enterprise graph; this module never traverses them. Its revision graph is a linear chain per identified record. There is no inheritance or transitive authority graph. Runtime package imports are separate from semantic crosswalk references and from JSON document composition. ## Types, fields and cardinalities All schema fields are required; arrays may be empty only where specified. No unknown keys. IDs and references are absolute URIs, at most 500 characters; no automatic canonicalization, alias merging or identity proof. Date/time is UTC `YYYY-MM-DDTHH:MM:SSZ`, real calendar values, half-open `[validFrom, validUntil)` with finite end. Use an explicitly chosen distant finite date if organizational policy needs it; an absent end is not accepted. Null is permitted only for genesis `previousDigest` and for no-value query outcomes. A URI is a reference, not proof its target exists. **FactAuthority and FactObservation envelope**: `id` 1 stable record identity; `dimension` 1 tenant boundary; `scope` 1 host-governed scope URI; `predicate` 1 governed fact type; `change` 1 of genesis/correction/closure/retraction; `revision` 1 integer ≥1; `previousDigest` 0-or-1 preceding record digest (null at revision 1); `recordedAt` 1 trusted receipt stamp at live admission; `validFrom`, `validUntil` 1 each claimed effective interval; `evidence` 1..n immutable evidence references. Dimension/scope/predicate cannot change within a lineage. Digest is SHA-256 of Python sorted compact UTF-8 JSON, no NaN; **not RFC 8785**. Unicode must encode before admission. **FactAuthority** adds: `governs` exactly `values`; `definitionAuthorityRef` 1 external record to consult for meaning-owner, not validated here; `issuedBy` 1 publisher matching the authenticated caller at admission; `accountable` 1 party responsible for values and escalation, not automatically a writer; `state` active/retracted; `stewardships` 0..n identified appointments; `rules` 0..n precedence rules; `writeGrants` 0..n submission grants. All are source-backed governance records, not legal adjudications. Changing accountable party normally creates a new effective term as described below; a revision may correct a mistaken appointment under the explicit governor's trust. **StewardshipAssignment**: `id` 1 distinct from authority/party; `party` 1 external actor; `duties` 1..n of maintain-quality, resolve-conflict, coordinate-transfer; valid bounds 1 each; evidence 1..n. Multiple stewards may be active; routing returns the set of active parties with resolve-conflict duty. These duties do not grant API writes or subdelegation. An absent steward is a visible context gap. **MastershipRule**: `id` 1; `source` 1 external source identity; `priority` 1 integer 0..1,000,000 (smaller wins); valid bounds 1 each; evidence 1..n. Active source rules must be unambiguous: duplicate active rules for one source result in authority-contested even if priorities agree. Rules neither authenticate sources nor confer rights. They rank observations at the **fact-valid** instant under the knowledge cut. **WriteGrant**: `id` 1; `source` 1; `writers` 1..n actor URIs; valid bounds 1 each; evidence 1..n. Grants apply at the **current trusted receipt** instant. There must be exactly one active grant for the source and it must name the caller. They do not rank or validate source truth. A source may have a grant but no precedence rule (record is retained, unranked), or a precedence rule but no live write grant (old observations remain rankable; new writes denied). Identified parts have authority 1 → parts 0..n; each part belongs to exactly one authority throughout its history. Part ID, kind, owning authority, and party/source are immutable. Intervals must be inside the authority term. Changes to duty, priority or authorized writer set are recorded in a new containing authority revision. Part removal is a whole-snapshot correction, not an independent deletion event. The exact part version is `(partId, authorityId, authorityRevision, authorityDigest)`. Independent streams and shared assignments are outside 0.1.0. **FactObservation** adds: `subject` 1 external canonical subject URI; `source` 1; `writer` 1 submitting actor; `state` asserted/retracted; `value` 1 `{datatype: URI, lexical: string ≤10000}`. Source and subject are immutable within the observation lineage. Writer is recorded per revision; a newly granted writer may correct or retract prior records of that same source, preserving earlier attribution. Value is a tagged lexical atom: `01` and `1` differ, different datatype URIs differ, empty string is a supplied value, null is invalid. Host validates the domain datatype, units, actual subject membership and single-valued predicate contract. No algebra, sets, numeric coercion or confidence inference. A different source must submit a separate competing observation, not revise another source's lineage. **TrustedConfiguration**: `id`, `dimension`, valid bounds; `governors` 1..n `(actor, scope, predicate)` authorizations; `readers` 1..n full-register actors; `purposes` 1..n admitted purpose strings. Deployment owns and authenticates this input separately; it is not inferred from the ledger. No bearer credentials. A matching governor may publish governance but does not automatically gain observation write/read rights. The Python function checks declarations but cannot authenticate a caller or configuration. **AuthorityRegister**: format vercy-fact-authority, version 0.1.0, dimension, authorities and observations arrays (0..n, bounded 10,000). Canonical aggregate ID in the native binding is `:authority-register`, one per Dimension for this reference. It has a declared boundary (only this profile's records), separate mastership per record family, governed revision rules and all-or-nothing disclosure. It does not replace a company instance. No global database is implied. ## Lifecycle, time and evaluation 1. Governor admits authority genesis/revision under current scoped configuration. Writer admits observation genesis/revision under exactly one active current authority and a separate WriteGrant. Issuer/writer must match the authenticated actor supplied by host. Two policy records can conflict; admitting one does not silently overwrite another. 2. Every new receipt equals trusted `now` and strictly follows **all** previous receipt timestamps. This serial reference supports one receipt per second, not high-throughput concurrent ingestion. Identical payload `(id,revision)` replay is a no-op after current authorization, ignoring only a host-restamped recordedAt and retaining the original receipt. Changed payload rejects. Failures leave the input untouched. Future/backdated receipt injection is rejected; past effective dates are allowed. 3. A revision replaces the **entire claimed interval** as currently known; it does not patch a subinterval. It must cite its immediate predecessor digest. Genesis requires change=genesis and a live state; retraction requires both change=retraction and state=retracted. Closure requires change=closure, a strictly reduced end, the original start/party/value, and clipped part ends; only revision/receipt/issuer-or-writer/evidence metadata may additionally change. A correction may intentionally amend an erroneous entire term and is distinct from closure. For a transfer, close the old term by a guarded closure revision preserving its start and old party, then create a new authority/assignment ID from the cutoff. A future-dated replacement alone would remove old valid-time coverage; use split terms instead. Temporary gaps are fail-closed. Durable multi-record atomic transfer is deferred. 4. Query filters by `recordedAt <= knownAt`, takes the latest revision per ID, then effective interval and active/asserted state. These operations happen in that order. `knownAt > now` rejects. Past knowledge does not see a policy correction received today. `recordedAt` is receipt, not source event time or authenticated publication proof; other clocks are deliberately not manufactured. 5. Match exact dimension/scope/predicate. Zero authorities → unknown; multiple active authority IDs → authority-contested. Duplicate active rules for a source → authority-contested. No inherited scope, arbitrary scope expression, jurisdiction precedence or implicit most-specific rule. The trusted host binds subject/scope; supplying an arbitrary complete forged register can bypass this reference because authentication is outside it. 6. Retain all active matching observations and evidence, including unranked and lower-priority ones. Among sources with a live rule choose the minimum priority. If their tagged lexical values disagree, return contested and no value. Otherwise return preferred with that value and all supporting IDs. Multiple competing records from **one** source can also contest. Source identity count is not a vote. 7. Outcomes carry profile version, authority/rule/route pins and observation revision digests, exact matched authority revision digests, known input-slice digest including register header and configuration digest. This is reproducibility metadata, not signed publication. `observationIds`, `evidence`, unranked IDs and preferred IDs expose only the matching temporal slice. Input digest covers the full known register as an integrity pin, not a summary of only this query. No side-effect notification occurs. Historical route is labeled by fact-valid time and must not be used as current contact authority. 8. Read permission is checked before ledger validation. An unauthorized actor or purpose receives only `Read denied`; no selective assertion filtering is implemented. Authorized readers are cleared for the entire register. Configuration is checked at current time even for historical queries. This does not recreate past authenticated access decisions or verify every old append was authorized. `validate_ledger`/`import_snapshot` validate structure and history consistency only. ## Executable invariants and question routes I01 Equal priority disagreement is contested; I02 import order never ranks; I03 owner/steward/model maintainer are not implicit writers; I04 no authority is unknown, never a grant; I05 duplicate policies/rules fail to select; I06 source preference and current WriteGrant are independent; I07 immutable scope/source/subject anchors and identified parts; I08 receipt order and predecessor digests; I09 previous knowledge cuts survive corrections; I10 interval containment and exclusive upper bounds; I11 no partial access filter; I12 no implicit value coercion; I13 transfer keeps old effective terms; I14 atomic in-memory rejection and payload-idempotent replay; I15 future knowledge/receipt rejection; I16 loss-bearing migration refused. `test_authority.py` implements representative positive/negative cases; it does not prove all possible states or domain truth. | Route | Finding → question | Artifact | Permitted action / unknown behavior | |---|---|---|---| | Q01 | FA-boundary → Is this a meaning, value assertion or ownership record? | boundary-decision + governs | Explain; do not infer title or definition ownership | | Q02 | FA-identity → What survives rename/transfer? | record IDs, anchors, revision chain | Follow exact lineage; transfer by new term, never merge parties | | Q03 | FA-meaning → Who defines this predicate? | definitionAuthorityRef | Resolve externally; insufficient context if absent/unverified | | Q04 | FA-accountable → Who answers for values at T? | authority slice | Read accountable; zero/multiple returns unknown/contested | | Q05 | FA-steward → Who handles the disagreement? | active assignment IDs and duties | Propose routing; missing route needs appointment, no approval | | Q06 | FA-write → May this actor submit for source S now? | separate WriteGrant + trust config | Call admit through host; absent/ambiguous rejects | | Q07 | FA-rank → Which source is preferred at fact time? | MastershipRule + policy pin | Evaluate; priority is not truth or permission | | Q08 | FA-conflict → What if equal sources disagree? | both observation IDs/evidence | Preserve contested; request human review, never overwrite | | Q09 | FA-overlap → Which of two authorities applies? | authority-contested outcome | Governor investigates; no recency fallback | | Q10 | FA-history → What was known at T about valid time V? | known input slice + authority pins | Re-evaluate; future knowledge rejected | | Q11 | FA-correction → How is a wrong claim corrected? | next observation revision | Currently granted same-source writer submits with evidence; retain prior rows | | Q12 | FA-transfer → What happens at responsible-party change? | closed old term + new term | Governor records both; gap stays unknown | | Q13 | FA-disclosure → What can this reader see? | trusted full-register read policy | All or deny; do not drop a hidden contradiction | | Q14 | FA-minimum → Does a startup need HRIS? | one-source minimal register | Use governed manual source with explicit rights | | Q15 | FA-context → What if source/policy is missing? | reason and unranked IDs | Ask for missing authority/rule; do not invent source truth | | Q16 | FA-binding → Does native validation prove semantics? | native + companion reports | Invoke both; nested V3 acceptance alone insufficient | | Q17 | FA-migration → Can earlier owner strings be imported? | migration.md | Stage candidates outside operative register; explicit mapping required | | Q18 | FA-evidence → Does provenance prove the value? | evidence references | Inspect externally; no inferred veracity or access grant | Every route is informational or explicitly guarded; no agent is authorized to act merely because a table lists an action. ## Host integration requirements after audit `admit` and its diagnostics are internal trusted-host APIs. A caller with write rights but no read rights must never receive the returned complete ledger, replay/conflict details, or configuration diagnostics. The host returns only a receipt for that submission or a generic Admission rejected; catch Denied separately from Invalid. Deploying raw functions as public endpoints would violate this contract. Root governance may explicitly grant its actors source-write rights; there is no separation-of-duties rule beyond no implicit grants. `validate_extension(previous, candidate, config)` requires identical headers, exact historical prefixes in both collections and all appended receipts after the prior global head. Use it with a trusted previous full snapshot, and admit every new row. It does not prove the previous snapshot itself is complete. Native acceptance demonstrates both and records supersedes/previousSnapshotDigest on snapshot-r2. Overlapping write grants remain representable conflicts in archives, but actual submission fails closed; snapshot validation does not deny their existence. Observation intervals may extend beyond a governance term; selection outside known authority is unknown with retained observation pins. Native identity is `vr.profile.enterprise-fact-authority@0.1.0` and its own JSON-compatible `spec.json` digest. WM-XCT-001 is installed only as semantic-only with binding=null; it is an optional exact semantic reference. Snapshot authority names the deployment register operator, not a steward or accountable party. Native storage authority is not domain precedence. Bare SHA-256 record pins and native sha256:-prefixed asset descriptors are explicitly distinct encodings.