Stack

What this site runs on and what it is built from, without a detour through a repository.

Architecture

Every read is a server-rendered response from one Rust binary behind CloudFront. Nothing is always on, and the only persistent state is a disposable table of check runs.

  1. Visitor

    • Browser

      Reads HTML. No JavaScript is required for any content on this site.

      Outside this stack

  2. Edge

    • Route 53

      Alias records at the apex, which is why DNS lives here rather than at the registrar.

      AWS::Route53::RecordSet

    • CloudFront

      Behaviour precedence is load-bearing: the POST endpoints are ordered ahead of the read-only default, which allows only GET and HEAD.

      AWS::CloudFront::Distribution

    • Cache policy

      Short TTL with ETag revalidation for HTML. Per-visitor responses are no-store, not briefly cached.

      AWS::CloudFront::CachePolicy

  3. Request path

    • Function URL

      No API Gateway. Nothing here needs a custom authorizer, usage plan, or request validation.

      AWS::Lambda::Url

    • site-handler

      One Rust binary routing every page and API path with axum. arm64 on provided.al2023.

      AWS::Lambda::Function

  4. Orchestration

    • Fit workflow

      Express, invoked synchronously. Extract, then four parallel matchers that each apply a different rule, then aggregate.

      AWS::StepFunctions::StateMachine

    • Provenance workflow

      Standard and asynchronous, because a dozen outbound checks with timeouts will not finish inside a request.

      AWS::StepFunctions::StateMachine

    • Task functions

      One binary per workflow, dispatching on a tagged payload. The matchers are pure compute with identical permissions, so separate artifacts would be copies.

      AWS::Lambda::Function

  5. State

    • Runs table

      Check-run projections, on-demand, with a TTL on every item. Reads render from the projection and make zero Step Functions calls.

      AWS::DynamoDB::Table

  6. Operations

    • Log groups

      Retention set explicitly on every one. The default never expires and becomes the largest line item on a project this size.

      AWS::Logs::LogGroup

    • Alarms

      Failed executions on both workflows, plus handler errors and throttles. The fit workflow falls back to inline analysis, so without an alarm a broken workflow is invisible.

      AWS::CloudWatch::Alarm

    • Alert topic

      One topic for the stack. The subscriber address comes from deploy context, never from a file in the repository.

      AWS::SNS::Topic

  7. Delivery

    • GitHub Actions

      Assumes a deploy role by OIDC. No long-lived access keys exist in the repository or in CI secrets.

      Outside this stack

    • ACM certificate

      A separate stack in us-east-1, because CloudFront accepts certificates from no other region.

      Outside this stack

Each component names the CloudFormation type it deploys as, and the build fails if the diagram claims a type this stack does not contain. That catches a diagram describing something it does not run. It cannot prove the diagram is complete, so treat it as checked rather than exhaustive.

Manifests

Verbatim, from the commit that built this page. A summarized dependency list is a claim; the file is the evidence.

Cargo.toml

Workspace dependencies, the lint that forbids unsafe, and the release profile. The comments are load-bearing: several of these pins exist because of a specific failure.

[workspace]
members = ["crates/*"]
resolver = "3"

[workspace.package]
edition = "2024"
license = "MIT"
publish = false

[workspace.dependencies]
check-runner = { path = "crates/check-runner" }
resume-core = { path = "crates/resume-core" }
run-store = { path = "crates/run-store" }

# `behavior-version-latest` is not optional: without a behaviour version the
# SDK panics at client construction rather than failing at compile time.
aws-config = { version = "1", features = ["behavior-version-latest"] }
aws-sdk-dynamodb = "1"
aws-sdk-sfn = "1"

axum = "0.8"
# For the Content Security Policy hashes only. Both are pure Rust with no
# system dependency, so `resume-core` stays WASM-capable, and both versions
# match what is already in the tree rather than pulling a second copy.
base64 = "0.22"
sha2 = "0.11"
# 1.x relaxed `run`'s error bound to any `E: Debug + Into<Diagnostic>`. The 0.5
# line required `Error = lambda_http::Error`, which an axum Router
# (Error = Infallible) cannot satisfy. Do not downgrade below 1.x.
lambda_http = "1.3"
lambda_runtime = "1.5"
maud = "0.27"
# rustls rather than native-tls: no system OpenSSL in the Lambda image, and
# one less thing that differs between local and deployed builds.
reqwest = { version = "0.12", default-features = false, features = [
  "json",
  "rustls-tls",
  "charset",
  "http2",
] }
schemars = "1"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "2"
tokio = { version = "1", features = ["macros", "net", "rt", "rt-multi-thread"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["json"] }

[workspace.lints.rust]
unsafe_code = "forbid"

[profile.release]
lto = true
codegen-units = 1
strip = true

infra/package.json

The only Node dependency tree in the project, and it exists solely to run CDK. Nothing in it reaches the browser.

{
  "name": "rader-resume-infra",
  "version": "0.1.0",
  "private": true,
  "bin": {
    "infra": "bin/app.js"
  },
  "scripts": {
    "build": "tsc",
    "synth": "cdk synth",
    "check:architecture": "ts-node --prefer-ts-exts bin/check-architecture.ts",
    "deploy": "cdk deploy",
    "diff": "cdk diff",
    "bootstrap:app": "cdk --app \"npx ts-node --prefer-ts-exts bin/bootstrap.ts\"",
    "diff:oidc": "npm run bootstrap:app -- diff rader-resume-github-oidc",
    "deploy:oidc": "npm run bootstrap:app -- deploy rader-resume-github-oidc",
    "diff:dns": "npm run bootstrap:app -- diff rader-resume-dns",
    "deploy:dns": "npm run bootstrap:app -- deploy rader-resume-dns"
  },
  "devDependencies": {
    "@types/node": "^22.0.0",
    "aws-cdk": "^2.1000.0",
    "ts-node": "^10.9.2",
    "typescript": "^5.6.0"
  },
  "dependencies": {
    "aws-cdk-lib": "^2.160.0",
    "cargo-lambda-cdk": "^0.0.36",
    "constructs": "^10.3.0"
  }
}