Prove Target Revenue adoption and prepare bounded issue-core delivery
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
This commit is contained in:
codex 2026-10-11 22:53:54 +02:00
parent 4d2bb19f8a
commit 1dc1d2f3a1
26 changed files with 1989 additions and 21 deletions

View file

@ -12,6 +12,7 @@ spec:
- https://forgejo.coulomb.social/coulomb/*.git
# Emergency rollback only (T12 Option A through 2026-08-07)
- https://gitea.coulomb.social/coulomb/*.git
- ssh://git@forgejo.coulomb.social:30022/coulomb/rapp-issue-core.git
destinations:
- server: https://kubernetes.default.svc
namespace: "*"

View file

@ -54,3 +54,45 @@ receipts, concurrent release, restart, failed health and successful rollback.
Run destructive failure fixtures in an isolated environment; production must not
be intentionally broken to manufacture proof. Admit only after tests and the
observation gate pass. Access, budget or scope expansion stays a monthly decision.
## Deterministic platform readiness gate
`python3 scripts/activity_promotion_readiness.py --live --observation observation.json
--receipt readiness.json` verifies only the current bounded adoption and reports
an explicit owner-proof wait until ACTIVITY-WP-0041-T03 acceptance exists. This
read-only check neither creates a principal nor activates a release worker. D2
removes the founder reapproval; the identity/custody and runtime proofs above
remain required. ACTIVITY-WP-0042 scheduling acceptance does not supply them.
Later activation checks require operator-owned `--trusted-owner-key` (raw
32-byte Ed25519 public key) and `--trusted-owner-principal`, supplied separately
from `--owner-acceptance`. No signer key supplied inside a receipt is trusted.
The acceptance envelope has exactly `payload` and `signature` (base64 Ed25519
signature of sorted compact JSON). Its payload uses
`schema_version: activity-core-release-acceptance/v1`, binds the existing
`owner_task: ACTIVITY-WP-0041-T03`, issuer, dedicated release principal,
`authority: ACTIVITY-WP-0041-image-only-v1`, application, exact estate cluster UID,
adoption revision and full broker implementation revision. It expires within
five minutes; the operator owns signer admission/revocation and actual native
evidence verification. An agent must not synthesize this production acceptance
from test fixtures or a producer's booleans.
The `targets` mapping is the exact single platform child
`targetRevision` path on `main`, selective root sync of only activity-core,
child activity-core and prune false, as named in the checker. `checks` must
contain exactly its named acceptance checks, all actual owner-verified: bounded
identity/custody/revocation/denials, independent authenticated receipts/CI digest
binding, continuous observer, image-only scope, source CAS/single-flight,
restart/lost-response recovery, retention, real failed-health rollback, Temporal
registration, durable audit sink and report/schedule invariants.
`continuous_health` binds the adoption revision and a current actual 24h sampled
interval with at most 90-second gaps. A source timestamp or snapshot is not this
proof. Signatures authenticate the accepted owner's assertions; the owner still
must ground them in actual runtime receipts.
Native adoption mismatch or malformed/forged/stale/widened owner acceptance
returns unverified. Missing owner acceptance/trust binding returns waiting on
the existing owner task, with its cross-owner coordination case. Only ready
returns exit code zero. No automatic-sync source candidate is generated:
ACTIVITY-WP-0041's current broker contract still relies on explicit selective
manual child/root sync and forbids an automated child policy.

View file

@ -0,0 +1,30 @@
# Activity-core bounded promotion readiness
```sh
python3 scripts/activity_promotion_readiness.py --live --observation observation.json --receipt readiness.json
python3 -m unittest discover -s tests -p 'test_activity_promotion_readiness.py'
```
The current result is waiting for ACTIVITY-WP-0041-T03 authenticated owner
acceptance. Live scoped adoption, elapsed 24h and Deployment readiness pass;
no automation/identity/principal has been activated. A pair of snapshots or an
old successful-sync timestamp cannot prove the owner's gap-sensitive observer.
Raw subprocess output/errors and credential/Secret objects are never emitted.
The initial strict future-timestamp refusal is retained. The revised collector
records both the remote timestamp and the local observer's receipt time, avoiding
unjustified clock tolerance or backfilled health.
For later activation, the operator supplies an independent trusted owner public
key/principal and signed native acceptance. The checker never loads a public key
from the submitted receipt, creates an identity, grants authority or changes a
child/root spec. Exact fields and source-derived proof requirements are recorded
in `docs/activity-core-release-admission.md`. Only `status: ready` exits zero;
waiting/unverified cannot activate anything. Generated fixture signatures in the
nine tests are not native acceptance evidence. The receipt and coordination case
accompany executable source changes, not an evidence-only checkpoint.
Abort owner: railiance-platform. Rollback of preparation: revert this gate source
change. Later bounded dispatcher activation requires its declared owner rollback
(disable admission and recover the prior pinned source through the reviewed
broker); no native activation or credential scope expansion follows from this
preparation. Existing Application remains manually reconciled, prune disabled.

View file

@ -0,0 +1,31 @@
{
"schema_version": "cross-owner-wait-receipt/v0.1",
"scenario_type": "cross_owner_wait",
"case_id": "RPF-WP-0048-T02--ACTIVITY-WP-0041-T03",
"state": "waiting",
"reason": "authenticated-owner-activation-acceptance-missing",
"beneficiary_workplan_id": "RPF-WP-0048",
"beneficiary_task_id": "RPF-WP-0048-T02",
"beneficiary_repo": "railiance-platform",
"obligor_workplan_id": "ACTIVITY-WP-0041",
"obligor_task_id": "ACTIVITY-WP-0041-T03",
"obligor_repo": "activity-core",
"owner_observation_refs": [
"activity-core/docs/release-broker.md",
"activity-core/docs/gitops-release.md",
"activity-core/docs/platform-recovery-scheduling-plan.md"
],
"needs_human": false,
"automatic_wakeup": false,
"foreign_task_changed": false,
"checkpoint": {
"summary": "Live scoped adoption eligible; authenticated bounded-release owner proof missing. Deterministic fail-closed readiness gate implemented.",
"files_changed": [
"scripts/activity_promotion_readiness.py",
"tests/test_activity_promotion_readiness.py",
"workplans/RPF-WP-0048-activity-core-gitops-adoption.md"
],
"next_action": "ACTIVITY-WP-0041-T03 owner supplies native identity/custody/issuers/continuous observation/rollback acceptance, then platform reruns gate before activation.",
"blocked_reason": "ACTIVITY-WP-0041-T03 authenticated owner activation acceptance absent."
}
}

View file

@ -0,0 +1,124 @@
{
"application_uid": "cd179999-852d-4d70-9017-29e867475bff",
"automated_present": false,
"captured_at": "2026-10-11T19:44:18.628842+00:00",
"cluster_uid": "a553c742-0115-43d4-99a4-a5ca56fe0786",
"condition_types": [],
"deployments": [
{
"available": 1,
"generation_observed": true,
"name": "actcore-api",
"ready": 1,
"replicas": 1,
"updated": 1
},
{
"available": 1,
"generation_observed": true,
"name": "actcore-worker",
"ready": 1,
"replicas": 1,
"updated": 1
},
{
"available": 1,
"generation_observed": true,
"name": "actcore-event-router",
"ready": 1,
"replicas": 1,
"updated": 1
}
],
"destination": {
"namespace": "activity-core",
"server": "https://kubernetes.default.svc"
},
"estate_ip": "92.205.62.239",
"health": "Healthy",
"operation": {
"finishedAt": "2026-10-04T14:13:25Z",
"phase": "Succeeded"
},
"pending_operation": false,
"project": "activity-core",
"project_scope_matches": true,
"resources": [
{
"group": null,
"kind": "ConfigMap",
"name": "actcore-external-activity-definitions",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": null,
"kind": "ConfigMap",
"name": "actcore-ops-service-inventory",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": null,
"kind": "ConfigMap",
"name": "actcore-report-schemas",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": null,
"kind": "ConfigMap",
"name": "actcore-runtime-config",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": null,
"kind": "Service",
"name": "actcore-api",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": null,
"kind": "Service",
"name": "actcore-worker-metrics",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": "apps",
"kind": "Deployment",
"name": "actcore-api",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": "apps",
"kind": "Deployment",
"name": "actcore-event-router",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": "apps",
"kind": "Deployment",
"name": "actcore-worker",
"namespace": "activity-core",
"status": "Synced"
}
],
"revision": "a86a14332d76d92a7ed176ea34dca4429902c396",
"source": {
"path": "k8s/gitops",
"repoURL": "https://forgejo.coulomb.social/coulomb/activity-core.git",
"targetRevision": "a86a14332d76d92a7ed176ea34dca4429902c396"
},
"sync": "Synced",
"sync_options": [
"CreateNamespace=false",
"ApplyOutOfSyncOnly=true",
"PruneLast=true",
"FailOnSharedResource=true"
]
}

View file

@ -0,0 +1,125 @@
{
"application_uid": "cd179999-852d-4d70-9017-29e867475bff",
"automated_present": false,
"captured_at": "2026-10-11T19:44:50.828034+00:00",
"cluster_uid": "a553c742-0115-43d4-99a4-a5ca56fe0786",
"condition_types": [],
"deployments": [
{
"available": 1,
"generation_observed": true,
"name": "actcore-api",
"ready": 1,
"replicas": 1,
"updated": 1
},
{
"available": 1,
"generation_observed": true,
"name": "actcore-worker",
"ready": 1,
"replicas": 1,
"updated": 1
},
{
"available": 1,
"generation_observed": true,
"name": "actcore-event-router",
"ready": 1,
"replicas": 1,
"updated": 1
}
],
"destination": {
"namespace": "activity-core",
"server": "https://kubernetes.default.svc"
},
"estate_ip": "92.205.62.239",
"health": "Healthy",
"operation": {
"finishedAt": "2026-10-04T14:13:25Z",
"phase": "Succeeded"
},
"pending_operation": false,
"project": "activity-core",
"project_scope_matches": true,
"resources": [
{
"group": null,
"kind": "ConfigMap",
"name": "actcore-external-activity-definitions",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": null,
"kind": "ConfigMap",
"name": "actcore-ops-service-inventory",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": null,
"kind": "ConfigMap",
"name": "actcore-report-schemas",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": null,
"kind": "ConfigMap",
"name": "actcore-runtime-config",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": null,
"kind": "Service",
"name": "actcore-api",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": null,
"kind": "Service",
"name": "actcore-worker-metrics",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": "apps",
"kind": "Deployment",
"name": "actcore-api",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": "apps",
"kind": "Deployment",
"name": "actcore-event-router",
"namespace": "activity-core",
"status": "Synced"
},
{
"group": "apps",
"kind": "Deployment",
"name": "actcore-worker",
"namespace": "activity-core",
"status": "Synced"
}
],
"revision": "a86a14332d76d92a7ed176ea34dca4429902c396",
"source": {
"path": "k8s/gitops",
"repoURL": "https://forgejo.coulomb.social/coulomb/activity-core.git",
"targetRevision": "a86a14332d76d92a7ed176ea34dca4429902c396"
},
"sync": "Synced",
"sync_options": [
"CreateNamespace=false",
"ApplyOutOfSyncOnly=true",
"PruneLast=true",
"FailOnSharedResource=true"
],
"remote_captured_at": "2026-10-11T19:44:52.074977+00:00"
}

View file

@ -0,0 +1,11 @@
{
"schema_version": "activity-promotion-readiness/v1",
"task": "RPF-WP-0048-T02",
"owner_dependency": "ACTIVITY-WP-0041-T03",
"native_mutation": false,
"automatic_sync_candidate": false,
"observed_at": "2026-10-11T19:44:17.229169+00:00",
"checker_sha256": "ed159e8128c0fbb2741fcff17e5b2eebcee279057da3c1c6bce285e48b233882",
"status": "unverified",
"reason": "adoption_metadata_unverified"
}

View file

@ -0,0 +1,18 @@
{
"schema_version": "activity-promotion-readiness/v1",
"task": "RPF-WP-0048-T02",
"owner_dependency": "ACTIVITY-WP-0041-T03",
"native_mutation": false,
"automatic_sync_candidate": false,
"observed_at": "2026-10-11T19:44:50.828539+00:00",
"checker_sha256": "93986567cc6ea01b646cebd2e47eb4a5f19ad43b54ecfe420079a45b60ce30f3",
"adoption_24h_eligible": true,
"adoption_snapshot_is_not_continuous_observation": true,
"observation_sha256": "a66b0d128292e24f7964ca90602166ff8b0d88799f31f605dd9fdf88f0b53c25",
"status": "waiting",
"reason": "authenticated_owner_activation_acceptance_missing",
"depends_on": [
"ACTIVITY-WP-0041-T03"
],
"needs_human": false
}

View file

@ -0,0 +1,32 @@
{
"schema_version": "activity-promotion-validation/v1",
"task": "RPF-WP-0048-T02",
"task_closed": false,
"task_status": "wait",
"depends_on": [
"ACTIVITY-WP-0041-T03"
],
"needs_human": false,
"native_mutation": false,
"child_source_changed": false,
"tests": {
"passed": 9,
"failed": 0
},
"compilation": "passed",
"live_checks": "adoption_24h_eligible",
"activation": "waiting-for-authenticated-owner-proof",
"readiness_ref": "readiness.json",
"coordination_case_ref": "coordination-case.json",
"checker_sha256": "93986567cc6ea01b646cebd2e47eb4a5f19ad43b54ecfe420079a45b60ce30f3",
"source_contracts": {
"activity-core/docs/release-broker.md": "bbc917f9b2a533b65d41deb79324b6bd43f8ad14e83587387aa9078fff238fb1",
"activity-core/docs/gitops-release.md": "b1ce725b881a4d506e1129ad330451b75d65d81a3db2a63351867710bbd89da7",
"activity-core/docs/platform-recovery-scheduling-plan.md": "3b86a1bddae65abd56697360303ae9f56a969c98ae98d757f1ed689aaa241698"
},
"new_attended_items": [],
"new_red_batch_items": [],
"failed_clock_observation_retained": "readiness-clock-refusal.json",
"timestamp_method": "local observer measured receipt after SSH return; remote timestamp retained separately, never used to backfill continuous health",
"validated_at": "2026-10-11T19:47:19.802659+00:00"
}

View file

@ -0,0 +1,19 @@
{
"work_record": "RPF-WP-0044-T04",
"scope_approval_ref": "89f1058f-33bc-47a8-8a49-0b44d426c67e",
"repository": "coulomb/rapp-issue-core",
"read_only": true,
"openbao_path": "platform/operators/argocd/repositories/rapp-issue-core",
"destination": "argocd/rapp-issue-core-repository",
"project": "railiance-tenants",
"url": "ssh://git@forgejo.coulomb.social:30022/coulomb/rapp-issue-core.git",
"wrap_ttl_seconds": 60,
"new_network_scope": false,
"owner_review_ref": null,
"ssh_egress_existing_proof_ref": null,
"runtime_identity_ref": null,
"rollback_ref": null,
"ssh_known_hosts_sha256": null,
"expires_at": "2026-10-12T23:59:59+00:00",
"execution_mode": "attended-founder-bounded"
}

View file

@ -0,0 +1,21 @@
{
"synthetic_only": true,
"no_actual_credentials_or_services": true,
"installed_cli_combined_path_stdin_value_preserved": true,
"installed_cli_cas0_body_verified": true,
"list404_class": {
"exit": 2,
"stdout": "{}",
"stderr_empty": true
},
"consumed_unwrap_error_class": {
"exit": 2,
"http_code": 400,
"exact_error": "wrapping token is not valid or does not exist"
},
"help_confirmed": [
"kv put field=- stdin semantics",
"cas=0 create-only",
"unwrap with no token argument uses current authenticated token"
]
}

View file

@ -0,0 +1,36 @@
{
"schema": "argocd-issue-core-fixed-command-review/v1",
"task": "RPF-WP-0044-T04",
"approval_ref": "89f1058f-33bc-47a8-8a49-0b44d426c67e",
"second_founder_approval_required": false,
"source_scope_already_approved": "Dedicated Argo reader, only coulomb/rapp-issue-core read-only, exact operator custody path",
"command": "BAO_ADDR=http://127.0.0.1:18200 VAULT_ADDR=http://127.0.0.1:18200 warden access openbao-platform-admin-login --exec -- python3 scripts/provision_argocd_issue_core_repository.py --contract <reviewed-fixed-contract.json> --contract-sha256 <exact-file-sha256> --journal <new-private-receipt.json>",
"runtime": "Existing attended Platform-admin login encloses nested warden forgejo-admin-api-token --exec; silent outer fds suppress proxy inherited fetch errors; credential injection stays inside child. Kubectl destination is fixed SSH railiance01 native API, never workstation kubecontext.",
"runtime_authority_limits": "Current admin lane is interim proxy, not native issuer. It requires caller OpenBao identity, and operatorpath create/read/update capability plus parent metadata list. Source plan autonomous label is not runtime proof. No exact delegated operatorpath identity found in source; absent such a proven identity the outer OIDC/MFA login is Orange. This command is explicitly attended-founder-bounded, not autopilot. Root capability is accepted only in this declared attended mode; refs are manual review attestations, not native approval tokens.",
"preflight": [
"exact contract references existing D2 and owner review, expiry and hash",
"node public IP exact 92.205.62.239 before trust",
"actual Argo SSH host CM hash matches trusted provider pin for [forgejo.coulomb.social]:30022",
"existing SSH egress proof, no new network scope",
"AppProject existing sourceRepos admits exact SSH repository",
"operatorpath create/read/update capabilities and fresh custody",
"fresh exact destination Secret and no matching provider deploykey"
],
"custody": "tmpfs generated ed25519 private key -> provider receives public key only -> OpenBao CAS0 exact SSH_PRIVATE_KEY -> 60-second response wrap -> exactly one unwrap with child token env -> Secret create encrypted SSH stdin, no last-applied annotation Installed Bao CLI actual synthetic HTTP fixture confirmed combined-path SSH_PRIVATE_KEY=- stdin and CAS0 request, LIST404 -> exit2 empty JSON {}, and unwrap400 specific native error.",
"receipt": "Fixed non-secret stages, provider key ID, public-key hash, Bao write/unwrap request IDs and wrap accessor, custody version. All raw provider/CLI stdout/stderr discarded. Successful issuance says delivered_not_adopted; Argo adoption/health remains independent. Exact wrap creation path verified/retained, enabled audit-device metadata/count checked before grant, consumed-token replay must return native OpenBao 400 specific invalid-wrapping-token error; transport/403/unrelated 400 are not proof.",
"replay": "Exclusive O_NOFOLLOW journal; any preexisting journal refuses. Pending/ambiguous stages retained uncertain_do_not_replay. Do not rerun; reconcile IDs/custody/destination first. No automatic second key, unwrap, retry, deletion or broad credential fallback.",
"rollback": "Owner verifies journal provider key ID + exact fixed repo and public hash, revokes only that deploykey through same admin exec lane. Remove only exact matched Secret version, soft-delete only exact new operatorpath custody version, restore Application previous Git transport/revision and manual sync; never delete shared policy/store or another repo key. Revocation/removal is separate reviewed owner recovery; issuer performs no destructive fallback.",
"limitations": [
"No native SSH-key expiry; maximum 180-day lifecycle rotation remains owner task.",
"No automatic rollback command executes.",
"No actual credential read, issue, unwrap, Secret create, or adoption executed.",
"Contract hostpin, egress, ownerreview/runtime/rollback refs must be filled and reviewed before command runs."
],
"checks": {
"unit_tests": 9,
"passed": true,
"installed_cli_synthetic_put_stdin_cas0": true,
"installed_cli_synthetic_list404_signature_verified": true,
"installed_cli_synthetic_unwrap400_signature_verified": true
}
}

View file

@ -0,0 +1,41 @@
{
"schema": "argocd-public-transport/v1",
"task": "RPF-WP-0044-T04",
"approval_ref": "89f1058f-33bc-47a8-8a49-0b44d426c67e",
"abort_owner": "railiance-platform with railiance-enablement",
"diff_ref": "source-manifest.json",
"rollback": "Run same helper --action rollback using reviewed plan; guarded exact after-to-before fields only. Revert corresponding owner source patches too.",
"namespace": "argocd",
"target": "railiance01",
"baseline_sha256": "28074ce931b8362d0aab101317aef2decae69af527f5b0ee0699b5877ff89bb3",
"public_authority_observation_sha256": "264a71f4bf8672dfb3ac5d75ed7a7f467ae17d2f6c19aaf55893ff13718e3093",
"provider_pod_uid": "bc771b51-e9b8-456d-b59c-e7041704389d",
"repo_server_tcp_30022_verified": true,
"resources": [
{
"kind": "configmap",
"name": "argocd-ssh-known-hosts-cm",
"uid": "e1481984-dc5d-4fcc-9f2a-118c054865b7",
"path": "/data/ssh_known_hosts",
"before": "# This file was automatically generated by hack/update-ssh-known-hosts.sh. DO NOT EDIT\n[ssh.github.com]:443 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=\n[ssh.github.com]:443 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl\n[ssh.github.com]:443 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=\nbitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE=\nbitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO\nbitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=\ngithub.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=\ngithub.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=\ngitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=\ngitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf\ngitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9\nssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H\nvs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H\n",
"after": "# This file was automatically generated by hack/update-ssh-known-hosts.sh. DO NOT EDIT\n[ssh.github.com]:443 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=\n[ssh.github.com]:443 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl\n[ssh.github.com]:443 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=\nbitbucket.org ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBPIQmuzMBuKdWeF4+a2sjSSpBK0iqitSQ+5BM9KhpexuGt20JpTVM7u5BDZngncgrqDMbWdxMWWOGtZ9UgbqgZE=\nbitbucket.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIazEu89wgQZ4bqs3d63QSMzYVa0MuJ2e2gKTKqu+UUO\nbitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdegZIa8e86EG2qOCsIsD1Xw0xSeiPDlCr7kq97NLmMbpKTX6Esc30NuoqEEHCuc7yWtwp8dI76EEEB1VqY9QJq6vk+aySyboD5QF61I/1WeTwu+deCbgKMGbUijeXhtfbxSxm6JwGrXrhBdofTsbKRUsrN1WoNgUa8uqN1Vx6WAJw1JHPhglEGGHea6QICwJOAr/6mrui/oB7pkaWKHj3z7d1IC4KWLtY47elvjbaTlkN04Kc/5LFEirorGYVbt15kAUlqGM65pk6ZBxtaO3+30LVlORZkxOh+LKL/BvbZ/iRNhItLqNyieoQj/uh/7Iv4uyH/cV/0b4WDSd3DptigWq84lJubb9t/DnZlrJazxyDCulTmKdOR7vs9gMTo+uoIrPSb8ScTtvw65+odKAlBj59dhnVp9zd7QUojOpXlL62Aw56U4oO+FALuevvMjiWeavKhJqlR7i5n9srYcrNV7ttmDw7kf/97P5zauIhxcjX+xHv4M=\ngithub.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=\ngithub.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl\ngithub.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=\ngitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY=\ngitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf\ngitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9\nssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H\nvs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H\n[forgejo.coulomb.social]:30022 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC7jadWwHX2j1aeXSonkdwP8CI5j1a+ihzj6kq7697h+8B5X2SpYBvwOi2brYmgoiccyapB2aowmctMLLTtrhMaARtvnZPeoFgPhBrdHaUhHdmTeSg7MbRBu5D8yYTt3CwDxF1+MUFE+NuRhCXRHQLbLCqTLlU9hgZV4xuqsv71lvNHzcF3vMcolTBtdVzTsgCfeV9J8wQMXTC7rFfVuRi5fC6m994KN+vt94VHIZcZwFgjdCEZ4uo7U07Fdp3MT6WMqgLftc9ewBL/p+i5BtzVkF725d5QMx6TL6vLrC7X8lrkUWQL+oy5CeUrnOnsyiuwbYwlFVLsdypa2WbdlHtkllBXVD2IdTxeu038BAjWBXkN1WCGEXWJvj829I8FzObnO+QoOsbwdmGSTFqBX7+2vSymbEHtNcS0/0jk5xUvdnvFRvkzDvhQjMgiF8LIVCk4zWTBeWPQ5r5lLooFn8B1hmsgqHVSd2DXMPUMOuTQRTdxpNicNkBlwEQSwFYSCf3vL+x2e2pIx4YvkLD+1bEwNwB8HIuzF1Vex7Cjbo07pTwxhTJ52ZFQNkja/LqyAzO0bOEb9MF6KIxXKS/qL5C2cf8kHB5eXbiAwbv3jkxVzBiYPEMJYxO0pJKaKK8Cvs8cT2MYsxQkly1MENsvf15eOHqg26CPz/PiruHkiifhXw==\n",
"owner": "railiance-enablement"
},
{
"kind": "appproject",
"name": "railiance-tenants",
"uid": "f899f3ec-2c55-4cd0-9cb0-b2b4c6eb9be2",
"path": "/spec/sourceRepos",
"before": [
"https://forgejo.coulomb.social/coulomb/*.git",
"https://gitea.coulomb.social/coulomb/*.git"
],
"after": [
"https://forgejo.coulomb.social/coulomb/*.git",
"https://gitea.coulomb.social/coulomb/*.git",
"ssh://git@forgejo.coulomb.social:30022/coulomb/rapp-issue-core.git"
],
"owner": "railiance-platform"
}
]
}

View file

@ -0,0 +1,159 @@
{
"application": {
"automated_present": false,
"condition_types": [
"OrphanedResourceWarning"
],
"destination": {
"namespace": "target-revenue",
"server": "https://kubernetes.default.svc"
},
"health": "Healthy",
"name": "target-revenue",
"operation": {
"finishedAt": "2026-09-28T14:23:27Z",
"phase": "Succeeded",
"startedAt": "2026-09-28T14:23:26Z"
},
"operation_revision": "a3a8a27a8cda32ae3c7b55353ee16a131c50a0a0",
"pending_operation": false,
"project": "railiance-tenants",
"resources": [
{
"group": null,
"kind": "Service",
"name": "target-revenue",
"namespace": "target-revenue",
"status": "Synced"
},
{
"group": "apps",
"kind": "Deployment",
"name": "target-revenue",
"namespace": "target-revenue",
"status": "Synced"
},
{
"group": "external-secrets.io",
"kind": "ExternalSecret",
"name": "target-revenue-runtime",
"namespace": "target-revenue",
"status": "Synced"
},
{
"group": "networking.k8s.io",
"kind": "Ingress",
"name": "target-revenue",
"namespace": "target-revenue",
"status": "Synced"
},
{
"group": "postgresql.cnpg.io",
"kind": "Cluster",
"name": "target-revenue-pg",
"namespace": "target-revenue",
"status": "Synced"
}
],
"revision": "a3a8a27a8cda32ae3c7b55353ee16a131c50a0a0",
"source": {
"path": "k8s/railiance",
"repoURL": "https://forgejo.coulomb.social/coulomb/target-revenue.git",
"targetRevision": "a3a8a27a8cda32ae3c7b55353ee16a131c50a0a0"
},
"sync": "Synced",
"sync_prune": false,
"sync_strategy_apply": true,
"sync_strategy_force": false,
"uid": "42285c08-97c6-452f-ad8a-4f46d9691bc9"
},
"captured_at": "2026-10-11T19:51:12.812423+00:00",
"estate_ip": "92.205.62.239",
"live_hooks": [],
"pinned_render_diff": {
"client_side_exit_code": 0,
"normalized_render_sha256": "3d08814b968978d634f4ecb444db31d24ff19d15ae12d8411dacb6e1448859ff",
"output_suppressed": true,
"path": "k8s/railiance",
"render_resource_count": 5,
"render_sha256": "c728d28ac2b7fd61be00e65d356d53a6b729573fdd5a15d420efb86b7c89f50a",
"revision": "a3a8a27a8cda32ae3c7b55353ee16a131c50a0a0",
"skipped_hooks": [
"target-revenue-bootstrap-binky",
"target-revenue-migrate"
]
},
"ready_checks": [
{
"available_replicas": 1,
"condition": "Available",
"generation": 6,
"instances": null,
"kind": "Deployment",
"name": "target-revenue",
"namespace": "target-revenue",
"observed_generation": 6,
"ready": [
{
"lastTransitionTime": "2026-08-15T22:30:36Z",
"status": "True"
}
],
"ready_instances": null,
"replicas": 1,
"tracking_matches": true,
"uid": "c6b7a312-968a-4d10-894d-d4f6b7b11205"
},
{
"available_replicas": null,
"condition": "Ready",
"generation": 2,
"instances": null,
"kind": "ExternalSecret",
"name": "target-revenue-runtime",
"namespace": "target-revenue",
"observed_generation": null,
"ready": [
{
"lastTransitionTime": "2026-09-05T16:39:12Z",
"status": "True"
}
],
"ready_instances": null,
"replicas": null,
"tracking_matches": true,
"uid": "cde6e839-a964-443d-a19d-32cc5b53a9cb"
},
{
"available_replicas": null,
"condition": "Ready",
"generation": 1,
"instances": 1,
"kind": "Cluster",
"name": "target-revenue-pg",
"namespace": "target-revenue",
"observed_generation": null,
"ready": [
{
"lastTransitionTime": "2026-08-05T15:51:45Z",
"status": "True"
}
],
"ready_instances": 1,
"replicas": null,
"tracking_matches": true,
"uid": "333e9409-0a9c-47fa-bb73-6c7309f0a099"
}
],
"tracking_settings": {
"controller_version": "v3.5.3",
"installation_id_absent": true,
"instance_label_key": "app.kubernetes.io/instance",
"method": "annotation"
},
"public_health": {
"url": "https://revenue.coulomb.social/healthz",
"status": 200
},
"metadata_captured_at": "2026-10-11T19:51:13.501350+00:00"
}

View file

@ -0,0 +1,24 @@
{
"schema_version": "argocd-workload-adoption-proof/v1",
"status": "verified",
"application": "target-revenue",
"revision": "a3a8a27a8cda32ae3c7b55353ee16a131c50a0a0",
"captured_at": "2026-10-11T19:51:12.812423+00:00",
"verified_at": "2026-10-11T19:51:12.813305+00:00",
"proving_seconds": 1142865.812423,
"resource_count": 5,
"ready_count": 3,
"manual_apply_prune_off": true,
"hooks_skipped": [
"target-revenue-bootstrap-binky",
"target-revenue-migrate"
],
"hooks_absent": true,
"child_automation_enabled": false,
"public_health_status": 200,
"native_mutation": false,
"verifier_sha256": "cf5d2113425d3e014f937371af31d9bcb11671ea036c1b8b8a65aaac47f954b4",
"tracking_helper_sha256": "c058c0ea646bcc3410e0d26db6b42a5471a8fa45a1df62b9ec85f2bf7d03f660",
"contract_sha256": "9946a3f3b5b7612ba9d6352b4dc795f2e5e0385d7d296cc4bf14411e1d7805dd",
"observation_sha256": "d77a033160e62b75f9f7df384222f8cd11ea6e8303f02e83909b4f25d201d1dd"
}

View file

@ -0,0 +1,210 @@
#!/usr/bin/env python3
"""Read-only activity-core promotion gate; signed owner acceptance is mandatory.
D2 grants scoped activation after proof, never substitutes for release-principal
custody, authenticated issuers or rollback. This checker cannot activate a worker,
issue credentials, change Argo policy or admit its own caller as a trusted signer.
"""
from __future__ import annotations
import argparse
import base64
from datetime import datetime, timezone, timedelta
import hashlib
import json
from pathlib import Path
import re
import subprocess
PIN = 'a86a14332d76d92a7ed176ea34dca4429902c396'
OWNER_TASK = 'ACTIVITY-WP-0041-T03'
AUTHORITY = 'ACTIVITY-WP-0041-image-only-v1'
APPLICATION_PATH = 'argocd/railiance01/applications/activity-core.application.yaml'
RESOURCES = {
('', 'ConfigMap', 'activity-core', name) for name in
('actcore-runtime-config', 'actcore-external-activity-definitions', 'actcore-report-schemas', 'actcore-ops-service-inventory')
} | {('', 'Service', 'activity-core', name) for name in ('actcore-api', 'actcore-worker-metrics')} | {
('apps', 'Deployment', 'activity-core', name) for name in ('actcore-api', 'actcore-worker', 'actcore-event-router')
}
CHECKS = {
'principal_scope_enforced', 'credential_custody_verified', 'revocation_denial_proven',
'independent_receipt_issuers_verified', 'authenticated_ci_digest_binding_proven',
'continuous_health_observer_active', 'live_and_rollback_retention_verified',
'image_only_admission_enforced', 'source_cas_and_single_flight_proven',
'restart_and_lost_response_recovery_proven', 'out_of_scope_denials_proven',
'forged_stale_mismatched_receipt_denials_proven', 'failed_health_rollback_proven',
'temporal_dispatch_registered', 'durable_audit_sink_verified', 'report_schedule_invariants_verified',
}
TARGETS = {
'platform_repository': 'coulomb/railiance-platform', 'branch': 'main',
'child_path': APPLICATION_PATH, 'child_field': '/spec/source/targetRevision',
'root_application': 'railiance-apps-root', 'root_sync_selects_only': 'activity-core',
'child_application': 'activity-core', 'prune': False,
}
def canonical(value):
return json.dumps(value, sort_keys=True, separators=(',', ':'), allow_nan=False).encode()
def stamp(value):
result = datetime.fromisoformat(value.replace('Z', '+00:00'))
if result.tzinfo is None:
raise ValueError('timezone required')
return result
def run(argv, *, input=None):
try:
result = subprocess.run(argv, input=input, capture_output=True, timeout=100)
if result.returncode:
raise ValueError('metadata read unverified; protected output suppressed')
return result.stdout
except (OSError, subprocess.SubprocessError):
raise ValueError('metadata read unverified; protected output suppressed') from None
def collect():
def get(args):
return json.loads(run(['kubectl', *args, '-o', 'json']))
nodes = get(['get', 'nodes'])
if '92.205.62.239' not in [a['address'] for n in nodes['items'] for a in n['status']['addresses']]:
raise ValueError('estate identity mismatch')
namespace = get(['get', 'namespace', 'kube-system'])
obj = get(['-n', 'argocd', 'get', 'application', 'activity-core'])
spec, status = obj['spec'], obj.get('status', {})
expected_source = {'repoURL': 'https://forgejo.coulomb.social/coulomb/activity-core.git',
'path': 'k8s/gitops', 'targetRevision': PIN}
if spec.get('source') != expected_source:
raise ValueError('exact activity source unverified')
op = status.get('operationState', {})
deployments = []
for name in ('actcore-api', 'actcore-worker', 'actcore-event-router'):
deployment = get(['-n', 'activity-core', 'get', 'deployment', name])
generation = deployment['metadata']['generation']; ds = deployment.get('status', {})
desired = deployment['spec'].get('replicas', 1)
deployments.append({'name': name, 'generation_observed': ds.get('observedGeneration') == generation,
'replicas': desired, 'ready': ds.get('readyReplicas', 0),
'updated': ds.get('updatedReplicas', 0), 'available': ds.get('availableReplicas', 0)})
project = get(['-n', 'argocd', 'get', 'appproject', 'activity-core'])['spec']
return {'captured_at': datetime.now(timezone.utc).isoformat(), 'estate_ip': '92.205.62.239',
'cluster_uid': namespace['metadata']['uid'], 'application_uid': obj['metadata']['uid'],
'source': expected_source, 'project': spec.get('project'),
'destination': spec.get('destination'), 'automated_present': 'automated' in spec.get('syncPolicy', {}),
'sync_options': spec.get('syncPolicy', {}).get('syncOptions', []),
'pending_operation': bool(obj.get('operation')), 'sync': status.get('sync', {}).get('status'),
'revision': status.get('sync', {}).get('revision'), 'health': status.get('health', {}).get('status'),
'operation': {k: op.get(k) for k in ('phase', 'finishedAt')},
'condition_types': [c.get('type') for c in status.get('conditions', [])],
'resources': [{k: r.get(k) for k in ('group', 'kind', 'namespace', 'name', 'status')} for r in status.get('resources', [])],
'project_scope_matches': (project.get('sourceRepos') == ['https://forgejo.coulomb.social/coulomb/activity-core.git']
and project.get('destinations') == [{'server': 'https://kubernetes.default.svc', 'namespace': 'activity-core'}]
and project.get('clusterResourceWhitelist', []) == []
and {(r.get('group') or '',r['kind']) for r in project.get('namespaceResourceWhitelist', [])}
== {('', 'ConfigMap'),('', 'Service'),('apps','Deployment')}),
'deployments': deployments}
def adoption_checks(observation, now):
if (not 0 <= (now-stamp(observation['captured_at'])).total_seconds() <= 300
or observation['estate_ip'] != '92.205.62.239' or not observation['cluster_uid']
or not observation['application_uid']):
raise ValueError('fresh exact estate observation required')
if (observation['source'] != {'repoURL':'https://forgejo.coulomb.social/coulomb/activity-core.git','path':'k8s/gitops','targetRevision':PIN}
or observation['project'] != 'activity-core' or observation['revision'] != PIN
or observation['destination'] != {'server':'https://kubernetes.default.svc','namespace':'activity-core'}
or observation['automated_present'] is not False or observation['pending_operation'] is not False
or set(observation['sync_options']) != {'CreateNamespace=false','ApplyOutOfSyncOnly=true','PruneLast=true','FailOnSharedResource=true'}
or observation['sync'] != 'Synced' or observation['health'] != 'Healthy'
or observation['condition_types'] or observation['project_scope_matches'] is not True):
raise ValueError('bounded manual adoption scope unverified')
op = observation['operation']
if op['phase'] != 'Succeeded' or (stamp(observation['captured_at'])-stamp(op['finishedAt'])).total_seconds() < 86400:
raise ValueError('24-hour adoption eligibility unverified')
resources = observation['resources']
if (len(resources) != 9 or {tuple(r.get(k) or '' for k in ('group','kind','namespace','name')) for r in resources} != RESOURCES
or any(r['status'] != 'Synced' for r in resources)):
raise ValueError('nine-resource runtime inventory unverified')
deployments = observation['deployments']
if (len(deployments) != 3 or {d['name'] for d in deployments} != {'actcore-api','actcore-worker','actcore-event-router'}
or any(d['generation_observed'] is not True or type(d['replicas']) is not int or d['replicas'] < 1
or any(d[k] != d['replicas'] for k in ('ready','updated','available')) for d in deployments)):
raise ValueError('deployment generation/readiness unverified')
def owner_acceptance(envelope, trusted_key, trusted_principal, observation, now):
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
if set(envelope) != {'payload','signature'} or not trusted_principal or len(trusted_key) != 32:
raise ValueError('trusted owner acceptance configuration required')
payload = envelope['payload']
Ed25519PublicKey.from_public_bytes(trusted_key).verify(base64.b64decode(envelope['signature'],validate=True), canonical(payload))
if (payload.get('schema_version') != 'activity-core-release-acceptance/v1'
or payload.get('owner_task') != OWNER_TASK or payload.get('issuer') != trusted_principal
or payload.get('authority') != AUTHORITY or payload.get('application') != 'activity-core'
or payload.get('cluster_uid') != observation['cluster_uid'] or payload.get('adoption_revision') != PIN
or payload.get('targets') != TARGETS or not payload.get('release_principal')
or not re.fullmatch('[a-f0-9]{40}',payload.get('broker_revision',''))
or set(payload.get('checks',{})) != CHECKS
or any(value is not True for value in payload['checks'].values())):
raise ValueError('owner acceptance scope or machine proof incomplete')
issued, expires = stamp(payload['issued_at']), stamp(payload['expires_at'])
if not 0 <= (now-issued).total_seconds() <= 300 or not now < expires <= issued + timedelta(minutes=5):
raise ValueError('owner acceptance stale or expired')
health = payload['continuous_health']
if (health.get('revision') != PIN or health.get('continuous') is not True
or type(health.get('max_gap_seconds')) is not int or not 0 < health['max_gap_seconds'] <= 90
or not 0 <= (now-stamp(health['observed_at'])).total_seconds() <= 90
or (stamp(health['observed_at'])-stamp(health['healthy_since'])).total_seconds() < 86400):
raise ValueError('owner continuous observation proof incomplete')
return payload
def readiness(observation, *, envelope=None, trusted_key=None, trusted_principal=None, now=None):
now = now or datetime.now(timezone.utc)
base = {'schema_version':'activity-promotion-readiness/v1','task':'RPF-WP-0048-T02',
'owner_dependency':OWNER_TASK,'native_mutation':False,'automatic_sync_candidate':False,
'observed_at':now.isoformat(),'checker_sha256':hashlib.sha256(Path(__file__).read_bytes()).hexdigest()}
try:
adoption_checks(observation,now)
except Exception:
return base | {'status':'unverified','reason':'adoption_metadata_unverified'}
base |= {'adoption_24h_eligible':True,'adoption_snapshot_is_not_continuous_observation':True,
'observation_sha256':hashlib.sha256(canonical(observation)).hexdigest()}
if envelope is None or trusted_key is None or trusted_principal is None:
return base | {'status':'waiting','reason':'authenticated_owner_activation_acceptance_missing',
'depends_on':[OWNER_TASK],'needs_human':False}
try:
payload = owner_acceptance(envelope,trusted_key,trusted_principal,observation,now)
except Exception:
return base | {'status':'unverified','reason':'owner_activation_acceptance_unverified'}
return base | {'status':'ready','owner_acceptance_sha256':hashlib.sha256(canonical(envelope)).hexdigest(),
'release_principal':payload['release_principal'],'broker_revision':payload['broker_revision'],
'scope':AUTHORITY,'rollback':'disable dedicated release dispatcher admission; retain manual child policy and prior source pin',
'abort_owner':'railiance-platform'}
def main():
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('--live',action='store_true');parser.add_argument('--remote',action='store_true',help=argparse.SUPPRESS)
parser.add_argument('--observation',type=Path);parser.add_argument('--receipt',type=Path)
parser.add_argument('--owner-acceptance',type=Path)
parser.add_argument('--trusted-owner-key',type=Path,help='operator-owned raw Ed25519 public key; never receipt-provided')
parser.add_argument('--trusted-owner-principal',help='operator-owned issuer binding')
args=parser.parse_args()
try:
if args.remote:
print(json.dumps(collect(),sort_keys=True));return 0
if args.live:
observation=json.loads(run(['ssh','railiance01','python3','-','--remote'],input=Path(__file__).read_bytes()))
observation['remote_captured_at']=observation['captured_at']
observation['captured_at']=datetime.now(timezone.utc).isoformat()
if args.observation:args.observation.write_text(json.dumps(observation,indent=2)+'\n')
else:observation=json.loads(args.observation.read_text())
envelope=json.loads(args.owner_acceptance.read_text()) if args.owner_acceptance else None
key=args.trusted_owner_key.read_bytes() if args.trusted_owner_key else None
result=readiness(observation,envelope=envelope,trusted_key=key,trusted_principal=args.trusted_owner_principal)
except Exception:result={'schema_version':'activity-promotion-readiness/v1','status':'unverified','reason':'protected_read_or_inputs_unverified','native_mutation':False}
if args.receipt:args.receipt.write_text(json.dumps(result,indent=2)+'\n')
print(json.dumps(result,sort_keys=True));return 0 if result['status']=='ready' else 1
if __name__=='__main__':raise SystemExit(main())

View file

@ -0,0 +1,121 @@
#!/usr/bin/env python3
"""Guarded public-only Argo transport prerequisite; no Secret or credential calls."""
import argparse
import copy
from datetime import datetime,timezone
import hashlib
import json
import os
from pathlib import Path
import re
import shlex
import subprocess
URL='ssh://git@forgejo.coulomb.social:30022/coulomb/rapp-issue-core.git'
D2='89f1058f-33bc-47a8-8a49-0b44d426c67e'
TARGETS=[('configmap','argocd-ssh-known-hosts-cm','/data/ssh_known_hosts','railiance-enablement'),('appproject','railiance-tenants','/spec/sourceRepos','railiance-platform')]
class Refused(Exception):pass
def require(ok,reason):
if not ok:raise Refused(reason)
def digest(value):return hashlib.sha256(json.dumps(value,sort_keys=True).encode()).hexdigest()
def run(args,body=None):
try:
result=subprocess.run(['ssh','-o','BatchMode=yes','-o','ConnectTimeout=10','railiance01',shlex.join(['kubectl','--request-timeout=15s',*args])],input=body,text=True,capture_output=True,timeout=60)
except Exception:raise Refused('command_outcome_unverified') from None
require(result.returncode==0,'command_outcome_unverified')
return result.stdout
def value(obj,path):
for key in path.strip('/').split('/'):obj=obj[key]
return obj
def replace(obj,path,wanted):
keys=path.strip('/').split('/');parent=obj
for key in keys[:-1]:parent=parent[key]
parent[keys[-1]]=wanted
def normalized(obj):
obj=copy.deepcopy(obj)
for field in ('managedFields','resourceVersion','generation'):obj.get('metadata',{}).pop(field,None)
return obj
def validate(plan):
require(plan.get('schema')=='argocd-public-transport/v1' and plan.get('task')=='RPF-WP-0044-T04' and plan.get('approval_ref')==D2,'plan_authority')
require(plan.get('target')=='railiance01' and plan.get('namespace')=='argocd' and plan.get('repo_server_tcp_30022_verified') is True,'plan_target')
require(all(isinstance(plan.get(k),str) and plan[k] for k in ('diff_ref','rollback','abort_owner','baseline_sha256','public_authority_observation_sha256')),'plan_receipt_contract')
require(len(plan.get('resources',[]))==2,'target_count')
for item,fixed in zip(plan['resources'],TARGETS):
require(tuple(item.get(k) for k in ('kind','name','path','owner'))==fixed,'fixed_target')
require(bool(re.fullmatch(r'[a-f0-9-]{36}',item.get('uid',''))),'target_uid')
cm,project=plan['resources']
require(isinstance(cm['before'],str) and cm['before'].endswith('\n') and isinstance(cm['after'],str),'host_field_type')
added=cm['after'][len(cm['before']):]
require(cm['after'].startswith(cm['before']) and bool(re.fullmatch(r'\[forgejo\.coulomb\.social\]:30022 (ssh-rsa|ssh-ed25519|ecdsa-sha2-nistp256) [A-Za-z0-9+/=]+\n',added)),'host_addition_scope')
require('[forgejo.coulomb.social]:30022 ' not in cm['before'],'host_preimage_already_admitted')
require(isinstance(project['before'],list) and all(isinstance(v,str) for v in project['before']) and URL not in project['before'] and project['after']==project['before']+[URL],'repository_addition_scope')
def patch(item,live,rollback=False):
before,after=(item['after'],item['before']) if rollback else (item['before'],item['after'])
require(live['metadata']['uid']==item['uid'],'target_uid_changed')
require(value(live,item['path'])==before,'target_preimage_changed')
require(isinstance(live['metadata'].get('resourceVersion'),str),'resource_version_required')
return [{'op':'test','path':'/metadata/uid','value':item['uid']},{'op':'test','path':'/metadata/resourceVersion','value':live['metadata']['resourceVersion']},{'op':'test','path':item['path'],'value':before},{'op':'replace','path':item['path'],'value':after}]
def perform(plan,action,receipt,checkpoint=lambda:None):
validate(plan)
nodes=json.loads(run(['get','nodes','-o','json']))['items']
require(len(nodes)==1 and any(a.get('address')=='92.205.62.239' for a in nodes[0]['status']['addresses']),'wrong_estate')
read=lambda item:json.loads(run(['-n','argocd','get',item['kind'],item['name'],'-o','json']))
rollback=action=='rollback'
# Validate both targets before the first write, avoiding an avoidable partial change.
live=[read(item) for item in plan['resources']]
for item,obj in zip(plan['resources'],live):
require(obj['metadata']['uid']==item['uid'],'target_uid_changed')
if action=='verify':require(value(obj,item['path'])==item['after'],'verification_field_changed')
elif rollback and value(obj,item['path'])==item['before']:continue
else:patch(item,obj,rollback)
for item,obj in zip(plan['resources'],live):
record={'kind':item['kind'],'name':item['name'],'uid':item['uid'],'field':item['path'],'before_sha256':digest(item['before']),'after_sha256':digest(item['after'])};receipt['resources'].append(record)
if action=='verify':record['verified']=True;continue
if rollback and value(obj,item['path'])==item['before']:record['already_restored']=True;continue
body=json.dumps(patch(item,obj,rollback));args=['-n','argocd','patch',item['kind'],item['name'],'--type=json','--patch-file=/dev/stdin']
admitted=json.loads(run(args+['--dry-run=server','-o','json'],body))
wanted=copy.deepcopy(obj);replace(wanted,item['path'],item['before'] if rollback else item['after'])
require(normalized(admitted)==normalized(wanted),'dry_run_modified_other_fields');record['server_dry_run']=True
if action=='dry-run':continue
receipt['pending_target']=item['kind']+'/'+item['name'];receipt['mutation_attempted']=True;checkpoint()
run(args+['-o','name'],body)
checked=read(item)
require(checked['metadata']['uid']==item['uid'] and normalized(checked)==normalized(wanted),'postchange_projection_unverified')
record['changed_verified']=True;receipt['pending_target']=None;checkpoint()
receipt['passed']=True;return receipt
def main():
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('--plan',type=Path,required=True);parser.add_argument('--plan-sha256',required=True)
parser.add_argument('--action',choices=('dry-run','execute','verify','rollback'),default='dry-run')
parser.add_argument('--receipt',type=Path,required=True)
args=parser.parse_args()
receipt={'schema':'argocd-public-transport-receipt/v1','task':'RPF-WP-0044-T04','approval_ref':D2,'action':args.action,'passed':False,'mutation_attempted':False,'resources':[],'secret_or_credential_calls':False,'captured_at':datetime.now(timezone.utc).isoformat()}
# Exclusive receipt is a replay guard. Never overwrite another attempt.
fd=None
try:
require(not args.receipt.exists(),'receipt_exists_do_not_replay')
fd=os.open(args.receipt,os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o600)
raw=args.plan.read_bytes();require(hashlib.sha256(raw).hexdigest()==args.plan_sha256,'plan_changed')
def checkpoint():
os.lseek(fd,0,os.SEEK_SET);os.ftruncate(fd,0);os.write(fd,(json.dumps(receipt,sort_keys=True)+'\n').encode());os.fsync(fd)
receipt['plan_sha256']=args.plan_sha256;checkpoint();perform(json.loads(raw),args.action,receipt,checkpoint)
except Refused as error:receipt['failure']=str(error)
except Exception:receipt['failure']='internal_outcome_unverified'
finally:
if fd is not None:
os.lseek(fd,0,os.SEEK_SET);os.ftruncate(fd,0);os.write(fd,(json.dumps(receipt,sort_keys=True)+'\n').encode());os.fsync(fd);os.close(fd)
# Only whitelist receipt fields are emitted. Every raw child error stays captured.
print(json.dumps(receipt,sort_keys=True));return 0 if receipt['passed'] else 1
if __name__=='__main__':raise SystemExit(main())

View file

@ -0,0 +1,198 @@
#!/usr/bin/env python3
"""Silent fixed-scope D2 repository deploy-key issuer/destination actuator.
Run through the existing Platform attended login and Forgejo admin --exec lane.
No lane grants itself authority. The reviewed contract seals transport/host trust
and existing egress; the command performs no RBAC, policy or network expansion.
No implicit recovery: an existing journal, ambiguous result or drift stops replay.
"""
import argparse
import base64
from datetime import datetime, timezone
import hashlib
import fnmatch
import json
import os
import re
from pathlib import Path
import stat
import shlex
import subprocess
import sys
import tempfile
import urllib.error
import urllib.request
REPO='coulomb/rapp-issue-core'
BAO='platform/operators/argocd/repositories/rapp-issue-core'
URL='ssh://git@forgejo.coulomb.social:30022/coulomb/rapp-issue-core.git'
SECRET='rapp-issue-core-repository'
TITLE='argocd-rapp-issue-core-readonly-D2'
D2='89f1058f-33bc-47a8-8a49-0b44d426c67e'
FIXED={'work_record':'RPF-WP-0044-T04','scope_approval_ref':D2,'repository':REPO,'read_only':True,'openbao_path':BAO,'destination':'argocd/'+SECRET,'project':'railiance-tenants','url':URL,'wrap_ttl_seconds':60,'new_network_scope':False,'execution_mode':'attended-founder-bounded'}
class Refused(Exception):pass
def require(ok,reason):
if not ok:raise Refused(reason)
def captured(argv,body=None,env=None):
try:
result=subprocess.run(argv,input=body,env=env,capture_output=True,text=True,timeout=60)
except Exception:
raise Refused('command_unverified') from None
return result
def run(argv,body=None,env=None):
result=captured(argv,body,env)
require(result.returncode==0,'command_unverified')
return result.stdout
def metadata_children():
result=captured(['bao','list','-format=json','platform/metadata/operators/argocd/repositories/'])
# Installed CLI represents an empty/404 LIST as exit 2, JSON {}, no stderr.
if result.returncode==2 and result.stdout.strip()=='{}' and not result.stderr.strip():return []
require(result.returncode==0,'custody_metadata_unverified')
children=json.loads(result.stdout);require(isinstance(children,list),'custody_metadata_unverified');return children
def replay_denied(env):
result=captured(['bao','unwrap','-format=json'],env=env)
text=result.stderr or ''
return result.returncode==2 and not result.stdout.strip() and bool(re.search(r'Code:\s*400\b',text)) and bool(re.search(r'^\* wrapping token is not valid or does not exist\s*$',text,re.M))
class NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self,*args,**kwargs):raise Refused('redirect_refused')
def api(token,method,path,payload=None,expected=(200,)):
require(path.startswith('/repos/'+REPO+'/') or path=='/repos/'+REPO,'provider_path_refused')
request=urllib.request.Request('https://forgejo.coulomb.social/api/v1'+path,method=method,
data=None if payload is None else json.dumps(payload).encode(),
headers={'Authorization':'token '+token,'Content-Type':'application/json'})
try:
with urllib.request.build_opener(NoRedirect()).open(request,timeout=30) as response:
require(response.status in expected,'provider_status_refused')
raw=response.read(1024*1024+1);require(len(raw)<=1024*1024,'provider_body_bound')
return json.loads(raw) if raw else None
except Refused:raise
except Exception:raise Refused('provider_outcome_unverified') from None
def validate_contract(contract):
require(isinstance(contract,dict),'contract_type')
for key,value in FIXED.items():
require(type(contract.get(key)) is type(value) and contract[key]==value,'contract_scope')
for key in ('owner_review_ref','ssh_egress_existing_proof_ref','runtime_identity_ref','rollback_ref'):
require(isinstance(contract.get(key),str) and contract[key].strip(),'missing_owner_proof')
require(isinstance(contract.get('ssh_known_hosts_sha256'),str) and len(contract['ssh_known_hosts_sha256'])==64,'host_pin_required')
require(datetime.now(timezone.utc)<datetime.fromisoformat(contract['expires_at']),'expired_contract')
def secret_payload(private_key):
return {'apiVersion':'v1','kind':'Secret','metadata':{'name':SECRET,'namespace':'argocd','labels':{'argocd.argoproj.io/secret-type':'repository','app.kubernetes.io/part-of':'railiance-gitops'},'annotations':{'railiance.io/credential-task':'RPF-WP-0044-T04'}},'type':'Opaque','stringData':{'type':'git','project':'railiance-tenants','url':URL,'sshPrivateKey':private_key}}
def execute(contract,journal):
validate_contract(contract)
require(os.environ.get('API_TOKEN'),'provider_identity_missing')
# Fixed native target over SSH; no workstation kube-context fallback.
# Private destination material travels only in encrypted stdin, never argv.
def kubectl(*args,body=None):return run(['ssh','-o','BatchMode=yes','-o','ConnectTimeout=10','railiance01',shlex.join(['kubectl','--request-timeout=15s',*args])],body)
nodes=json.loads(kubectl('get','nodes','-o','json'))['items']
require(len(nodes)==1 and any(a.get('address')=='92.205.62.239' for a in nodes[0]['status']['addresses']),'wrong_estate')
known=json.loads(kubectl('-n','argocd','get','configmap','argocd-ssh-known-hosts-cm','-o','json'))['data']['ssh_known_hosts']
require(hashlib.sha256(known.encode()).hexdigest()==contract['ssh_known_hosts_sha256'],'host_pin_changed')
require('[forgejo.coulomb.social]:30022 ' in known,'host_pin_missing')
project=json.loads(kubectl('-n','argocd','get','appproject','railiance-tenants','-o','json'))
require(any(fnmatch.fnmatchcase(URL,p) for p in project.get('spec',{}).get('sourceRepos',[])),'project_source_refused')
caps=run(['bao','token','capabilities','platform/data/operators/argocd/repositories/rapp-issue-core'])
capability_set={x.strip() for x in caps.strip().split(',')}
capability_mode='scoped' if {'create','update','read'}<=capability_set else 'attended-root' if capability_set=={'root'} and contract['execution_mode']=='attended-founder-bounded' else None
require(capability_mode,'operatorpath_capability_missing')
audit_devices=json.loads(run(['bao','audit','list','-format=json']))
require(isinstance(audit_devices,dict) and 0<len(audit_devices)<=32,'enabled_audit_metadata_required')
metadata=metadata_children()
require('rapp-issue-core' not in metadata and 'rapp-issue-core/' not in metadata,'existing_custody_refused')
# Metadata-presence read only: no Secret object or value is fetched.
existing=kubectl('-n','argocd','get','secret',SECRET,'--ignore-not-found','-o','name')
require(not existing.strip(),'existing_destination_refused')
repo=api(os.environ['API_TOKEN'],'GET','/repos/'+REPO)
require(repo.get('full_name')==REPO and repo.get('private') is True,'repository_identity')
keys=api(os.environ['API_TOKEN'],'GET','/repos/'+REPO+'/keys?limit=100')
require(isinstance(keys,list) and len(keys)<100,'deploy_key_list_bound')
require(not any(k.get('title')==TITLE for k in keys),'existing_provider_key_refused')
receipt={'schema':'argocd-issue-core-credential/v1','task':'RPF-WP-0044-T04','approval_ref':D2,'contract_sha256':hashlib.sha256(json.dumps(contract,sort_keys=True).encode()).hexdigest(),'state':'prepared','secret_values_observed_by_agent':False,'provider_key_id':None,'destination': 'argocd/'+SECRET,'wrap_ttl_seconds':60,'private_key_rotation_max_days':180,'execution_mode':'attended-founder-bounded','operatorpath_capability_mode':capability_mode,'audit_device_count':len(audit_devices),'audit_enabled_metadata':True}
fd=os.open(journal,os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o600)
def save(state):
receipt['state']=state;receipt['updated_at']=datetime.now(timezone.utc).isoformat()
os.lseek(fd,0,os.SEEK_SET);os.ftruncate(fd,0);os.write(fd,(json.dumps(receipt,sort_keys=True)+'\n').encode());os.fsync(fd)
try:
save('prepared')
# Issuer uses private tmpfs; destination is the fixed native railiance01 API.
with tempfile.TemporaryDirectory(prefix='argocd-issue-core-',dir='/dev/shm') as folder:
private=Path(folder)/'key'
run(['ssh-keygen','-q','-t','ed25519','-N','','-C',TITLE,'-f',str(private)])
require(stat.S_IMODE(private.stat().st_mode)==0o600,'private_file_mode')
public=Path(str(private)+'.pub').read_text().strip();key=private.read_text()
receipt['public_key_sha256']=hashlib.sha256(public.encode()).hexdigest()
save('provider_request_pending')
created=api(os.environ['API_TOKEN'],'POST','/repos/'+REPO+'/keys',{'title':TITLE,'key':public,'read_only':True},expected=(201,))
require(type(created.get('id')) is int and created.get('read_only') is True and created.get('key','').split()[:2]==public.split()[:2],'provider_key_unverified')
receipt['provider_key_id']=created['id'];save('provider_created')
saved=run(['bao','kv','put','-format=json','-cas=0',BAO,'SSH_PRIVATE_KEY=-','SSH_PUBLIC_KEY='+public,'PROVIDER_KEY_ID='+str(created['id']),'REPOSITORY='+REPO],key)
version=json.loads(saved).get('data',{}).get('version');require(type(version) is int,'custody_version_unverified')
receipt['custody_version']=version;receipt['custody_write_request_id']=json.loads(saved).get('request_id');save('custody_stored')
wrap=json.loads(run(['bao','kv','get','-wrap-ttl=60s','-format=json',BAO]))['wrap_info']
require(wrap.get('ttl')==60 and isinstance(wrap.get('token'),str) and wrap.get('creation_path')=='platform/data/operators/argocd/repositories/rapp-issue-core','wrap_unverified')
receipt['wrap_creation_path']=wrap['creation_path']
receipt['wrap_accessor']=wrap.get('accessor');save('unwrap_request_pending')
# Token travels only in this fixed child environment, never argv/stdout.
wrap_env={**os.environ,'BAO_TOKEN':wrap['token'],'VAULT_TOKEN':wrap['token']}
unwrapped=json.loads(run(['bao','unwrap','-format=json'],env=wrap_env))
receipt['unwrap_request_id']=unwrapped.get('request_id');delivered=unwrapped['data']['data'];require(delivered['SSH_PRIVATE_KEY']==key and str(delivered['PROVIDER_KEY_ID'])==str(created['id']),'unwrap_content_unverified');save('unwrap_consumed')
require(replay_denied(wrap_env),'consumed_wrap_replay_not_proven')
receipt['consumed_wrap_replay_denied_400']=True;save('consumed_replay_denied')
manifest=json.dumps(secret_payload(delivered['SSH_PRIVATE_KEY']))
kubectl('create','--dry-run=server','-f','-','-o','name',body=manifest)
save('destination_request_pending')
kubectl('create','--field-manager=argocd-issue-core-credential','-f','-','-o','name',body=manifest)
# No client-side apply annotation; only one exact Secret is created.
require(kubectl('-n','argocd','get','secret',SECRET,'-o','name').strip()=='secret/'+SECRET,'destination_unverified')
save('delivered_not_adopted')
except BaseException:
save('uncertain_do_not_replay');raise
finally:os.close(fd)
def main():
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('--inner',action='store_true');parser.add_argument('--contract',required=True,type=Path);parser.add_argument('--contract-sha256',required=True);parser.add_argument('--journal',required=True,type=Path)
args=parser.parse_args()
# Suppress the inherited fetch stderr and all child output, including tracebacks.
sink=os.open(os.devnull,os.O_WRONLY);os.dup2(sink,1);os.dup2(sink,2);os.close(sink)
try:
raw=args.contract.read_bytes();require(hashlib.sha256(raw).hexdigest()==args.contract_sha256,'contract_changed')
validate_contract(json.loads(raw));require(not args.journal.exists(),'journal_exists_do_not_replay')
if not args.inner:
source=Path(__file__).resolve()
result=subprocess.run(['warden','access','forgejo-admin-api-token','--field','API_TOKEN','--exec','--',sys.executable,str(source),'--inner','--contract',str(args.contract),'--contract-sha256',args.contract_sha256,'--journal',str(args.journal)],capture_output=True,timeout=900)
return 0 if result.returncode==0 else 1
execute(json.loads(raw),args.journal);return 0
except BaseException as error:
# Fixed diagnostic only; never overwrite a prior/uncertain execution journal.
failure=str(error) if isinstance(error,Refused) else 'internal_outcome_unverified'
try:
fd=os.open(args.journal,os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o600)
os.write(fd,(json.dumps({'schema':'argocd-issue-core-credential/v1','state':'preflight_refused','failure':failure,'secret_values_observed_by_agent':False})+'\n').encode());os.fsync(fd);os.close(fd)
except Exception:pass
return 1
if __name__=='__main__':raise SystemExit(main())

View file

@ -0,0 +1,245 @@
#!/usr/bin/env python3
"""Read-only manual workload adoption proof; never enables automation or runs hooks."""
from datetime import datetime, timezone
import argparse
import copy
import hashlib
import json
from pathlib import Path
import re
import subprocess
from urllib.request import urlopen
from argocd_adoption_proof import checked_run, identity, timestamp, tracking_settings
PIN = 'a3a8a27a8cda32ae3c7b55353ee16a131c50a0a0'
CONTRACT = {
'estate_ip': '92.205.62.239', 'application': 'target-revenue',
'project': 'railiance-tenants', 'destination': {'server': 'https://kubernetes.default.svc', 'namespace': 'target-revenue'},
'repo_url': 'https://forgejo.coulomb.social/coulomb/target-revenue.git', 'source_path': 'k8s/railiance',
'revision': PIN, 'tracking_method': 'annotation', 'controller_version': 'v3.5.3',
'minimum_proving_seconds': 86400, 'maximum_observation_age_seconds': 300,
'health_url': 'https://revenue.coulomb.social/healthz',
'resources': [{'group': group, 'kind': kind, 'namespace': 'target-revenue', 'name': name}
for group, kind, name in [('', 'Service', 'target-revenue'), ('apps', 'Deployment', 'target-revenue'),
('external-secrets.io', 'ExternalSecret', 'target-revenue-runtime'),
('networking.k8s.io', 'Ingress', 'target-revenue'), ('postgresql.cnpg.io', 'Cluster', 'target-revenue-pg')]],
'hooks': ['target-revenue-bootstrap-binky', 'target-revenue-migrate'],
'ready_checks': [{'kind': kind, 'namespace': 'target-revenue', 'name': name, 'condition': condition}
for kind, name, condition in [('Deployment', 'target-revenue', 'Available'),
('ExternalSecret', 'target-revenue-runtime', 'Ready'), ('Cluster', 'target-revenue-pg', 'Ready')]],
}
def validate_contract(contract):
if (not re.fullmatch(r'[a-f0-9]{40}', contract['revision']) or contract['minimum_proving_seconds'] < 86400
or not 0 < contract['maximum_observation_age_seconds'] <= 300):
raise ValueError('invalid proof bounds')
if any(r['kind'] not in {'Service', 'Deployment', 'ExternalSecret', 'Ingress', 'Cluster'} for r in contract['resources']):
raise ValueError('resource kinds not allowlisted')
if len({identity(r) for r in contract['resources']}) != len(contract['resources']):
raise ValueError('duplicate resource identities')
for r in [*contract['resources'], *contract['ready_checks']]:
if r['kind'] not in {'Service', 'Deployment', 'ExternalSecret', 'Ingress', 'Cluster'}:
raise ValueError('readiness kind not allowlisted')
if any(not re.fullmatch(r'[a-z0-9][a-z0-9.-]*', r[k]) for k in ('name', 'namespace')):
raise ValueError('invalid resource identity')
def normalize(items, contract, settings):
validate_contract(contract)
if (settings['method'] != 'annotation' or settings['controller_version'] != contract['controller_version']
or settings['installation_id_absent'] is not True):
raise ValueError('tracking semantics unverified')
resources, hooks = [], []
for raw in items:
obj = copy.deepcopy(raw)
meta = obj['metadata']
annotation = meta.get('annotations', {})
if 'argocd.argoproj.io/hook' in annotation:
if obj['kind'] != 'Job' or annotation['argocd.argoproj.io/hook'] != 'Sync':
raise ValueError('unsupported hook')
hooks.append(meta['name'])
continue
group = obj['apiVersion'].split('/')[0] if '/' in obj['apiVersion'] else ''
ident = (group, obj['kind'], meta.get('namespace', ''), meta['name'])
if ident not in {identity(r) for r in contract['resources']}:
raise ValueError('render resource not admitted')
tracking = f"{contract['application']}:{group}/{obj['kind']}:{meta['namespace']}/{meta['name']}"
annotations = meta.setdefault('annotations', {})
if annotations.get('argocd.argoproj.io/tracking-id', tracking) != tracking:
raise ValueError('conflicting source tracking annotation')
annotations['argocd.argoproj.io/tracking-id'] = tracking
resources.append(obj)
if (len(resources) != len(contract['resources']) or len({(r['apiVersion'], r['kind'], r['metadata']['name']) for r in resources}) != len(resources)
or sorted(hooks) != sorted(contract['hooks'])):
raise ValueError('render resource or hook set differs')
return resources
def decode_objects(raw):
text = raw.decode()
decoder = json.JSONDecoder()
items = []
while text.strip():
value, end = decoder.raw_decode(text.lstrip())
items.extend(value["items"] if value.get("kind") == "List" else [value])
text = text.lstrip()[end:]
return items
def collect(rendered, contract):
validate_contract(contract)
def get(args):
return json.loads(checked_run(['kubectl', *args, '-o', 'json']))
nodes = get(['get', 'nodes'])
if contract['estate_ip'] not in [a['address'] for n in nodes['items'] for a in n['status']['addresses']]:
raise ValueError('estate identity unverified')
settings = tracking_settings(contract)
parsed = decode_objects(checked_run(['kubectl', 'create', '--dry-run=client', '--validate=false', '-f', '-', '-o', 'json'], input=rendered))
desired = normalize(parsed, contract, settings)
payload = json.dumps({'apiVersion': 'v1', 'kind': 'List', 'items': desired}, sort_keys=True).encode()
diff = subprocess.run(['kubectl', 'diff', '-f', '-'], input=payload, capture_output=True, timeout=120)
if diff.returncode not in (0, 1):
raise ValueError('native client diff failed; protected output suppressed')
obj = get(['-n', 'argocd', 'get', 'application', contract['application']])
spec, status = obj['spec'], obj.get('status', {})
op = status.get('operationState', {})
sync = op.get('operation', {}).get('sync', {})
checks = []
for check in contract['ready_checks']:
r = get(['-n', check['namespace'], 'get', check['kind'], check['name']])
ready = [{k: c.get(k) for k in ('status', 'lastTransitionTime')} for c in r.get('status', {}).get('conditions', []) if c.get('type') == check['condition']]
group = r['apiVersion'].split('/')[0] if '/' in r['apiVersion'] else ''
tracking = f"{contract['application']}:{group}/{r['kind']}:{check['namespace']}/{check['name']}"
checks.append({**check, 'uid': r['metadata']['uid'], 'ready': ready,
'tracking_matches': r['metadata'].get('annotations', {}).get('argocd.argoproj.io/tracking-id') == tracking,
'observed_generation': r.get('status', {}).get('observedGeneration'), 'generation': r['metadata'].get('generation'),
'replicas': r.get('status', {}).get('replicas'), 'available_replicas': r.get('status', {}).get('availableReplicas'),
'instances': r.get('status', {}).get('instances'), 'ready_instances': r.get('status', {}).get('readyInstances')})
jobs = get(['-n', contract['destination']['namespace'], 'get', 'jobs'])
live_hooks = sorted(r['metadata']['name'] for r in jobs['items'] if r['metadata']['name'] in contract['hooks'])
return {'captured_at': datetime.now(timezone.utc).isoformat(), 'estate_ip': contract['estate_ip'], 'tracking_settings': settings,
'application': {'name': obj['metadata']['name'], 'uid': obj['metadata']['uid'], 'project': spec.get('project'),
'source': {k: spec.get('source', {}).get(k) for k in ('repoURL', 'path', 'targetRevision')}, 'destination': spec.get('destination'),
'automated_present': 'automated' in spec.get('syncPolicy', {}), 'pending_operation': bool(obj.get('operation')),
'sync': status.get('sync', {}).get('status'), 'health': status.get('health', {}).get('status'), 'revision': status.get('sync', {}).get('revision'),
'condition_types': [c.get('type') for c in status.get('conditions', [])],
'operation': {k: op.get(k) for k in ('phase', 'startedAt', 'finishedAt')},
'sync_prune': sync.get('prune', False), 'sync_strategy_apply': 'apply' in sync.get('syncStrategy', {}),
'sync_strategy_force': sync.get('syncStrategy', {}).get('apply', {}).get('force', False), 'operation_revision': sync.get('revision'),
'resources': [{k: r.get(k) for k in ('group', 'kind', 'namespace', 'name', 'status')} for r in status.get('resources', [])]},
'ready_checks': checks, 'live_hooks': live_hooks,
'pinned_render_diff': {'revision': contract['revision'], 'path': contract['source_path'], 'client_side_exit_code': diff.returncode,
'render_sha256': hashlib.sha256(rendered).hexdigest(), 'normalized_render_sha256': hashlib.sha256(payload).hexdigest(),
'render_resource_count': len(desired), 'skipped_hooks': sorted(contract['hooks']), 'output_suppressed': True}}
def verify(observation, contract, now=None):
validate_contract(contract)
now = now or datetime.now(timezone.utc)
captured = timestamp(observation['captured_at'])
if not 0 <= (now - captured).total_seconds() <= contract['maximum_observation_age_seconds']:
raise ValueError('observation stale or future')
if not -5 <= (captured - timestamp(observation['metadata_captured_at'])).total_seconds() <= contract['maximum_observation_age_seconds']:
raise ValueError('metadata observation stale or clock skew exceeds bound')
settings = observation['tracking_settings']
if (observation['estate_ip'] != contract['estate_ip'] or settings.get('method') != contract['tracking_method']
or settings.get('controller_version') != contract['controller_version'] or settings.get('installation_id_absent') is not True):
raise ValueError('estate or tracking semantics unverified')
app = observation['application']
if (app['name'] != contract['application'] or not app['uid'] or app['project'] != contract['project'] or app['destination'] != contract['destination']
or app['source'] != {'repoURL': contract['repo_url'], 'path': contract['source_path'], 'targetRevision': contract['revision']}
or app['revision'] != contract['revision']):
raise ValueError('source or application identity mismatch')
if (app['automated_present'] is not False or app['pending_operation'] is not False or app['sync'] != 'Synced' or app['health'] != 'Healthy'
or any(c != 'OrphanedResourceWarning' for c in app['condition_types'])):
raise ValueError('manual idle healthy adoption unverified')
op = app['operation']
if (op['phase'] != 'Succeeded' or app['sync_prune'] is not False or app['sync_strategy_apply'] is not True or app['sync_strategy_force'] is not False or app['operation_revision'] != contract['revision']):
raise ValueError('pinned manual apply strategy unverified')
start, finish = timestamp(op['startedAt']), timestamp(op['finishedAt'])
proof_age = (captured - finish).total_seconds()
if finish < start or proof_age < contract['minimum_proving_seconds']:
raise ValueError('completed 24h proving period unverified')
expected = {identity(r) for r in contract['resources']}
if (len(app['resources']) != len(expected) or {identity(r) for r in app['resources']} != expected or any(r['status'] != 'Synced' for r in app['resources'])):
raise ValueError('exact synced resource set unverified')
checks = observation['ready_checks']
expected_checks = {(c['kind'], c['namespace'], c['name'], c['condition']) for c in contract['ready_checks']}
if len(checks) != len(expected_checks) or {(c['kind'], c['namespace'], c['name'], c['condition']) for c in checks} != expected_checks:
raise ValueError('readiness checks incomplete')
for c in checks:
if not c['uid'] or c['tracking_matches'] is not True or len(c['ready']) != 1 or c['ready'][0]['status'] != 'True':
raise ValueError('tracked resource readiness unverified')
if timestamp(c['ready'][0]['lastTransitionTime']) > start:
raise ValueError('readiness changed during proving period')
if c['kind'] == 'Deployment' and (c['observed_generation'] != c['generation'] or not c['replicas'] or c['available_replicas'] != c['replicas']):
raise ValueError('deployment availability incomplete')
if c['kind'] == 'Cluster' and (not c['instances'] or c['ready_instances'] != c['instances']):
raise ValueError('CNPG readiness incomplete')
diff = observation['pinned_render_diff']
if (diff.get('revision') != contract['revision'] or diff.get('path') != contract['source_path'] or type(diff.get('client_side_exit_code')) is not int
or diff['client_side_exit_code'] != 0 or diff.get('render_resource_count') != len(expected)
or diff.get('skipped_hooks') != sorted(contract['hooks']) or diff.get('output_suppressed') is not True
or any(not re.fullmatch(r'[a-f0-9]{64}', diff.get(k, '')) for k in ('render_sha256', 'normalized_render_sha256'))):
raise ValueError('pinned normalized client zero-diff unverified')
if observation.get('live_hooks') != [] or observation.get('public_health') != {'url': contract['health_url'], 'status': 200}:
raise ValueError('hook absence or public health unverified')
return {'schema_version': 'argocd-workload-adoption-proof/v1', 'status': 'verified', 'application': contract['application'],
'revision': contract['revision'], 'captured_at': observation['captured_at'], 'verified_at': now.isoformat(),
'proving_seconds': proof_age, 'resource_count': len(expected), 'ready_count': len(checks),
'manual_apply_prune_off': True, 'hooks_skipped': sorted(contract['hooks']), 'hooks_absent': True,
'child_automation_enabled': False, 'public_health_status': 200, 'native_mutation': False,
'verifier_sha256': hashlib.sha256(Path(__file__).read_bytes()).hexdigest(),
'tracking_helper_sha256': hashlib.sha256(Path(__file__).with_name('argocd_adoption_proof.py').read_bytes()).hexdigest(),
'contract_sha256': hashlib.sha256(json.dumps(contract, sort_keys=True).encode()).hexdigest(),
'observation_sha256': hashlib.sha256(json.dumps(observation, sort_keys=True).encode()).hexdigest()}
def remote_program(common, rendered):
import base64
return ('import sys,types,base64,json\n' + 'm=types.ModuleType("argocd_adoption_proof");sys.modules[m.__name__]=m\n'
+ 'exec(compile(base64.b64decode(' + repr(base64.b64encode(common).decode()) + '),"argocd_adoption_proof.py","exec"),m.__dict__)\n'
+ 'n={"__name__":"workload_proof"};exec(compile(base64.b64decode(' + repr(base64.b64encode(Path(__file__).read_bytes()).decode())
+ '),"workload_adoption_proof.py","exec"),n)\n'
+ 'try:\n print(json.dumps(n["collect"](base64.b64decode(' + repr(base64.b64encode(rendered).decode()) + '),n["CONTRACT"]),sort_keys=True))\n'
+ 'except Exception:\n raise SystemExit("adoption observation incomplete; protected output suppressed")\n').encode()
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--live', action='store_true')
parser.add_argument('--source-root', type=Path)
parser.add_argument('--observation', type=Path, required=True)
parser.add_argument('--receipt', type=Path, required=True)
args = parser.parse_args()
try:
if args.live:
if not args.source_root:
raise ValueError('source root required')
import tempfile
with tempfile.TemporaryDirectory(prefix='workload-adoption-pin-') as temp:
archive = checked_run(['git', '-C', str(args.source_root), 'archive', CONTRACT['revision'], CONTRACT['source_path']])
checked_run(['tar', '-x', '-C', temp], input=archive)
rendered = checked_run(['kubectl', 'kustomize', str(Path(temp) / CONTRACT['source_path'])])
common = Path(__file__).with_name('argocd_adoption_proof.py').read_bytes()
observation = json.loads(checked_run(['ssh', 'railiance01', 'python3', '-'], input=remote_program(common, rendered), timeout=180))
with urlopen(CONTRACT['health_url'], timeout=30) as response:
observation['public_health'] = {'url': response.geturl(), 'status': response.status}
observation['metadata_captured_at'] = observation['captured_at']
observation['captured_at'] = datetime.now(timezone.utc).isoformat()
args.observation.write_text(json.dumps(observation, indent=2) + '\n')
else:
observation = json.loads(args.observation.read_text())
receipt = verify(observation, CONTRACT)
except Exception:
receipt = {'schema_version': 'argocd-workload-adoption-proof/v1', 'status': 'unverified',
'error': 'adoption proof incomplete; protected output suppressed', 'native_mutation': False}
args.receipt.write_text(json.dumps(receipt, indent=2) + '\n')
print(json.dumps(receipt, sort_keys=True))
return 0 if receipt['status'] == 'verified' else 1
if __name__ == '__main__':
raise SystemExit(main())

View file

@ -0,0 +1,22 @@
import hashlib,json,os,subprocess,threading
from http.server import BaseHTTPRequestHandler,HTTPServer
captured=[]
class Handler(BaseHTTPRequestHandler):
def log_message(self,*args):pass
def do_GET(self):
if '/metadata/' in self.path:
self.send_response(404);self.end_headers();self.wfile.write(b'{"errors":[]}');return
self.send_response(200);self.end_headers();self.wfile.write(b'{"data":{"path":"platform/","type":"kv","options":{"version":"2"}}}')
def do_POST(self):self.do_PUT()
def do_PUT(self):
body=self.rfile.read(int(self.headers.get('Content-Length','0')));captured.append((self.command,self.path,json.loads(body or b'{}')))
if self.path=='/v1/sys/wrapping/unwrap':self.send_response(400);self.end_headers();self.wfile.write(b'{"errors":["wrapping token is not valid or does not exist"]}')
else:self.send_response(200);self.end_headers();self.wfile.write(b'{"data":{"version":1}}')
def do_LIST(self):self.send_response(404);self.end_headers();self.wfile.write(b'{"errors":[]}')
server=HTTPServer(('127.0.0.1',0),Handler);threading.Thread(target=server.serve_forever,daemon=True).start()
env={**os.environ,'BAO_ADDR':'http://127.0.0.1:'+str(server.server_port),'VAULT_ADDR':'http://127.0.0.1:'+str(server.server_port),'BAO_TOKEN':'SYNTHETIC_NON_SECRET_FIXTURE','VAULT_TOKEN':'SYNTHETIC_NON_SECRET_FIXTURE'}
put=subprocess.run(['bao','kv','put','-format=json','-cas=0','platform/operators/argocd/repositories/rapp-issue-core','SSH_PRIVATE_KEY=-','REPOSITORY=coulomb/rapp-issue-core'],input='SYNTHETIC_KEY_FIXTURE\n',text=True,env=env,capture_output=True)
listing=subprocess.run(['bao','list','-format=json','platform/metadata/operators/argocd/repositories/'],env=env,capture_output=True,text=True)
unwrap=subprocess.run(['bao','unwrap','-format=json'],env=env,capture_output=True,text=True)
server.shutdown()
print(json.dumps({'synthetic_only':True,'installed_cli_kv_put_exit':put.returncode,'stdin_field_exact':any(item[1]=='/v1/platform/data/operators/argocd/repositories/rapp-issue-core' and item[2].get('data',{}).get('SSH_PRIVATE_KEY')=='SYNTHETIC_KEY_FIXTURE\n' and item[2].get('options',{}).get('cas')==0 for item in captured),'list_404_exit':listing.returncode,'list_404_safe_error':(listing.stdout+listing.stderr).strip(),'unwrap_400_exit':unwrap.returncode,'unwrap_400_safe_error':(unwrap.stdout+unwrap.stderr).strip()},indent=2))

View file

@ -0,0 +1,127 @@
import base64
from datetime import datetime, timezone, timedelta
import importlib.util
from pathlib import Path
import unittest
from unittest import mock
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
SPEC=importlib.util.spec_from_file_location('readiness',Path(__file__).parents[1]/'scripts/activity_promotion_readiness.py')
p=importlib.util.module_from_spec(SPEC);SPEC.loader.exec_module(p)
NOW=datetime(2026,10,11,20,tzinfo=timezone.utc)
def observation():
return {'captured_at':NOW.isoformat(),'estate_ip':'92.205.62.239','cluster_uid':'cluster-uid','application_uid':'app-uid',
'source':{'repoURL':'https://forgejo.coulomb.social/coulomb/activity-core.git','path':'k8s/gitops','targetRevision':p.PIN},
'project':'activity-core','revision':p.PIN,'destination':{'server':'https://kubernetes.default.svc','namespace':'activity-core'},
'automated_present':False,'pending_operation':False,
'sync_options':['CreateNamespace=false','ApplyOutOfSyncOnly=true','PruneLast=true','FailOnSharedResource=true'],
'sync':'Synced','health':'Healthy','condition_types':[],'project_scope_matches':True,
'operation':{'phase':'Succeeded','finishedAt':'2026-10-04T14:13:25Z'},
'resources':[dict(zip(('group','kind','namespace','name'),r),status='Synced') for r in sorted(p.RESOURCES)],
'deployments':[{'name':name,'generation_observed':True,'replicas':1,'ready':1,'updated':1,'available':1}
for name in ('actcore-api','actcore-worker','actcore-event-router')]}
def payload():
return {'schema_version':'activity-core-release-acceptance/v1','owner_task':p.OWNER_TASK,'issuer':'owner-acceptance-principal',
'authority':p.AUTHORITY,'application':'activity-core','cluster_uid':'cluster-uid','adoption_revision':p.PIN,
'targets':dict(p.TARGETS),'release_principal':'activity-core-release-broker','broker_revision':'a'*40,
'checks':{c:True for c in p.CHECKS},'issued_at':NOW.isoformat(),'expires_at':(NOW+timedelta(minutes=4)).isoformat(),
'continuous_health':{'revision':p.PIN,'continuous':True,'max_gap_seconds':90,'observed_at':NOW.isoformat(),
'healthy_since':(NOW-timedelta(days=1)).isoformat()}}
class GateTest(unittest.TestCase):
def setUp(self):
self.private=Ed25519PrivateKey.generate()
self.public=self.private.public_key().public_bytes(Encoding.Raw,PublicFormat.Raw)
def envelope(self,data=None):
data=data or payload()
return {'payload':data,'signature':base64.b64encode(self.private.sign(p.canonical(data))).decode()}
def evaluate(self,envelope=None,obs=None,key=None):
return p.readiness(obs or observation(),envelope=envelope or self.envelope(),trusted_key=key or self.public,
trusted_principal='owner-acceptance-principal',now=NOW)
def test_complete_signed_fixture_passes_without_activation(self):
result=self.evaluate()
self.assertEqual(result['status'],'ready')
self.assertFalse(result['native_mutation'])
self.assertFalse(result['automatic_sync_candidate'])
def test_snapshot_and_elapsed_time_cannot_substitute_for_owner_proof(self):
result=p.readiness(observation(),now=NOW)
self.assertEqual(result['status'],'waiting')
self.assertEqual(result['depends_on'],['ACTIVITY-WP-0041-T03'])
self.assertFalse(result['needs_human'])
self.assertTrue(result['adoption_snapshot_is_not_continuous_observation'])
def test_every_acceptance_check_required(self):
for check in p.CHECKS:
for missing in (False,None,'true'):
data=payload();data['checks'][check]=missing
with self.subTest(check=check,value=missing):self.assertEqual(self.evaluate(self.envelope(data))['status'],'unverified')
def test_unknown_key_forged_tampered_or_self_introduced_trust_refused(self):
envelope=self.envelope();envelope['payload']['release_principal']='attacker'
self.assertEqual(self.evaluate(envelope)['status'],'unverified')
unknown=Ed25519PrivateKey.generate().public_key().public_bytes(Encoding.Raw,PublicFormat.Raw)
self.assertEqual(self.evaluate(key=unknown)['status'],'unverified')
envelope=self.envelope();envelope['public_key']=self.public.hex()
self.assertEqual(self.evaluate(envelope)['status'],'unverified')
envelope=self.envelope();envelope['signature']='invalid-base64!'
self.assertEqual(self.evaluate(envelope)['status'],'unverified')
def test_wrong_scope_identity_cluster_commit_or_expired_owner_proof_refused(self):
for key,value in [('authority','admin'),('application','other'),('cluster_uid','other'),
('adoption_revision','b'*40),('owner_task','other'),('issuer','producer'),
('broker_revision','main'),('release_principal',''),
('issued_at',(NOW-timedelta(minutes=6)).isoformat()),
('issued_at',(NOW+timedelta(seconds=1)).isoformat()),
('expires_at',NOW.isoformat())]:
data=payload();data[key]=value
with self.subTest(key=key):self.assertEqual(self.evaluate(self.envelope(data))['status'],'unverified')
for key,value in [('prune',True),('root_sync_selects_only','*'),('child_path','other')]:
data=payload();data['targets'][key]=value
with self.subTest(target=key):self.assertEqual(self.evaluate(self.envelope(data))['status'],'unverified')
def test_continuous_sampling_requires_owner_signed_fresh_bounded_interval(self):
for key,value in [('continuous',False),('max_gap_seconds',91),('max_gap_seconds',True),
('revision','b'*40),('healthy_since',(NOW-timedelta(hours=23)).isoformat()),
('observed_at',(NOW-timedelta(seconds=91)).isoformat()),
('observed_at',(NOW+timedelta(seconds=1)).isoformat())]:
data=payload();data['continuous_health'][key]=value
with self.subTest(key=key):self.assertEqual(self.evaluate(self.envelope(data))['status'],'unverified')
def test_exact_live_adoption_scope_and_freshness_refusals(self):
for key,value in [('estate_ip','other'),('project_scope_matches',False),('project','other'),
('automated_present',True),('pending_operation',True),('revision','b'*40),
('health','Degraded'),('sync','OutOfSync'),('condition_types',['ComparisonError']),
('captured_at',(NOW-timedelta(minutes=6)).isoformat()),
('captured_at',(NOW+timedelta(seconds=1)).isoformat()),
('resources',[]),('deployments',[])]:
data=observation();data[key]=value
with self.subTest(key=key):self.assertEqual(self.evaluate(obs=data)['status'],'unverified')
data=observation();data['resources'].append(data['resources'][0])
self.assertEqual(self.evaluate(obs=data)['status'],'unverified')
for key,value in [('ready',0),('generation_observed',False),('updated',0),('replicas',0)]:
data=observation();data['deployments'][0][key]=value
with self.subTest(deployment=key):self.assertEqual(self.evaluate(obs=data)['status'],'unverified')
def test_no_signature_verification_attempt_without_trusted_operator_config(self):
self.assertEqual(p.readiness(observation(),envelope=self.envelope(),now=NOW)['status'],'waiting')
def test_protected_subprocess_errors_and_timeouts_never_leak_canary(self):
import subprocess
from types import SimpleNamespace
canary='SECRET-CANARY-NOT-OUTPUT'
with mock.patch.object(p.subprocess,'run',return_value=SimpleNamespace(returncode=1,stdout=canary,stderr=canary)):
with self.assertRaises(ValueError) as exc:p.run(['kubectl','get','nodes'])
self.assertNotIn(canary,str(exc.exception))
with mock.patch.object(p.subprocess,'run',side_effect=subprocess.TimeoutExpired('cmd',1,output=canary,stderr=canary)):
with self.assertRaises(ValueError) as exc:p.run(['kubectl','get','nodes'])
self.assertNotIn(canary,str(exc.exception))

View file

@ -0,0 +1,92 @@
import importlib.util
import json
import os
from pathlib import Path
import subprocess
import tempfile
import unittest
from unittest.mock import patch
spec=importlib.util.spec_from_file_location('issuer',Path(__file__).resolve().parents[1]/'scripts/provision_argocd_issue_core_repository.py')
issuer=importlib.util.module_from_spec(spec);spec.loader.exec_module(issuer)
class IssuerTests(unittest.TestCase):
def contract(self):return {**issuer.FIXED,'owner_review_ref':'fixed-review','ssh_egress_existing_proof_ref':'fixed-egress','runtime_identity_ref':'attended-platform','rollback_ref':'fixed-rollback','ssh_known_hosts_sha256':'a'*64,'expires_at':'2099-01-01T00:00:00+00:00'}
def test_existing_d2_covers_exact_scope_but_broadening_refused(self):
issuer.validate_contract(self.contract())
for key,value in [('repository','coulomb/*'),('read_only',False),('scope_approval_ref','self-approved'),('destination','argocd/broad-creds'),('new_network_scope',True)]:
data=self.contract();data[key]=value
with self.assertRaises(issuer.Refused):issuer.validate_contract(data)
def test_wrong_estate_prevents_credentials_and_grants(self):
calls=[]
def runner(args,*a,**kw):
calls.append(args);return json.dumps({'items':[{'status':{'addresses':[{'address':'192.0.2.1'}]}}]})
with patch.dict(os.environ,{'API_TOKEN':'SYNTHETIC_TEST_ONLY'}),patch.object(issuer,'run',runner),patch.object(issuer,'api') as api:
with self.assertRaises(issuer.Refused):issuer.execute(self.contract(),Path('/tmp/unused-fixture-journal'))
api.assert_not_called()
self.assertEqual(len(calls),1)
def test_provider_cannot_redirect_or_use_other_repo(self):
with self.assertRaises(issuer.Refused):issuer.api('synthetic','GET','/repos/coulomb/other/keys')
with self.assertRaises(issuer.Refused):issuer.NoRedirect().redirect_request(None,None,None,None,None,None)
def test_secret_has_exact_scope_no_apply_annotation(self):
body=issuer.secret_payload('SYNTHETIC_PRIVATE_CANARY')
self.assertEqual(body['metadata']['namespace'],'argocd');self.assertEqual(body['metadata']['name'],issuer.SECRET)
self.assertNotIn('kubectl.kubernetes.io/last-applied-configuration',body['metadata']['annotations'])
self.assertNotIn('password',body['stringData']);self.assertEqual(body['stringData']['url'],issuer.URL)
def test_silent_main_does_not_echo_invalid_contract_or_raw_child_errors(self):
with tempfile.TemporaryDirectory() as tmp:
p=Path(tmp)/'contract.json';p.write_text('SECRET_CANARY')
result=subprocess.run(['python3',str(Path(__file__).resolve().parents[1]/'scripts/provision_argocd_issue_core_repository.py'),'--contract',str(p),'--contract-sha256','a'*64,'--journal',str(Path(tmp)/'journal.json')],capture_output=True,text=True)
self.assertEqual(result.returncode,1);self.assertEqual(result.stdout,'');self.assertEqual(result.stderr,'');self.assertEqual(json.loads((Path(tmp)/'journal.json').read_text())['failure'],'contract_changed')
def test_synthetic_end_to_end_uses_one_unwrap_and_exact_destination(self):
commands=[];public='ssh-ed25519 SYNTHETIC_PUBLIC fixture';private='SYNTHETIC_PRIVATE_CANARY';known='[forgejo.coulomb.social]:30022 ssh-ed25519 SYNTHETIC_HOST\n'
contract=self.contract();contract['ssh_known_hosts_sha256']=__import__('hashlib').sha256(known.encode()).hexdigest()
with tempfile.TemporaryDirectory() as tmp:
journal=Path(tmp)/'journal.json';keydir=Path(tmp)/'keys';keydir.mkdir()
class FakeTmp:
def __enter__(self):return str(keydir)
def __exit__(self,*args):return False
def runner(argv,body=None,env=None):
commands.append((argv,body,env));text=' '.join(argv)
if 'get nodes' in text:return json.dumps({'items':[{'status':{'addresses':[{'address':'92.205.62.239'}]}}]})
if 'get configmap' in text:return json.dumps({'data':{'ssh_known_hosts':known}})
if 'get appproject' in text:return json.dumps({'spec':{'sourceRepos':[issuer.URL]}})
if argv[:3]==['bao','token','capabilities']:return 'create, read, update'
if argv[:3]==['bao','audit','list']:return json.dumps({'file/':{'type':'file'}})
if 'get secret' in text:return '' if '--ignore-not-found' in text else 'secret/'+issuer.SECRET
if argv[0]=='ssh-keygen':
path=Path(argv[-1]);path.write_text(private);path.chmod(0o600);Path(str(path)+'.pub').write_text(public);return ''
if argv[:3]==['bao','kv','put']:return json.dumps({'request_id':'write-fixture','data':{'version':1}})
if argv[:3]==['bao','kv','get']:return json.dumps({'wrap_info':{'ttl':60,'token':'SYNTHETIC_WRAP','accessor':'fixture-accessor','creation_path':'platform/data/operators/argocd/repositories/rapp-issue-core'}})
if argv[:2]==['bao','unwrap']:
self.assertEqual(env['BAO_TOKEN'],'SYNTHETIC_WRAP');return json.dumps({'request_id':'unwrap-fixture','data':{'data':{'SSH_PRIVATE_KEY':private,'PROVIDER_KEY_ID':'7'}}})
return 'secret/'+issuer.SECRET
def capture(argv,body=None,env=None):
commands.append((argv,body,env))
if argv[:2]==['bao','list']:return subprocess.CompletedProcess(argv,2,'{}','')
return subprocess.CompletedProcess(argv,2,'','Code: 400. Errors:\n\n* wrapping token is not valid or does not exist\n')
def provider(token,method,path,payload=None,expected=(200,)):
if method=='POST':
self.assertEqual(payload,{'title':issuer.TITLE,'key':public,'read_only':True});return {'id':7,'key':public,'read_only':True}
return [] if '/keys?' in path else {'full_name':issuer.REPO,'private':True}
with patch.dict(os.environ,{'API_TOKEN':'SYNTHETIC_ADMIN'}),patch.object(issuer,'run',runner),patch.object(issuer,'captured',capture),patch.object(issuer,'api',provider),patch.object(issuer.tempfile,'TemporaryDirectory',lambda **kw:FakeTmp()):issuer.execute(contract,journal)
receipt=json.loads(journal.read_text());self.assertEqual(receipt['state'],'delivered_not_adopted');self.assertNotIn(private,journal.read_text());self.assertNotIn('SYNTHETIC_WRAP',journal.read_text())
self.assertEqual(sum(argv[:2]==['bao','unwrap'] for argv,body,env in commands),2);self.assertTrue(receipt['consumed_wrap_replay_denied_400']);self.assertEqual(receipt['wrap_creation_path'],'platform/data/operators/argocd/repositories/rapp-issue-core')
for argv,body,env in commands:
self.assertNotIn(private,' '.join(argv));self.assertNotIn('SYNTHETIC_WRAP',' '.join(argv));self.assertNotIn(' apply ',' '.join(argv));self.assertNotIn(' patch ',' '.join(argv))
def test_empty_metadata_list_404_is_accepted_other_errors_refused(self):
with patch.object(issuer,'captured',return_value=subprocess.CompletedProcess([],2,'{}','')):self.assertEqual(issuer.metadata_children(),[])
for value in [subprocess.CompletedProcess([],2,'{}','SECRET_CANARY'),subprocess.CompletedProcess([],1,'','Code: 403'),subprocess.CompletedProcess([],2,'','network unreachable')]:
with patch.object(issuer,'captured',return_value=value):
with self.assertRaisesRegex(issuer.Refused,'^custody_metadata_unverified$'):issuer.metadata_children()
def test_replay_denial_requires_specific_400_not_transport_or_forbidden(self):
good='Error unwrapping: Error making API request.\nCode: 400. Errors:\n\n* wrapping token is not valid or does not exist\n'
for code,text,expected in [(2,good,True),(2,good.replace('400','403'),False),(2,'dial tcp: connection refused SECRET_CANARY',False),(1,good,False),(2,'Code: 400\n* unrelated failure',False)]:
with patch.object(issuer,'captured',return_value=subprocess.CompletedProcess([],code,'',text)):self.assertEqual(issuer.replay_denied({}),expected)
def test_raw_command_output_timeout_and_error_suppressed(self):
for result in [subprocess.CompletedProcess(['fixture'],1,'SECRET_CANARY','SECRET_CANARY'),subprocess.TimeoutExpired(['fixture'],60,output='SECRET_CANARY',stderr='SECRET_CANARY')]:
with patch.object(issuer.subprocess,'run',side_effect=result if isinstance(result,Exception) else None,return_value=result):
with self.assertRaisesRegex(issuer.Refused,'^command_unverified$'):issuer.run(['fixture'])
if __name__=='__main__':unittest.main()

View file

@ -0,0 +1,88 @@
import copy
import importlib.util
import json
from pathlib import Path
import subprocess
import unittest
from unittest.mock import patch
spec=importlib.util.spec_from_file_location('transport',Path(__file__).resolve().parents[1]/'scripts/argocd_public_transport.py')
t=importlib.util.module_from_spec(spec);spec.loader.exec_module(t)
class TransportTests(unittest.TestCase):
def plan(self):return json.loads((Path(__file__).resolve().parents[1]/'docs/evidence/2026-10-11-issue-core-transport/transport-plan.json').read_text())
def objects(self,plan):
result={}
for item in plan['resources']:
obj={'metadata':{'uid':item['uid'],'resourceVersion':'17','labels':{'unrelated':'retain'}},'data':{},'spec':{}}
t.replace(obj,item['path'],copy.deepcopy(item['before']));result[item['kind']]=obj
return result
def runner(self,objects,calls,modify_dry=False):
def run(args,body=None):
calls.append((args,body))
if args[:2]==['get','nodes']:return json.dumps({'items':[{'status':{'addresses':[{'address':'92.205.62.239'}]}}]})
kind=args[3]
if args[2]=='get':return json.dumps(objects[kind])
obj=copy.deepcopy(objects[kind])
for op in json.loads(body):
if op['op']=='test':self.assertEqual(t.value(obj,op['path']),op['value'])
else:t.replace(obj,op['path'],op['value'])
if '--dry-run=server' in args:
if modify_dry:obj['metadata']['labels']['unrelated']='changed'
return json.dumps(obj)
objects[kind]=obj;return kind+'/'+args[4]
return run
def receipt(self):return {'resources':[],'mutation_attempted':False}
def test_dry_run_changes_no_live_values(self):
plan=self.plan();objects=self.objects(plan);before=copy.deepcopy(objects);calls=[]
with patch.object(t,'run',self.runner(objects,calls)):r=t.perform(plan,'dry-run',self.receipt())
self.assertEqual(objects,before);self.assertTrue(r['passed']);self.assertFalse(r['mutation_attempted']);self.assertEqual(sum(args[2]=='patch' for args,body in calls if len(args)>2),2)
def test_execute_and_guarded_rollback_preserve_other_fields(self):
plan=self.plan();objects=self.objects(plan);before=copy.deepcopy(objects);calls=[];checkpoints=[];receipt=self.receipt()
with patch.object(t,'run',self.runner(objects,calls)):
t.perform(plan,'execute',receipt,lambda:checkpoints.append(copy.deepcopy(receipt)))
for item in plan['resources']:self.assertEqual(t.value(objects[item['kind']],item['path']),item['after'])
self.assertTrue(any(x.get('pending_target') for x in checkpoints))
t.perform(plan,'verify',self.receipt());t.perform(plan,'rollback',self.receipt())
self.assertEqual(objects,before)
for args,body in calls:
if body:
ops=json.loads(body);self.assertEqual([op['op'] for op in ops],['test','test','test','replace']);self.assertEqual(ops[0]['path'],'/metadata/uid');self.assertEqual(ops[1]['path'],'/metadata/resourceVersion')
def test_other_target_preimage_drift_stops_before_first_patch(self):
plan=self.plan();objects=self.objects(plan);objects['appproject']['spec']['sourceRepos'].append('ssh://unreviewed/repo');calls=[]
with patch.object(t,'run',self.runner(objects,calls)):
with self.assertRaisesRegex(t.Refused,'^target_preimage_changed$'):t.perform(plan,'execute',self.receipt())
self.assertFalse(any(args[2]=='patch' for args,body in calls if len(args)>2))
def test_partial_second_write_is_recorded_and_rollback_can_restore_first(self):
plan=self.plan();objects=self.objects(plan);before=copy.deepcopy(objects);calls=[];runner=self.runner(objects,calls);receipt=self.receipt();snapshots=[]
def failing(args,body=None):
if len(args)>3 and args[2]=='patch' and args[3]=='appproject' and '--dry-run=server' not in args:raise t.Refused('command_outcome_unverified')
return runner(args,body)
with patch.object(t,'run',failing):
with self.assertRaises(t.Refused):t.perform(plan,'execute',receipt,lambda:snapshots.append(copy.deepcopy(receipt)))
self.assertEqual(receipt['pending_target'],'appproject/railiance-tenants');self.assertTrue(receipt['resources'][0]['changed_verified']);self.assertTrue(snapshots[-1]['mutation_attempted'])
with patch.object(t,'run',runner):t.perform(plan,'rollback',self.receipt())
self.assertEqual(objects,before)
def test_target_uid_change_refused(self):
plan=self.plan();objects=self.objects(plan);objects['configmap']['metadata']['uid']='foreign'
with patch.object(t,'run',self.runner(objects,[])):
with self.assertRaisesRegex(t.Refused,'^target_uid_changed$'):t.perform(plan,'execute',self.receipt())
def test_server_admission_extra_change_refused(self):
plan=self.plan();objects=self.objects(plan);before=copy.deepcopy(objects)
with patch.object(t,'run',self.runner(objects,[],True)):
with self.assertRaisesRegex(t.Refused,'^dry_run_modified_other_fields$'):t.perform(plan,'execute',self.receipt())
self.assertEqual(objects,before)
def test_broader_repo_or_host_replacement_refused(self):
for kind in ('host','repo'):
plan=self.plan()
if kind=='host':plan['resources'][0]['after']='unreviewed replacement\n'
else:plan['resources'][1]['after'].append('ssh://forgejo.coulomb.social/coulomb/*')
with self.assertRaises(t.Refused):t.validate(plan)
def test_wrong_estate_and_raw_canary_refused(self):
with patch.object(t,'run',return_value=json.dumps({'items':[{'status':{'addresses':[{'address':'192.0.2.8'}]}}]})) as run:
with self.assertRaisesRegex(t.Refused,'^wrong_estate$'):t.perform(self.plan(),'execute',self.receipt())
self.assertEqual(run.call_count,1)
with patch.object(t.subprocess,'run',return_value=subprocess.CompletedProcess([],1,'SECRET_CANARY','SECRET_CANARY')):
with self.assertRaisesRegex(t.Refused,'^command_outcome_unverified$'):t.run(['get','nodes'])
if __name__=='__main__':unittest.main()

View file

@ -0,0 +1,114 @@
import copy
from datetime import datetime, timedelta, timezone
import importlib.util
import json
from pathlib import Path
import sys
import pytest
SCRIPTS = Path(__file__).resolve().parents[1] / 'scripts'
if not SCRIPTS.exists(): SCRIPTS = Path(__file__).resolve().parent
sys.path.insert(0, str(SCRIPTS))
import workload_adoption_proof as proof
NOW = datetime(2026, 10, 11, 20, 0, tzinfo=timezone.utc)
def observation():
c = proof.CONTRACT
old = (NOW - timedelta(days=2)).isoformat()
settings = {'method': 'annotation', 'controller_version': 'v3.5.3', 'installation_id_absent': True}
return {'captured_at': NOW.isoformat(), 'metadata_captured_at': NOW.isoformat(), 'estate_ip': c['estate_ip'], 'tracking_settings': settings,
'application': {'name': c['application'], 'uid': 'application-uid', 'project': c['project'], 'destination': c['destination'],
'source': {'repoURL': c['repo_url'], 'path': c['source_path'], 'targetRevision': c['revision']}, 'revision': c['revision'],
'automated_present': False, 'pending_operation': False, 'sync': 'Synced', 'health': 'Healthy', 'condition_types': [],
'operation': {'phase': 'Succeeded', 'startedAt': old, 'finishedAt': old}, 'sync_prune': False,
'sync_strategy_apply': True, 'sync_strategy_force': False, 'operation_revision': c['revision'], 'resources': [{**r, 'status': 'Synced'} for r in c['resources']]},
'ready_checks': [{**check, 'uid': 'resource-uid', 'tracking_matches': True,
'ready': [{'status': 'True', 'lastTransitionTime': old}], 'generation': 2, 'observed_generation': 2,
'replicas': 1, 'available_replicas': 1, 'instances': 1, 'ready_instances': 1} for check in c['ready_checks']],
'live_hooks': [], 'public_health': {'url': c['health_url'], 'status': 200},
'pinned_render_diff': {'revision': c['revision'], 'path': c['source_path'], 'client_side_exit_code': 0,
'render_resource_count': len(c['resources']), 'skipped_hooks': sorted(c['hooks']), 'output_suppressed': True,
'render_sha256': 'a' * 64, 'normalized_render_sha256': 'b' * 64}}
def test_verified_receipt_is_manual_adoption_only():
receipt = proof.verify(observation(), proof.CONTRACT, now=NOW)
assert receipt['status'] == 'verified'
assert receipt['resource_count'] == 5
assert receipt['ready_count'] == 3
assert receipt['proving_seconds'] == 172800
assert receipt['native_mutation'] is False
assert receipt['child_automation_enabled'] is False
@pytest.mark.parametrize('field,value', [('automated_present', True), ('pending_operation', True), ('sync_prune', True),
('sync_strategy_apply', False), ('sync_strategy_force', True), ('revision', 'f'*40), ('health', 'Progressing'), ('condition_types', ['ComparisonError'])])
def test_wrong_runtime_gate_fails(field, value):
obj = observation(); obj['application'][field] = value
with pytest.raises(ValueError): proof.verify(obj, proof.CONTRACT, now=NOW)
@pytest.mark.parametrize('mutation', ['missing-resource', 'extra-hook-resource', 'resource-not-synced', 'hook-live',
'short-proving', 'stale-observation', 'future-observation', 'metadata-stale', 'client-diff', 'missing-check', 'ready-false',
'new-ready-transition', 'deployment-generation', 'deployment-replicas', 'cnpg-instances', 'tracking', 'health-url', 'health-status'])
def test_missing_or_wrong_proof_fails(mutation):
obj = observation()
if mutation == 'missing-resource': obj['application']['resources'].pop()
elif mutation == 'extra-hook-resource': obj['application']['resources'].append({'group': 'batch', 'kind': 'Job', 'namespace': 'target-revenue', 'name': proof.CONTRACT['hooks'][0], 'status': 'Synced'})
elif mutation == 'resource-not-synced': obj['application']['resources'][0]['status'] = 'OutOfSync'
elif mutation == 'hook-live': obj['live_hooks'] = [proof.CONTRACT['hooks'][0]]
elif mutation == 'short-proving': obj['application']['operation']['finishedAt'] = (NOW-timedelta(hours=23)).isoformat()
elif mutation == 'stale-observation': obj['captured_at'] = (NOW-timedelta(minutes=6)).isoformat()
elif mutation == 'future-observation': obj['captured_at'] = (NOW+timedelta(seconds=1)).isoformat()
elif mutation == 'metadata-stale': obj['metadata_captured_at'] = (NOW-timedelta(minutes=6)).isoformat()
elif mutation == 'client-diff': obj['pinned_render_diff']['client_side_exit_code'] = 1
elif mutation == 'missing-check': obj['ready_checks'].pop()
elif mutation == 'ready-false': obj['ready_checks'][1]['ready'][0]['status'] = 'False'
elif mutation == 'new-ready-transition': obj['ready_checks'][1]['ready'][0]['lastTransitionTime'] = NOW.isoformat()
elif mutation == 'deployment-generation': obj['ready_checks'][0]['observed_generation'] = 1
elif mutation == 'deployment-replicas': obj['ready_checks'][0]['available_replicas'] = 0
elif mutation == 'cnpg-instances': obj['ready_checks'][2]['ready_instances'] = 0
elif mutation == 'tracking': obj['ready_checks'][0]['tracking_matches'] = False
elif mutation == 'health-url': obj['public_health']['url'] = 'https://unexpected.test/healthz'
elif mutation == 'health-status': obj['public_health']['status'] = 503
with pytest.raises(ValueError): proof.verify(obj, proof.CONTRACT, now=NOW)
def sources():
docs = []
for r in proof.CONTRACT['resources']:
docs.append({'apiVersion': r['group']+'/v1' if r['group'] else 'v1', 'kind': r['kind'],
'metadata': {'name': r['name'], 'namespace': r['namespace']}})
for name in proof.CONTRACT['hooks']:
docs.append({'apiVersion': 'batch/v1', 'kind': 'Job', 'metadata': {'name': name, 'namespace': 'target-revenue', 'annotations': {'argocd.argoproj.io/hook': 'Sync'}}})
return docs
def test_normalization_skips_hooks_and_only_injects_tracking_metadata():
docs = sources(); original = copy.deepcopy(docs)
settings = observation()['tracking_settings']
normalized = proof.normalize(docs, proof.CONTRACT, settings)
assert len(normalized) == 5
assert docs == original
assert not any(r['kind'] == 'Job' for r in normalized)
assert normalized[0]['metadata']['annotations']['argocd.argoproj.io/tracking-id'] == 'target-revenue:/Service:target-revenue/target-revenue'
@pytest.mark.parametrize('bad', ['secret', 'extra-resource', 'wrong-hook', 'missing-hook', 'duplicate-resource', 'conflicting-tracking'])
def test_normalization_fails_closed(bad):
docs = sources()
if bad == 'secret': docs.append({'apiVersion': 'v1', 'kind': 'Secret', 'metadata': {'name': 'secret', 'namespace': 'target-revenue'}})
elif bad == 'extra-resource': docs.append({'apiVersion': 'v1', 'kind': 'Service', 'metadata': {'name': 'extra', 'namespace': 'target-revenue'}})
elif bad == 'wrong-hook': docs[-1]['metadata']['annotations']['argocd.argoproj.io/hook'] = 'PreSync'
elif bad == 'missing-hook': docs.pop()
elif bad == 'duplicate-resource': docs.append(copy.deepcopy(docs[0]))
elif bad == 'conflicting-tracking': docs[0]['metadata']['annotations'] = {'argocd.argoproj.io/tracking-id': 'other'}
with pytest.raises(ValueError): proof.normalize(docs, proof.CONTRACT, observation()['tracking_settings'])
def test_kubectl_stream_and_list_decoding():
docs = sources()
assert proof.decode_objects(('\n'.join(json.dumps(r) for r in docs)).encode()) == docs
assert proof.decode_objects(json.dumps({'kind': 'List', 'items': docs}).encode()) == docs

View file

@ -268,36 +268,25 @@ proving period without changing sync/automation policy or using a new human gate
```task
id: RPF-WP-0044-T04
status: todo
status: wait
needs_human: true
intervention_note: "Orange attended Platform OpenBao OIDC/MFA login for the already D2-approved exact repository reader; no second source-scope approval."
decision_id: 89f1058f-33bc-47a8-8a49-0b44d426c67e
priority: high
state_hub_task_id: "0e619658-0453-51ed-b9a0-bed28b5544fd"
```
2026-10-11: requalified after founder decision D2 (ArgoCD owns production) resolved — see the-custodian docs/decisions/2026-10-11-security-unblock-decisions.md.
D2 already authorizes this exact private repository read-only reader and the ordered adoption. No renewed founder go-ahead is required. The remaining human act is the existing Platform OpenBao attended OIDC/MFA login; route it through the single attended-window checklist.
**Waits on the founder's go-ahead**, and on two preconditions:
Source preparation now disables wrapper direct deployment/rollback and verifies Argo ownership using the exact HTTPS or SSH source URL. The fixed credential executor is `scripts/provision_argocd_issue_core_repository.py`, reviewed in `docs/evidence/2026-10-11-issue-core-credential/owner-review.json`. It creates one repository-only read-only SSH deploy key, stores it at `platform/operators/argocd/repositories/rapp-issue-core`, response-wraps for 60 seconds, unwraps once, proves consumed-token denial, and creates only `argocd/rapp-issue-core-repository`. Tests and installed Bao synthetic checks pass; native issuance/adoption have not run. The contract example is incomplete and cannot authorize execution.
- `rapp-issue-core` agrees (hub message) that ArgoCD owns production and its
`make deploy` stops being a production path; it would fight self-heal.
Image releases become commits to `manifests/30-runtime.yaml`.
- A CCR for the ArgoCD repository credential, source at
`platform/operators/argocd/repositories/rapp-issue-core`, read-only deploy
token. Applied with `make argocd-repo-apply`; no value is handled in this
plan.
Zero diff against live for both the raw `manifests/` and the rendered output
(digest `sha256:a56c80cc…b92cf`). All kinds are in the `railiance-tenants`
whitelist. Live check: `rapp-issue-core make verify-live`. Workload restore:
`rapp-issue-core make rollback`.
2026-10-03: human gate routed to hub decision 89f1058f-33bc-47a8-8a49-0b44d426c67e (D2: ArgoCD owns production: go-ahead sequence for railiance-apps-root, issue-core, policy-nexus and activity-core automation) by CUST-WP-0075; resolving that decision raises C-40 here.
Public host trust and exact project admission are prepared in owner source and the bounded `scripts/argocd_public_transport.py`; its server dry-run passed. Preserve each exact attempt and any partial failure. Finish those prerequisites, seal the owner-reviewed contract, use the attended login, then pin the newly committed wrapper source in the Application, inspect client-side native diff, manually sync with prune/force disabled, and run the bounded owner verifier. Image releases and rollback use Git revisions plus Argo; direct `make rollback` is disabled. Never adopt the stale wrapper revision that predates the ExternalSecret metadata guard.
## Adopt target-revenue
```task
id: RPF-WP-0044-T05
status: todo
status: done
decision_id: 89f1058f-33bc-47a8-8a49-0b44d426c67e
priority: medium
state_hub_task_id: "d418068a-6fb0-5416-aac5-d23c93924d9c"
@ -321,6 +310,24 @@ target-revenue commit.
2026-10-03: human gate routed to hub decision 89f1058f-33bc-47a8-8a49-0b44d426c67e (D2: ArgoCD owns production: go-ahead sequence for railiance-apps-root, issue-core, policy-nexus and activity-core automation) by CUST-WP-0075; resolving that decision raises C-40 here.
2026-10-11: **manual adoption proving complete**. Fresh read-only proof at 2026-10-11T19:51:12.812423+00:00
verified exact pin `a3a8a27a8cda32ae3c7b55353ee16a131c50a0a0`, manual apply strategy,
prune/force off and no pending operation. The last successful pinned apply finished
2026-09-28T14:23:27Z; 1142865 seconds of proving exceeds 24 hours.
All five non-hook objects are tracked and Synced; Deployment Available (generation observed),
ExternalSecret Ready and CNPG Ready (1/1). ArgoCD remains Synced/Healthy; normalized native
client-side diff is zero and `https://revenue.coulomb.social/healthz` returns 200. Both declared
Sync-hook Jobs are absent and excluded from the apply-strategy diff. No live mutation or
Secret read was performed. Receipt: `docs/evidence/2026-10-11-target-revenue-adoption-proof/receipt.json`;
sanitized observation alongside it. Reusable check: `scripts/workload_adoption_proof.py`;
35 new failure/normalization tests plus 13 existing OpenBao adoption tests pass.
This closes T05 adoption/proving only. Child automated sync stays off. The existing
target-revenue owner handoff for hook re-execution safety remains a prerequisite to future
automation; it is not silently resolved and no new residual is invented here. The observed
OrphanedResourceWarning is non-blocking; other Application condition types fail verification.
## Adopt external-secrets (highest risk)
```task

View file

@ -8,7 +8,7 @@ status: blocked
owner: codex
topic_slug: railiance
created: "2026-09-27"
updated: "2026-10-03"
updated: "2026-10-11"
state_hub_workstream_id: "b8cf2fc2-60c2-5d4e-a60a-55f1304d9f54"
---
@ -40,9 +40,9 @@ health, resource inventory, schedules and original deployment generations.
```task
id: RPF-WP-0048-T02
status: todo
status: wait
decision_id: 89f1058f-33bc-47a8-8a49-0b44d426c67e
depends_on: [ACTIVITY-WP-0041]
depends_on: [ACTIVITY-WP-0041-T03]
priority: high
state_hub_task_id: "63b44949-39f8-52fd-ab63-e618b67ef992"
```
@ -58,6 +58,36 @@ activating bounded routine promotion. Destructive pruning remains disabled.
2026-10-03: human gate routed to hub decision 89f1058f-33bc-47a8-8a49-0b44d426c67e (D2: ArgoCD owns production: go-ahead sequence for railiance-apps-root, issue-core, policy-nexus and activity-core automation) by CUST-WP-0075; resolving that decision raises C-40 here.
2026-10-11: qualified once as an **owner-proof wait**, not a founder gate.
`scripts/activity_promotion_readiness.py` now checks the exact live source pin
`a86a143`, local estate/cluster identity, narrow AppProject, nine tracked runtime
objects, manual/no-prune policy, successful Oct4 sync, elapsed 24h eligibility and
all three Deployment generations/readiness. Native read-only checks pass. Elapsed
time and healthy snapshots are explicitly not gap-sensitive continuous-observation
proof. The gate requires authenticated owner acceptance for the dedicated release
principal, custody/revocation/denials, independently trusted receipts, real
continuous sampling, source CAS/single-flight/restart, retention, Temporal/audit
sink/invariants and successful failed-health rollback before returning ready.
Nine fixture tests (including forged trust and substantive scope failures) pass.
No release identity or trusted signer is created by this gate.
Owner evidence is still absent: `activity-core/docs/release-broker.md` explicitly
records its modules as not activated in production, and
`activity-core/docs/gitops-release.md` retains the actual release-identity and
rollback requirements. ACTIVITY-WP-0042's accepted scheduling boundary remains
scheduling-only; `docs/platform-recovery-scheduling-plan.md` does not admit a
release principal or new mutating recovery operation. D2 resolves the founder
question but does not supply those machine proofs. Therefore wait on the existing
ACTIVITY-WP-0041-T03 once; no new `needs_human` flag or per-item permission request.
Cross-owner case and checkpoint:
`docs/evidence/2026-10-11-activity-promotion-readiness/coordination-case.json`.
Read-only receipt: the same directory's `readiness.json` and `validation.json`.
No worker was injected or foreign task changed. Next action: owner supplies
authenticated native acceptance and trusted issuer binding, then rerun the gate
before bounded dispatcher activation. No child source/Argo automation candidate
was changed, and this wait does not authorize direct automated sync.
## Make registry retention aware of digest-pinned releases
```task