Skip to content

deploy: bundle truffle into the web-API Lambda so /api/propose can price#67

Merged
scttfrdmn merged 1 commit into
mainfrom
feat/bundle-truffle-lambda-pricing
Jun 28, 2026
Merged

deploy: bundle truffle into the web-API Lambda so /api/propose can price#67
scttfrdmn merged 1 commit into
mainfrom
feat/bundle-truffle-lambda-pricing

Conversation

@scttfrdmn

Copy link
Copy Markdown
Owner

What & why

The deployed web-API Lambda's brain prices each rung by shelling out to truffle (the spore.host "call the tool, don't reimplement" rule — internal/spore). truffle is a local CLI, absent from the stock Lambda PATH, so /api/propose could not price in the deployed control plane — the pricing half of the deploy gap documented in PR #64.

This bundles truffle into the foray-web Lambda:

  • make lambdas cross-compiles truffle (linux/arm64, CGO_ENABLED=0, stripped) from a spore.host/truffle checkout (TRUFFLE_SRC, default ../spore-host/truffle) into the zip under bin/.
  • lambda.tf prepends /var/task/bin to the Lambda PATH so the spore exec runner's LookPath("truffle") resolves it — no Go-adapter change (the exec seam already does LookPath).
  • The webapi IAM role gains exactly truffle's read-only spot-path actions: ec2:DescribeSpotPriceHistory, DescribeInstanceTypes, DescribeInstanceTypeOfferings, DescribeRegions, pricing:GetProducts.
  • The foray-gateway zip never prices, so it stays truffle-free.

Stays ~$0: a non-VPC Lambda keeps default internet egress, so truffle's read-only calls reach AWS with no VPC, no endpoints, no NAT.

The other half of the #64 gap — gateway→worker reachability — is filed as #66 with the two candidate shapes (public-IP+token vs full VPC) for a later, GPU-validated decision. Not in this PR.

Verification

  • make demo-fake, go test ./..., golangci-lint run ./..., make license-check — all green (no Go changed; offline gate untouched).
  • terraform fmt -check + terraform validate + make deploy-check — green.
  • make lambdas — bundles a stripped arm64 truffle; web zip is 17 MB compressed (under Lambda's 50 MB direct-upload limit), bin/truffle path preserved; forayd zip stays truffle-free. Missing-TRUFFLE_SRC guard produces a clear error.
  • Not run: real make deploy (hand-validation-pending, per the step-9 precedent — not CI).

Checklist

  • make lint and make test pass
  • CHANGELOG.md updated under [Unreleased]
  • New files carry the Apache 2.0 header (no new source files; .tf/Makefile edits keep existing headers)
  • Tests added/updated — N/A (no Go/behavior change; the price path is already unit-tested behind the spore fake)

Invariant check (see CLAUDE.md)

  • Ephemeral by default — unchanged
  • Control plane rests at ~$0 — upheld: no VPC/endpoints/NAT; non-VPC Lambda egress only
  • Cost is per-session; budgets/ceilings respected — unchanged (this restores the $/session estimate at propose time)
  • No automatic egress — unchanged
  • Single-tenant — unchanged
  • Device-agnostic — unchanged
  • The question stays load-bearing; brain never auto-accepts — unchanged (LLM still never touches the money path; truffle does)

Refs #66 (follow-on). Closes the pricing half of the PR #64 deploy gap.

The web-API Lambda's brain prices each rung by shelling out to truffle (the
spore 'call the tool, don't reimplement' rule). truffle is a local CLI, absent
from the stock Lambda PATH, so /api/propose could not price in the deployed
control plane — the pricing half of the deploy gap documented in PR #64.

Cross-compile truffle (linux/arm64, CGO_ENABLED=0, stripped) from a
spore.host/truffle checkout (TRUFFLE_SRC, default ../spore-host/truffle) into
the foray-web zip under bin/, and prepend /var/task/bin to the Lambda PATH so
the spore exec runner's LookPath resolves it — no Go-adapter change. The
foray-gateway zip never prices, so it stays truffle-free.

Stays ~$0: a non-VPC Lambda keeps default internet egress, so truffle's
read-only EC2/Price-List calls reach AWS with no VPC, no endpoints, no NAT. The
webapi IAM role gains exactly those read-only pricing actions.

gateway->worker reachability (the other half of the gap) remains a documented
follow-on; README captures the two candidate shapes (public-IP+token vs full
VPC) for a later, GPU-validated decision.

Offline gate untouched and green (make demo-fake, go test ./...); make lambdas
verified to bundle a stripped arm64 truffle (17MB compressed web zip, under the
50MB direct-upload limit).
@scttfrdmn
scttfrdmn merged commit c6dc596 into main Jun 28, 2026
7 checks passed
@scttfrdmn
scttfrdmn deleted the feat/bundle-truffle-lambda-pricing branch June 28, 2026 18:37
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