Skip to content

Agent-native factory: sim replay viewer, order dock, live kerf quote rail, receipt-gated ordering - #511

Merged
ecto merged 3 commits into
mainfrom
claude/mcp-latest-updates-b0ebc5
Jul 9, 2026
Merged

ecto merged 3 commits into
mainfrom
claude/mcp-latest-updates-b0ebc5

Conversation

@ecto

@ecto ecto commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Implements the full purple-cow spec (docs/agent-native-factory.md, M0–M4 + kerf rail). One sentence: an agent designs a part in chat, you watch it move, tap approve, and the receipt proves both the geometry and the commerce.

What changed

▶ Physics replay in the inline viewer (M1)

  • create_robot_env now mounts the viewer (writesDoc + geometry; registers the env's document as a session, env_id in structuredContent for ChatGPT-shim parity)
  • 600-step trajectory ring buffer on gym_step; app-only get_sim_replay / get_sim_version
  • Per-step instance transforms computed server-side via kernel solveForwardKinematics — the viewer does zero joint math, FK parity is exact by construction
  • get_preview_glb { instances: true }: one named node per assembly instance with TRS, meshes deduped per partDef (glb.ts gains node transforms + meshKey)
  • Viewer transport bar: play/pause/scrub/speed, reward sparkline, joint readout, live-follow badge riding the existing adaptive poll

📦 Order dock (M2)

  • App-only get_order_feed: six-stop state_chip mapping (exhaustive, never-checked switches over all 16 vcad OrderStates and all 17 kerf JobStates), pricing-basis pills, approval banner → vcad.io/authorize/<id> deep link, receipt/evidence chips, wallet footer
  • The iframe is read-only for money — get_order_feed is the only new widget-callable, asserted in viewer-meta tests

🏭 Live kerf rail

  • Mirrored @kerf/core contract (drift-checked against the sibling clone when present) + byte-exact intentHash reproduction
  • Production KerfClient (bearer auth, AbortController timeouts, degrade-to-estimate on unreachable) + SendCutSend adapter: vendor-native SCS config from the sheet-metal doc, single-DXF bytes_base64 wire contract, sha256-verified at both ends
  • Honesty rule: scripted-mode rehearsal prices are downgraded to estimate basis — only live vendor runs carry quoted
  • Companion branch ecto/kerf#feat/http-quote-api (unpushed): POST /api/quote + job/evidence GETs, assertTransition-guarded job store, Browser-Use CDP host, ScriptedHost exported ($5.58 canary verified via curl)

✅ Approval + receipt gates (M3/M4, always-on, no flags)

  • authorize_spend issues URL-mode elicitation when the client advertises the capability (SDK 1.29.0); decline revokes via compare-and-set; full integration test through the real server pipeline
  • place_order gates before any debit: quote doc_hash recompute (mismatch → durable EXPIRED, per ACP-CM "intent changed ⇒ quote dead") and clearance-claim re-verification (fail/unverifiable → refuse fail-closed, persisted receipt_status: violated); consumed-authz idempotent replay skips gates so a crashed debit can always finalize
  • Migration 033_fabricate_order_enrichment.sql (not pushed — operator action)

🧹 M0: deprecated-surface tripwire test (roots/sampling/logging — zero usage, now enforced).

How it was verified

  • 743 passed / 2 skipped across 54 files (baseline 706/46); build + tsc clean; local MCP-apps smoke green
  • 133-agent adversarial review (7 dimensions × 3 refuters per finding) over both repos: 42 raw findings triaged, all confirmed money-path bugs fixed — highlights: session hydration before the gates for signed-in users, event-history preservation in setOrderState, tolerant-retry only on real column skew, order-feed windowing/version-token fixes, euler order aligned to the kernel's Rz·Ry·Rx (authority: vcad-eval/src/kinematics.rs)
  • Known out-of-scope issues filed as follow-ups: kernel HashMap joint ordering, web-app euler order, engine kinematics.ts Map bug (all running as separate sessions)

Reviewer notes

  • tool-surface.fixture.json regen is deliberate: +3 app-only tools, mount flips on create_robot_env/quote_manufacturing, get_preview_glb.instances, description-only diffs on the ordering pair — nothing else
  • Replay/envs are in-process (warm-instance scope), same caveat as the existing gym
  • Operator actions after merge: supabase db push (033), push + deploy the kerf branch, set KERF_URL/KERF_API_TOKEN, build the /authorize/<id> app route for the L2 lane

🤖 Generated with Claude Code

… kerf quote rail, receipt-gated ordering

Implements docs/agent-native-factory.md (M0–M4 + kerf rail):

- Physics replay in the inline viewer: create_robot_env mounts the canvas
  with a play/pause/scrub/speed transport bar, reward sparkline, and
  live-follow; trajectories ride a 600-step ring buffer and per-step
  instance transforms come from kernel solveForwardKinematics (FK stays
  single-source-of-truth in Rust; euler order aligned to the kernel's
  Rz·Ry·Rx). get_preview_glb gains an instances mode with per-instance
  named nodes, node TRS, and shared meshes.
- Order dock: app-only get_order_feed renders the fused vcad+kerf
  lifecycle (six-stop chips, pricing-basis pills, approval banner with
  vcad.io deep link, receipt/evidence chips, wallet footer). The iframe
  stays read-only for money.
- Live kerf rail: mirrored @kerf/core contract + byte-exact intentHash,
  production KerfClient (timeouts, bearer auth, degrade-to-estimate),
  SendCutSend adapter with vendor-native SCS config + single-DXF
  bytes_base64 wire contract. Scripted-mode rehearsal prices are
  honestly downgraded to estimate basis; only live runs carry "quoted".
- Protocol-native approval: authorize_spend issues URL-mode elicitation
  when the client supports it (capability-gated, no flag); decline
  revokes via compare-and-set.
- Receipt-gated ordering (always-on, fail-closed when evidence exists):
  place_order re-verifies clearance claims and the quote doc_hash before
  any debit, with durable refusals (EXPIRED on geometry drift, persisted
  receipt_status "violated") and consumed-authz replay finalization.
- M0: deprecated-surface tripwire (roots/sampling/logging never adopted).
- Supabase migration 033 (orders.fab_artifact/receipt_status/
  kerf_intent_hash, quotes.kerf_intent_hash/kerf_job_id) — not pushed.

Hardened by a 133-agent adversarial review (42 findings triaged; all
confirmed money-path bugs fixed, incl. signed-in session hydration
before the gates, event-history preservation, and column-skew-only
tolerant retries). Tests: 743 passed / 2 skipped across 54 files
(baseline 706/46); companion kerf HTTP API on ecto/kerf
feat/http-quote-api.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
vcad-mcp Building Building Preview, Comment Jul 8, 2026 11:21pm
3 Skipped Deployments
Project Deployment Actions Updated (UTC)
mecheval Ignored Ignored Jul 8, 2026 11:21pm
vcad Ignored Ignored Jul 8, 2026 11:21pm
vcad-docs Ignored Ignored Jul 8, 2026 11:21pm

Request Review

…METADATA

- adopt resolveArtifactRefAsync/getArtifactFileAsync in the ordering and
  kerf-intent paths (durable artifact store from #510)
- keep main's post-connect maybeAutoDock retry with our typed hostContext
- TOOL_METADATA entries for get_sim_replay/get_sim_version/get_order_feed
- tool-surface fixture regenerated from the merged surface (770/772 green)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collided with 033_mcp_artifacts from #510 (duplicate schema_migrations
version key in the Verify migrations check). Comment references updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ecto
ecto merged commit b17751e into main Jul 9, 2026
15 checks passed
@chojiai

chojiai Bot commented Jul 9, 2026

Copy link
Copy Markdown

What shipped

Three new capabilities are now live in the vcad viewer and ordering flow.

  • Watch your simulation move. When an AI agent runs a physics simulation of your design, a playback bar now appears in the viewer — you can play, pause, scrub through the motion, and see a live reward chart and joint readout, all without leaving the conversation.
  • Track your fabrication orders in one place. A new order dock in the viewer shows the full lifecycle of every manufacturing order — current status, pricing, vendor, and history — so you can follow a part from quote to delivery without switching tabs.
  • Stronger safeguards before any money moves. When you approve a spend and the agent goes to place an order, two checks now run automatically: the design must not have changed since the quote was generated, and any safety or geometry checks on the part must still pass. If either fails, the order is blocked and no charge is made.

Plain-English summary generated by Choji from this pull request.

ecto added a commit that referenced this pull request Jul 9, 2026
…#516)

The agent-side elicitation lane (authorize_spend, PR #511) deep-links
humans to https://vcad.io/authorize/<authorization_id> — but that URL
404'd and there was no approval write-path anywhere: migration 027 left
users read-only on spend_authorizations, with all writes service-role
only. This is the missing human half of the handshake.

Migration 035:
- approve_spend_authorization(uuid) / decline_spend_authorization(uuid)
  SECURITY DEFINER RPCs, granted to authenticated only. RLS-equivalent
  guards inside: auth.uid() must own the row, only pending_human +
  unexpired rows transition, row locked FOR UPDATE so concurrent
  decisions get exactly one winner. Not-owner folds into not_found so
  foreign ids are indistinguishable from missing ones.
- No wallet/ledger touches — debit_wallet (027) still re-verifies
  status, expiry, ownership, caps, and allowlists at consume time.
- Verified behaviorally on an ephemeral Postgres with a stubbed auth
  schema: happy paths stamp approved_by/approved_at/revoked_at; unauth,
  foreign-owner, re-approve, expired, and consumed all return the
  guarded {ok:false, reason} shapes; anon has no execute grant.

App:
- AuthorizePage at /authorize/<id>, mounted standalone from main.tsx by
  pathname match (same zero-risk pattern as /cli-auth). Requires a
  permanent identity (anon sessions would RLS-read nothing and mislabel
  the row not-found), loads the row via the user's own client, renders
  cap / fab allowlist / live expiry countdown, and resolves every
  outcome by re-reading the DB row — never inferring from the RPC echo.
- Vercel rewrites for /authorize/(.*) in both deploy configs (the 404
  root cause), plus a uuid-strict route parser with vitest coverage so
  junk ids fall through to the editor.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

This branch was successfully deployed

1 active deployment
Preview – vcad-mcp — 2cc99268 Deployed Jul 8, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant