Repository navigation
Agent-native factory: sim replay viewer, order dock, live kerf quote rail, receipt-gated ordering - #511
Merged
Conversation
… 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>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…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>
What shippedThree new capabilities are now live in the vcad viewer and ordering flow.
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_envnow mounts the viewer (writesDoc + geometry; registers the env's document as a session,env_idin structuredContent for ChatGPT-shim parity)gym_step; app-onlyget_sim_replay/get_sim_versionsolveForwardKinematics— the viewer does zero joint math, FK parity is exact by constructionget_preview_glb { instances: true }: one named node per assembly instance with TRS, meshes deduped per partDef (glb.tsgains node transforms +meshKey)📦 Order dock (M2)
get_order_feed: six-stopstate_chipmapping (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 footerget_order_feedis the only new widget-callable, asserted in viewer-meta tests🏭 Live kerf rail
@kerf/corecontract (drift-checked against the sibling clone when present) + byte-exactintentHashreproductionKerfClient(bearer auth, AbortController timeouts, degrade-to-estimateon unreachable) + SendCutSend adapter: vendor-native SCS config from the sheet-metal doc, single-DXFbytes_base64wire contract, sha256-verified at both endsestimatebasis — only live vendor runs carryquotedecto/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_spendissues 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 pipelineplace_ordergates before any debit: quotedoc_hashrecompute (mismatch → durableEXPIRED, per ACP-CM "intent changed ⇒ quote dead") and clearance-claim re-verification (fail/unverifiable → refuse fail-closed, persistedreceipt_status: violated); consumed-authz idempotent replay skips gates so a crashed debit can always finalize033_fabricate_order_enrichment.sql(not pushed — operator action)🧹 M0: deprecated-surface tripwire test (roots/sampling/logging — zero usage, now enforced).
How it was verified
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)kinematics.tsMap bug (all running as separate sessions)Reviewer notes
tool-surface.fixture.jsonregen is deliberate: +3 app-only tools, mount flips oncreate_robot_env/quote_manufacturing,get_preview_glb.instances, description-only diffs on the ordering pair — nothing elsesupabase db push(033), push + deploy the kerf branch, setKERF_URL/KERF_API_TOKEN, build the/authorize/<id>app route for the L2 lane🤖 Generated with Claude Code