Notice response

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

A letter from the IRS, answered. The AI reads it, your code matches each payment against the periods the letter shows, and sorts it. A representative claims it, the officer grants a Form 2848 that names them by CAF number for this form and these periods, and the response goes out under it. Or, for $99, the officer answers it herself.

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

A corporation's notice is usually about money: a balance due, a payment posted to the wrong period, or a penalty. The Notice Response reads the letter, finds the facts in the taxpayer's own payments, and answers through a representative under a grant that names them.

captured/tax-notice.txt · magic values: none
$ cat services/notice-response.ts
import { Service } from 'services.dev'
import { classify, matchPayments } from '../lib/tax.ts'
import { preparers } from '../pools/preparers.ts'
import rules from '../rules.ts'

// A letter from the agency, answered. The AI reads it, your code matches each payment the taxpayer kept against the
// periods the letter shows them posted to, and sorts it: pay what is owed, ask for a misapplied payment to be moved, ask
// for a penalty to be abated, or reply. A representative claims it, and only then is the officer asked for a Form 2848
// that names them by CAF number, for this form and these periods, for a year, withdrawn once the reply is accepted. The
// reply date is the representative's to answer for. For $99 the officer answers it themselves, in their own name. On an
// abatement, a quarter of the penalty taken off is the fee, $99 at least. A letter asking for more time to assess gets
// the officer's signature on a Form 872, and the date it sets is kept on the taxpayer, so the year's clocks move to it.
export default Service({
  name: 'Notice Response',
KeyHereWhat it does
matchmatchPayments, your codeLists each payment the brand holds a receipt for, the period it was for, and the period the letter shows it posted to
classifyroutes by kindAgree and pay; a misapplied payment, a penalty to abate, or anything else, to the representative
respond.draftsby kindThe AI drafts a transfer request citing the receipt, or a request to abate, for the representative to stamp
poa.after'respond.claim'The grant is asked only once a representative claims, so it can name them
poa.what, poa.names'Form 2848', { claimant: 'caf' }The authorization names the representative who claimed, by CAF number
poa.scoperepresent and send, income tax, Form 1120, the letter's periods, 365 daysThe acts, the matter and the span it gives
poa.withdrawn['accepted', 'for']Withdrawn once the reply is accepted, or when its span runs out
needs'poa', on respond and sendThe gate refuses the step needs_grant until the grant is live
clocks.replydue reply_by, owned by the representativeTen days out a notice, five days out the rung that asks the IRS for more time
price.self, price.outcome99; 25% of a penalty abated, $99 at leastThe officer answers it herself, or the fee rides on what is taken off

Here it's ordered on its own.

Run
npx services.dev check --routes services/notice-response.ts
magic values: none
  agree       the balance is right       → pay · the owner pays it, or you route it to the Treasury · CP161
  misapplied  a payment posted wrong     → respond · a transfer request, citing the receipt · CP161 on a period the brand paid
  penalty     a penalty to take off      → respond · a request to abate · 25% of what is taken off, $99 at least · CP162, CP215
  respond     anything else              → respond · the representative's reply · a letter asking for records

The letter says Acme owes $76,289.85 for 2026. The match finds why: the extension's deposit was posted to 2027:

Call
→ POST /returns {"service":"notice-response","owner":{"name":"Ada Lovelace","email":"ada@example.com"},"ein":"12-3456789","notice":"cp161.pdf","reply_by":"2027-12-14","tax_years":["2026","2027"],"max_usd":299,"key":"cp161"}
magic values: none
← job_4Tx2 · waiting · on claim · $299.00 held · respond · tsk_7Hq2
  read      CP161 · balance due $76,289.85 for 2026: tax $73,710.00, failure-to-pay penalty $2,579.85 · reply by 2027-12-14
  match     rcp_7HqB · US $73,710.00 · Form 7004 for 2026, paid 2027-04-12 · posted to 2027
  classify  misapplied → respond, to draft a transfer request citing rcp_7HqB

Katherine Johnson claims the review. Only then is Ada asked for the Form 2848, naming Katherine by CAF number, for Form 1120 and both periods:

Call
→ GET /asks/ask_7Hq2?t=…
magic values: none
← 200 ask_7Hq2 · poa · to grant · Form 2848 · Ada Lovelace · open
  names     Katherine Johnson · enrolled agent · CAF 0312-45678R · PTIN P01234568
  matters   income · Form 1120 · 2026, 2027
  acts      represent, send · for 365 days · withdrawn when the reply is accepted

Responding needs the grant live, and Ada hasn't given it yet:

Call
→ POST /practitioners/returns/job_4Tx2/approve {"checklist":[]}
magic values: none
← 403 needs_grant: respond needs the poa grant live, and the party hasn't given it yet.

She grants it, e-signed:

Call
→ POST /asks/ask_7Hq2?t=… {}
magic values: none
← 200 done

← job_4Tx2 · waiting · on person · $299.00 held · respond · tsk_7Hq2

Katherine stamps the transfer request, and it's sent under the grant:

Call
→ POST /practitioners/returns/job_4Tx2/approve {"checklist":[]}
200 · magic values: none

← job_4Tx2 · delivered · $299.00 charged

  grants  [{"step":"poa","form":"2848","names":{"member":"mbr_8Ea1","caf":"0312-45678R"},"scope":{"acts":["represent","send"],"matters":[{"tax":"income","form":"1120","periods":["2026","2027"]}],"for":"365d"},"status":"live","until":"2028-11-13T15:00:00.000Z","withdrawn_on":"accepted"}]
Call
→ GET /owner/returns/job_4Tx2   # the owner console
magic values: none
  record  read · ai · CP161 | match · code · rcp_7HqB posted to 2027 | classify · code · misapplied → respond | review · ai · pass | respond · claimed · mbr_8Ea1 | poa · asked · names mbr_8Ea1, CAF 0312-45678R | respond · representative · refused · needs_grant · respond needs the poa grant live, and the party hasn't given it yet. | poa · owner · Form 2848 · esign | respond · person · enrolled agent · * · mbr_8Ea1 · a transfer request citing rcp_7HqB · stamped | send · the agency · accepted · rcp_7Hq2
  clocks  reply · due 2027-12-14 · mbr_8Ea1 · satisfied · its request-time rung, 5 days out, never needed
  ledger  +$299.00 · AI $0.84 · representative $90.00 · you $208.16

With posture: 'self', the AI drafts the same response, Ada signs and sends it herself, and the grant is skipped. It costs $99. On a penalty the IRS takes off, the fee is a quarter of what is abated: the money.

Grants and decisions covers scope, needs and revoking a grant. In the year, the plan mints this Service from a November notice.