| name | collections-ai |
| description | Project skill for the Riverline self-learning collections AI. Load when working on the three-agent debt collections pipeline (Assessment chat, Resolution voice, Final Notice chat), the Temporal workflow that orchestrates them, the events-DB handoff layer, the self-learning loop, the Darwin Gödel Machine meta-evaluator, the Vapi voice integration, the FastAPI backend, or the Vite frontend dashboard. |
Collections AI — Project Skill
You are pair-programming on a graded job-application build. The submission is followed by a live, no-AI technical interview. The user must be able to navigate this codebase fluently, defend every decision, explain the statistics, and modify the system on the spot. Optimise for human defensibility, not cleverness.
If you have not already, read .agents/AGENTS.md and .agents/knowledge.md before writing or modifying code.
Workflow rules (in priority order)
1. Phase discipline
The build is split into 5 phases (see .agents/AGENTS.md §11). Do not skip ahead. Each phase has an exit criterion. If the exit criterion is not provably met (test passes, endpoint returns expected response, Temporal UI shows expected state), the phase is not complete. Update the phase status table when a phase completes.
2. Investigate before acting
- The user mentioned a file → read it before answering.
- A constraint is unclear → re-read the relevant section of
AGENTS.md.
- A model name is unfamiliar → check
cf_client.MODELS, do not invent.
- A library API is uncertain → check the actual import path or test it before committing to it.
3. Tests for the load-bearing pieces, before the implementation
Three modules are load-bearing for the science of the submission. Tests come first:
learning/stats.py — Welch's t-test, Cohen's d, bootstrap CI. Tests verify against scipy.stats ground truth.
context/compressor.py — token budget enforcement, drop policy, critical-field protection.
compliance/checker.py — adversarial conversations that must trigger each of the 8 rules.
For everything else, write tests where bugs would silently corrupt outputs, not for coverage's sake.
4. Token budget is asserted at the call site
Every place that builds a system prompt for an LLM call must call assert_token_budget(prompt, max=2000) before sending. Every place that builds a HandoffPacket must call assert_handoff_budget(packet, max=500). Never rely on "it should be small enough." Assert it.
5. Every CF call is logged
The cf_client.call_cf_ai(...) function writes a row to cf_calls on every successful call: (model, purpose, latency_ms, ts). All LLM calls go through this function. If you find yourself reaching for httpx to talk to CF outside of cf_client.py, stop.
6. Verify before claiming done
- "It compiles" is not done.
- "Tests pass" is done for tested modules.
- "Endpoint returns 200" + correct payload is done for routes.
- "Workflow visible in Temporal UI with expected state transitions" is done for workflows.
- "Vapi call connected and produced a transcript in DB" is done for voice.
- If you cannot verify, say so explicitly. Do not imply success.
When the user asks for a phase
- Re-read the phase plan in
AGENTS.md §11 + the matching detail in knowledge.md.
- List the files you will create/modify and the exit criterion.
- Write tests for any load-bearing module first (see rule 3).
- Implement.
- Run the test or smoke check.
- Report: what was built, decisions made and why, what could break, what to test before moving on.
- Update the phase status table.
When the user asks for a fix
- Reproduce the bug (run the failing test, hit the endpoint, etc.) before changing code.
- Diagnose the root cause. Don't patch symptoms.
- Fix.
- Add a regression test if the bug was in a load-bearing module.
- Re-run.
When the user asks "should we build X?"
If X is not in the assignment brief or the build plan in AGENTS.md §11, the default answer is no. Push back, name the trade-off, ask whether the time is better spent finishing graded deliverables. The user is time-constrained (5-day deadline).
When the user proposes an architectural change
- Restate it in your own words to confirm understanding.
- List what it would replace and what would have to change.
- Estimate cost in hours. The deadline is hard.
- Identify the risk it introduces (latency, complexity, demo fragility, defensibility in interview).
- Recommend, don't dictate. The user decides.
If the change relaxes a non-negotiable from AGENTS.md §0, say so and refuse to silently weaken it.
Code style for this project specifically
- Files ≤ ~200 lines is a soft target, not a hard rule. If a file exceeds it, ask whether to split. Don't over-split —
agents/assessment.py containing the prompt + a chat loop is one cohesive unit, even at 250 lines.
- No factories, no managers, no abstract base classes unless there's a second concrete implementation already needed. YAGNI.
- One Pydantic model per concept, not Pydantic-on-Pydantic-on-Pydantic.
- Use
pathlib.Path for filesystem paths. Never string-concatenate paths.
- Use
logging, not print, in backend code. print in scripts is fine.
- Async sparingly. FastAPI handlers, Temporal activities, httpx calls — async. SQLite, file I/O, stats — sync. Don't mix without reason.
Defaults and decisions already made
These are settled. Do not relitigate without strong cause:
- CF Workers AI is the only LLM provider. OpenRouter free is fallback for the simulator only.
- Voice routing: Vapi → CF directly via OpenAI-compat endpoint. Voice agent uses 8b model.
- Handoff: events DB + raw transcript + derived HandoffPacket + lookup_prior tool. No prose summaries. No knowledge graph.
- Stats: Welch's t-test + Cohen's d ≥ 0.2 + bootstrap CI + Bonferroni for multi-comparison.
- Webhook → workflow: Temporal signal, not DB polling.
- DB: SQLite. Schema in
db/schema.sql. Connection via db/connection.py.
- Frontend: Vite + React, single page, three panels + chat input. Tailwind via CDN.
- DGM: honest run, no planted flaws. Validation test if no real flaws emerge by submission.
- Decision journal: written by the user, not by an LLM. Do not generate it.
Dangerous operations — confirm first
- Deleting files the user did not explicitly mention.
- Renaming functions/modules that have callers outside the file you're editing.
- Schema changes to
db/schema.sql after data has been written.
- Bumping a CF model alias (changes evaluation results, breaks reproducibility).
- Touching
learning/stats.py after the loop has produced results.
- Anything with
--force.
These need the user's explicit OK.
Output discipline
- Concise responses. The user is reviewing many tool results in one session.
- Use tables / diagrams when comparing options or showing flows. The diagram block format is described in your system prompt.
- Link files using the
file:// URL convention. Never paste full file contents in a reply when a link suffices.
- After each meaningful change, briefly tell the user: what changed, what to test, what's next.
On the live interview
The user will be asked to:
- Open random files and explain the code line by line.
- Defend statistical choices (why Welch, why d ≥ 0.2, why N=30, why bootstrap).
- Modify the system live (e.g. "make Agent 2 ask for verbal confirmation before quoting an offer").
- Explain the meta-evaluator's findings.
- Show the cost log and reproduce a learning-loop result.
Every file you produce should be one the user can sit down with, read, and understand without you. If a piece of code requires a paragraph of explanation to be understood, simplify the code, not the explanation.