1- # Agent brief — read this first
1+ # Agent brief, read this first
22
33You're working on ** ledgerloop** , a procure-to-pay demo built as a job/freelance
44asset for Didero (procurement-AI). Two surfaces: an ** onboarding agent** that reads a
55client's HRIS and derives an approval workflow, and a ** pipeline** that runs invoices
66through that workflow. This file is the context a fresh session needs so it doesn't
77re-derive or break conventions. (` .product/*.md ` has deeper strategy notes but is
8- gitignored, so it may be absent in a worktree — this committed brief is the source.)
8+ gitignored, so it may be absent in a worktree, this committed brief is the source.)
99
10- ## Current state (the two surfaces are LINKED — done, don't re-derive)
10+ ## Current state (the two surfaces are LINKED, done, don't re-derive)
1111
1212The "complete loop" is built and on ` main ` . Key facts a fresh session must know:
1313
@@ -39,7 +39,7 @@ The "complete loop" is built and on `main`. Key facts a fresh session must know:
3939- ** e2e** (` pnpm e2e ` , local-only, needs keys): ` approval.e2e.ts ` (HITL on the default) +
4040 ` onboarding-to-pipeline.e2e.ts ` (the flagship loop: discover → dept gate → post).
4141
42- ## Hard conventions (non-negotiable — the user is strict about these)
42+ ## Hard conventions (non-negotiable, the user is strict about these)
4343
4444- ** No ` as ` casts.** ESLint ` @typescript-eslint/no-unsafe-type-assertion ` is ON.
4545 Narrow with a type guard (` isRecord ` in ` lib/assert.ts ` ), validate with a Zod
@@ -53,10 +53,10 @@ The "complete loop" is built and on `main`. Key facts a fresh session must know:
5353- ** The API is oRPC.** Typed procedures in ` lib/orpc/router.ts ` , shared i/o schemas
5454 in ` lib/orpc/schemas.ts ` , browser client + TanStack Query in ` lib/orpc/client.ts ` ,
5555 one handler at ` app/rpc/[[...rest]]/route.ts ` . Add a procedure there, not a new
56- ` app/api/* ` route. (The only plain REST route left is ` /api/pdf ` — binary.)
56+ ` app/api/* ` route. (The only plain REST route left is ` /api/pdf ` , binary.)
5757- ** "AI at the edge, deterministic core."** LLM calls do fuzzy intent (structured
5858 output); deterministic code does structure. The chat-edit is a hand-written
59- bounded loop (` lib/workflow-edit-agent.ts ` ) over the Claude SDK — NOT a Mastra
59+ bounded loop (` lib/workflow-edit-agent.ts ` ) over the Claude SDK, NOT a Mastra
6060 Agent (see its header comment for why). Mastra owns the P2P pipeline
6161 (` src/mastra/workflows/p2p.ts ` ) and the exception-investigator agent.
6262- ** Bounded persistence, not stateless.** The run writes ONE thing: an append-only
@@ -66,7 +66,7 @@ The "complete loop" is built and on `main`. Key facts a fresh session must know:
6666 A nightly Vercel Cron (` /api/reset ` , ` vercel.json ` ) truncates+reseeds Postgres so
6767 the demo stays pristine; the reset touches Postgres only, never the sandboxes.
6868 HITL resume stays REPLAY-based (recompute the deterministic prefix from the
69- decisions), NOT Mastra snapshot/suspend — keep it that way (the snapshot path has
69+ decisions), NOT Mastra snapshot/suspend, keep it that way (the snapshot path has
7070 a known Postgres-bloat footgun). Don't reintroduce writes to the document tables.
7171- ** The recorded HRIS fixture is SEED-BUILT** , not a live capture
7272 (` scripts/build-recorded-fixture.ts ` → ` pnpm fixture:build ` ). recorded == live ==
@@ -83,7 +83,7 @@ pnpm typecheck && pnpm lint && pnpm knip && pnpm test && pnpm format:check && pn
8383
8484- ` pnpm test ` = node: test , all faked (free, no API).
8585- Evals: ` pnpm eval:edit --dry-run ` and ` pnpm eval:edit-agent --dry-run ` are free
86- (stubs). Live evals cost Anthropic tokens — only run a live eval to PROVE a model
86+ (stubs). Live evals cost Anthropic tokens, only run a live eval to PROVE a model
8787 change works, never casually. The user's rule: don't waste tokens.
8888- Screenshots: the dev server hits live BambooHR if the key is set (~ 12s). For fast,
8989 deterministic screenshots run dev with ` BAMBOO_HR_API_KEY= BAMBOO_HR_SUBDOMAIN= `
@@ -100,23 +100,23 @@ pnpm typecheck && pnpm lint && pnpm knip && pnpm test && pnpm format:check && pn
100100
101101## Where things are
102102
103- - ` lib/approval-workflow.ts ` — the workflow DAG model, conditions, ` humanizeCondition ` ,
103+ - ` lib/approval-workflow.ts ` , the workflow DAG model, conditions, ` humanizeCondition ` ,
104104 ` diffWorkflows ` .
105- - ` lib/approval-engine.ts ` — executes the DAG (AND-join, skipped = pass-through).
106- - ` lib/workflow-validate.ts ` — structural + AP-best-practice checks (the validator).
107- - ` lib/workflow-edit.ts ` / ` -agent.ts ` / ` -model.ts ` — the chat-edit ops, the
105+ - ` lib/approval-engine.ts ` , executes the DAG (AND-join, skipped = pass-through).
106+ - ` lib/workflow-validate.ts ` , structural + AP-best-practice checks (the validator).
107+ - ` lib/workflow-edit.ts ` / ` -agent.ts ` / ` -model.ts ` , the chat-edit ops, the
108108 bounded agent loop, the Claude planner.
109- - ` lib/onboarding.ts ` / ` -model.ts ` — derive the workflow from an org.
110- - ` lib/hris.ts ` — BambooHR adapter (live + recorded) + the mapper.
111- - ` lib/erp.ts ` — two seams: the reconciliation POST stub (fake-netsuite) AND the
109+ - ` lib/onboarding.ts ` / ` -model.ts ` , derive the workflow from an org.
110+ - ` lib/hris.ts ` , BambooHR adapter (live + recorded) + the mapper.
111+ - ` lib/erp.ts ` , two seams: the reconciliation POST stub (fake-netsuite) AND the
112112 PO PULL (QuickBooks live + recorded fixture, same shape as HRIS). ` defaultErp() `
113113 picks live/recorded by env; ` loadRunBundle ` matches invoices against pulled POs.
114- - ` src/mastra/ ` — the P2P pipeline + investigator agent + run-stream generator.
115- - ` components/ ` — onboarding, workflow-editor, workflow-graph (React Flow),
114+ - ` src/mastra/ ` , the P2P pipeline + investigator agent + run-stream generator.
115+ - ` components/ ` , onboarding, workflow-editor, workflow-graph (React Flow),
116116 dashboard, trace-timeline.
117117
118118## Your task
119119
120- Ask the user — the link-workflow / department / live-graph work (see "Current state"
120+ Ask the user, the link-workflow / department / live-graph work (see "Current state"
121121above) is done and merged. There may be a ` TASK.md ` in this folder from a past branch;
122122treat it as scaffolding, not a live instruction, unless the user points you at it.
0 commit comments