The Vault ← The Vault
Onyx Legal · Technology · ModuleDWG · ONYX-BILLS · SHEET V

A single module, in detail

Onyx BillS

Cutting-edge legal-billing infrastructure — built local-first, for the firm's own work.

Sheet
V · Onyx BillS
Module
Billing
Status
Internal
Rev
2026.06

The premise

Determinism you can audit.
The same inputs always yield the same number — and the number can be recomputed by hand.
AI that cannot act alone.
It may only propose. It never books, finalises, or moves money.
Local-first
Silent by default; the network is opt-in, not assumed.
OnyxSecurity.swift:174-225
Propose-then-seal
Every consequential act carries its proposer, then is written and sealed.
AdminCore.swift:1741-1815
Re-verifiable
A finalised invoice attests to its own totals under a hash seal.
AdminCore.swift:1446-1488
The mathematics

The architecture

The mathematics it is designed around

Every figure on this page is computed by an explicit rule. Sheet A is shipped and carries its line of code; Sheet B is specified-but-not-yet-wired — named as design, with no code mark claimed.

SHEET AComputed & shipped — as-builteach figure carries its file · line; re-verifiable against source
FIG. A·01Reciprocal-rank fusionAS-BUILT
hybrid lexical ⊕ vector retrievalOnyxSearch · Rag.swift:314
FIG. A·02Wilson 95% lower boundAS-BUILT
small-sample retrieval-eval gate floorai-eval · EvalMetrics.swift:8
FIG. A·03Write-off recordAS-BUILT
enumerated reason, atomic with the audit eventAdminCore.swift:851
FIG. A·04VAT — basis pointsAS-BUILT
subtotal · VAT · total residuals reconcile to 0AdminCore · VatEngine.swift:26
FIG. A·05Time → tenths → billedAS-BUILT
6-minute units, truncated client-favourableAdminCore.swift:90
FIG. A·06Rational minor-unit scalingAS-BUILT
one half-away rounding over a 128-bit productOnyxCommon · RationalMath.swift:143
FIG. A·07Physical day-capacity gateAS-BUILT
> 24h booked on one day blocks finalisationBillingIntegrity+DayCapacity.swift:50
FIG. A·08HMAC-SHA256 audit chainAS-BUILT
append-only; HKDF keys; SQLite refuses editsOnyxAudit.swift:200
FIG. A·09Cosine vector legAS-BUILT
brute-force over local embeddingsOnyxSearch · Rag.swift:375
FIG. A·10BM25 lexical legAS-BUILT
FTS5, k₁ = 1.2, b = 0.75OnyxPersistence.swift:414
FIG. A·11Frozen nearest-centroid classifierAS-BUILT
rules-first; proposal-onlyPhaseClassifierML.swift:48
FIG. A·12Confidence-margin gateAS-BUILT
5-clause envelope, or it declines to guessPhaseClassifierML.swift:157
SHEET B — FOR REFERENCE
SHEET BThe architecture it is designed aroundspecified in full, not yet wired into the build — named to its design spec, no code mark claimed
FIG. B·01Maximal marginal relevanceFOR REFERENCE
relevance vs diversity rerank, λ = 0.7SPEC · C4 · Phase 1
FIG. B·02Robust outlier — modified z / MADFOR REFERENCE
median-based; flags entries for reviewSPEC · C3 · Phase 1
FIG. B·03Contingency expected valueFOR REFERENCE
PPM-weighted scenarios, integer-exactSPEC · B5 · Phase 3
FIG. B·04Interest present valueFOR REFERENCE
30E/360 day-count; legal-cap clampSPEC · B4 · Phase 3
FIG. B·05Retainer depletion & top-upFOR REFERENCE
burn-rate runway forecastSPEC · B2 · Phase 2
FIG. B·06Capped-fee burn — budget-at-completionFOR REFERENCE
conservative overrun forecastSPEC · B1 · Phase B
FIG. B·07Markov collections agingFOR REFERENCE
one-step matrix; absorbing “paid” stateSPEC · C5 · Phase 4
FIG. B·08Kaplan–Meier time-to-paymentFOR REFERENCE
median collection time, right-censoredSPEC · C5 · Phase 4
FIG. B·09Multicurrency FX — audit-preservingFOR REFERENCE
exact rational rate; triangle checkSPEC · B3 · Phase 4
Section I — Layer I

Layer I

Deterministic billing arithmetic

Every billed figure is computed by an explicit, floored rule in minor units.

Time is billed in tenths of an hour. Minutes are floored to a six-minute tenth — never less than one — the gross line is taken in minor units (truncated toward zero, so the firm never over-bills), and any discount is subtracted to a floor of zero. Value-added tax is computed on the rounded base in basis points and reconciled so the minor-unit residuals of subtotal, VAT and total all agree. The whole computation is integer arithmetic on minor units; there is no floating ambiguity to drift, and the result reproduces under recomputation by hand.

worked — one timesheet line, recomputed 180 min @ AED 1500.00/hr → floor((180+3)/6) = 30 tenths 30 × 150000 / 10 = AED 4 500.00 net VAT 5% = round_half_away(450000 × 500 / 10000) = AED 225.00 total = AED 4 725.00 → sealed OL-INV-2026-0001
AdminCore.swift:90-99, 737-742, 758 · billed-tenths / gross (truncated) / billed minor-unit formulae
VatEngine.swift:26-31, 114-141 · VAT in basis points with minor-unit subtotal / VAT / total reconciliation
OnyxCommon · RationalMath.swift:143-199 · the single money-scaling primitive — one half-away rounding over a 128-bit product
BillingIntegrity+DayCapacity.swift:50-112 · AdminCore.swift:3826-3845 · a physically-impossible day (> 24h booked) hard-blocks finalisation
Section II — Layer II

Layer II

The tamper-evident ledger

Records are appended, never edited. Each event hashes the one before it into a chain.

Every event embeds the hash of its predecessor and contributes its own; the sequence, the previous-hash links and the truncation of the tip are all checkable, so any break is detectable rather than assumed. The store blocks mutation outright: immutable SQLite triggers abort update and delete, and the sequence is unique, so the chain cannot fork. Each hash is an HMAC-SHA256 over canonical content under keys derived through HKDF from the vault key, so a record cannot be silently rewritten and re-signed.

OnyxAudit.swift:200-311 · eventHash = HMAC-SHA256 over canonical content embedding prevEventHash
OnyxAudit.swift:345-425 · verifier checks sequence, previous-hash binding and tip-hash truncation
OnyxAudit.swift:680-709 · 313-343 · immutable SQLite triggers (UPDATE/DELETE abort); HKDF-derived audit keys
Section III — Layer III

Layer III

The exact-token retrieval floor

Search fuses lexical and vector ranking; a floor guarantees exact tokens are never lost.

Retrieval is hybrid: a reciprocal-rank fusion of a BM25 lexical leg and a brute-force cosine vector leg, with a fusion constant of k = 60 (the active default weights the two legs equally; a protected-retrieval profile weights the lexical leg higher to harden exact-token recall). Above the fusion, a floor holds: under the protected guard, exact tokens — UTBMS codes, clause references, dates, AED amounts, percentages — are pinned into the top results with recall 1.0, so semantic ranking may only add on top of the floor, never regress it. The guarantee is enforced as an evaluation gate: a new method must beat the floor with no exact-token regression, measured against a Wilson 95% lower bound alongside Recall@k and nDCG@k.

OnyxSearch · Rag.swift:314-323 · RRF score, k=60; default weights equal, protected-hybrid weights lexical higher
Rag.swift:375-389 · OnyxPersistence.swift:414-429 · brute-force cosine vector leg; FTS5 BM25 lexical leg
Rag.swift:1052-1073, 911-914 · exact-token preservation pins lexical hits into top-k under the protected guard
ai-eval · EvalMetrics.swift:8-16, 22-41 · Wilson 95% lower bound · Recall@k · nDCG@k — the adoption gate
Section IV — Layer IV

Layer IV

The cryptographic perimeter

By construction the vault is local and quiet — and where it does reach out, it does so through one audited gate.

The default network policy is no inbound, no outbound, and an empty allowlist — the billing core consults this contract before it ever reaches the network. At rest the database is sealed with SQLCipher, the cipher version checked on open; backups travel in AES-GCM envelopes under an Argon2id-derived key, and vault blobs are content-addressed by a keyed SHA-256 hash. The recovery key is minted once, returned for a printed sheet, and never persisted, logged, or written to the audit chain. Where an off-device feature is enabled, every send passes a single audited gate that refuses secrets, records a payload hash, and fails closed when offline; vault sync itself is opt-in, default-disabled and ciphertext-only.

SQLCipher
database at rest · version checked on open
HMAC-chain
tamper-evident append-only ledger
HKDF
domain-separated audit keys
Argon2id
portable-backup key derivation
AES-GCM
sealed backup envelopes
Keyed SHA-256
content-addressed vault blobs
Deny-by-default
no inbound / outbound · ∅ allowlist
Audited off-device gate
refuses secrets · fails closed · hashed
OnyxSecurity.swift:174-225 · default network policy: no inbound, no outbound, empty allowlist
OnyxPersistence.swift:112-167 · 632-708 · OnyxSecurity.swift:132-172 · SQLCipher at rest; AES-GCM backup envelopes under Argon2id
OnyxVault.swift:102-144 · OnyxSecurity.swift:561-572, 659-691 · keyed-SHA-256 content addressing; one-time recovery key never persisted/logged
OffDeviceSendGate.swift:35-104 · VaultCloudPortabilitySync.swift:5-15, 64-107 · audited off-device funnel; vault sync opt-in, default-disabled, ciphertext-only
Section V — Layer V

Layer V

AI that cannot act alone

Classification is rules-first; where a model assists it is frozen, gated, and proposal-only. The model proposes a code; a person decides.

Where a model assists, it is a small, frozen, on-device classifier — no cloud, and no client matter in its training. Its corpus is synthetic: 440 constructed legal narratives across the 22 phases, built with deliberate hard-negatives, so the model learns the shape of the work without ever seeing a real client. A new model is admitted only after it clears an offline evaluation gate bound to its own weight-hash; until those weights are vendored the classifier runs rules-first, adding nothing it cannot prove. When it does assist, it scores a suggested UTBMS code by cosine behind a five-clause confidence margin and, below margin, declines rather than guesses — and it only ever proposes: a draft becomes a record solely by passing back through the deterministic workflow with a step-up, with conflicts, AML, sanctions and payment outcomes refused outright.

FIG. V·aMac · AI Assist — refusalprint surface
Onyx BillS AI Assist refusing to act: payment decisions remain operator-only; AI cannot decide conflict, AML, sanctions, acceptance or payment outcomes.
FIG. V·bMac · assistant chat proposalreal capture
Mac assistant chat panel showing a reviewed AI proposal, kept as an operator-confirmed draft rather than an autonomous action.
predict(x) : if rule_match(x) → rule_label else ĉ = argmaxc cos(tfidf(x), μc) gate : adopt only if the 5-clause envelope holds emit : suggestion(proposedBy = model) — never a commit
A101A102A103A104A105A106A107A108A109A111

UTBMS activity codes, hash-pinned (A110 is intentionally absent); the 22-phase DIFC/ADGM taxonomy maps to UTBMS L-codes.

PhaseClassifierML.swift:48-95, 157-176 · frozen TF-IDF nearest-centroid + five-clause confidence-margin gate
ActivityClassifier.swift:29-86 · onyx_billing_rules.json:214 · MatterPhase.swift:8-77 · A101–A109/A111 from a SHA-256 hash-pinned ruleset; 22-phase taxonomy → L-codes
AssistantActionDraft+Confirm.swift:31-75 · a model draft commits only through the deterministic workflow — re-checked, re-validated, step-up required
phase-training-data/…_exemplars_440.jsonl · ModelEvalClearance.swift:18-60 · OnyxSecurity.swift:227-242 · 440-example synthetic training corpus (22 phases, hard-negatives); adoption clears an eval-gate bound to the weight-hash; rules-first until the model is vendored (PhaseExemplars.swift)
Section IX — Operational proof

Operational proof

Invoices, proformas & controls

The rules hold up on a real invoice.

Invoices are gap-numbered as OL-INV-YYYY-NNNN and, once finalised, carry a re-verifiable SHA-256 economic seal over identity, lines, VAT, subtotal and total — the document attests to its own totals. A proforma advances through separated, audited steps — create, review, approve, finalise — with a step-up before a final invoice issues. Voiding requires a reason; write-offs carry minutes, value, description and an enumerated reason. The billing-item taxonomy is fixed: three kinds — fixed-fee, external-at-cost and disbursement — and no more.

FIG. IX·bPDF · invoice templatereal capture
Rendered invoice PDF from Onyx BillS — client identity, bank accounts, IBANs and SWIFT redacted; totals and matter kept.
FIG. IX·cPDF · timesheet templatereal capture
Rendered timesheet PDF page generated from Onyx BillS with activity rows and totals visible.
fixed-feeexternal-at-costdisbursement
AdminCore.swift:2391-2394 · 1446-1488 · gap-numbered OL-INV-YYYY-NNNN; finalised SHA-256 economic seal over identity/lines/VAT/subtotal/total
AdminCore.swift:1121-1127 · 3347-3422 · proforma create / review / approve / finalise; step-up authorizer before a final invoice issues
AdminCore.swift:3082-3092 · 852-857, 3137-3165 · voiding requires a reason; write-offs carry minutes / value / description / enumerated reason
AdminCore.swift:901-904 · BillingItemKind has exactly three cases (fixed-fee / external-at-cost / disbursement) — no separate “expense” kind
Section X — At the edge

At the edge

Biometric unlock & signed pairing

The same local-first guarantees, across devices. A companion joins only through an explicit, signed ceremony; the running timer shows only a non-secret matter code — not the client's name.

The vault opens by biometrics. Step-up re-authentication is built on one-time proofs that are bound to their target and expire — a proof cannot be replayed, reused, or aimed elsewhere. A companion device joins through a signed pairing ceremony: import an invitation, create a device response, save the signed handoff; the verification code is the first eight characters of a SHA-256 over the pairing secret, responses are HMAC-signed and compared in constant time, and the secret never leaves the Keychain. Capture surfaces are privacy-clean by construction: the running timer and its Live Activity carry only a non-secret matter code, never the client’s name — so a glance at a lock screen can’t reveal who the work is for.

step-up : one-time · target-bound · expiring pairing : import .onyxpair → device response → save .onyxdevice display code : SHA-256(secret).prefix(8) (HMAC-signed, constant-time verify) live activity: MAT-2231 (matter code only)
OnyxSecurity.swift:245-378 · biometric step-up — one-time, target-bound, expiring proofs
DevicePairingService.swift:103-181, 237-309 · display code = SHA-256(secret).prefix(8); HMAC-signed responses; constant-time verify; Keychain ThisDeviceOnly
VaultCloudPortabilitySync.swift:5-15, 64-107 · offline by default; any cloud sync is opt-in, flagged, ciphertext-only
In brief

In brief

Questions, answered

What is Onyx BillS?

Onyx BillS (the Onyx Billing System) is local-first legal-billing infrastructure built by Onyx Legal. Every billed figure is computed by an explicit, floored rule in integer minor units, and every consequential action is written to a tamper-evident, HMAC-SHA256 hash-chained audit ledger that admits additions and refuses edits.

Is the AI in Onyx BillS autonomous?

No. AI in Onyx BillS only ever proposes. Classification is rules-first; where a model assists it is a frozen, on-device classifier — trained on a synthetic corpus, no client data — held behind a confidence gate. A suggestion becomes a record only after human review and a step-up, and conflicts, AML, sanctions and payment outcomes are refused outright.

Where is data stored, and does anything leave the device?

Data is stored locally by default. The default network policy is no inbound, no outbound and an empty allowlist; the database is encrypted at rest with SQLCipher and backups travel in AES-GCM envelopes under an Argon2id-derived key. Where an off-device feature is enabled, every send passes a single audited gate that refuses secrets and fails closed when offline.

How is an Onyx BillS invoice verified?

Each finalised invoice is gap-numbered as OL-INV-YYYY-NNNN and carries a re-verifiable SHA-256 economic seal over its identity, lines, VAT, subtotal and total, so the document attests to its own totals.

What platforms does Onyx BillS run on?

Onyx BillS runs natively on macOS, with an iPhone and iPad companion vault. It is built local-first, for a firm's own work.

What is The Vault?

The Vault is Onyx Legal's suite of local-first legal instruments, built for the firm's own practice and not offered for sale. Onyx BillS is its billing module; the suite also includes Onyx ATXE (an evidence workbench) and Onyx LiTT (litigation technology).