Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
bbcfd44
fix(evidence): name the Transit fault that stops signing initialization
jeremi Sep 24, 2026
8b2883c
feat(evidence): check a candidate beside the running writer without i…
jeremi Sep 24, 2026
c1f70e3
feat(evidence): trust a private CA for the access-token issuer throug…
jeremi Sep 24, 2026
ddd8595
feat(evidence): refuse a derivation that reads a fact its source does…
jeremi Sep 24, 2026
536f0aa
feat(breg): rehearse successor migrations in bregctl test
jeremi Sep 24, 2026
0c4fa41
feat(breg)!: rebaseline history coverage without a live-row limit
jeremi Sep 24, 2026
90ba604
feat(breg)!: journal every reviewed chunked backfill chunk
jeremi Sep 24, 2026
2545828
feat(bregctl): state that removed field values remain in history
jeremi Sep 24, 2026
e555b10
feat(breg): raise a text field's maxLength on live data
jeremi Sep 24, 2026
9d573e0
docs(breg): record the rehearsal and rebaseline changes in the changelog
jeremi Sep 24, 2026
39296d2
feat(breg)!: name the SQLSTATE of a statement apply refuses
jeremi Sep 24, 2026
d130530
feat(breg): lower a string field's minLength on live data
jeremi Sep 24, 2026
5d14f5d
fix(casework): name the failed doctor check and fail readiness on stu…
jeremi Sep 24, 2026
c146a54
feat(casework): refuse a policy package that strands pinned in-flight…
jeremi Sep 24, 2026
2310eea
fix(casework): refuse a BReg engine from another release by name
jeremi Sep 24, 2026
e7dc48a
fix(platform): verify a segmented audit chain from its archived head
jeremi Sep 24, 2026
2a3bc2f
feat(casework): verify and export the audit chain and serve operator …
jeremi Sep 24, 2026
b91f481
feat(breg): recover reviews an authority lost and poll live reviews f…
jeremi Sep 25, 2026
9bea9a4
fix(casework): publish audit records from one replica at a time
jeremi Sep 25, 2026
5608593
fix(casework): refuse to publish audit records after a mismatched res…
jeremi Sep 25, 2026
0e788f6
fix(breg): classify server-ended sessions as connection failures
jeremi Sep 25, 2026
1fa1399
fix(breg): refuse history-step SQL the metadata check cannot read
jeremi Sep 25, 2026
2e46d88
feat(platform)!: add the shared runtime configuration loader and blocks
jeremi Sep 24, 2026
7727455
feat(scheduling)!: read runtime.yaml through the shared configuration…
jeremi Sep 24, 2026
5b88fea
feat(render)!: read runtime.yaml through the shared configuration loader
jeremi Sep 24, 2026
b073b77
feat(platform): bound listener.bind to 128 characters
jeremi Sep 24, 2026
1d6863d
feat(discovery)!: read runtime.yaml through the shared configuration …
jeremi Sep 24, 2026
9f033d5
feat(platform): serialize the shared configuration blocks
jeremi Sep 24, 2026
d6fe874
feat(relay)!: read runtime.yaml through the shared configuration loader
jeremi Sep 25, 2026
9af96df
feat(relay,render)!: refuse environment expressions in authored files
jeremi Sep 25, 2026
53dd059
feat(platform): add the runtime configuration conformance gate
jeremi Sep 25, 2026
496cd19
fix(platform)!: refuse other members beside a discovery jwksSource
jeremi Sep 25, 2026
51cd91b
fix(platform)!: withhold configured text and fail closed on unreadabl…
jeremi Sep 25, 2026
c47d924
fix(render)!: resolve the audit-verify key only through declared prov…
jeremi Sep 25, 2026
a5e76b4
fix(render): refuse a .. component in audit.directory
jeremi Sep 25, 2026
b32c5f3
fix(relay): pin the runtime envelope in the editor schema
jeremi Sep 25, 2026
8d7f267
test(platform): cite RFC 8037 as the source of the Ed25519 thumbprint…
jeremi Sep 25, 2026
26633fd
fix(platform): hold schema-less runtimes and hand-written blocks to t…
jeremi Sep 25, 2026
1107665
docs(relay): state where runtime substitution applies and that no lit…
jeremi Sep 25, 2026
d00d823
feat(breg): add the import operation that change control does not cou…
jeremi Sep 24, 2026
b6a1d0d
feat(breg): serve import grants through the ingestion-run surface
jeremi Sep 24, 2026
9bd95a0
feat(breg): open import authorities and require one to create an impo…
jeremi Sep 24, 2026
6b359d4
feat(breg): count every import chunk against its authority and block …
jeremi Sep 24, 2026
e2f319c
feat(bregctl): open, close, settle, and list import authorities
jeremi Sep 24, 2026
8888fec
fix(breg): name no single cause in the blocked-run problem detail
jeremi Sep 24, 2026
ea9b95e
feat(bregctl): name the import authority when a data import stops
jeremi Sep 24, 2026
71bec0d
docs(breg): document import authorities for operators and in the prod…
jeremi Sep 24, 2026
9df4c32
feat(breg): require a verified export and a retention floor before pr…
jeremi Sep 24, 2026
53c8bfc
feat(breg): refuse to serve a restored copy until an operator adopts …
jeremi Sep 25, 2026
6733d16
fix(breg): list import authorities without taking the registry lock
jeremi Sep 25, 2026
62baa0d
fix(breg): record an authority block as its own last-attempt outcome
jeremi Sep 25, 2026
4f19ac9
fix(platform): refuse a segmented audit chain whose oldest files are …
jeremi Sep 25, 2026
34f8986
fix(casework): refuse an upgrade that would publish records the audit…
jeremi Sep 25, 2026
9d2fe73
fix(casework): keep the audit publication lease out of the single-key…
jeremi Sep 25, 2026
b7e5611
fix(casework): give up a stalled audit publication lease and bound de…
jeremi Sep 25, 2026
988809e
fix(casework): verify every retained audit record before acknowledgin…
jeremi Sep 25, 2026
29840d6
fix(casework): report a head the running writer hides as unverified, …
jeremi Sep 25, 2026
b5f2ccc
fix(casework): count open work items from a removed source as strande…
jeremi Sep 25, 2026
8b52b20
fix(casework): match a development build of BReg to the release of th…
jeremi Sep 25, 2026
3057231
fix(casework): bound the database work behind metrics scrapes
jeremi Sep 25, 2026
6255076
docs(breg): state what closing and resubmitting a lost review commit to
jeremi Sep 25, 2026
7e2bd77
docs(casework): list the audit commands in the CLI wire contract table
jeremi Sep 25, 2026
84d5d01
docs(casework): say what an acknowledged restore gives up and how to …
jeremi Sep 25, 2026
d46f8f5
feat(platform): add the shared audit key and OIDC issuer blocks
jeremi Sep 25, 2026
f69919c
feat(evidence)!: read runtime.yaml through the shared configuration l…
jeremi Sep 25, 2026
79f5a86
docs: fold the split Registry Discovery changelog entry
jeremi Sep 25, 2026
03601be
feat(breg)!: read runtime.yaml through the shared configuration loader
jeremi Sep 25, 2026
c138a3f
feat(platform): share OIDC client admission and static JWKS parsing
jeremi Sep 25, 2026
be93b61
refactor(scheduling)!: use the shared OIDC and audit key blocks
jeremi Sep 25, 2026
a9f611e
feat(platform): share the removed jwksUri key and static JWKS schema …
jeremi Sep 25, 2026
6239811
feat(casework)!: read runtime.yaml through the shared configuration l…
jeremi Sep 25, 2026
4b07004
test: prove each runtime's static JWKS arm refuses untrusted key sets
jeremi Sep 25, 2026
1ba3a63
test(breg): hold the shared configuration crate on the compiler surface
jeremi Sep 25, 2026
5b3677d
fix(platform): refuse a query component in the shared OIDC issuer
jeremi Sep 25, 2026
c14451d
fix(casework): report an authored expression before the typed project…
jeremi Sep 25, 2026
c7b5eea
feat(casework)!: require named OIDC clients behind an operator-contro…
jeremi Sep 25, 2026
253e4a6
ci(casework): run the Evidence deployment fixture regression by exact…
jeremi Sep 25, 2026
767a68e
docs(evidence): state what enabling the environment secret provider g…
jeremi Sep 25, 2026
3c1784b
docs(breg): recommend an https issuer for production deployments
jeremi Sep 25, 2026
49b4ab5
docs(casework): cite the configuration symbols the shared loader uses
jeremi Sep 25, 2026
7a61f15
chore(identifiers): refresh catalog digests for the readiness runtime…
jeremi Sep 25, 2026
bf7537d
feat(platform): add the shared package writer and verifier
jeremi Sep 25, 2026
d76c79b
feat(casework)!: serve the shared package format
jeremi Sep 25, 2026
07630bc
fix(platform): name every missing file when a package lost all of them
jeremi Sep 25, 2026
bd32984
feat(scheduling)!: serve the shared package format
jeremi Sep 25, 2026
90c613c
feat(platform): let a product name package.root instead of its directory
jeremi Sep 25, 2026
c2df3e5
feat(relay)!: serve the shared package format
jeremi Sep 25, 2026
1999c70
feat(breg)!: serve the shared package format
jeremi Sep 25, 2026
1f34e35
fix(platform): refuse invisible package revision controls
jeremi Sep 25, 2026
2135d7e
fix(casework): bind served files to package identity
jeremi Sep 25, 2026
c88fac2
fix(scheduling): log the served package identity
jeremi Sep 25, 2026
66f0442
fix(breg): bind consumers to verified package bytes
jeremi Sep 25, 2026
eae983f
fix(casework): validate consumers from one package load
jeremi Sep 25, 2026
6f7d6aa
style(casework): apply pending package loader formatting
jeremi Sep 26, 2026
2b84a82
test(breg): assert exact database secret canaries
jeremi Sep 26, 2026
2808d75
feat(evidence)!: serve the shared package format
jeremi Sep 26, 2026
7d28781
feat(render): adopt shared package envelope
jeremi Sep 26, 2026
87460c8
docs(render): correct package authoring guidance
jeremi Sep 26, 2026
6dccdaf
feat(discovery)!: package immutable indexes
jeremi Sep 26, 2026
a927c08
fix(discovery): close package migration review gaps
jeremi Sep 26, 2026
f0faa0a
feat(platform): close shared package convergence
jeremi Sep 26, 2026
773761b
docs(evidence): remove retired package layout claims
jeremi Sep 26, 2026
144240f
docs(evidence): use bundle-relative fixture paths
jeremi Sep 26, 2026
66fa779
test(evidence): republish mutated fixture packages
jeremi Sep 26, 2026
9068c35
test(breg): expect shared package refusal at startup
jeremi Sep 26, 2026
55a46c2
test(breg): republish mutated package fixtures
jeremi Sep 26, 2026
f8194ed
test(breg): publish real Evidence fixture package
jeremi Sep 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
30 changes: 30 additions & 0 deletions .github/scripts/ci_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,30 @@
SCHEDULING_PACKAGES = frozenset(SHARDS["scheduling"])
STACK_CLIENT_PACKAGES = frozenset(SHARDS["stack-client"])

# The runtime configuration conformance gate reads the sources of the runtimes
# it holds rows for, their generated runtime schemas, and the canonical shared
# configuration blocks schema. A product that joins the gate joins this set.
CONFIG_CONFORMANCE_PACKAGES = frozenset(
{
"registry-platform-config",
"registry-breg",
"registry-casework",
"registry-discovery",
"registry-evidence",
"registry-relay-v2",
"registry-relayctl",
"registry-render",
"registry-scheduling",
}
)
CONFIG_CONFORMANCE_INPUTS = (
"products/platform/generated/*",
"products/platform/scripts/*config-conformance*",
"products/breg/generated/runtime/*",
"products/casework/generated/runtime/*",
"products/scheduling/generated/runtime/*",
)

# These are the cross-product semantic commitments implemented independently by
# Base Registry Engine and Relay V2. A change must replay both real product routers,
# while profile-only tooling and ordinary positive/negative fixtures remain on
Expand Down Expand Up @@ -1105,6 +1129,11 @@ def classify(
or path in {"clippy.toml", "deny.toml", "rustfmt.toml"}
for path in paths
)
config_conformance = (
complete
or any(matches(path, *CONFIG_CONFORMANCE_INPUTS) for path in paths)
or bool(affected & CONFIG_CONFORMANCE_PACKAGES)
)
release_tool = (
complete
or "release_tool" in security_workflow_gates
Expand Down Expand Up @@ -1275,6 +1304,7 @@ def classify(
"platform": platform,
"platform_assurance": platform_assurance,
"platform_hygiene": platform_hygiene,
"config_conformance": config_conformance,
"discovery_contracts": complete
or bool(affected & DISCOVERY_PACKAGES)
or any(matches(path, *DISCOVERY_PROVIDER_INPUTS) for path in paths)
Expand Down
70 changes: 69 additions & 1 deletion .github/scripts/test_ci_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from __future__ import annotations

import fnmatch
import importlib.util
import json
import os
import re
Expand Down Expand Up @@ -30,6 +31,7 @@
RELAY_CLIENT_PACKAGES,
RELAY_TUTORIAL_INPUTS,
STACK_CLIENT_PACKAGES,
CONFIG_CONFORMANCE_PACKAGES,
SECURITY_WORKFLOW_GATES,
SHARDS,
LockChange,
Expand Down Expand Up @@ -305,6 +307,9 @@ def test_deferred_ci_work_keeps_its_selector_and_explicit_status_guard(
),
"docs-archives": "needs.changes.outputs.docs_archives == 'true'",
"editor-extensions": "needs.changes.outputs.editors == 'true'",
"config-conformance": (
"needs.changes.outputs.config_conformance == 'true'"
),
}
deferred = {
name
Expand Down Expand Up @@ -347,6 +352,7 @@ def test_ci_scheduling_graph_retains_every_job_and_aggregate_dependency(
"breg-contracts",
"breg-wasm",
"identifiers",
"config-conformance",
"rust-result",
"casework-postgres",
"scheduling-contracts",
Expand Down Expand Up @@ -386,6 +392,7 @@ def test_ci_scheduling_graph_retains_every_job_and_aggregate_dependency(
"casework-postgres",
"scheduling-postgres",
"scheduling-contracts",
"config-conformance",
),
"release-tool-required": ("changes", "release-tool"),
"release-source-proof-required": ("changes", "release-source-proof"),
Expand All @@ -411,6 +418,7 @@ def test_ci_scheduling_graph_retains_every_job_and_aggregate_dependency(
"casework-postgres",
"scheduling-postgres",
"scheduling-contracts",
"config-conformance",
"release-tool",
"release-source-proof",
"evidence-tutorials",
Expand Down Expand Up @@ -466,7 +474,7 @@ def test_final_aggregate_flattens_rust_results_with_equivalent_outcomes(
final_needs,
previous_final_needs.difference({"rust-result"}).union(rust_needs),
)
self.assertEqual(31, len(final_needs))
self.assertEqual(32, len(final_needs))

def embedded_python(job: dict[str, Any]) -> str:
run = job["steps"][0]["run"]
Expand Down Expand Up @@ -518,6 +526,66 @@ def run_aggregate(script: str, variable: str, results: dict[str, str]) -> int:
self.assertEqual(expected_status, rust_status)
self.assertEqual(rust_status, final_status)

def test_config_conformance_inputs_select_the_conformance_gate(self) -> None:
for path in (
"crates/registry-platform-config/src/blocks.rs",
"crates/registry-breg/src/runtime_config.rs",
"crates/registry-relay-v2/src/contract.rs",
"crates/registry-relayctl/schemas/authoring/runtime.schema.json",
"crates/registry-render/src/manifest.rs",
"crates/registry-discovery/src/startup.rs",
"crates/registry-evidence/src/config.rs",
"crates/registry-casework/src/config.rs",
"crates/registry-scheduling/src/config.rs",
"products/platform/generated/runtime-config-blocks.schema.json",
"products/platform/scripts/check-config-conformance.py",
"products/breg/generated/runtime/runtime.schema.json",
"products/casework/generated/runtime/runtime.schema.json",
"products/scheduling/generated/runtime/runtime.schema.json",
):
with self.subTest(path=path):
self.assertTrue(
classify(self.workspace, (path,))["config_conformance"]
)
self.assertFalse(
classify(self.workspace, ("docs/site/src/content/docs/index.mdx",))[
"config_conformance"
]
)

def test_every_config_conformance_row_is_routed(self) -> None:
script = Path("products/platform/scripts/check-config-conformance.py")
spec = importlib.util.spec_from_file_location("config_conformance", script)
assert spec is not None and spec.loader is not None
gate = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = gate
spec.loader.exec_module(gate)
packages = {
Path(source).parts[1]
for row in gate.ROWS
for source in row.loader_sources
}
self.assertLessEqual(packages, CONFIG_CONFORMANCE_PACKAGES)
self.assertIn("registry-platform-config", CONFIG_CONFORMANCE_PACKAGES)
schemas = {
entry.path for row in gate.ROWS for entry in row.hand_schemas
} | {
row.runtime_schema
for row in gate.ROWS
if isinstance(row.runtime_schema, str)
}
for path in sorted(schemas):
with self.subTest(path=path):
self.assertTrue(
classify(self.workspace, (path,))["config_conformance"]
)
digest_tests = {row.digest_mismatch.path for row in gate.ROWS}
for path in sorted(digest_tests):
with self.subTest(path=path):
self.assertTrue(
classify(self.workspace, (path,))["config_conformance"]
)

def test_shards_cover_every_workspace_package_once(self) -> None:
assigned = [package for packages in SHARDS.values() for package in packages]
self.assertCountEqual(assigned, self.workspace.package_names)
Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ jobs:
platform: ${{ steps.filter.outputs.platform }}
platform_assurance: ${{ steps.filter.outputs.platform_assurance }}
platform_hygiene: ${{ steps.filter.outputs.platform_hygiene }}
config_conformance: ${{ steps.filter.outputs.config_conformance }}
discovery_contracts: ${{ steps.filter.outputs.discovery_contracts }}
relay_v2_contracts: ${{ steps.filter.outputs.relay_v2_contracts }}
relay_client_contracts: ${{ steps.filter.outputs.relay_client_contracts }}
Expand Down Expand Up @@ -691,6 +692,18 @@ jobs:
CASEWORKCTL_BIN: ${{ github.workspace }}/target/debug/caseworkctl
BREGCTL_BIN: ${{ github.workspace }}/target/debug/bregctl
run: products/casework/scripts/check-checkpoint.sh
- name: Verify the rewritten Evidence deployment loads through the Evidence loader
# The fixture machinery lives behind postgres-test, but this test needs
# neither a database nor an issuer. An inexact name filter that selects
# nothing still exits 0, so the step names the test exactly and fails
# unless it reports one pass.
shell: bash
run: |
set -euo pipefail
cargo test --locked -p registry-casework --features postgres-test --lib \
-- --exact task_grants::native_exchange_tests::the_rewritten_evidence_deployment_loads_through_the_evidence_loader \
| tee "${RUNNER_TEMP}/casework-evidence-fixture.log"
grep -q 'test result: ok\. 1 passed' "${RUNNER_TEMP}/casework-evidence-fixture.log"
- name: Verify claims, reconciliation, and durable attempts
env:
CASEWORK_TEST_DATABASE_URL: postgresql://casework:casework_test@localhost:${{ job.services.postgres.ports['5432'] }}/casework
Expand Down Expand Up @@ -1069,6 +1082,34 @@ jobs:
- name: Check Registry Record profile artifacts
run: products/registry-record/scripts/check.sh

config-conformance:
name: Runtime configuration conformance
needs:
- changes
- rust-policy
if: ${{ !cancelled() && needs.changes.result == 'success' && needs.changes.outputs.config_conformance == 'true' }}
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false
submodules: false

- name: Cache Cargo registry
uses: Swatinem/rust-cache@f0d9c3887740aee45f6153b24b3a6b815192ec16 # v2
with:
shared-key: workspace-registry
cache-targets: false
save-if: ${{ github.ref == 'refs/heads/main' }}

- name: Test runtime configuration conformance gate
run: python3 -m unittest products/platform/scripts/test_check_config_conformance.py

- name: Check runtime configuration conformance
run: products/platform/scripts/check-config-conformance.py --check-generated

rust-result:
name: Rust workspace
if: always()
Expand All @@ -1087,6 +1128,7 @@ jobs:
- casework-postgres
- scheduling-postgres
- scheduling-contracts
- config-conformance
runs-on: ubuntu-slim
timeout-minutes: 5
env:
Expand Down Expand Up @@ -2118,6 +2160,7 @@ jobs:
- casework-postgres
- scheduling-postgres
- scheduling-contracts
- config-conformance
- release-tool
- release-source-proof
- evidence-tutorials
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1764,7 +1764,7 @@ jobs:
"${casework_install_dir}/caseworkctl" test "${casework_project}"
"${casework_install_dir}/caseworkctl" package \
"${casework_project}" --output "${casework_package}"
test -f "${casework_package}/casework.package.json"
test -f "${casework_package}/SHA256SUMS"
rm candidate/bundle-root/SHA256SUMS
fi
evidencectl_installer="evidencectl-${{ needs.validate.outputs.tag }}-install.sh"
Expand Down
15 changes: 11 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/registry-breg-client-node/client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ export type BRegIngestionAttemptOutcome =
| 'invalidItem'
| 'refused'
| 'bindingChanged'
| 'importAuthorityClosed'
| 'chunkMismatch'
| 'runNotOpen'
| 'unavailable'
Expand Down
Loading
Loading