feat: invariant CI gates — no-always-on (#31) + no-auto-egress (#32)#68
Merged
Conversation
Two build-failing gates that formalize existing ad-hoc protection into explicit, named CI checks: - #31 (no always-on): scripts/invariant-check.sh (make invariant-check) statically scans go.mod for broker/cluster/queue clients and deploy/terraform/ for always-on resource types, and requires the DynamoDB table to be PAY_PER_REQUEST. Mirrors the deploy-check.sh idiom. - #32 (no auto-egress): internal/webapi.TestNoTensorEgressBoundaries reflects over every trace-result boundary struct (gateway.TraceResult, brain.RawResult, brain.Result, webapi.resultView) and fails on any tensor-bearing field type. Centralizes the scattered JSON-key guards. Both run in a new 'invariant' CI job. Offline/fake-green gate untouched. Closes #31 Closes #32
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.
What & why
Formalizes two CLAUDE.md invariants into explicit, build-failing CI gates. Both were partly guarded already (ad-hoc tests, the on-demand DDB choice); this turns that protection into named gates that fail the build on a violation. No AWS, no GPU — pure static + reflective checks.
Closes #31
Closes #32
#31 — control plane rests at ~$0 (no always-on)
scripts/invariant-check.sh(make invariant-check), mirroring thedeploy-check.shidiom:go.modfor always-on infra clients (Ray/k8s, NATS/AMQP/Kafka, Temporal, Redis, job-queue brokers);deploy/terraform/*.tffor always-on resource types (aws_instance, ECS/EKS, autoscaling/launch templates, MQ/MSK, RDS, ElastiCache, load balancers, NAT gateways, Redshift/EMR/Kinesis) — GPU EC2 is launched at runtime by spore'sspawn, never by control-plane TF, so anyaws_instancehere is a true violation;billing_mode = "PAY_PER_REQUEST"(provisioned throughput = always-on billing).#32 — no automatic egress
internal/webapi.TestNoTensorEgressBoundariesreflects over every trace-result boundary struct —gateway.TraceResult,brain.RawResult,brain.Result,webapi.resultView— and fails if any field has a tensor-bearing type ([]byte, a numeric slice/array, a map, orinterface{}). This is the structural complement to the existing runtime JSON-key guards: a new non-scalar field on any boundary breaks the build before it can reach a wire test. The only egress path stays the user-initiated presigned export.Both run in a new
invariantCI job. Verified each gate fails on an injected violation (aws_instance,PROVISIONEDDDB, ak8s.iodep, a[]bytefield) and passes on clean state.Checklist
make lintandmake testpassCHANGELOG.mdupdated under[Unreleased]Invariant check (see CLAUDE.md)