Record first verified runtime distribution
This commit is contained in:
@@ -221,26 +221,39 @@ references and archive hashes; mutable tags or incomplete bundles are rejected.
|
|||||||
|
|
||||||
## Current Production Gates
|
## Current Production Gates
|
||||||
|
|
||||||
The tool deliberately reports blockers instead of pretending the source tree is
|
The first immutable production-distribution baseline is published as
|
||||||
a production distribution:
|
[`v0.1.14`](https://git.add-ideas.de/GovOPlaN/govoplan/releases/tag/v0.1.14)
|
||||||
|
from source commit `1f039dd39c1ce2672f4978c8abc6dff862ef1445`. Runtime
|
||||||
|
Distribution [run #459](https://git.add-ideas.de/GovOPlaN/govoplan/actions/runs/459)
|
||||||
|
proved migrations, schema compatibility, non-root API/Web readiness, and worker
|
||||||
|
delivery/shutdown on both `linux/amd64` and `linux/arm64`. Its signed manifest
|
||||||
|
has SHA-256
|
||||||
|
`d703267e01855dee63200cb20921c91c3f95fbff550c8ca76e9a35cba3f69109`
|
||||||
|
and pins these runtime indexes:
|
||||||
|
|
||||||
1. **First publication.** The protected workflow and fail-closed artifact
|
- API: `git.add-ideas.de/govoplan/runtime-api@sha256:197ed01790986f2bc927eaa5d8348fa118702e5d2dc05feb851fc2643c23764a`
|
||||||
contracts are implemented, but a release operator must configure the Gitea
|
- WebUI: `git.add-ideas.de/govoplan/runtime-web@sha256:e936cca124f1fad29a067834cf17627d4c236410fdc3fa129e0ccb26b8193812`
|
||||||
registry/release tokens and runtime Ed25519 key, publish the first pinned
|
|
||||||
release, and retain its amd64/arm64 readiness evidence.
|
The signed bootstrap has SHA-256
|
||||||
3. **First administrator.** Production needs a one-time, restricted enrollment
|
`1ff946fba82b0895d153b23352d06e30fe18388450dfd37fed6fb9912310efc5`
|
||||||
|
and key id `runtime-distribution-2026-01`. The managed-ingress boundary passed
|
||||||
|
the same publication run and the independently dispatchable Runtime Ingress
|
||||||
|
Drill [run #458](https://git.add-ideas.de/GovOPlaN/govoplan/actions/runs/458).
|
||||||
|
Every later release must renew this evidence; the following target-specific
|
||||||
|
gates remain:
|
||||||
|
|
||||||
|
1. **First administrator.** Production needs a one-time, restricted enrollment
|
||||||
identity. The development bootstrap must not be enabled in production.
|
identity. The development bootstrap must not be enabled in production.
|
||||||
4. **Image/module composition.** The deployer now enforces the signed
|
2. **Image/module composition.** The deployer enforces the signed
|
||||||
composition. A selected module not shipped by that release cannot be
|
composition. A selected module not shipped by that release cannot be
|
||||||
enabled.
|
enabled.
|
||||||
5. **Deployment agent.** Web updates need a separate privileged reconciler with
|
3. **Deployment agent.** Web updates need a separate privileged reconciler with
|
||||||
a typed command allowlist. The API and browser must never receive the Docker
|
a typed command allowlist. The API and browser must never receive the Docker
|
||||||
socket or arbitrary shell access.
|
socket or arbitrary shell access.
|
||||||
6. **Ingress reachability evidence.** Managed Caddy ingress and the
|
4. **Target reachability evidence.** Managed Caddy ingress and the
|
||||||
existing-proxy contract are implemented. A production claim still requires
|
existing-proxy contract are implemented. A production claim still requires
|
||||||
running `doctor` from the target host after public DNS/firewall changes and
|
running `doctor` from the target host after public DNS/firewall changes and
|
||||||
retaining the first successful container drill and public TLS/readiness
|
retaining public TLS/readiness evidence for that deployment.
|
||||||
evidence.
|
|
||||||
|
|
||||||
`apply --allow-unverified-images` is therefore restricted to the evaluation
|
`apply --allow-unverified-images` is therefore restricted to the evaluation
|
||||||
profile. It explicitly acknowledges both mutable image identities and
|
profile. It explicitly acknowledges both mutable image identities and
|
||||||
|
|||||||
@@ -141,12 +141,16 @@ The canonical backlog item is
|
|||||||
|
|
||||||
Implementation status as of the current source tree:
|
Implementation status as of the current source tree:
|
||||||
|
|
||||||
- Slice 1 now has the source-controlled production artifact boundary: offline
|
- Slice 1 has a published production-artifact baseline. Immutable
|
||||||
per-architecture wheel resolution, non-root API/Web image definitions,
|
[`v0.1.14`](https://git.add-ideas.de/GovOPlaN/govoplan/releases/tag/v0.1.14)
|
||||||
multi-architecture OCI publication, signed composition/SBOM/provenance,
|
binds source commit `1f039dd39c1ce2672f4978c8abc6dff862ef1445`, a signed
|
||||||
immutable Gitea assets, a signed one-file deployer, and fail-closed manifest
|
one-file deployer, exact API/Web and managed-dependency image digests,
|
||||||
adoption. The first real published release and cross-architecture runtime
|
composition, SBOMs, and provenance. Runtime Distribution
|
||||||
evidence remain release-operator work rather than source-code claims.
|
[run #459](https://git.add-ideas.de/GovOPlaN/govoplan/actions/runs/459)
|
||||||
|
passed migrations, schema checks, non-root API/Web readiness, and worker
|
||||||
|
delivery/shutdown on both amd64 and arm64. Each future release must renew the
|
||||||
|
evidence, and a real installation must still produce topology-specific
|
||||||
|
ingress, failover, backup, and recovery receipts.
|
||||||
- Slice 6 has a working application-tier foundation: state profiles, shared
|
- Slice 6 has a working application-tier foundation: state profiles, shared
|
||||||
object storage, runtime node registration/heartbeats/drain, fenced scheduler,
|
object storage, runtime node registration/heartbeats/drain, fenced scheduler,
|
||||||
migration serialization, exact-head startup waiting, Ops visibility, and a
|
migration serialization, exact-head startup waiting, Ops visibility, and a
|
||||||
|
|||||||
@@ -93,6 +93,14 @@ class RuntimeDistributionTests(unittest.TestCase):
|
|||||||
with self.assertRaisesRegex(DistributionError, "active trusted key"):
|
with self.assertRaisesRegex(DistributionError, "active trusted key"):
|
||||||
verify_manifest(unknown, self.keyring, now=self.now)
|
verify_manifest(unknown, self.keyring, now=self.now)
|
||||||
|
|
||||||
|
with self.assertRaisesRegex(DistributionError, "expected 'candidate'"):
|
||||||
|
verify_manifest(
|
||||||
|
self._manifest(),
|
||||||
|
self.keyring,
|
||||||
|
expected_channel="candidate",
|
||||||
|
now=self.now,
|
||||||
|
)
|
||||||
|
|
||||||
def test_offline_image_index_is_complete_and_digest_bound(self) -> None:
|
def test_offline_image_index_is_complete_and_digest_bound(self) -> None:
|
||||||
with tempfile.TemporaryDirectory(prefix="govoplan-offline-images-") as value:
|
with tempfile.TemporaryDirectory(prefix="govoplan-offline-images-") as value:
|
||||||
root = Path(value)
|
root = Path(value)
|
||||||
|
|||||||
Reference in New Issue
Block a user