Appearance
Skills
~5 min read · section overview · skim the table, then drill into Auto-tagging
TAKE-HOME BRIEF
The brief offered three workflows to choose from — W1 (auto-tag card spend to general ledger codes), W2 (evaluate policy rules against spend events), or W3 (manage the bill-payment flow end to end) — and asked for something "runnable enough to understand how you would start building the real system." This section documents all three, plus a fourth scheduled skill. Each skill is a direct answer to that ask; the platform underneath them is the argument for why all three belong together.
A "skill" here is one well-scoped job that the AI controller can do end-to-end: take in a finance event, decide what to do about it, and write that decision somewhere a human can review. This submission ships four skills. Each lives on its own page in this section, and every page is laid out the same way so you can move between them without re-learning the structure.
A short glossary before you read
A few terms come up on every page. Defining them once here keeps the rest of the section short.
- Event. A single thing that happened — a card was swiped, a bill arrived in the inbox, the morning brief is due. Everything that enters the system enters as an event.
- Skill. A small program that knows how to react to a particular kind of event. Auto-tagging reacts to spend; the daily pulse reacts to the clock.
- Decision. What a skill writes back after it has thought about an event. A decision is one of four types — apply (the system did it itself), suggest (a human should confirm it), refuse (the system declined to act and said why), or escalate (a human with more authority needs to look). Every decision is saved, with the evidence used to reach it.
- Autonomy gate. A single switch per tenant that decides which of those four outcomes the system is allowed to act on without a human. The skills never decide their own authority — they propose, the gate disposes.
- Override. When a human in the review queue changes a decision. Overrides are saved as their own corrections and feed back into the system so the same surprise does not cost twice.
That is the whole vocabulary. The rest of the section is the four skills using it.
If you only read one page
Read Auto-tagging. It is the only one of the four where a large language model is doing real work, and it is where you see the full pattern: try a deterministic shortcut first, fall back to a constrained model call if needed, gate the result, log everything, and learn from the human's correction. The other three skills are variations on the same theme.
The four skills at a glance
W1Auto-taggingReactive · model in the live path behind a Zod schema · classify card / payout / bill to a GL code.
W2Policy enforcementReactive · pure rule engine, no model in the hot path · allow, flag, or deny in sub-milliseconds.
W3Accounts payableReactive · deterministic planner with fraud gates first · suggest, escalate, refuse — never auto-applies.
+1Daily pulseScheduled · arithmetic over the day's data, optional narration · morning brief for the CFO.
| Skill | When it runs | How it thinks | What it tends to do |
|---|---|---|---|
| W1: Auto-tagging | Whenever a card swipe, payout, or bill arrives | Vendor memory first, then a language model with a strict schema | Apply when confident, otherwise suggest; refuse rather than guess |
| W2: Policy enforcement | Whenever a card swipe or bill arrives | A plain rule engine — no model in the live path | Allow, flag, or deny — explainable in milliseconds |
| W3: Accounts Payable agent | Whenever a new bill arrives | Plain code: scheduling, fraud gates, source-of-funds picker | Suggest, escalate, or refuse — never moves money on its own |
| Daily pulse | On a schedule (morning brief) | Plain arithmetic over the day's data, then optional narration | Suggest a calm day or escalate if the cash floor is about to be hit |
The "How it thinks" column is the most important one to scan. Notice that only one skill uses a language model in the live path. The others either need to be too fast (policy), too safe (payments), or too explainable (the brief) for that to be a good trade.
What the four skills share
The four pages can stand alone, but they hang together because they share five properties. Each property is a small claim, and the bracketed clause says why it matters in plain terms.
- One way for an event to come in. Every skill reads the same input shape, so adding a fifth skill later does not require new plumbing. [One input contract.]
- One place where decisions get written. The review queue, the bills page, the morning brief, and the evaluation harness all read from the same table of decisions. [One source of truth.]
- The same four outcomes, everywhere. Apply, suggest, refuse, escalate. The autonomy switch decides which of those a tenant lets the system act on. [The trust boundary lives in one place, not scattered.]
- Refusing is not failing. When a skill does not know, it says so with a reason code instead of guessing. The review queue surfaces refusals next to suggestions. [Silent miscoding, silent over-spend, or silent payment to the wrong bank account is impossible by construction.]
- Every decision is replayable. Decisions are stamped with the prompt version, model identifier, policy bundle version, or rules version that was active when they were made. Re-running an old transaction against today's settings is a normal operation, not a forensic exercise. [Appeals and audits read a stable snapshot.]
The human in the review queue is also part of the design: every override they make becomes a corrected coding that the system uses next time. The reviewer's work compounds — that is the closest thing to a learning loop here.
The shared contract, in one type
If you only look at one piece of code in this submission, look at this one. The platform stays generic across all four skills because every skill conforms to this shape.
The Skill interface — one shape, four cognition styles
ts
// src/skills/types.ts
export type Skill<PayloadSchema extends z.ZodTypeAny = z.ZodTypeAny> = {
id: SkillId; // "auto-tagging" | "policy-enforcement" | "ap-agent" | "daily-pulse"
label: string;
payloadSchema: PayloadSchema; // Zod schema for the payload inside an Outcome
triggers: (evt: FinanceEvent) => boolean; // does this skill care about this event?
run: (
evt: FinanceEvent,
opts: { tenantId: string; modelOverride?: string },
) => Promise<SkillRunResult>; // event in → Outcome + telemetry out
goldenPath: string; // where the eval harness finds the golden set
};Notice what is not in here. There is no autoApply() method — autonomy is the platform's call, not the skill's. There is no costBudget or latencyBudget — the runtime decides. There is no prompt — the skill owns its cognition but exposes only run. That is the small surface area that lets the platform graduate skills through autonomy independently and swap the runtime from synchronous to durable as a deploy.
The autonomy ladder
Each tenant can graduate each skill independently up this ladder. The default for a new tenant is suggest on every skill; nothing auto-applies until the eval and override history earn the rung above.
1
Shadow
Log onlyThe skill runs and writes decisions, but nothing surfaces to the operator or applies. Used to calibrate before exposing the skill to reviewers.
2
Suggest
Operator ratifies every decisionDecisions land in the review queue; the human accepts or overrides each one. This is the default rung for any new tenant or skill.
3
Assisted
High-confidence auto, rest reviewedConfidence above the skill's threshold auto-applies; everything below still routes to the queue. The autonomy gate is the only switch.
4
Autonomous
Auto by default, exceptions routedPer-tenant, per-skill. Accounts payable can never reach this rung — its type signature blocks
autoApply by construction.Why these four
The take-home asks for three workflows. I shipped all three and added a fourth, scheduled skill (the daily pulse) for one specific reason: the most interesting thing Reap can build is not another agent that competes with Ramp on coding accuracy. It is a proactive layer that uses Reap's privileged view across card spend, stablecoin payouts, balance sleeves, and bill schedules to speak first instead of waiting to be asked.
The four together make that point. Auto-tagging shows where the model is useful. Policy enforcement shows where it is not. Accounts payable shows the safety stance on money movement. The daily pulse shows that a proactive layer can sit on top of the same machinery as the other three.
What is shipped versus mocked
The code paths are real and you can run them locally. The demo uses a seeded SQLite database with synthetic tenant data, and the auto-tagging classifier currently uses a stamped synthetic decision in the demo seed (labelled synthetic/demo-seed) instead of calling a live model on every page load. Flipping that to a real model is one environment-variable change; the schema, the queue, the autonomy gate, and the override flow are identical either way. The page on trade-offs calls out exactly which pieces are mocked and what would change in production.
How each skill page is laid out
So you know what to expect on the next four pages:
- A one-paragraph summary of what the skill is and is not.
- The brief from the take-home (W1–W3), restated, with how the shipped skill answers it.
- A diagram of the decision flow.
- The rules, gates, or rail logic, shown as a chart or matrix rather than prose.
- The submission stance — the load-bearing design choices and why I will defend them.
- A pointer to the worked example, which walks one real database row from the demo end-to-end and names the design patterns the skill uses.
Where to go next
- For a guided tour of the live demo rows: Live data examples.
- For the architectural choices that hold the four skills together: Cross-cutting decisions.
- For everything I am assuming about Reap's data and tenants: Labeled assumptions.
- For how I measured the skills: Eval harness in Operations.