Visual proof of correctness
Close → attestation → export receipt
The brand is auditable artifacts, not neon dashboards. Step through what Close + Attest produces — then verify offline with open verification tooling.
Every close input becomes a graph node with a reproducible state: open, matched, settled, attested, or carried forward.
{
"period": "2026-05",
"closePolicyVersion": "close-graph-v1",
"canonicalLedger": "matched/unmatched source of truth",
"nodeStates": {
"open": 1,
"matched": 14,
"settled": 9,
"attested": 4,
"carried_forward": 1
}
}Product spine
Close Graph
A period-close graph where every close input becomes a node. Each node has a clear status, an evidence trail, and a readiness score.
Lawenots treats close inputs as graph nodes, not separate records scattered across different tools. This covers transactions, reconciliation items, AR and AP expectations, compensation expectations, and settlement anchors. Each one is checked against the same ledger before a period can close.
Node lifecycle
Transaction
Plaid row, CSV import, exchange/on-chain activity
Must be categorized and either matched, settled, attested, or carried forward.
Reconciliation item
Bank reconciliation difference, duplicate suspect, feed gap
Open reconciliation nodes block close until cleared or explicitly carried forward.
Invoice / AR expectation
Stripe MRR, Coinbase Commerce, invoice draft, pipeline revenue expectation
Expected-vs-received revenue reconciles into the same canonical ledger; missing receipts remain close blockers.
Bill / AP expectation
Vendor bill, expected processor payout, unpaid obligation
Unpaid or unresolved payables remain blockers unless carried forward with evidence.
Compensation expectation
Gusto/Deel/ADP/PEO register import, contractor accrual, recurring compensation journal
Expected compensation must reconcile to posted GL and provider-register evidence; Lawenots does not run payroll tax or disbursement.
Settlement anchor
Plaid ACH, Stripe payout, on-chain USDC tx hash, Close + Attest anchor
Should-settle vs did-settle evidence anchors must reference GL rows and hashes before attestation.
Readiness formula
readiness = round((sum(weight for passed nodes) / sum(all node weights)) * 100)
Open nodes block close. Matched, settled, attested, or explicitly carried-forward nodes pass according to their type and close policy.
Carry-forward with content-hashed note
Carry-forward is a first-class graph transition, not a loose comment. The operator states why an open item belongs in the next period; Lawenots hashes the note and includes it in the period evidence package.
Evidence package
- Serialized period subgraph (nodes, states, edges, weights, close policy version)
- Locked trial balance and statement exports
- Lawenots Verify findings and remediation/carry-forward notes
- Canonical matched/unmatched ledger used by AR, AP, comp, and settlement references
- Export receipts with SHA-256 content hashes and source revision
- Close timeline: hash-chained activity log of node mutations
- Close + Attest metadata when enabled (Merkle root, Ed25519 signature, public key id)
Hash-chained close timeline
Every graph mutation records previousEventHash + eventBodyHash + actor + timestamp. The resulting eventHash turns the close timeline into evidence: reviewers can detect missing or reordered mutations.
{
"eventId": "evt_close_01HW...",
"nodeId": "node_txn_9421",
"transition": "matched -> settled",
"actor": "user_123",
"previousEventHash": "b83f...19aa",
"eventBodyHash": "ad91...0e7c",
"eventHash": "1c4d...91bf"
}[
{
"id": "node_txn_9421",
"type": "transaction",
"state": "settled",
"label": "Stripe payout matched to bank deposit",
"weight": 12
},
{
"id": "node_recon_117",
"type": "reconciliation_item",
"state": "matched",
"label": "Duplicate suspect resolved",
"weight": 10
},
{
"id": "node_ar_2026_05_mrr",
"type": "ar_expectation",
"state": "open",
"label": "Expected MRR not received by cutoff",
"weight": 15
},
{
"id": "node_ap_vendor_17",
"type": "ap_expectation",
"state": "carried_forward",
"label": "Vendor bill carried to next period with hashed note",
"weight": 8
},
{
"id": "node_anchor_331",
"type": "settlement_anchor",
"state": "attested",
"label": "Settlement anchor included in evidence package",
"weight": 10
}
]{
"period": "2026-05",
"closePolicyVersion": "close-graph-v1",
"readinessFormula": "readiness = round((sum(weight for passed nodes) / sum(all node weights)) * 100)",
"canonicalLedger": "single matched/unmatched ledger for transactions, AR, AP, comp, settlement",
"nodeCounts": {
"open": 1,
"matched": 1,
"settled": 1,
"attested": 1,
"carried_forward": 1
},
"evidencePackage": "locked trial balance + issue list + graph JSON + export receipts + timeline hashes + attestation metadata"
}Close feeds
Revenue, settlement, and compensation reconciliation feed one close engine
Lawenots does not become an invoice generator, bill-pay rail, or payroll tax engine. It imports what should have happened, reconciles it against what did happen, and contributes typed expectation nodes into the same Close Graph and canonical matched/unmatched ledger.
Expectation objects
Each module creates typed expectation nodes that enter the same readiness formula, issue taxonomy, evidence package, and carry-forward rules. One engine, three feeds.
Revenue reconciliation
nodeType: ar_expectation
Expected: Stripe MRR, Coinbase Commerce receipts, invoice drafts, pipeline expectations
Observed: Imported cash receipts, processor exports, or on-chain evidence
Blocker: Expected but not received by close
Integrations, not an invoice generator
Settlement reconciliation
nodeType: settlement_anchor
Expected: Plaid ACH, Stripe payouts, and on-chain USDC that should settle
Observed: Imported payout events, bank confirmations, and tx-hash evidence
Blocker: Should-settle vs did-settle mismatch
Evidence and anchoring, not a bill-pay UI
Compensation reconciliation
nodeType: comp_expectation
Expected: Comp run-rate, payroll calendar, and provider register imports (Gusto, Deel, ADP, PEO)
Observed: Posted GL, provider register rows, and optional crypto-leg evidence
Blocker: Register / GL discrepancy by close
Reconciliation only, not payroll tax or disbursement
Crypto-leg evidence reuse
Crypto legs carry tx hash + FMV as evidence, reuse the lot and 8949 machinery, and can emit an outflow event into allocation drift when that module is provisioned.
{
"id": "exp_settlement_usdc_2026_05_01",
"module": "settlement",
"provider": "Ethereum",
"closeGraphNodeType": "settlement_anchor",
"expectedAmount": 1200,
"currency": "USD",
"expectedAt": "2026-05-28T17:00:00Z",
"evidence": {
"txHash": "0x7e3a...91bc",
"fmvUsd": 1200,
"ledgerReference": "gl_44291"
}
}#2 product surface
Lawenots Verify
Lawenots can review any books — and close them
Import QuickBooks, Xero, or CSV. Lawenots Verify surfaces close blockers, scores readiness, and returns a hashed readiness report that looks like a real close package. Works even if the client never migrates.
Standalone Close Readiness Check
Import QB / Xero / CSV → Lawenots Verify flags uncategorized rows, duplicates, feed gaps, open recon, lot mismatch, and ledger imbalance → readiness score + fix list.
Firm / CPA mode
A reviewer runs the check across client books they don't own. One CPA, many accounts — the multi-client distribution node.
Mini evidence artifact
Every check produces a content-hashed readiness report with the same receipt look as a full close package — natural upsell to attested close.
Built-in migration path
Every blocker fixed in the check is one step toward running the whole close on Lawenots. Import first; Close Graph when ready.
Import is the top of the funnel. Close Graph is the destination.
Close Graph model
Close Graph is Lawenots' named period-close model. Every close input becomes a node with a type, weight, state, evidence links, and timeline history. The supported node types are transaction, reconciliation item, invoice / AR expectation, bill / AP expectation, compensation expectation, and settlement anchor. These nodes all resolve against one canonical matched/unmatched ledger so AR, AP, compensation, settlement, and bank reconciliation do not maintain separate truths.
Transaction
Plaid row, CSV import, exchange/on-chain activity
Must be categorized and either matched, settled, attested, or carried forward.
Reconciliation item
Bank reconciliation difference, duplicate suspect, feed gap
Open reconciliation nodes block close until cleared or explicitly carried forward.
Invoice / AR expectation
Stripe MRR, Coinbase Commerce, invoice draft, pipeline revenue expectation
Expected-vs-received revenue reconciles into the same canonical ledger; missing receipts remain close blockers.
Bill / AP expectation
Vendor bill, expected processor payout, unpaid obligation
Unpaid or unresolved payables remain blockers unless carried forward with evidence.
Compensation expectation
Gusto/Deel/ADP/PEO register import, contractor accrual, recurring compensation journal
Expected compensation must reconcile to posted GL and provider-register evidence; Lawenots does not run payroll tax or disbursement.
Settlement anchor
Plaid ACH, Stripe payout, on-chain USDC tx hash, Close + Attest anchor
Should-settle vs did-settle evidence anchors must reference GL rows and hashes before attestation.
Expectation objects: one engine, three feeds
Revenue reconciliation, settlement reconciliation, and compensation reconciliation all enter Lawenots through the same abstraction: typed expectation objects. These are close items, not mini-apps. Each expectation contributes a node into the canonical matched/unmatched ledger, the readiness score, Lawenots Verify taxonomy, evidence package, and carry-forward workflow.
- Revenue reconciliation: expected (Stripe MRR, Coinbase Commerce, invoice drafts, pipeline) vs received by close.
- Settlement reconciliation: should-settle (Plaid ACH, Stripe payouts, on-chain USDC) vs did-settle, with evidence anchored into the period package.
- Compensation reconciliation: expected comp run-rate plus provider-register imports (Gusto, Deel, ADP, PEO) vs posted general ledger.
Lawenots never moves money, runs disbursement, or becomes a payroll tax engine in this model. It imports evidence, reconciles expectation vs outcome, and blocks close until the discrepancy is resolved or explicitly carried forward.
Node states and readiness formula
Each Close Graph node moves through the same lifecycle: open → matched → settled → attested → carried-forward. The period readiness score is a deterministic rollup of node weights and node states.
readiness = round((sum(weight for passed nodes) / sum(all node weights)) * 100)
- A node passes only when it reaches the terminal state required by its type and close policy.
- Open nodes are blockers; carried-forward nodes pass only with a content-hashed note and reviewer-visible reason.
- The score is reproducible from the serialized graph, weights, node states, and close policy version — not a black box.
Open
Input exists but has not been matched to the canonical ledger or resolved for close.
Matched
Input has a canonical ledger match or approved accounting treatment.
Settled
Cash, crypto, or GL settlement evidence is attached and reconciled.
Attested
Evidence hash is included in the period package and optional Close + Attest proof chain.
Carried forward
Operator explicitly carries the item into the next period with a content-hashed note and reviewer-visible reason.
Evidence package
A close package is a serialized period subgraph for CPA or auditor review — not just a zip of PDFs. It contains the graph state, ledger outputs, issue history, and integrity metadata needed to reproduce what Lawenots scored and exported.
- Serialized period subgraph (nodes, states, edges, weights, close policy version)
- Locked trial balance and statement exports
- Lawenots Verify findings and remediation/carry-forward notes
- Canonical matched/unmatched ledger used by AR, AP, comp, and settlement references
- Export receipts with SHA-256 content hashes and source revision
- Close timeline: hash-chained activity log of node mutations
- Close + Attest metadata when enabled (Merkle root, Ed25519 signature, public key id)
Close timeline and carry-forward transition
Every graph mutation records previousEventHash + eventBodyHash + actor + timestamp. The resulting eventHash turns the close timeline into evidence: reviewers can detect missing or reordered mutations. Carry-forward is also a formal graph transition: open -> carried_forward. It only passes readiness when the operator supplies a reviewer-visible, content-hashed note.
{
"nodeId": "node_ap_2026_05_vendor_17",
"reason": "Vendor invoice received after cutoff; obligation carried to 2026-06 close.",
"contentSha256": "4f2a8d...c913",
"reviewerVisible": true
}Lawenots Verify — review any books
Lawenots Verify is the close-blocker classifier behind both native period close and the standalone Close Readiness Check. Import QuickBooks, Xero, or CSV — or run against books already on Lawenots — and get a readiness score, fix list, and content-hashed readiness report.
Firm / CPA mode lets a reviewer run the check across client books they do not own. Every blocker cleared in the check is one step toward running the whole close on the Close Graph. Positioning: Lawenots can review any books and close them.
What “tax-ready” means here
Lawenots produces working papers and export artifacts (including Form 8949–compatible schedules) from your books and lot engine. “Tax-ready” means figures are traceable to underlying transactions and lots, generated under an explicit lot method, and accompanied by an export receipt (content hash + source revision). It does not mean CPA attestation, IRS acceptance, or filing on your behalf.
Lawenots is not a CPA firm, enrolled agent, or tax attorney. Confirm all outputs with your tax professional before filing.
Inputs
- Posted books transactions and ledger entries for the selected period
- Lot acquisitions/disposals (cost basis, proceeds, holding period)
- Configured lot method (FIFO / Specific ID where enabled)
- Bank feed and import provenance (when connected)
- Optional settlement anchors coupled to the general ledger
Assumptions
- Amounts are in the organization’s functional currency unless stated otherwise
- Dates use the organization’s books timezone for day boundaries
- Wash-sale detection is advisory and rule-based; edge cases may need manual review
- Corporate actions (splits/mergers) require lot adjustments to be recorded before export
- Missing categories or open reconciliations block period close via readiness checks
Sample scenarios we validate against
- Wash sale (30-day window): disposal at a loss followed by substantially identical repurchase — flag + basis adjustment advisory
- Partial lot disposition: Specific ID override vs FIFO remainder
- Transfer in / transfer out: basis carries; no spurious gain
- Multi-leg same-day trades: chronological lot consumption
- Reconciled period export: readiness score 100% before 8949 CSV
Lot identity & traceability
Every disposal on a tax export traces to a lot record with acquisition date, basis, and source transaction id. Export receipts record a SHA-256 of the artifact body plus sourceRevision so you can prove what was generated — then verify each line against underlying lots in the product or via your CPA.
- FIFO — default consumption order for disposals
- Specific ID — per-disposal lot selection when enabled on the org
- Transfer in/out — basis carries; no spurious gain on internal moves
Reconciliation studio — automated vs assumed
Lawenots Verify classifies mismatches before period close. The table below states what the product automates and what still requires operator or firm judgment.
Duplicate suspects
Automated: Flags same-amount / same-date pairs with memo similarity scoring; surfaces in Lawenots Verify as duplicate_suspect.
Assumed / manual: Operator or firm staff confirms merge vs legitimate repeat charges. Lawenots does not auto-void without approval.
Bank feed gaps
Automated: Detects missing sync windows and stale connection status; blocks period close when feed_gap is open.
Assumed / manual: Operator reconnects Plaid or imports CSV for the gap. Historical gaps before onboarding are not inferred.
Multi-entity / multi-org
Automated: Each organization has isolated books, RLS-scoped data, and per-org close readiness. Firm switcher scopes all exports.
Assumed / manual: Intercompany eliminations and consolidated group reporting are not auto-generated — export per entity unless configured otherwise.
Lot identity before tax export
Automated: FIFO consumption by default; Specific ID override when enabled. lot_mismatch blocks export readiness.
Assumed / manual: Wash-sale advisory flags need manual review for edge cases; corporate actions require lot adjustments before export.
Uncategorized / pending review
Automated: Readiness score counts uncategorized and PENDING rows; period close blocked until cleared or explicitly resolved.
Assumed / manual: Automation rules reduce volume but do not replace firm judgment on ambiguous vendor memos.
Expected revenue not received by close
Automated: Imports Stripe, Coinbase Commerce, invoice drafts, and pipeline expectations as revenue expectation objects; expected_revenue_gap blocks close when receipts are missing or mismatched.
Assumed / manual: Operator confirms whether the item should be written off, re-dated, or carried forward with a reviewer-visible hashed note.
Settlement should-settle vs did-settle mismatch
Automated: Imports Plaid ACH, Stripe payout, and on-chain settlement evidence; expected_settlement_gap blocks close until the canonical ledger and settlement anchor agree.
Assumed / manual: Lawenots does not initiate or reroute payments; the operator resolves the external settlement and re-imports evidence.
Compensation register vs posted GL discrepancy
Automated: Imports provider registers (Gusto, Deel, ADP, PEO) as compensation expectation objects and flags expected_comp_gap when the posted GL does not match.
Assumed / manual: Lawenots does not run payroll tax, filings, or disbursement. Provider-side corrections and approvals remain outside the product.
Sample export receipt (illustrative)
Form 8949 exports ship with a receipt like the JSON below. Verify the content hash with @lawenots/attestation-verify.
{
"receiptId": "a1b2c3d4e5f6a1b2c3d4e5f6",
"formType": "8949",
"organizationId": "org_demo",
"periodId": "period_2026_q2",
"generatedAt": "2026-07-16T12:00:00.000Z",
"contentSha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"sourceRevision": "workspace-live",
"disclaimer": "This receipt proves artifact integrity at generation time. It is not a CPA attestation or tax advice. Verify figures against underlying lots and transactions before filing."
}Traceability
Every exported tax figure should link back to lots and source transactions. Export receipts record a SHA-256 of the artifact body, generation timestamp, organization id, optional period id, and source revision. Use the receipt to prove what was generated — then verify line items in the product before filing.
What it does not do
- Does not file returns with the IRS or state agencies
- Does not replace professional tax advice for entity structure, elections, or nexus
- Does not guarantee completeness if imports or feeds are incomplete
- Does not cover every jurisdiction’s crypto or securities nuance at launch