- 18 agent specs across Software, Support, Marketing, Cross-cutting (orchestrator + 7 software + 5 support + 3 cross-cutting + leads-finder) - 8 reusable skills (handoff, pr-review, dokploy-deploy, campaign-structure, content-calendar, ticket-triage, license-lifecycle, invoice-draft) - 3 JSON schemas: handoff, deliverable, approval - Policies: autonomy levels, tool risk classification, compliance (DSGVO/GoBD/UWG) - routing.toml: model tiers T1/T2/T3 + provider config (PII gating) - Rust workspace (5 crates, all compile + 16 tests pass): - aos-mcp: tool registry + risk tagging - aos-policy: autonomy levels, budget enforcement, approval requests - aos-license: ed25519 license issue/verify (real crypto + CLI binary) - aos-ledger: integer-cents money math, gapless numbering, VAT, audit chain - aos-sync: frontmatter validator (18/18 specs pass), CLI binary - CLAUDE.md entry point with architecture overview + roadmap
94 lines
4.6 KiB
Markdown
94 lines
4.6 KiB
Markdown
---
|
|
name: invoice-draft
|
|
version: 1.0.0
|
|
applies_to: [accounting-lead, invoice-agent]
|
|
risk: medium
|
|
---
|
|
|
|
# Invoice Draft
|
|
|
|
## When to use
|
|
When a task requires drafting an invoice for a client. Drafting the record
|
|
is medium-risk; sending it is a separate, always-approved high-risk step.
|
|
|
|
## Steps
|
|
1. Read the task: client id, billing period, contract (rates, VAT rule,
|
|
currency, reverse-charge applicability, payment terms).
|
|
2. Pull billable time + expenses from AOS via `aos-mcp` reads: approved
|
|
timesheets (not raw drafts), receipts already attached and approved,
|
|
any pass-through costs (hosting, ad spend, license fees billed on).
|
|
3. Confirm the contract's VAT rule: standard rate, reverse-charge (EU B2B
|
|
with valid VAT ID), Kleinunternehmer, or Drittland. If unclear →
|
|
`blocked`. Never guess a VAT rate.
|
|
4. **Compute via the `aos-ledger` Rust crate.** Net / VAT / gross and
|
|
rounding (2 dp, banker's per §14 UStG) are calculated by the crate —
|
|
never by arithmetic in the prompt. The crate assigns the **next
|
|
gapless invoice number** from the client's fiscal-year sequence; the
|
|
agent never picks, reuses, or skips a number.
|
|
5. Assemble line items: description (DE / EN per client language),
|
|
quantity, unit, unit price (net), per-line VAT rate.
|
|
6. Validate against the contract: rates match the price list, expense
|
|
markups match, currency matches. Any mismatch → `blocked`.
|
|
7. Write the invoice record to AOS via the crate's `commit` call with
|
|
`status: draft`. The crate owns the write (gapless numbering, hash
|
|
chain on the audit log).
|
|
8. Produce the E-Rechnung attachment: the crate renders ZUGFeRD
|
|
(XRechnung-compliant) XML in the PDF. Validate the XML against the
|
|
XRechnung schema; on failure → `blocked`, do not send.
|
|
9. Attach all expense receipts and time-entry refs to the invoice record
|
|
(GoBD — Belegführung).
|
|
10. Surface the draft to `accounting-lead` for review (rates, period,
|
|
VAT rule, substantiation, E-Rechnung validity).
|
|
11. On lead approval, emit an `ApprovalRequest` (`schemas/approval.json`):
|
|
`action: send_invoice`, `risk: high`, `rationale` (number, client,
|
|
period, gross, due), `diff_summary` ("Send invoice <number> for
|
|
<gross> <currency> to <client.email>; due <date>"), `payload` with
|
|
invoice_id/number/net/vat/gross/currency/due_at/delivery_channel,
|
|
`estimated_cost_eur: 0`.
|
|
12. **Pause.** The policy crate will not execute `aos:send_invoice`
|
|
without an approved matching approval. The agent does not send.
|
|
|
|
## Inputs
|
|
- A task with `task_id`, client id, billing period.
|
|
- The client's contract (rates, VAT rule, currency, payment terms,
|
|
reverse-charge status, VAT ID).
|
|
- Approved time entries and expenses in AOS for the period.
|
|
- The client's `language.deliverables` setting for the invoice language.
|
|
|
|
## Outputs
|
|
An `AgentDeliverable` (`schemas/deliverable.json`) with:
|
|
- `status`: `needs_review` | `needs_approval` | `blocked`
|
|
- `deliverables[]`: AOS invoice record ref (`aos_record`, status: draft),
|
|
the E-Rechnung PDF/XML ref (`file`), receipt attachments list, the
|
|
invoice number assigned by the crate.
|
|
- `risks[]`: rate inferred, expense unverified, reverse-charge without
|
|
recent VIES check, rounding edge case, contract mismatch flagged
|
|
rather than blocked.
|
|
- `cost`: tokens only (sending is a separate gate).
|
|
|
|
## Guard rails / compliance
|
|
- **GoBD — gapless numbering**: the `aos-ledger` crate assigns every
|
|
number. The agent never invents, picks, reuses, or skips one.
|
|
- **GoBD — no deletion**: a wrong invoice is storniert (reversed) with an
|
|
audit entry citing the original number. Drafts never sent are retained.
|
|
- **GoBD — Belegführung**: every line references a substantiating record
|
|
(time entry / receipt / contract clause).
|
|
- **Never do money math in the prompt.** Net / VAT / gross, currency
|
|
conversion, and rounding happen in the crate.
|
|
- **E-Rechnung compliance**: ZUGFeRD / XRechnung XML must validate before
|
|
send. Invalid XML blocks.
|
|
- **Never send without an approved `ApprovalRequest` of action
|
|
`send_invoice`.**
|
|
- **Reverse-charge**: only applied when the client's VAT ID is valid and
|
|
current — re-check with VIES at draft time; record the check timestamp.
|
|
- **Retention**: invoices 8 years, business letters 6 years (crate-enforced).
|
|
Currency conversion uses the ECB reference rate for the invoice date;
|
|
the crate records the rate used.
|
|
|
|
## References
|
|
- `schemas/approval.json` — `send_invoice` action
|
|
- `schemas/deliverable.json` — `draft` output format
|
|
- `policies/compliance.md` — GoBD, E-Rechnung, DSGVO
|
|
- `policies/tool-risk.md` — `aos:send_invoice` is `risk: high`
|
|
- `crates/aos-ledger` — money math, gapless numbering, hash chain, storno
|