data-schema
All records share these base fields:
$ npx -y skills add gethouston/houston --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
All records share these base fields:
Agent definition
data-schema.mdBookkeeping - Data Schema
All records share these base fields:
interface BaseRecord {
id: string; // UUID v4
createdAt: string; // ISO-8601 UTC
updatedAt: string; // ISO-8601 UTC
}All writes are atomic: write `*.tmp`, then rename onto the target path. Never edit in-place. **Never write anywhere under `.houston/<agent-path>/`** - the Houston file watcher (`crates/houston-tauri/src/agent_watcher.rs`) skips that prefix and dashboard reactivity breaks.
---
`config/` - the context ledger + learned facts
Nothing under `config/` is shipped in the repo. Every field appears at runtime, written by the first skill that needs it.
`config/context-ledger.json`
Single living file that every skill reads first. Shape:
interface ContextLedger {
universal: {
company?: {
legalName: string;
dba?: string;
entityType: "c-corp" | "s-corp" | "llc" | "partnership" | "sole-prop";
ein?: string;
state: string; // state of incorporation
fiscalYearEnd: string; // "12-31" | "06-30" etc.
foundedOn?: string; // YYYY-MM-DD
stage: "pre-seed" | "seed" | "series-a" | "series-b" | "growth";
industry?: string;
source: "paste" | "url" | "file" | "connected-app";
capturedAt: string;
};
accountingMethod?: {
method: "cash" | "accrual";
switchedOn?: string; // YYYY-MM-DD if switched
capturedAt: string;
};
coa?: {
present: boolean;
path: "config/chart-of-accounts.json";
framework: "gaap-startup" | "ifrs" | "tax-basis";
lastUpdatedAt?: string;
};
openingBalances?: {
asOf: string; // YYYY-MM-DD
source: "prior-books" | "fresh-start" | "qbo-import" | "xero-import";
trialBalancePath?: string; // e.g. "config/opening-trial-balance.json"
capturedAt: string;
};
suspenseCode?: {
code: string; // account code, stored as string
name: string; // e.g. "Suspense"
capturedAt: string;
};
};
domains: {
banks?: {
accounts: {
last4: string;
type: "checking" | "savings" | "credit-card" | "payment-processor";
bank: string; // "Chase", "Mercury", "SVB", "Stripe"
glCode: string; // text, prefixed with ' in Sheets
glName: string;
}[];
capturedAt: string;
};
payroll?: {
provider: "gusto" | "rippling" | "justworks" | "deel" | "adp" | "none";
cadence: "weekly" | "biweekly" | "semimonthly" | "monthly";
teamSize: number;
stockCompPosture: "iso" | "nso" | "rsu" | "mix" | "none";
capturedAt: string;
};
revenue?: {
model: "saas-subscription" | "usage" | "services" | "marketplace" | "mix";
asc606: "standalone" | "combined" | "n/a";
contractSource: "stripe" | "hubspot" | "spreadsheet" | "other";
capturedAt: string;
};
budget?: {
cadence: "none" | "quarterly" | "rolling";
path?: string; // "config/budget.json"
capturedAt: string;
};
investors?: {
cadence: "monthly" | "quarterly" | "both";
anchorKpis: string[]; // e.g. ["Annual Revenue","Gross Margin","Burn","Runway"]
format: "email" | "gdoc" | "notion" | "other";
capturedAt: string;
};
tax?: {
preparerName?: string;
preparerEmail?: string;
lastYearFiled?: string; // YYYY
rdCreditEligible: "yes" | "no" | "tbd";
stateFilingFootprint: string[]; // ["CA","DE","NY"]
capturedAt: string;
};
};
}**Capture rule.** Every skill declares in its body which ledger fields it needs. Before doing work, it reads the ledger; for any missing field it asks ONE targeted question with a modality hint, writes the field atomically, and continues. Never asks the same field twice.
Other `config/` files
- `config/chart-of-accounts.json` - the authoritative chart of accounts. Shape:
`[{code, name, type, parent?, statementSection, description?}]` where `type ∈ {"asset","liability","equity","revenue","cogs","expense"}` and `statementSection` groups lines on financial statements (e.g., `"operating-expenses.rd"`). Written by `build-chart-of-accounts`. **Locked at run start** for any categorization run.
- `config/party-rules.json` - user-confirmed exact-match vendor
rules: `{canonical_party: gl_code}`. Written by user confirmation inside `categorize-transactions` / `process-statements`.
- `config/prior-categorizations.json` - rolling memory of vendor →
account code assignments, only for categorizations with `confidence ≥ 0.95` or `source ∈ {rule, prior_year, transfer}`. Written atomically after each successful run.
- `config/budget.json` - optional quarterly/rolling budget rows,
`[{period, glCode, amount, note?}]`. Consumed by `run-variance-analysis`.
- `config/opening-trial-balance.json` - opening balances at the
start of the books: `[{glCode, debit, credit}]`. Must balance.
---
`context/` - living documents owned by this agent
`context/bookkeeping-context.md`
The bookkeeping brief. **Every skill reads this before it writes any substantive artifact.** Owned and updated exclusively by `define-bookkeeping-context`.
Structure (filled in by `define-bookkeeping-context`):
- Company overview (legal name, entity type, state, fiscal year,
EIN, stage, industry).
- Accounting posture (cash vs. accrual, framework, any mid-year
switches with date).
- Bank accounts and credit cards (grouped by `last4`; each tied
to an account code).
- Revenue model (subscription / usage / services; ASC 606 posture).
- Payroll posture (provider, cadence, team size, stock-comp plan).
- Compliance footprint (state-filing footprint, R&D-credit posture,
sales-tax exposure notes).
- Investor cadence (monthly / quart
Read more
Bookkeeping - Data Schema
All records share these base fields:
interface BaseRecord {
id: string; // UUID v4
createdAt: string; // ISO-8601 UTC
updatedAt: string; // ISO-8601 UTC
}All writes are atomic: write `*.tmp`, then rename onto the target path. Never edit in-place. **Never write anywhere under `.houston/<agent-path>/`** - the Houston file watcher (`crates/houston-tauri/src/agent_watcher.rs`) skips that prefix and dashboard reactivity breaks.
---
`config/` - the context ledger + learned facts
Nothing under `config/` is shipped in the repo. Every field appears at runtime, written by the first skill that needs it.
`config/context-ledger.json`
Single living file that every skill reads first. Shape:
interface ContextLedger {
universal: {
company?: {
legalName: string;
dba?: string;
entityType: "c-corp" | "s-corp" | "llc" | "partnership" | "sole-prop";
ein?: string;
state: string; // state of incorporation
fiscalYearEnd: string; // "12-31" | "06-30" etc.
foundedOn?: string; // YYYY-MM-DD
stage: "pre-seed" | "seed" | "series-a" | "series-b" | "growth";
industry?: string;
source: "paste" | "url" | "file" | "connected-app";
capturedAt: string;
};
accountingMethod?: {
method: "cash" | "accrual";
switchedOn?: string; // YYYY-MM-DD if switched
capturedAt: string;
};
coa?: {
present: boolean;
path: "config/chart-of-accounts.json";
framework: "gaap-startup" | "ifrs" | "tax-basis";
lastUpdatedAt?: string;
};
openingBalances?: {
asOf: string; // YYYY-MM-DD
source: "prior-books" | "fresh-start" | "qbo-import" | "xero-import";
trialBalancePath?: string; // e.g. "config/opening-trial-balance.json"
capturedAt: string;
};
suspenseCode?: {
code: string; // account code, stored as string
name: string; // e.g. "Suspense"
capturedAt: string;
};
};
domains: {
banks?: {
accounts: {
last4: string;
type: "checking" | "savings" | "credit-card" | "payment-processor";
bank: string; // "Chase", "Mercury", "SVB", "Stripe"
glCode: string; // text, prefixed with ' in Sheets
glName: string;
}[];
capturedAt: string;
};
payroll?: {
provider: "gusto" | "rippling" | "justworks" | "deel" | "adp" | "none";
cadence: "weekly" | "biweekly" | "semimonthly" | "monthly";
teamSize: number;
stockCompPosture: "iso" | "nso" | "rsu" | "mix" | "none";
capturedAt: string;
};
revenue?: {
model: "saas-subscription" | "usage" | "services" | "marketplace" | "mix";
asc606: "standalone" | "combined" | "n/a";
contractSource: "stripe" | "hubspot" | "spreadsheet" | "other";
capturedAt: string;
};
budget?: {
cadence: "none" | "quarterly" | "rolling";
path?: string; // "config/budget.json"
capturedAt: string;
};
investors?: {
cadence: "monthly" | "quarterly" | "both";
anchorKpis: string[]; // e.g. ["Annual Revenue","Gross Margin","Burn","Runway"]
format: "email" | "gdoc" | "notion" | "other";
capturedAt: string;
};
tax?: {
preparerName?: string;
preparerEmail?: string;
lastYearFiled?: string; // YYYY
rdCreditEligible: "yes" | "no" | "tbd";
stateFilingFootprint: string[]; // ["CA","DE","NY"]
capturedAt: string;
};
};
}**Capture rule.** Every skill declares in its body which ledger fields it needs. Before doing work, it reads the ledger; for any missing field it asks ONE targeted question with a modality hint, writes the field atomically, and continues. Never asks the same field twice.
Other `config/` files
- `config/chart-of-accounts.json` - the authoritative chart of accounts. Shape:
`[{code, name, type, parent?, statementSection, description?}]` where `type ∈ {"asset","liability","equity","revenue","cogs","expense"}` and `statementSection` groups lines on financial statements (e.g., `"operating-expenses.rd"`). Written by `build-chart-of-accounts`. **Locked at run start** for any categorization run.
- `config/party-rules.json` - user-confirmed exact-match vendor
rules: `{canonical_party: gl_code}`. Written by user confirmation inside `categorize-transactions` / `process-statements`.
- `config/prior-categorizations.json` - rolling memory of vendor →
account code assignments, only for categorizations with `confidence ≥ 0.95` or `source ∈ {rule, prior_year, transfer}`. Written atomically after each successful run.
- `config/budget.json` - optional quarterly/rolling budget rows,
`[{period, glCode, amount, note?}]`. Consumed by `run-variance-analysis`.
- `config/opening-trial-balance.json` - opening balances at the
start of the books: `[{glCode, debit, credit}]`. Must balance.
---
`context/` - living documents owned by this agent
`context/bookkeeping-context.md`
The bookkeeping brief. **Every skill reads this before it writes any substantive artifact.** Owned and updated exclusively by `define-bookkeeping-context`.
Structure (filled in by `define-bookkeeping-context`):
- Company overview (legal name, entity type, state, fiscal year,
EIN, stage, industry).
- Accounting posture (cash vs. accrual, framework, any mid-year
switches with date).
- Bank accounts and credit cards (grouped by `last4`; each tied
to an account code).
- Revenue model (subscription / usage / services; ASC 606 posture).
- Payroll posture (provider, cadence, team size, stock-comp plan).
- Compliance footprint (state-filing footprint, R&D-credit posture,
sales-tax exposure notes).
- Investor cadence (monthly / quart
Open source platform for AI-native products. Pre-built AI agents with real tools and 1000+ integrations, in a Rust engine + Tauri desktop app. Free forever.

