Skip to content

feat: invariant CI gates — no-always-on (#31) + no-auto-egress (#32)#68

Merged
scttfrdmn merged 1 commit into
mainfrom
feat/invariant-ci-gates
Jun 28, 2026
Merged

feat: invariant CI gates — no-always-on (#31) + no-auto-egress (#32)#68
scttfrdmn merged 1 commit into
mainfrom
feat/invariant-ci-gates

Conversation

@scttfrdmn

Copy link
Copy Markdown
Owner

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 the deploy-check.sh idiom:

  • scans go.mod for always-on infra clients (Ray/k8s, NATS/AMQP/Kafka, Temporal, Redis, job-queue brokers);
  • scans deploy/terraform/*.tf for 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's spawn, never by control-plane TF, so any aws_instance here is a true violation;
  • requires the DynamoDB table to be billing_mode = "PAY_PER_REQUEST" (provisioned throughput = always-on billing).

#32 — no automatic egress

internal/webapi.TestNoTensorEgressBoundaries reflects 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, or interface{}). 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 invariant CI job. Verified each gate fails on an injected violation (aws_instance, PROVISIONED DDB, a k8s.io dep, a []byte field) and passes on clean state.

Checklist

  • make lint and make test pass
  • CHANGELOG.md updated under [Unreleased]
  • New files carry the Apache 2.0 header
  • Tests added/updated

Invariant check (see CLAUDE.md)

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
@scttfrdmn
scttfrdmn merged commit 8878087 into main Jun 28, 2026
8 checks passed
@scttfrdmn
scttfrdmn deleted the feat/invariant-ci-gates branch June 28, 2026 23:41
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.

invariant gate: no automatic egress of activations invariant gate: control plane has no always-on server/broker/cluster

1 participant