Set 7 November 2026, after a week of AI-initiative meetings. The desk becomes the home of Business Operations’ tools under Robbie: procurement today, then a chat agent, reporting and receipts, and recruitment one day. Adam’s and Claude’s working list, to check goals off as they land; operational state stays in HANDOFF.md.
00030-kez); next, Robbie’s own reportsAlongside:
00026-san (7 November)main (HANDOFF, “Goal”): in place before Ask the desk shipssrc/app.css is 2,154 lines), with the new sections’
navigation so they don’t copy the bloat5 and 6’s discovery steps need no code and run alongside 1-4.
gmail.readonly, vendor APIs GET only, with a
test that fails the build otherwise (the Zoom dashboard’s pattern).hillspire-procurement, read only by
purchasing-desk-runtime@; never chat, the repo or a ticket.PSA answers most questions: spend by entity, vendor and month, order counts and cycle time come from its fields, titles and changelog. What it lacks is the items. Total Order Cost is one number per ticket, often several vendors’ orders together, and no ticket holds a part number or a price per item, so “how many X1 Carbons” or “why did the X1s go up” can’t be answered from it. The desk reads both from every vendor email and kept only the total it posts; the mailbox covers 90 days.
Decided (Adam, 7 November): BigQuery, in the desk’s own project and separate from Harry’s CSAT. The ledger holds only what the vendors’ emails said; JSM stays the record of the ticket, and Ask says which source each answer used. Chosen over keeping items on the ticket because it catches every order the mailbox sees, including the ones a buyer handles by hand, and later Amazon’s actual charges and ABM’s serials. How it works: README, “Order ledger”.
purchasing_desk, log sink purchasing-desk-ledger and its grant
(7 November; HANDOFF)desk.ledger line per vendor email; views in
ledger_bigquery.sql, checked in BigQuery against the fixtures (7 November)00026-san (7 November)Today everyone on the access list can approve Jira writes. Before Kelly (CIO), or
anyone who only reads, gets in: buyers approve; viewers see Orders, Requests,
Reports and Ask but get no approve buttons, enforced on the server, not just hidden.
One Okta group per role; PROCUREMENT_ALLOWED_EMAILS stays the second check.
A chat panel on the desk for Kelly, Robbie and the buyers: “how many Lenovos did we order this month?”, “how much have we spent on Lenovo laptops?”, finance’s “the X1s were $2.5k, now $3k, why?”. Asked for by the CIO on 3 November. Mock (invented numbers): https://claude.ai/artifact/TLTB72QSnR9kBTP5AUQEWH.
claude-opus-5-5 since 7 November, when every agent moved to it; one setting) and the same
agentic tool loop. The desk is Node, so @anthropic-ai/sdk; the shape (system
prompt, tools, loop, limits) follows Oscar’s.purchasing-desk-anthropic-api-key, not Harry’s. A record of use (who
asked, which tools ran) as structured logs.Order-level questions work on PSA alone from day one; item-level ones (“how many X1 Carbons”, price history) cover what the ledger holds (from 20 October on), and say so.
feat/procurement-ask (README, “Ask the desk”): the loop,
three tools (purchase_requests, vendor_orders, ordered_items), the Ask
tab; 161 tests with ABM’s, 62 UI checkspurchasing-desk-anthropic-api-key in Secret Manager (a Console
service account, 7 November)scripts/try-ask.mjs), #272, deployed as 00028-qux00030-kez): the Reports tab
over PSA and the ledger: filters, groupings, a cross-tab, a chart over time, the
period before, CSV, links and print, with rejected requests left out of spend.
README, “Reports”. Not yet: cycle time from Jira’s changelog (it has days from
created to closed), and whatever Robbie reports today.The plan decided 28 October stands (HANDOFF, “Apple”): Apple’s emails drive the flow, already copied to procurement@; ABM adds serial numbers. Adam has the ABM API key (7 November).
server/abm-client.mjs) and a local preflight
(scripts/abm-preflight.mjs), from Apple’s docs (7 November,
feat/procurement-abm). An ABM API account can also reassign devices,
release them from the organization and edit Blueprints, so the client is GET
only, pinned by test.AAA… number on
PSA-2486 (AAA6828504)? That decides whether serials can be matched to tickets
at all. Also W1610319216 (an in-store pickup) and AFH0099144.vendors.mjs; serials on the order, added to the ticket on
approval; serials go into the ledger too; later the helpdesk hand-off.Worth doing, but not first, and not a Concur integration first.
Not started; waiting on Robbie’s details. Candidates’ personal information is a different kind of data from orders, so plan its access (its own Okta group at least) and retention with InfoSec then, before building.
Amazon Business API (carrier tracking, later Reconciliation for receipts) and the morning “Needs you” Slack message. The name stays “Purchasing Desk” until it holds more than purchasing; the Cloud Run service and project names don’t change.