Skip to content
CommonLayer
Documentation menu
On this page

Implementation status

The final record of what CommonLayer implements, where, how it was tested and where that testing happened, and what is not done. It is compiled from the work-package status files in docs/status/ (WP-01 to WP-81), the security review of November 2026, and the list of GitHub Actions runs of this repository as read on 2026-11-10 around 22:40 UTC. Where a status file and the code disagreed, the code was read and this page follows it.

Repository stewardship and onboarding through the GitHub App (WP-80, WP-81; plan 13) were added on 2026-11-11. Their commits were pushed without workflow runs to save runner minutes (ADR-0048); the final tree (0c3ffd0) was then checked on GitHub runners by ci, security, docs and infra. What ran for the stewardship work, and where, is stated in each section below.

After that, the first-party projects were corrected (WP-83, plan 14, ADR-0049): the base image, nginx, Valkey and PostgreSQL had been built as directories of this repository, by its workflows. Each is now a complete repository tree of its own (commonlayer-org/<project>), kept under projects/ only until those repositories exist. The same day a missing object storage bucket became its own error, the development GitHub learned to serve a project directory of the checkout, and a helper registers the GitHub App from a manifest (WP-82).

On 2026-11-12 the portal was reworked by one rule, "don't make me think" (WP-90, plan 15): every page says where you are, what the state is and what to do next; dashboards start with what is waiting; explanations moved behind disclosures or into the documentation. A check holds 117 page types to the countable parts of that rule.

Words used on this page:

  • Tested locally: automated tests or a scripted drill ran and passed in the build sandbox (linux/amd64, Docker 29, one shared machine), as recorded in a status file.
  • Tested on a GitHub runner: a workflow job ran and passed on a GitHub-hosted runner (ubuntu-24.04, linux/amd64). The run id is given.
  • Validated statically: linted, schema-checked, rendered or unit-tested as configuration, but never executed against the thing it configures.
  • Never run: exists in the repository; nothing has executed it.

Nothing is in production. No artifact has been published to a CommonLayer registry, no contribution has been accepted with real money, and no payout has been made.

Not done or not verified

Read this section before relying on any part of the platform. It is ordered by consequence: what has never run at all, then what ran only on GitHub runners or only locally, what is implemented only in part, and the decisions that only the operating entity can make.

Never run anywhere

ItemWhat exists instead
The four first-party projects as repositories on GitHub (commonlayer-org/base, commonlayer-org/nginx, commonlayer-org/valkey, commonlayer-org/postgresql): they do not exist yet. Their own workflows (validation per version line, the checkout of the base project through CL_BASE_REPOSITORY, release, scheduled scan) have never runEach tree was exported to a directory outside this checkout and built there (see "Ran only locally"); the workflows were checked with actionlint in the exported trees. Creating the repositories and pushing the exports (scripts/export-project.sh) is the owner's step
scripts/ops/github-app-create.py against github.comTested against a local stand-in for GitHub: manifest, state check, exchange, files readable by the owner only, no secret printed
The GitHub App and everything behind it on github.com: the installation callback and its code exchange, installation tokens, the repository picker, collaborator invitations and removals, mirror clones with an installation token, transfer webhooks, a stewardship-hosted restoreNo GitHub App has been created for this platform. The code paths are tested against an in-memory GitHub, wiremock and local bare repositories, and one test mirrors a small public repository over HTTPS without a token. In development a labelled stand-in replaces GitHub (github.provider = "development", refused elsewhere). The operator guide (the GitHub App) lists the settings the code expects and says they are unverified
Keyless signing and its verification (Fulcio, Rekor, Sigstore TUF root, GitHub Actions OIDC identities)The pipeline's keyless code path and the template's release workflow exist. The publish drill signed with a cosign key pair without a transparency-log entry (COMMONLAYER__REGISTRY__COSIGN_REQUIRE_TRANSPARENCY_LOG=false, refused in production)
Provenance from actions/attest-build-provenance discovered and verified by the pipeline (threat model O11)The drill's provenance is an SLSA v1 statement written and signed by scripts/dev/e2e-publish.sh itself; it proves parsing and checking, not that a build service attested anything
Any release workflow: release (platform images), every project's own release.yml and scheduled security-scan.yml (in the four trees and the template), opsactionlint and shellcheck clean; a WP-20 rehearsal against a throwaway local registry covered push by digest, index merge, release SBOMs and chart publication. No GitHub run of these workflows is recorded. This repository no longer has workflows that release or rescan projects
linux/arm64 builds of any imageThe workflows build arm64 only when the repository is public or the variable CL_ARM64_RUNNER names a runner; neither is the case. Release workflows refuse to release without arm64
Live Stripe: payments, refunds, disputes, fees, invoice-payment linking, subscriptionsTested against fixtures built from the API reference and a mock server (crates/commonlayer-funding/tests/it/stripe.rs). Which invoice_payments list filters Stripe accepts was taken from the object reference, not observed
Live payouts through Stripe ConnectOnly against a mock; simulated payout runs are tested
A real GitHub App installation (webhooks from GitHub, App API calls, the GitHub issue channel) and a real Actions OIDC token at a deployed platformGitHub's documented example payloads, wiremock and locally generated keys; the acceptance tests use the test kit's OIDC verifier
Repository verification and manifest sync against GitHubThe SSRF-safe client deliberately ignores the sandbox's egress proxy. The drill used clctl dev manifest-sync (development only) and the seed's pre-verified repository
The numeric-id check of a repository against GitHub (review MEDIUM-5 fix)Tested with wiremock (repositories::numeric_github_ids_are_checked_and_cannot_be_squatted)
Security feeds against the real services (OSV, EPSS, CISA KEV, NVD)Recorded responses only; the FeedStale alert is pending in every local stack because the feeds cannot be fetched
CloudNativePG backups (Barman Cloud Plugin, volume snapshots), the Pooler, PodMonitor, synchronous replicationChart values and CRD schema validation only
Anything on a real Kubernetes cluster or on AWSkind in CI (see below); OpenTofu modules validated (tofu validate, tflint) but never planned or applied
The Playwright suite on a GitHub runner, and against the containerised stackThe suite ran green locally against the development backend (below). The e2e workflow's only run (Dependabot pull request, commit f920636) failed before any test; it has been changed since and has not run again
Load and stress profiles of the k6 scenarios; the webhook-ingestion scenarioSmoke runs of three scenarios against the Compose stack (WP-50)
Email to real mailboxesMailpit only
Platform images signed or attested (threat model O12)The release workflow would sign and attest them; it has never run
A data-subject request process (export, deletion of personal data while keeping financial and audit records)Not implemented

Ran only on GitHub runners

ItemEvidenceCaveat
CloudNativePG high availability: operator install, three instances, failover (primary killed, standby promoted in about 3 s, data kept, old primary rejoined), rolling update, helm testprojects run 42882522865 (commit a562cb9), job projects/postgresql 18 (amd64)Passed in its original form (run 42882522865) and again after the test moved into chart hooks (projects/postgresql/tests/kind/): run 42920329890 (commit 812a77d). In between, the first run of the hook form (run 42901650680) failed because the wait hook looked for a Cluster under a name the chart does not produce; the hooks now find it by its release label. PostgreSQL 18 on one kind node, linux/amd64 only
Chart install and upgrade on kind for nginx and the project templateprojects runs 42868563456 and 42901650680linux/amd64
PostgreSQL 16, 17 images with the extension test (pgvector example)runs 42882522865, 42901650680—
The platform chart on kind: install with the migration hook and least-privilege role check, helm test, upgrade, helm test againinfra runs 42915487605 (commit d00e5d2) and 42925002412 (commit 629ebdd), every job greenEarlier runs failed on configuration faults in the kind values and on the default-deny NetworkPolicy blocking the test pod; both fixed. linux/amd64, one node, development-grade values
Rust format, clippy, the whole Rust test suite against PostgreSQL 18, migrations; web lint, typecheck, unit tests and build; generated-file staleness; buf lint; cargo-denyci green on every push since commit 7ce0cb7 (runs 42881955149, 42882523029, 42901650588, 42904755656)These also ran locally
gitleaks, pnpm audit, cargo-audit, Trivy filesystem and configuration scans, CodeQL (TypeScript)security green on every push since 7ce0cb7Results go to workflow artifacts and job summaries, not to code scanning (not enabled; ADR-0044). OpenSSF Scorecard and dependency review are skipped on a private repository

Ran only locally (build sandbox)

ItemEvidence
Each project tree as a repository of its own (WP-83): exported outside the checkout as a git repository, then the project's own make validate build test scan sbom chart-test there for the base, the template and nginx; for Valkey the 9.1 line (Sentinel failover test included) and for PostgreSQL the 18 line; make validate and actionlint for all five. A check finds no file in any tree that refers outside it. The rule engine checks every tree with every rule, without exemptionsWP-83. For the base and nginx the same then passed on a GitHub runner, nginx with its chart installed on kind (projects, run 43083172187). Not run: the other version lines of Valkey and PostgreSQL after the restructuring, Valkey, PostgreSQL and the template on a runner in the new form, arm64
With SELinux enforcing (the owner's Fedora machine): the Compose services after the bind mounts got the relabel optionreported by the owner as failing before the change; the change itself was checked only on a host without SELinux
Repository stewardship (WP-80): onboarding through the App with the callback's binding rules, the rule engine over the template and every project tree, source backups against local bare repositories (bundle verified, manifest equal to for-each-ref, token never in arguments, URLs, errors, logs or stored rows), access reconciliation that never touches people CommonLayer did not add, succession by transfer and by restore with the successor rule, and the whole flow over HTTP with the development provider (acceptance workflows F, G and H)WP-80: cargo test --workspace, 914 passed, 0 failed, 7 ignored, on the final tree (coordinator, 2026-11-11). The same suite then passed on a GitHub runner (ci, run 43028990763), so this item no longer ran only locally; the browser tests below still did
The backend and worker images built from the final tree (make image-backend image-worker: release build inside the image's narrow build context, which is what failed in the nightly run). The worker image carries git 2.54.1 at /usr/bin/git and runs as uid 10001; the backend image has no git. Before that, the Dockerfile's git stage alone was run on the base image with a read-only root and the worker's cleared environment: ls-remote and fetch of a public repository over HTTPS, bundle create, bundle verifycoordinator, 2026-11-11. The three platform images were then built on a GitHub runner and the chart installed on kind (infra, run 43029000216). The containerised stack (make stack) was not started again after WP-80
The portal for onboarding and stewardship in a browser against the development provider: connect, install, pick, scan with findings, fixing push, rescan, propose; repository administration; succession by restore; rule waiver and approvalWP-81: Playwright stewardship.spec.ts within the whole suite (1188 tests, 1076 passed, 112 skipped by design, 0 failed)
The publish drill: nginx built with the project's scripts, pushed to the source registry, SBOMs, cosign signature and three attestations, submitted by a CI service-account token, verified, scanned with real Trivy and Grype databases, evaluated (15 image checks pass, 2 not applicable), mirrored through the registry's token authentication and promoted; anonymous pull by digest with a pull-only token; cosign verify and verify-attestation at the CommonLayer reference; SBOM download; the Helm chart promoted with chart.images_pinned and chart.schema; an unsigned image rejected and absent from the registry (404)docs/status/WP-70g.md, transcripts var/drill/transcript-final-{1,2}.md (not committed); run twice, both exit 0, against an independent backend instance and the registry-alt registry (publish drill)
The whole Playwright suite: 1080 tests, 993 passed, 87 skipped by design, 0 failed (375/768/1280 px × light/dark, axe WCAG 2.2 AA)WP-70e, against next start on :3000 and the seeded development backend
The containerised stack (make stack, make stack-seed): database roles, migration as owner, every process healthy and read-only, least privilege confirmed by /readyz and commonlayer_db_privileged_connection 0, monitoring profile with all targets upWP-70g
Backup, restore and restore drill against the stack, as owner and runtime role (ledger sound, audit chain intact, object inventory complete); clctl secrets rotate on a restored copyWP-70g
The full platform images (commonlayer/{backend,worker,web}) built from the tree and scannedWP-70g
Valkey's Sentinel failover test on all five lines, including a reproduction of the runner's slow-DNS conditionWP-70f locally; also green on GitHub: projects run 42932208078 (commit 63b4dca), job projects/valkey (amd64) — validate, build, tests including the Sentinel failover test, scan gate, SBOM, chart tests, and chart install and upgrade on kind all passed. Three earlier runs failed in the test setup (slow DNS answers on the runner, then two behaviours of the runner's Docker 28 that differ from Docker 29)
make -C projects/<name> validate build test scan sbom chart-test for base, template, nginx, Valkey and PostgreSQL 18 with the declared-SBOM-component changesWP-70f (PostgreSQL 16 and 17 were not rebuilt locally with that change; they passed on a runner)
Known-vulnerable demonstrations of declared SBOM components (nginx 1.25.3 and Valkey 8.0.1 fail the gate through Grype)WP-70f
Development cookie relaxation in a browserWP-70e's Playwright runs (the earlier WP-02 check was curl only)

Implemented but partial, and open requests nobody picked up

Repository stewardship (WP-80, WP-81):

  • The API process holds the GitHub App key as well as the worker, because the repository picker asks GitHub synchronously (threat model O16). The plan wanted it in the worker only.
  • Backups hold git history only. Issues, pull requests, release pages, wikis and Git LFS objects are not backed up; every manifest says so. A bundle is assembled in memory before upload, bounded by github.backup_max_bytes (2 GiB by default).
  • An accepted collaborator invitation is noticed at the next reconciliation, not when it happens (the member webhook is not processed).
  • The rule catalogue knows one template version. A second version needs versioned rule sets. First-party projects in this repository report their CI rules as not applicable, because this repository's workflows build them.
  • Five of the new metrics are on no dashboard; the three alerts and their runbook sections exist.
  • The development GitHub provider resolves concurrent writes to one repository by last write wins, and reads its repositories from the checkout, so it works in make dev and in the Compose stack (checkout mounted) and nowhere else.
  • A release backup links to the release history, not to one release: the portal has no page per release.
  • Verifying a restore needs project.maintainers.manage. The successor creates the new repository; a project admin or a platform reviewer runs the verification.
  • The stewardship-hosted restore was never run end to end, in the portal or against GitHub: the development stack has no stewardship organization. Its service path is tested with wiremock and a local bare repository.
  • The seeded RabbitMQ project was seeded in review directly, not through an onboarding, so its repository link reads pending; a project that comes through onboarding has a verified primary repository.
  • The project trees still live in this repository. They are complete repositories (projects/base, nginx, valkey, postgresql), exported unchanged by scripts/export-project.sh, and stay here until commonlayer-org/<project> exist. After that the trees, the projects workflow, mk/projects.mk and the platform's local base image fallback are removed from this repository.
  • No base image is released, so nginx, Valkey and PostgreSQL have an empty images[].base.digest and build from a base built out of a checkout of the base project. Their release workflows refuse to release until the digest is filled in.

Platform and backend:

  • Platform binaries carry no dependency metadata. syft and Trivy see no Rust crate in the platform images; only cargo-deny and cargo-audit in CI cover the Rust dependencies. Request (WP-70g): build release binaries with cargo auditable.
  • commonlayer_build_info reports commit="unknown" in the images: the build passes VCS_REF as a label only. Request (WP-70g): pass the commit to the metric.
  • The bundled cosign 3.1.4 (worker image and scripts/dev/install-tools.sh) contains golang.org/x/net 0.61.0 (CVE-2026-78661, HIGH, fixed in 0.62.0), go-chi/chi 5.3.2 (CVE-2026-114437, MEDIUM) and x/crypto 0.58.0 (GO-2026-5932). Request (WP-70g): update when a cosign release with the fixes exists.
  • The seed writes before it has read every manifest, so a failing seed leaves the database marked seed.partial and has to be reset. Request (WP-70g to WP-40).
  • No public list of organizations, so organization pages are not in the sitemap (WP-70e). Also requested by WP-70e and not done: GET /admin/maintenance/sla (the platform default SLA can be written but not read), usernames on payout runs and on updated_by of settings, project slugs on ledger accounts and evaluation details, and a paginated public contributor list per project (first requested by WP-31).
  • Ledger and audit tamper resistance against the owner role or a superuser (threat model O1, O2): the runtime role cannot disable the triggers, but whoever holds the owner credentials can. Not done: a hash chain over the ledger, and exporting audit checkpoint digests outside the database.
  • The API still holds the payment provider's secret key and the registry token signing key (O7): checkout, refunds and subscription changes are synchronous provider calls, and the token realm signs pull tokens. Moving provider calls into worker jobs and a separate promoter process are follow-ups.
  • Repository links verified before migration 0016 are not re-checked against GitHub's numeric id (review MEDIUM-5).
  • Areas the security review did not cover: registry retention and registry-event ingestion beyond authentication; the SBOM, VEX, Trivy and Grype parsers and the subprocess adapter; outbound webhook sending; organization role APIs and the last-admin trigger; password reset details (reset tokens issued before an email change stay valid, noted, not analysed); lockout and rate-limit internals; audit and log redaction coverage; the web content security policy and the development-only pages; gRPC parity for maintenance, security and artifact mutations; rounding in settlement beyond the largest-remainder approach. The review also did not run the test suites.
  • Rate limiting during a Valkey outage is per process: N API replicas allow up to N times each limit (ADR-0019).
  • Registry retention protects digests with open findings or named in a published advisory (the security domain's retention_protection, since WP-70g) and promoted digests with any present vulnerability; blobs are reclaimed only by Distribution's offline garbage collection. Retention was outside the security review.
  • OSV pagination beyond the first page is not followed; CVSS v4 vectors are not scored.
  • Stripe: the invoice_payment.paid event must be enabled on the webhook endpoint; without it the link is resolved on demand (one API call per unmatched refund or dispute). A refund hold whose provider webhook arrives before the request stored the refund reference lapses after 7 days instead of being released.
  • clctl registry verify-preservation ran against the drill's registry, where 15 of 18 preserved digests are reported missing_manifest: the development seed records digests it never pushes.
  • gRPC has no RPC for operations that need an interactive session, and no GRPCRoute; the chart exposes it through an Ingress with h2c to the pod (rendered, not installed).
  • Portal: three maintainer actions have API operations but no portal page, found while writing the handbooks (not recorded in any status file): reviewing a community contribution (POST /contributions/{id}/review), submitting a contribution by hand (POST /projects/{slug}/contributions) and deciding a task waiver (POST /tasks/{id}/waive with a decision). The platform default SLA editor starts from a project that uses it (no read API); "set back to the default" for a runtime setting stores the default as an override (no delete); the unknown-payout resolve dialog has not run end to end (no seeded unknown payout); contribution targets can be reported for abuse only through the API; ledger accounts and payout-run initiator/approver show ids, resolved on the page.
  • Compose stack: all portal traffic counts against the web container's address unless the stack trusts it (ADR-0040).
  • Load: the musl allocator under multi-threaded load was not measured (WP-50 asked WP-70 to).

Images, charts, catalog and CI:

  • Scanner coverage of source-built components rests on Grype alone: Trivy evaluates none of the declared nginx, Valkey, PostgreSQL and darkhttpd components (ADR-0039). CommonLayer's own helpers (cl-probe, cl-kube-label) have no vulnerability feed; Valkey's vendored deps/ are not declared separately.
  • Requests of WP-70f to the CI owner not yet done: upload the SBOM-scan SARIF (sarif/trivy-sbom, sarif/grype-sbom) to code scanning when it is available (only the image-scan SARIF is uploaded); run make -C projects/postgresql chart-test-kind instead of the scripts/test-kind.sh wrapper. Done in the workflows as they stand: the "Keep reports" step uploads hidden files, projects-rescan installs syft, and one tool installer is used everywhere.
  • The Valkey HA test and the PostgreSQL HA hooks, which failed on GitHub runners during this work, pass there now (runs 42932208078 and 42920329890; see above).
  • Base image not released, so images[].base.digest is empty in every manifest; the release order is in projects/base/README.md.
  • Bitnami catalog: nginx, Valkey and PostgreSQL are in_development (built and tested here, nothing published) (ADR-0042).

Decisions that belong to the operating entity

DecisionWhere it shows
Creating the project repositories. The four first-party trees name commonlayer-org/<project> as registry source (ghcr.io/commonlayer-org/<project>) and signing identity (https://github.com/commonlayer-org/<project>/.github/workflows/*@refs/tags/v*). Until those repositories exist and the exported trees are pushed, nothing can be released or onboarded for real. Informational references in the platform still name a commonlayer organization: runbook URLs in the alert rules, the platform chart's image repositories, home and repositoryUrl, the default SOURCE_REPOSITORY build argument of the platform images (the release workflow passes the real one) and Compose's web REPOSITORY_URLprojects/*/commonlayer.yaml, scripts/export-project.sh, infrastructure/monitoring/prometheus/rules/commonlayer-alerts.yaml
Legal review of the privacy and terms pages, which are templatesapps/web/src/app/(public)/legal/
Creating the GitHub App under the operating entity's account, with Administration: write on connected repositories, and accepting what that permission meansthe GitHub App, threat model B10
Whether funded projects must be connected at the managed level (default yes), and the grace period for a transfer (default 30 days)runtime setting projects.require_managed_repository; projects.repository_transfer_grace_days
Whether to run a stewardship organization that can host a project continued from a backupgithub.stewardship.*; without it the successor hosts the new repository
Legal review of maintenance agreement v2 (keep the App installed; transfer the repository on stepping back; continuation from the backup otherwise)the seed's agreement text, crates/commonlayer-app/src/seed.rs
Security and conduct contacts (address, key, response targets, conduct team): until filled there is no monitored private channelSECURITY.md, CODE_OF_CONDUCT.md
The Bitnami catalog's licensing rule (OSI-approved upstream licence required)projects/bitnami-migration/README.md
The reward single-approval limit (default $100; two colluding members can reward a third account up to it, once per approved contribution; threat model O6) and whether a per-recipient cap is wantedruntime setting funding.reward_single_approval_max_minor
The not_affected confirmation threshold (default high)runtime setting security.not_affected_confirmation_min_severity
CODEOWNERS team handles (@commonlayer/* are placeholders).github/CODEOWNERS
Repository variables: CL_BASE_IMAGE (released base by digest, required before the first platform release), CL_ARM64_RUNNER (arm64 on a private repository), in each project repository COMMONLAYER_API_URL (registration from its release workflow) and CL_BASE_REPOSITORY (the base project, while no base release exists)repository settings
Enabling GitHub Code Security (or making the repository public) for code scanning, dependency review and Scorecard; required checksrepository settings
Recovery objectives (RPO, RTO)disaster recovery
Payment provider, legal entity, tax handling, live payouts (all payout gates)deployment, ledger specification

State of the GitHub workflows (2026-11-11, after the push for the standalone projects)

The stewardship commits were pushed without workflow runs (ADR-0048). The final push (0c3ffd0) then ran ci, security and docs, and infra was started by hand for the same commit, because its path filter only sees the last push. Scheduled workflows ran regardless of the markers. The work after that (WP-82, WP-83) was pushed the same way; its final push (d6e382b) ran ci, security and docs, and projects was started by hand for two trees.

WorkflowLatest completed resultNotes
cisuccess (d6e382b, run 43083162371)the tree with the standalone projects: format, build-context check, clippy, the Rust tests, migrations, cargo-deny, generated files, web lint, typecheck, unit tests and build, protobuf
securitysuccess (d6e382b, run 43083162441)code scanning unavailable on this private repository
docssuccess (d6e382b, run 43083162454)markdownlint, links, Mermaid
infrasuccess (0c3ffd0, run 43029000216, started by hand), every jobthe backend, worker and web images built on the runner and the platform chart installed, upgraded and tested on kind with migrations 0022 to 0025. Not run since: two migrations, the template files the backend embeds and the monitoring check's mount option changed after it
projectssuccess (d6e382b, run 43083172187, started by hand for base and nginx)the rewritten workflow: schema tests, template drift, the self-contained and bind-mount checks; then each tree exported outside the checkout and its own targets run there. nginx: base built from the exported base tree by the project's own script, validate, build, test, scan gate, SBOM, chart tests, chart install and upgrade on kind. base: validate, build, test, scan gate, SBOM. Not run in this form: Valkey, PostgreSQL and the template (their last runner results are from before the restructuring: runs 42932208078 and 42920329890)
e2efailure (e6d070e, scheduled run 42998340850): the backend image did not build, because template files the rule engine embeds were outside the image's build contextfixed in f35e8b2 with a check in the Rust lint step; the infra run above built the same images. The workflow has not run since and has never been green; the next nightly run is its first with the fix
projects-rescan, projects-releaseremoved in WP-83releasing and rescanning belong to each project's own repository. projects-rescan ran once on schedule before (dad9320, run 43011850364) and scanned nothing, because nothing is published
release, opsno run recorded—

Acceptance workflows A–E

The product brief's five workflows, and what proves each. "Fakes at the boundary" means the real composition (AppContext::assemble) over a real PostgreSQL database per test, with fakes only for time, the source and destination registries, cosign, Trivy/Grype, repository files, the Actions OIDC verifier and SMTP; the payment provider is the real simulator with signed webhooks; jobs run through the real job registry.

WorkflowAcceptance test (fakes at the boundary)Real toolsBrowser
A · Project onboardingcrates/commonlayer-app/tests/it/workflow_a_onboarding.rs: proposal, repository link and verification, review, manifest sync, treasury, assignments, CI submission over HTTP with an OIDC bearer, all 15 image checks and chart.images_pinned pass, promotion; an unsigned build is rejected and nothing is mirroredThe publish drill: real build, cosign (key pair), Trivy, Grype, syft, Helm, Distribution; submission by API token, not OIDC; manifest synced from a local fileProject administration specs (admin-pages, admin-project-flows)
B · Fundingworkflow_b_funding.rs: organization, recurring checkout confirmed only by signed provider events, coverage and states, evaluation, settlement (primary 200, secondary 150, flexible 100, infrastructure 50 USD), public ledger, audit, verify_ledger, audit checkpoint. Also WP-14's fifteen-step scenarioSimulated provider only; no live Stripeportal-funding.spec.ts (simulated checkout to confirmed receipt; guest status token; organization checkout)
C · Security remediationworkflow_c_remediation.rs: scheduled rescan finds a critical CVE, deadlines, notifications and mail, assessment, contributed fix, new revision promoted, finding resolved with the fixing digest and contribution, old digest still affectedThe drill's scans ran real Trivy and Grype on the promoted digest; no remediation cycle with real toolsMaintainer and project security specs; the second-reviewer flow in wiring.spec.ts
D · Maintainer replacementworkflow_d_replacement.rs: paid March obligation, replacement on April 15, every ledger balance and the transaction count unchanged, April split 15/15 days. Also WP-13's no_financial_effect tests and WP-14's example 9—admin-project-flows.spec.ts (replacement; public funding unchanged)
E · Consumer verificationworkflow_e_verification.rs: search, three separate states, digest mapping, ES256 pull token with pull only, verification record, provenance, SBOM download, verify instructions, chart default image digestThe publish drill: anonymous docker pull by digest, cosign verify and verify-attestation (SLSA v1, SPDX, CycloneDX) at the CommonLayer reference, helm pull, unsigned image 404portal-catalog.spec.ts (artifact, version and digest pages)

Not proven by any of these: keyless signatures, GitHub's provenance format, live payments and payouts, a GitHub App, and anything on a cluster.

Repository stewardship added three workflows of its own (plan 13 §10, §11):

WorkflowAcceptance testReal toolsBrowser
F · Successionworkflow_f_succession.rs: the owner's assignment ends, the case opens with a backup, a transfer into the wrong hands is refused, a transfer to an appointed maintainer closes it; the restore path is verified against the backup; ledger balances and the transaction count are identical before and aftergit against local bare repositories in the backup and restore tests; never github.comstewardship.spec.ts: admin plans the restore of the seeded overdue case, a maintainer verifies the restored repository
G · Onboardingworkflow_g_onboarding.rs: installation bound only after GitHub lists it for the person, picker, scan fails on findings, fix, rescan passes, propose creates the project with the repository as verified primary; approval rulesThe rule engine runs over this repository's template and projects (repository_rules.rs)stewardship.spec.ts: connect, install, pick, findings, fixing push, rescan, propose
H · The same over HTTP with the development providerworkflow_h_dev_github.rs: install redirect, development installation, callback, paged picker, findings, simulated push, rescan, propose; another person's installation and a non-administrator are refused; a successor-hosted restore completes and a non-maintainer's is refused—the browser tests above run against this provider

Test inventory

Counts as recorded in the status files; the date of every run is 2026-11-10.

SuiteCountWhere it ran
Rust workspace (cargo test --workspace)926 passed, 0 failed, 7 ignored (full local run of 2026-11-12, coordinator)locally; ci / rust on a GitHub runner last for the tree before WP-90 (run 43083162371)
of which acceptance workflows A–E and the seed test5 + 1 (commonlayer-app integration tests: 25 in total at WP-70g)locally and on runners
of which gRPC8 unit + 25 integration (WP-41), plus pull_statistics_over_grpc (WP-70b)locally and on runners
of which hardening and review regressionsevery finding of the review has a named regression test except LOW-1, whose refusal is not separately asserted (docs/status/WP-70b.md)locally and on runners
Ignored Rust testsmanual real-scanner tests (real_scan, installed_scanners) and doc examples; the real-scanner tests passed when run by hand (WP-12)locally
Web unit and component tests (Vitest)271 passed (WP-90)locally; ci / web on a GitHub runner last for the tree before WP-90 (run 43083162371)
Playwright1902: 1312 passed, 590 skipped by design, 0 failed (WP-90, on a fresh seed with the development GitHub provider; the count grew with the rule check over 117 page types at two widths)locally only; the e2e workflow has never been green on a runner
Platform charthelm lint ×5, kubeconform ×10 (Kubernetes 1.31 and 1.37), helm-unittest 66/66, trivy config clean (WP-80)locally; infra / chart on a GitHub runner for the final tree (run 43029000216)
Monitoringpromtool: 22 rules with unit tests; metric references: 139 expressions, 88 metrics (84 catalog, 4 Distribution) (WP-70g)locally; infra / monitoring on runners
Image and chart projectsbase: 51 project checks; nginx: 30 per line, 33 chart unit tests; Valkey: 570 ok checks over 5 lines, 73 chart unit tests; PostgreSQL 18.6: 101 ok checks, 45 + 31 chart unit tests; template: 31 chart unit tests (WP-70f)locally; on runners as listed above
Manifest schema4 valid, 26 invalid manifests; template drift 81 files, 4 projectslocally and on runners
Bitnami catalog20 candidates, 0 problems; kubeconform and jsonschema 20/20locally and on runners
Publish drill2 runs, exit 0locally
k6smoke profiles of browsing, search and registry tokenlocally (WP-50)
Documentationmarkdownlint 0 findings; every relative link and anchor resolves; every Mermaid block parses (WP-70h)locally; docs on runners (links and Mermaid green, markdownlint red before WP-70h)

Status by work package

WPTitleStatusReport
WP-01Foundation: workspace, kernel, schema, dev environmentdoneWP-01
WP-02Identity, organizations, API skeletondoneWP-02
WP-10ProjectsdoneWP-10
WP-11Artifacts and registrydoneWP-11
WP-12SecuritydoneWP-12
WP-13Maintenance and eligibilitydoneWP-13
WP-14Funding and ledgerdoneWP-14
WP-15GitHub and notificationsdoneWP-15
WP-20Project template, base image, nginxdone; release workflow never runWP-20
WP-21Valkeydone; green on a GitHub runner (run 42932208078)WP-21
WP-22PostgreSQL (single and HA)done; HA test green on a runner in its hook form (run 42920329890)WP-22
WP-23Bitnami migration catalogdone; three entries in_developmentWP-23
WP-30Web shell and design systemdoneWP-30
WP-31Public portaldone (gaps closed by WP-70e)WP-31
WP-32Authentication pages and dashboardsdone (gaps closed by WP-70e)WP-32
WP-33Project and platform administrationdone (gaps closed by WP-70e)WP-33
WP-40Integration, seed, acceptance testsdoneWP-40
WP-41gRPCdoneWP-41
WP-50Deployment, CI, monitoringdone; kind job green on runners (runs 42915487605, 42925002412)WP-50
WP-60Documentation and ADRsdone; revised by WP-70hWP-60
WP-70aBackend hardeningdoneWP-70a
WP-70bAPI gaps and review fixesdoneWP-70b
—Independent security review (19 findings)all fixedreview
WP-70dCI from real runsdone; see workflow state aboveWP-70d
WP-70eWeb follow-ups and full e2edoneWP-70e
WP-70fSBOM, catalog and project pipelinesdone; the two runner failures were fixed (runs 42920329890, 42932208078)WP-70f
WP-70gDeployment and the publish drilldoneWP-70g
WP-70hFinal documentation passdoneWP-70h
WP-80Repository stewardship: App onboarding, rule engine, source backups, managed access, succession, development GitHub providerdone; never against github.comWP-80
WP-81Portal: onboarding and stewardship pagesdoneWP-81
WP-82Missing bucket named as such; a project directory as a development repository; GitHub App key by file; App registration helperdoneWP-82
WP-83Every project is its own repository: standalone trees, export, no exemptions in the rule enginedone locally; the repositories do not exist yetWP-83
WP-90Portal reworked by "don't make me think"; invitations and reward approvers in the API; webhook processing without a second connectiondoneWP-90

Feature areas

Foundation

FeatureStatusImplementationTestsOutstanding / limitations
Workspace, lints (unsafe_code forbidden, unwrap/expect denied outside tests), cargo-deny, cargo-auditdoneCargo.toml, clippy.toml, deny.toml, .cargo/audit.tomlclippy; cargo-deny and cargo-audit locally and in CIone justified ignore (RUSTSEC-2026-0459, SQLite driver never compiled), review by 2027-01-31
Kernel: ids, Money with largest-remainder allocation, Digest, Period, Clock, errors, paginationdonecrates/commonlayer-core/src/unit and property testscurated table of 32 currencies
Permission matrix, Actor, token scopes, never-by-token set, human-only setdonecrates/commonlayer-core/src/authz/literal matrix test, service_accounts_never_hold_human_only_permissionsADR-0035
Crypto: SecretBox v2 with key ids, keyring and re-sealing; token hashing; HMACdonecrates/commonlayer-core/src/crypto.rs, clctl secrets rotateRFC 4231 vector, tamper tests, rotation tests; rotation run on a restored copy (WP-70g)—
Configuration with validation, redaction and per-process loadingdonecrates/commonlayer-config/cargo test -p commonlayer-configproduction refuses the simulator, a non-__Host- session cookie, http URLs, missing secrets
Metric catalog, JSON logging with trace and span ids, OTLP, Sentry error layer, ops serverdonecrates/commonlayer-observability/staleness test of metrics.md, redaction testsno trace store shipped; Sentry sends errors only
Schema (18 migration files, version 21, 121 tables at WP-70a's make db-check) and database invariantsdonecrates/commonlayer-database/migrations/make db-check; invariant and role tests—
Runtime database role and clctl db check-roledonecrates/commonlayer-database/src/roles.rs, apps/cli/src/ops.rsroles::*; stack and restore drillowner or superuser can still disable triggers (ADR-0036)
Job queue, outbox, scheduler, idempotency storedonecrates/commonlayer-database/src/job, outbox and scheduler teststhroughput not load-tested
Audit recorder, hash-chain checkpoints, clctl audit verifydonecrates/commonlayer-audit/audit tests; drill and stack runscheckpoints live in the same database (O2)
SSRF-safe clientdonecrates/commonlayer-net/blocked ranges, redirects, rebinding, limitsignores proxies by design, so nothing outbound was exercised from the sandbox
Development environmentdonedocker-compose.yml, scripts/dev/, mk/make up, make dev-backend, make seed used by every later packageMinIO image from Chainguard

Identity and organizations

FeatureStatusImplementationTestsOutstanding / limitations
Registration, verification, login, lockout, enumeration resistance, password reset and change, email changedonecrates/commonlayer-auth/src/service/accounts::*, sessions::*; Playwright wp32/auth.spec.tsusernames are public by design; reset tokens issued before an email change stay valid (noted by the review)
Sessions (__Host- cookie required outside development), CSRF, API tokens, service accounts (created only by a person in a session)donecrates/commonlayer-auth/sessions::*, tokens::*, authz::*—
GitHub OAuth and generic OIDC, state bound to the browser (HIGH-6)donesrc/service/oauth.rs, src/http/cookies.rswiremock provider; oauth::a_callback_is_accepted_only_in_the_browser_that_started_the_loginnever against real GitHub
Rate limiting with per-process fallback; client address only behind trusted proxiesdonesrc/adapters/rate_limit.rs, src/http/middleware.rsrate_limits::* (real Valkey), stack checks with forged headersper-process limits during an outage
Organizations, members, invitations, billing profiles, notes; public funding totalsdonecrates/commonlayer-organizations/, crates/commonlayer-funding/src/service/read.rsintegration tests; wp70::organization_checkout_covers_…no public organization list
Abuse reports: intake, own list, admin queue, assign, resolve (not by the reporter)donecrates/commonlayer-organizations/src/service/abuse.rs, migration 0021organizations/tests/it/abuse.rs; Playwright abuse flowcontribution targets only through the API

Projects

FeatureStatusImplementationTestsOutstanding / limitations
Lifecycle, derived funding, security and lifecycle states (thresholds from runtime settings)donecrates/commonlayer-projects/src/domain/, src/service/derived.rstable-driven tests; refresh::coverage_thresholds_follow_the_runtime_settingsno withdraw or un-deprecate; no per-project threshold overrides
Search with facets and keyset paginationdonesrc/repo/search.rssearch::*facets on the first page only
Manifest validation, sync, repository verification with the numeric GitHub id checkdonesrc/domain/manifest.rs, src/adapters/mod.rs, src/service/repositories.rsconformance over every repository manifest; wiremocknever against GitHub; links verified before 0016 not re-checked; plain git repositories cannot be read
Declared SBOM components in the manifest modeldone (carried only)src/domain/manifest.rs (build.components)declared_sbom_components_are_optional_and_typedthe platform stores the field; generation happens in project CI
Members, project service accounts, follows, migration candidates, catalog syncdonesrc/service/, crates/commonlayer-auth/src/service/project_service_accounts.rsmembers::*, tokens::project_service_accounts, catalog loads 20 candidates—

Artifacts and registry

FeatureStatusImplementationTestsOutstanding / limitations
Verification policy (17 checks), waivers, project tightening; only the count of blocking findings on public pages (MEDIUM-7)donecrates/commonlayer-artifacts/src/domain/policy.rspass and fail case per check; drill—
Submission pipeline, resumable; resume re-runs scan and evaluation (MEDIUM-2); release-shaped tags of other versions refused (MEDIUM-1)donesrc/service/pipeline.rs, src/service/submissions.rspipeline tests with fakes; hardening::*; the drill with real tools—
cosign adapterdonesrc/adapters/cosign.rsreal cosign 3.1.4 key pair (WP-11, drill)keyless never run
Verify instructions (key or keyless, with the right note)donesrc/domain/instructions.rsinstructions::tests; drillthe commands assume a transparency-log entry; the drill's key-signed artifacts also need --insecure-ignore-tlog=true
OCI client, mirror with referrers through the tag schemadonecrates/commonlayer-registry/src/adapters/real mirror test; drillGitHub's referrers-API attestations not tested (O11)
Registry token endpoint (rate-limited per IP), key rotation, JWKSdonesrc/service/token.rsreal registry accepts and refuses tokens; drill—
Registry events, pull statistics (GET …/artifacts/{name}/pulls, gRPC GetPullStats), preservation checks, retentiondonesrc/service/events, preservation, retention and pull-statistics testsoffline GC needed (advisory-only digests are protected since WP-70g: retention::a_digest_named_in_a_published_advisory_is_kept)

Security

FeatureStatusImplementationTestsOutstanding / limitations
Trivy, Grype and OSV adapters; subprocess rulesdonecrates/commonlayer-security/src/adapters/captured fixtures; real scanner runs (manual tests, drill)OSV first page only; CVSS v4 not scored; parsers not covered by the review
Ingestion, resolution, digest isolation, deadlines, KEV escalation, permanent breachesdonesrc/service/ingest.rs, src/domain/ingestion::*, sla::*—
Assessments, OpenVEX import and export, exceptions (decided by a person other than the requester)donesrc/service/triage.rs, src/domain/vex.rsvex::*, exception lifecycle, confirmations::a_service_account_cannot_decide_an_exception—
Second reviewer for not_affected at or above the thresholddonesrc/service/confirmations.rs, migration 0015confirmations::*; Playwrightbelow the threshold one person decides (ADR-0037)
Feeds (EPSS, KEV, OSV refresh, NVD)donesrc/adapters/feeds.rsrecorded responsesnever against real hosts
Advisories, encrypted private reports (any key of the keyring decrypts), incidentsdonesrc/service/{advisories,reports,incidents}.rsvisibility tests for every role—

Maintenance and eligibility

FeatureStatusImplementationTestsOutstanding / limitations
Eligibility engine with explanations, finalization, appeals, overrides (session only)donecrates/commonlayer-maintenance/src/domain/eligibility/, src/service/eligibility.rsunit and property tests, eligibility::*, human_decisions::*rule set version 1; no appeal withdrawal
Assignments, replacement without financial effect, occupancydonesrc/service/assignments.rsassignments::*, no_financial_effect::*, workflow Dhand-overs take effect now or earlier in the current month
Applications, profiles, agreements (text published and served), suspensions (listed), SLA versions, platform default SLA (write only)donesrc/service/{profiles,sla,listings}.rswp70::*no read of the platform default SLA
Tasks with generation, waivers (decided by a person), public task list without private evidencedonesrc/service/tasks.rs, src/service/listings.rstasks::*, wp70::the_public_task_list_hides_private_evidence_and_waiver_reasonssecurity-acknowledgement tasks are left out of the public list
Community contributions, review by a person, contributor role, tracked pull requestsdonesrc/service/contributions.rs, crates/commonlayer-app/src/reactions.rscontributions::*, seams::*only merged PRs by non-bot authors become contributions

Funding and ledger

FeatureStatusImplementationTestsOutstanding / limitations
Ledger posting with idempotency and ordered locksdonecrates/commonlayer-funding/src/ledger.rsledger::*, propertiesowner or superuser can rewrite (O1)
Settlement and cycles (finance lock before reading eligibility, MEDIUM-6)donesrc/domain/settlement.rs, src/service/cycles.rsworked examples, property tests, hardening::settlement_reads_eligibility_under_the_finance_locka failing cycle stays open and is retried
Contributions, receipts, fees, subscriptions, webhooks; guest status tokendonesrc/service/{contributions,webhooks}.rsduplicate, reordered and concurrent delivery tests; wp70::a_guest_follows_their_payment_with_the_status_token—
Providers: none, simulated (development and test only), Stripe, bank transfer (references used once)donesrc/adapters/Stripe fixtures and mock serverno live Stripe; payment_methods unused
Refunds with holds, dispute waterfall, provider withdrawals applied once, invoice-payment linkingdonesrc/service/webhooks.rs, src/domain/waterfall.rsstripe::*, hardening::*see Stripe limits above
Obligations, payout runs with gates, unknown payouts and resolution, destination fixed at planningdonesrc/service/{obligations,payouts}.rspayouts::*, hardening::*live payouts only against a mock (ADR-0041)
Rewards: proposer never approves, one per contribution, people onlydonesrc/service/rewards.rshardening::a_proposer_never_approves_and_a_contribution_is_rewarded_onceO6 residual (ADR-0045)
Reconciliation, clctl ledger verify (also --remote over gRPC)donesrc/service/reconciliation.rsreconciliation::*; drill, stack and restore drillprovider balance check only with Stripe

GitHub and notifications

FeatureStatusImplementationTestsOutstanding / limitations
Webhook intake, delivery store, processing; push to default branch syncs the manifestdonecrates/commonlayer-github/signature, redelivery, retry tests; seams::*never against GitHub
Actions OIDC verification, workload actor on submissionsdonesrc/adapters/oidc.rs, crates/commonlayer-app/src/workload.rslocally generated keys; seams::actions_oidc_bearers_become_workload_actorsno real token verified
Notifications: rules, templates, in-app, SMTP, signed outbound webhooks, GitHub channel; public event-kind listdonecrates/commonlayer-notifications/every template rendered, Mailpit, SSRF rejection, event_kinds_are_listed_publicly_from_the_rules_tableEnglish only; at most 10 endpoints per owner; send-time behaviour not reviewed

Repository stewardship and onboarding

FeatureStatusImplementationTestsOutstanding / limitations
Onboarding through the GitHub App: install redirect with single-use state, callback that binds only what GitHub confirms and decides once, identity link, paged repository picker, onboardings, proposedonecrates/commonlayer-github/src/service/onboarding.rs, crates/commonlayer-app/src/stewardship_http.rsstewardship::the_callback_binds_only_installations_github_lists_for_the_person, stewardship_review::*, workflows G and Hnever against github.com
One rule engine for the onboarding scan and the guardrail check: 43 rules, static reads only, results with rule, standard, file and line; required rules, declared deviations, public waiversdonesrc/domain/rules/, src/service/scans.rsrules.rs (a failing case per rule, hostile files), repository_rules.rs (template and every first-party project comply)one template version; first-party CI rules not applicable
Access levels and managed access: collaborators invited and removed for appointed maintainers only, stale logins refused by account iddonesrc/domain/{access,reconcile}.rs, src/service/access.rsexhaustive reconciliation test; access_is_reconciled_without_touching_people_commonlayer_did_not_addinvitation acceptance seen at the next reconciliation
Source backups: verified git bundle of every branch and tag with a manifest, release binding, retention, signed download with restore commandsdonesrc/adapters/{git,subprocess}.rs, src/service/backups.rsbundle and manifest tests, token-leak tests, size and time limitsno LFS, issues or pull requests; bundle assembled in memory
Succession: automatic and manual opening, transfer only into appointed hands, restore planned by a platform reviewer and verified against the backup, primary switchdonecrates/commonlayer-projects/src/service/succession.rs, src/domain/succession.rsprojects::succession::*, stewardship_review::*, workflow Fstewardship-hosted restore never pushed to github.com
Approval rules: managed level, finished scan, no failing required rule unless waiveddonecrates/commonlayer-projects/src/service/succession.rs (check_stewardship_for_approval)approval_fails_closed_without_a_finished_scan, workflows A and G—
Events, notifications, metrics, alerts, runbooksdonecrates/commonlayer-core/src/events/, infrastructure/monitoring/notification catalogue tests, make monitoring-checkfive metrics on no dashboard
Development GitHub provider and its routesdone (development and test only)crates/commonlayer-app/src/{devkit_github,dev_github_http}.rs, migration 0025workflow H; the_development_github_is_refused_outside_development_and_testlast write wins; needs the checkout
Portal: onboarding, repository administration, public maintenance panel, succession queue, waivers, development installation pagedoneapps/web/src/features/stewardship/, apps/web/src/app/dashboard/onboarding/, apps/web/src/app/admin/successions/stewardship.test.tsx, stewardship.spec.tssee WP-81

gRPC

FeatureStatusImplementationTestsOutstanding / limitations
12 services, 59 RPCs, health, reflection, error details, shared rate-limit buckets, metricsdoneproto/commonlayer/v1/, crates/commonlayer-grpc/8 unit + 25 integration + pull statistics; manual run with generated clientsAPI tokens only; no session-only operations; grpcurl was not available for the manual run (gRPC API)

Web portal

FeatureStatusImplementationTestsOutstanding / limitations
Shell, design system, documentation section, SEO, CSPdoneapps/web/src/Vitest; Playwright—
Public portal: catalog, project pages, artifact/version/digest pages with pull statistics, security centre, funding transparency, contribution flow (guest status token, organizations), maintainers, organization profiles with totals, Bitnami catalogdoneapps/web/src/app/(public)/portal-*.spec.ts, wiring.spec.tsorganization pages not in the sitemap
Authentication pages and dashboards (user, organization, maintainer)doneapps/web/src/app/(auth)/, app/dashboard/wp32/*.spec.ts—
Project administration and platform administration (including abuse queue, settings registry, unknown payouts, suspensions, agreements)doneapp/dashboard/projects/, app/admin/admin-*.spec.tssee the portal limits above
Legal pagestemplatesapp/(public)/legal/smokeunreviewed by counsel
"Don't make me think" (plan 15): attention lists from real data on the dashboard, in project and platform administration; steps for onboarding; use-first project page; one navigation per context; destructive actions in a danger zonedonesrc/features/attention/, src/components/domain/{next-step,steps,disclosure,danger-zone,status-list}.tsxe2e/ux-rules.spec.ts (117 page types at 1280 and 375 px: one filled button at most, no destructive control in a page header, at most seven navigation entries per level, a word budget before the first data), e2e/attention.spec.ts, unit tests of the attention ruleslong pages that pass the check but were not restructured: maintainer tasks, project funding administration, payouts, the verification guide. The check counts and measures; whether a page is self-evident still needs a person to look

Images, charts and template

ProjectStatusTestsOutstanding / limitations
schemas/commonlayer-v1.schema.json (with build.components)done4 valid, 26 invalid manifests—
Base image (projects/base), rebuilt BusyBox, cl-probe with its SBOM declarationdone51 project checks; green on runnersnot released
Project templatedonemake validate build test scan sbom chart-test; kind on runnersrelease workflow never run
nginx 1.30.6, 1.31.8done30 checks per line, 33 chart unit tests; kind on runnersHTTP/3 only the QUIC listener verified
PostgreSQL 18.6, 17.11, 16.15; postgresql and postgresql-ha chartsdonesee aboveHA hook failed on its last runner run
Valkey 9.1.3, 9.0.7, 8.1.11, 8.0.12, 7.2.15; chart with standalone, replication, Sentineldone570 ok checks locallyamd64 only; all steps including the HA test and kind passed on a runner (run 42932208078)
Scan results (Trivy 0.76.2, Grype 0.121.3, databases of 2026-11-10)—every image passes the critical gate; Grype suppresses CVE-2025-60876 by the base VEX, and Valkey 8.0/7.2 NVD backport ranges by the Valkey VEXcoverage limits in ADR-0039
Bitnami migration catalogdonecatalog validationthree entries in_development

Platform deployment, CI and operations

FeatureStatusImplementationTestsOutstanding / limitations
Platform images (backend, worker with cosign/Trivy/Grype, web)doneinfrastructure/docker/built and scanned locally (WP-70g)arm64 never built; Rust crates invisible to scanners; cosign CVEs
Compose stack (make stack, stack-seed, stack-monitoring) with database rolesdonedocker-compose.yml, mk/infra.mklocally (WP-70g)—
Platform Helm chart (roles, per-process secrets, gRPC exposure, trusted proxies, NetworkPolicies)done (static)infrastructure/helm/commonlayer/lint, kubeconform, 63 unit tests; kind install reached deployed oncekind job never green; never on a real cluster
OpenTofu modules (AWS object storage, database, cache)validatedinfrastructure/terraform/tofu validate, tflintnever planned or applied
Monitoring: 22 alerts, dashboards, collectordoneinfrastructure/monitoring/promtool unit tests; Prometheus in the stackevery alert has a runbook section
Operations scripts: backup, restore, restore drill, preservationdonescripts/ops/locally against the stack (WP-70g)—
Workflows (10)see the workflow state above.github/workflows/actionlint, shellcheckrelease workflows never run

Documentation

FeatureStatusImplementation
README, CONTRIBUTING, SECURITY and CODE_OF_CONDUCT (contacts are placeholders)donerepository root
Architecture, API (REST and gRPC), security (threat model, privacy rules, verification policy, review report), funding, handbooks, guides, operationsdonedocs/
45 architecture decision recordsdonedecisions