Year-end close

The running jobjob_4Tx2 · delivered · workpapers-2026.txt · return.txt · $1,800.00 charged

The year's books, reconciled and closed before the return reads them. AI reconciles each account and proposes the entries, the officer decides which to post, and for $900 instead of $300 an accountant from gigs.accountants attests the close. The closed books are kept on the taxpayer for that year's return.

tax's wordsreturn is a jobtaxpayer is a subjectreview is a taskpreparer is a member

A return is only as good as the books it reads. The Year-End Close closes them first: the AI reconciles each account to its statement and proposes the adjusting entries, an adversarial tie-out checks them, and the officer decides which to post. It sells two ways on one order, the AI's close for $300, or the same close attested by an accountant for $900.

Run
cat services/year-end-close.ts
magic values: none
import { Service } from 'services.dev'

// The year's books, closed before the return reads them. The AI reconciles each account to its statement and proposes
// the adjusting entries, an adversarial tie-out checks them, and the officer decides which to post. For $900 instead of
// $300, an accountant from gigs.accountants reviews the close and attests it in their own session: the brand imports that
// Pool, so it recruits no one and pays its operator a placement line on each filled review. The closed books are kept on
// the taxpayer for the year, and that year's return opens with its books item answered.
export default Service({
  name: 'Year-End Close',
  description: "A year's books, reconciled and closed.",
  input: {
    owner: 'party: the officer who decides', ein: 'text: such as 12-3456789', tax_year: 'text: such as 2026',
    books: 'url: a read-only link to the ledger, such as https://books.example/acme', statements: "file[]: each account's year-end statement",
  },
  output: { trial_balance: 'file', entries: 'file: each adjusting entry, with its source', closed_books: 'url: the books, closed for the year' },
  subject: { kind: 'taxpayer', key: 'ein', period: 'tax_year', keeps: { closed_books: 'closed_books' } },
  roles: { accountant: { pool: 'gigs.accountants/accountants', pay: 250 } },
  deliver: {
    reconcile: { by: 'ai', cite: 'each account against its statement' },
    check: { review: 'adversarial', lenses: ['numeric tie-out', 'cutoff'] },

check reads it back. The accountant comes from another operator's Pool, imported by name, with its terms pinned:

Run
npx services.dev check
magic values: none
  ledger  +$900.00 · AI $1.26 (example) · preparer $150.00 · signer $105.00 · you $643.74 · 4 jurisdictions
services/year-end-close.ts · 15 lines · $300 per job, or $900 with an accountant's approval, within 48 hours, charged on delivery.
  roles   accountant · from gigs.accountants/accountants, a Pool another operator runs · $250 an approval · placement $20.00 a filled review
  import  gigs.accountants · its operator runs the roster, verification, dispatch and payouts · terms pinned at 2026-09 · $250 is at or above its $200 minimum
          +$900.00 · AI $1.26 (example) · accountant $250.00 · placement $20.00 · you $628.74 · approved
  margin  at least $240.00 a job (80%), $450.00 approved (50%) · a job that stops costs you at most $450.00

Without max_usd, the order answers an OFFER with both, and the buyer picks one with approved:

captured/tax-money.txt · 402 · OFFER · $300 for the AI's close, or $900 with an accountant's approval. · magic values: owner.email = signs@example.test, metadata.sandbox.asks = {"organizer.books":"after 160d","organizer.assets":"waive","organizer #2":"after 2d","w9":"after 19d"}, metadata.sandbox.outside = {"reject":{"file.US-NY":["ein_mismatch"]}}, metadata.sandbox.events = { notice.received: { at: 2027-11-14T15:00:00Z, data: { notice, reply_by, tax_years } } }
→ POST /returns {"service":"year-end-close","owner":{"name":"Ada Lovelace","email":"ada@example.com"},"ein":"12-3456789","tax_year":"2026","books":"https://books.example/acme","statements":["bank-2026.pdf","card-2026.pdf"],"key":"close-2026"}
  choices   approved: false · $300.00 · AI reconciles every account and proposes the entries; you decide which to post
            approved: true · $900.00 · an accountant from gigs.accountants reviews the close and attests it before you get it
  next      POST /returns {…,"max_usd":300} or {…,"approved":true,"max_usd":900}

The approval is a step the accountant attests in their own session, on gigs.accountants, after the officer posts. The brand pays its operator $20 for each review it fills, never out of the accountant's $250:

captured/tax-money.txt · 200 · job_4Tz2 · year-end-close · delivered · $900.00 charged · approved · magic values: owner.email = signs@example.test, metadata.sandbox.asks = {"organizer.books":"after 160d","organizer.assets":"waive","organizer #2":"after 2d","w9":"after 19d"}, metadata.sandbox.outside = {"reject":{"file.US-NY":["ein_mismatch"]}}, metadata.sandbox.events = { notice.received: { at: 2027-11-14T15:00:00Z, data: { notice, reply_by, tax_years } } }
→ GET /owner/returns/job_4Tz2   # approved
  record  reconcile · ai · 14 accounts | check · ai · adversarial · 2 lenses · pass | post · owner · decided "post every entry" · 6 entries | approve · accountant · tsk_7Hz2 · mbr_ga_4410 of gigs.accountants · attested
  ledger  +$900.00 · AI $1.26 · accountant $250.00 · placement $20.00 to gigs.accountants · you $628.74 · approved
  take    on $630.00 · the accountant's pay and the placement leave the base

keeps: { closed_books } writes the closed books on the taxpayer for the year. That year's annual return opens with its organizer's books item answered, and says where it came from. Annual return reads it, and Two doors covers importing a Pool.