Bind concrete protected release executor and final owner-reviewed decision packet
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
This commit is contained in:
parent
9268c9ac0b
commit
bc6494cd1b
118 changed files with 26156 additions and 46 deletions
|
|
@ -9,13 +9,20 @@
|
|||
| Kind | ID | Status | Lane | Source |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| workplan | INFD-WP-ADHOC-2026-10-03 | finished | — | workplans/ADHOC-2026-10-03.md |
|
||||
| workplan | INFD-WP-ADHOC-2026-10-11 | finished | — | workplans/ADHOC-2026-10-11.md |
|
||||
| workplan | INFD-WP-0003 | finished | — | workplans/INFD-WP-0003-my-decisions-overview.md |
|
||||
| workplan | INFD-WP-0005 | finished | — | workplans/INFD-WP-0005-frictionless-decision-intake.md |
|
||||
| workplan | INFD-WP-0006 | finished | — | workplans/INFD-WP-0006-fresh-review-authentication.md |
|
||||
| workplan | INFD-WP-0007 | finished | — | workplans/INFD-WP-0007-decision-lifecycle-service.md |
|
||||
| workplan | INFD-WP-0008 | backlog | — | workplans/INFD-WP-0008-lifecycle-expansion-contracts.md |
|
||||
| workplan | INFD-WP-0009 | active | — | workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md |
|
||||
| task | INFD-WP-ADHOC-2026-10-03-T01 | done | — | workplans/ADHOC-2026-10-03.md |
|
||||
| task | INFD-WP-ADHOC-2026-10-03-T02 | done | — | workplans/ADHOC-2026-10-03.md |
|
||||
| task | INFD-WP-ADHOC-2026-10-11-T01 | done | — | workplans/ADHOC-2026-10-11.md |
|
||||
| task | INFD-WP-ADHOC-2026-10-11-T02 | done | — | workplans/ADHOC-2026-10-11.md |
|
||||
| task | INFD-WP-ADHOC-2026-10-11-T03 | done | — | workplans/ADHOC-2026-10-11.md |
|
||||
| task | INFD-WP-ADHOC-2026-10-11-T04 | done | — | workplans/ADHOC-2026-10-11.md |
|
||||
| task | INFD-WP-ADHOC-2026-10-11-T05 | done | — | workplans/ADHOC-2026-10-11.md |
|
||||
| task | INFD-WP-0003-T01 | done | — | workplans/INFD-WP-0003-my-decisions-overview.md |
|
||||
| task | INFD-WP-0003-T02 | done | — | workplans/INFD-WP-0003-my-decisions-overview.md |
|
||||
| task | INFD-WP-0003-T03 | done | — | workplans/INFD-WP-0003-my-decisions-overview.md |
|
||||
|
|
@ -43,6 +50,11 @@
|
|||
| task | INFD-WP-0008-T02 | todo | — | workplans/INFD-WP-0008-lifecycle-expansion-contracts.md |
|
||||
| task | INFD-WP-0008-T03 | todo | — | workplans/INFD-WP-0008-lifecycle-expansion-contracts.md |
|
||||
| task | INFD-WP-0008-T04 | todo | — | workplans/INFD-WP-0008-lifecycle-expansion-contracts.md |
|
||||
| task | INFD-WP-0009-T01 | done | — | workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md |
|
||||
| task | INFD-WP-0009-T02 | done | — | workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md |
|
||||
| task | INFD-WP-0009-T03 | done | — | workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md |
|
||||
| task | INFD-WP-0009-T04 | progress | — | workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md |
|
||||
| task | INFD-WP-0009-T05 | todo | — | workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md |
|
||||
| intake | INFD-IN-0001 | closed | blue | intakes/intakes.md |
|
||||
| intake | INFD-IN-0002 | closed | blue | intakes/intakes.md |
|
||||
| intake | INFD-IN-0003 | closed | blue | intakes/intakes.md |
|
||||
|
|
@ -51,3 +63,4 @@
|
|||
| intake | INFD-IN-0006 | closed | blue | intakes/intakes.md |
|
||||
| intake | INFD-IN-0007 | open | blue | intakes/intakes.md |
|
||||
| intake | INFD-IN-0008 | open | blue | intakes/intakes.md |
|
||||
| intake | INFD-IN-0009 | open | blue | intakes/intakes.md |
|
||||
|
|
|
|||
|
|
@ -4,4 +4,6 @@ Actual CI task11484/run3 at3e4bcb26 published immutable763c. The registry proof,
|
|||
|
||||
This stage prepares owner admission/service source candidates, protected native backup/restore protocol and20document offline-valid informed-decision memo. Native workload remains7f5/config6c. No native backup/export/restore, image change or human approval occurred. Initial failed CI/native preflight evidence remains in owner history. The original36path7c packet is fully archived and remains refinement-required, not approved. The amended gate adds pre-open stdlib readonlyschema5/integrity/count checks, explicitlocal/remote optimizationrefusal and actualCM/PVC UID/content/custody seals. The immutable original native capture stays sealed; future preflight requires unique output outside the sealed packet and owner source tree.
|
||||
|
||||
The memo's actual rawscan attachment plus hash-linked rawSBOM/base scan totalamended boundedpacketbytes (under256KiB); source/image receipt binds raw evidence filenames and hashes. Full owner source manifest includes all raw evidence and helper/tests. Source preparation or local checks do not approve native execution.
|
||||
The memo directly attaches exact execution-bundle.json in place of the rawscan, with unchanged rawscan/SBOM/base scan hash-linked by published-verification.json; twenty documents remain under256KiB; source/image receipt binds raw evidence filenames and hashes. Full owner source manifest includes all raw evidence and helper/tests. Source preparation or local checks do not approve native execution.
|
||||
|
||||
The original78pathb1 packet is archived under initial-b1e3e66b with original manifest and exact source map. No previously recorded capture or product/Platform review is relabelled as review of this new packet. Exact23path mechanical helper review agreement is separate from founder approval. The all-phase deadline, isolated UID0 initializer, four Git blobs, rollback-verify and native_provider=false limitation are explicitly refined in the new decision packet/protocol.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"source_hash_negative_cases": [
|
||||
{
|
||||
"case": "executor:authority_journal.py",
|
||||
"refused_before_authority_or_dispatch": true
|
||||
},
|
||||
{
|
||||
"case": "case:sealed-native-dependencies.json",
|
||||
"refused_before_authority_or_dispatch": true
|
||||
},
|
||||
{
|
||||
"case": "owner:deploy/lifecycle/kustomization.yaml",
|
||||
"refused_before_authority_or_dispatch": true
|
||||
},
|
||||
{
|
||||
"case": "owner:deploy/lifecycle/registries.candidate.json",
|
||||
"refused_before_authority_or_dispatch": true
|
||||
}
|
||||
],
|
||||
"combined_manifest_hashes_pass": true,
|
||||
"exact_reviewed_23_helper_paths_pass": true,
|
||||
"original_scan_sbom_base_evidence_hashes_pass": true,
|
||||
"all_execution_plan_case_hashes_pass": true,
|
||||
"native_actions_executed": false,
|
||||
"data_backup_export_restore_executed": false
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Requested decision
|
||||
|
||||
Approve the exact purpose-only image rollout and protected real-data backup/restore protocol for the existing Informed Decision service on railiance01. This request is separate from the already approved config-only repair. Only the existing Deployment image changes through the owner's manual Argo workflow, with prune disabled. Runtime ConfigMap `informed-decision-runtime-6c221878d051`, schema5, PVC, credentials, audience, policies, registries, access, replica1 and Recreate strategy remain fixed. Execute by 2026-10-12T23:59:59Z, after refreshed sealed-source/UID/configuration checks and backup/restore gates. Expiry stops authorization for an unstarted release; it does not install a controller or automatically roll back an already released image.
|
||||
Approve the exact purpose-only image rollout and protected real-data backup/restore protocol for the existing Informed Decision service on railiance01. This request is separate from the already approved config-only repair. Only the existing Deployment image changes through the owner's manual Argo workflow, with prune disabled. Runtime ConfigMap `informed-decision-runtime-6c221878d051`, schema5, PVC, credentials, audience, policies, registries, access, replica1 and Recreate strategy remain fixed. Execute by 2026-10-12T23:59:59Z, after refreshed sealed-source/UID/configuration checks and backup/restore gates. All phases, including recovery and verification, must begin before this deadline. If the window is exhausted, stop and obtain a fresh founder decision; this may delay recovery. No timer/controller automatically changes the released image.
|
||||
|
||||
## Artifact and known finding
|
||||
|
||||
|
|
@ -31,3 +31,11 @@ Proceed with this narrow release plus explicit inherited-medium follow-through,
|
|||
## Independent review refinements
|
||||
|
||||
The initial36path/20document packet at manifest7c6738b3 and submissionac41c8ae is preserved in source preparation evidence, with the failed/conditional review. Independent Platform review identified admin auto-migration, optimization bypass, and actual same-name ConfigMap/PVC replacement gaps. The amended packet adds pre-open stdlib read-only schema/integrity/count gates, explicit local/remote optimization refusal, and independently sealed actual native config/PVC custody checks. These are refinements in the same proposal/trial, with no original or amended founder approval claimed.
|
||||
|
||||
## Mechanically bound helper and recovery refinement
|
||||
|
||||
The directly attached execution-bundle.json binds exact supervised helper sources, plan, tests and PENDING authority template. It verifies all four committed owner Kustomize inputs and rejects present automated:{} as well as source overrides. Root must freshly authenticate the exact founder native disposition before every phase; receipt bookkeeping is not an autonomous signed grant. The same proposal/trial preserves the earlier36path7c packet, amended78pathb1 packet and original11file653 helper plus conditional review findings.
|
||||
|
||||
The offline copy uses one UID0/CAP_CHOWN-only initializer confined to the NEW nonce-bound local volume, exact candidate image, networknone/readonlyroot/no-newprivileges/CPU1/128Mi, no host/livePVC/config/token mounts. All following pre-open/admin/post-open checks are UID10001. Post-admin readonly schema5/integrity/counts must match the frozen snapshot and original snapshot SHA must remain unchanged. Rollback dispatch never requires the failing candidate to be Ready or opens its database; seals/source/image pair/admission CAS still gate it. A separate rollback-verify proves recovered old-image Ready1/scoped operation/schema5 retained-current-DB integrity. Same-phase retries are refused after ambiguous outcomes.
|
||||
|
||||
Raw scan/SBOM/base-scan bytes remain retained unchanged, hash-bound by the directly attached published-verification receipt; the bundle replaces only the direct raw scan attachment to stay within twenty documents. Known fixable inherited MEDIUM and T05 follow-through remain visible. Ten installed synthetic checks, including those later on actual placement, explicitly have native_provider=false. Actual provider/PDP authority evidence is a distinct T04 completion gate and is not supplied by these checks. Source preparation basis e0359bcb6cdfad9ab3e868054121fe0cebec2d68 plus9268c9ac0bbee508fe35c0b90dcefef4c24da2f5 is recorded; the final applied owner commit must be pinned before execution.
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,17 @@
|
|||
# Supervised Informed Decision purpose release executor — unapproved preparation
|
||||
|
||||
No native database read, backup/export/restore or workload action has been run. This source implements the reviewed protocol; its additional mechanical details need peer review and an amended hash-bound packet before first human submission. The original78path packet/reviews remain historical technical agreement, not founder approval of this executor.
|
||||
|
||||
Run one phase at a time only after the coordinator has freshly authenticated the exact founder disposition at the existing fixed Informed Decision origin. Root writes the protected0600 fixed files `/tmp/security-infd-purpose-root-authority.json` and `/tmp/security-infd-purpose-native-outcome-latest.json`. The receipt template is PENDING and cannot authorize anything. The helper checks exact nested confirmed person/platform-root ACCEPT version1, original memo identity/current memo SHA, source commit, plan SHA and freshness120seconds. This is supervised receipt bookkeeping, not cryptographic provider verification, a signed grant or agent autonomy promotion. Root/harness supervision remains the authority boundary. Never synthesize an approval receipt from a technical review or caller assertion.
|
||||
|
||||
Invocation after actual approval: `python3 execution/actuator.py --phase <fixed-phase> --root-authority-receipt /tmp/security-infd-purpose-root-authority.json --root-native-outcome /tmp/security-infd-purpose-native-outcome-latest.json --source-revision <exact-final-owner-commit>`. Order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. Rollback is a distinct authorized recovery after a recorded release attempt. Root refreshes actual native acceptance immediately before each phase.
|
||||
|
||||
The private ignored Custodian custody parent `.private-backups` must already exist,0700 owned by the workstation agent user; the exact case child20261011-infd-purpose-r1 is created only after authority checks. Native parent `/data/private/purpose-overlay-r1` is uniquely created by UID10001 for drill/cutover SQLite-consistent snapshots, each0600/nonsymlink/single-link. The attached stdlib readonly checker must report schema5/integrity/counts before any Store/admin on native source or offlineclone. Invalid states/count shapes and all raw child outputs are withheld. Main-only snapshot closure is verified before binary transfer; stdin/stdout snapshot bytes reach only private files or the isolated restore copy, never tool/chat/log output. Streams stop beyond frozen byte count/512MiB; failures retain partial private evidence.
|
||||
|
||||
New private offline volume `infd-purpose-r1-restore-20261011` is created only on the pinned local workstation Docker socket/engine bnt-lap001, with localdriver/nooptions and attemptnonce labels. One-time initializer runs exact763c as UID0 with only CAP_CHOWN, networknone/read-onlyroot/no-newprivileges, one NEW namedvolume mount, no host/livePVC/credential/config mounts. It receives only the protected snapshot on stdin, verifies bytes, sets folder0700/file0600 owned10001. Then UID10001 performs readonly pre-open validation and `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite`, never the service entrypoint. Cleanup compares exact nonce/creation identity and removes only this clone volume, retaining all native/offcluster originals. CPU1/memory128MiB; private offcluster capacity at least1GiB+16MiB and native estimated two/one-snapshot headroom required.
|
||||
|
||||
Every phase fsyncs RUNNING intent before dispatch. Any failure/interruption/ambiguous result remains UNCERTAIN; same-phase retry is refused. Separate operator diagnosis and any needed recovery are recorded; neither snapshots nor unresolved/new records are removed to make checks green. Frozen snapshot/clone counters must agree; live post-cutover/rollback counters can include legitimate concurrent commits/state transitions.
|
||||
|
||||
Existing Application UID and actual Deployment/Pod/CM/PVC custody/source are checked. All four owner render Git blobs must match; overrides/plugins/multiple sources and even automated:{} are rejected. The existing Application.operation API is used (native argocd CLI is absent), with server dry-run, resourceVersion/UID/source tests, one Deployment only, prune=false. Dispatch acknowledgment is not rollout completion. Verify requires exact succeeded operation/controller generation/Ready1, same schema5 DB, actual installed hash/mode/UID and10purpose checks plus bounded localhosthealth/readiness. Purpose transport remains synthetic and is explicitly not a native PDP authority test. Rollback pins prior7db/7f5 through the same scoped workflow and retains the current live database; it never restores an older snapshot over later writes.
|
||||
|
||||
Twelve synthetic tests pass against frozen case metadata: authority/expiry/actor/ambiguity refusals, crash intent/no retry/order, credential-output withholding, private bounded binarycopy, volume recreation cleanup refusal, source/automation/CM/PVC/Ready drift, pre-open gate refusal and exact Deployment-only operation/dry-run. These are source tests, not native backup or release proof.
|
||||
|
|
@ -0,0 +1,343 @@
|
|||
"""One fixed supervised phase; never run this during source preparation."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import selectors
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
if sys.flags.optimize:
|
||||
raise SystemExit('optimized interpreter refused')
|
||||
|
||||
PHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',
|
||||
'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback')
|
||||
|
||||
|
||||
def require(value, reason):
|
||||
if not value:
|
||||
raise ValueError(reason)
|
||||
|
||||
|
||||
def sha(path):
|
||||
digest = hashlib.sha256()
|
||||
with Path(path).open('rb') as stream:
|
||||
for block in iter(lambda: stream.read(1024**2), b''):
|
||||
digest.update(block)
|
||||
return digest.hexdigest()
|
||||
|
||||
|
||||
def private(path, directory=False):
|
||||
info = Path(path).lstat()
|
||||
require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))
|
||||
and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)
|
||||
and (directory or info.st_nlink == 1), 'private owned custody required')
|
||||
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
CASE = ROOT.parent
|
||||
OWNER = Path('/home/worsch/informed-decision')
|
||||
CUSTODIAN = Path('/home/worsch/the-custodian')
|
||||
CUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1'
|
||||
SOCKET = 'unix:///var/run/docker.sock'
|
||||
IMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'
|
||||
VOLUME = 'infd-purpose-r1-restore-20261011'
|
||||
MAX_BYTES = 512 * 1024**2
|
||||
|
||||
|
||||
def run(argv, body=None, timeout=90):
|
||||
return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout)
|
||||
|
||||
|
||||
def json_result(result):
|
||||
try:
|
||||
value = json.loads(result.stdout)
|
||||
except (ValueError, TypeError):
|
||||
raise ValueError('safe phase receipt unavailable; outcome uncertain') from None
|
||||
require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True,
|
||||
'phase did not verify complete; raw output withheld; no retry')
|
||||
permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root',
|
||||
'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly',
|
||||
'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private',
|
||||
'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts',
|
||||
'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision',
|
||||
'resources', 'prune', 'rollout_verified', 'latest_live_database_retained',
|
||||
'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained',
|
||||
'private_copy_verified', 'installed_purpose_checks', 'policy_sha256',
|
||||
'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe'}
|
||||
require(set(value) <= permitted, 'unexpected output fields withheld')
|
||||
from receipt_safety import counts
|
||||
for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'):
|
||||
if name in value:
|
||||
counts(value[name])
|
||||
for name in ('snapshot_sha256', 'client_diff_sha256'):
|
||||
if name in value:
|
||||
require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld')
|
||||
if 'snapshot_bytes' in value:
|
||||
require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES,
|
||||
'invalid output size withheld')
|
||||
if 'snapshot_file' in value:
|
||||
require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld')
|
||||
return value
|
||||
|
||||
|
||||
def docker(argv, body=None, timeout=120):
|
||||
return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv,
|
||||
body=body, timeout=timeout)
|
||||
|
||||
|
||||
def remote(phase, revision, approved):
|
||||
# Fixed module imported only after main verifies every executor source hash.
|
||||
from native_program import PROGRAM
|
||||
payload = {'phase': phase, 'source_revision': revision, 'approval': approved,
|
||||
'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()),
|
||||
'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()),
|
||||
'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()),
|
||||
'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),
|
||||
'receipt_safety': (ROOT / 'receipt_safety.py').read_text(),
|
||||
'purpose_checks': (CASE / 'check_installed.py').read_text(),
|
||||
'readonly': (CASE / 'sqlite_readonly.py').read_text()}
|
||||
script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(
|
||||
'__GUARD__', repr((CASE / 'change_guard.py').read_text()))
|
||||
return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200))
|
||||
|
||||
|
||||
def copy_snapshot(phase, revision, approved, journal):
|
||||
metadata = remote(phase, revision, approved)
|
||||
backup_phase = 'drill-backup' if phase == 'drill-copy' else 'cutover-backup'
|
||||
prior = journal.data['phases'][backup_phase]['result']
|
||||
for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'):
|
||||
require(metadata[key] == prior[key], 'closed frozen snapshot changed')
|
||||
name = metadata['snapshot_file']
|
||||
require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES,
|
||||
'fixed bounded snapshot required')
|
||||
pod = metadata['pod_name']
|
||||
require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required')
|
||||
local = CUSTODY / name
|
||||
fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)
|
||||
# Binary snapshot stdout goes only to a private file, never tool/chat/log output.
|
||||
# Snapshot schema/count metadata was validated before opening this destination.
|
||||
with os.fdopen(fd, 'wb') as destination:
|
||||
command = ('kubectl exec -n informed-decision ' + pod +
|
||||
' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name)
|
||||
transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL)
|
||||
selector = selectors.DefaultSelector()
|
||||
selector.register(transfer.stdout, selectors.EVENT_READ)
|
||||
deadline = time.monotonic() + 150
|
||||
received = 0
|
||||
try:
|
||||
while True:
|
||||
remaining = deadline - time.monotonic()
|
||||
require(remaining > 0 and selector.select(remaining), 'private transfer timed out')
|
||||
block = os.read(transfer.stdout.fileno(), 1024**2)
|
||||
if not block:
|
||||
break
|
||||
received += len(block)
|
||||
require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES,
|
||||
'private copy exceeds frozen snapshot size')
|
||||
destination.write(block)
|
||||
transfer.wait(timeout=max(1, deadline - time.monotonic()))
|
||||
finally:
|
||||
selector.close()
|
||||
transfer.stdout.close()
|
||||
if transfer.poll() is None:
|
||||
transfer.kill()
|
||||
transfer.wait()
|
||||
destination.flush()
|
||||
os.fsync(destination.fileno())
|
||||
private(local)
|
||||
require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes']
|
||||
and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry')
|
||||
# Re-read identity/hash after transfer. This is verification, not a write retry.
|
||||
after = remote(phase, revision, approved)
|
||||
require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'],
|
||||
'source identity/snapshot changed during transfer')
|
||||
return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False}
|
||||
|
||||
|
||||
def offline_verify(journal):
|
||||
from receipt_safety import counts
|
||||
snapshot = CUSTODY / 'drill.sqlite'
|
||||
private(snapshot)
|
||||
previous = journal.data['phases']['drill-copy']['result']
|
||||
require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed')
|
||||
identity = docker(['info', '--format', '{{json .Name}}'])
|
||||
require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',
|
||||
'local offline Docker engine identity changed')
|
||||
listed = docker(['volume', 'ls', '--format', '{{.Name}}'])
|
||||
require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),
|
||||
'disposable volume absence not verified')
|
||||
nonce = journal.data['phases']['offline-verify']['attempt_id']
|
||||
labels = {'informed-decision.case': 'infd-purpose-20261011-r1',
|
||||
'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce}
|
||||
created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1',
|
||||
'--label', 'informed-decision.attempt=' + nonce,
|
||||
'--label', 'informed-decision.use=offline-restore-only', VOLUME])
|
||||
require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry')
|
||||
inspected = docker(['volume', 'inspect', VOLUME])
|
||||
require(inspected.returncode == 0, 'new volume identity unavailable')
|
||||
volume = json.loads(inspected.stdout)
|
||||
require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels
|
||||
and volume[0].get('Driver') == 'local' and not volume[0].get('Options')
|
||||
and volume[0].get('Scope') == 'local', 'new isolated volume identity changed')
|
||||
identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')}
|
||||
journal.note('offline-verify', 'created_volume_identity', identity)
|
||||
# One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume.
|
||||
# No host/live PVC/config/token mount exists; this detail needs packet review.
|
||||
initializer = """import hashlib,os,stat,sys
|
||||
if sys.flags.optimize:raise RuntimeError('optimized interpreter refused')
|
||||
folder='/restore';expected=EXPECTED
|
||||
if os.listdir(folder):raise ValueError('new empty private volume required')
|
||||
os.chmod(folder,0o700)
|
||||
fd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600)
|
||||
digest=hashlib.sha256();size=0
|
||||
with os.fdopen(fd,'wb') as target:
|
||||
while True:
|
||||
block=sys.stdin.buffer.read(1024**2)
|
||||
if not block:break
|
||||
size+=len(block)
|
||||
if size>512*1024**2:raise ValueError('private restore size exceeds bound')
|
||||
target.write(block);digest.update(block)
|
||||
target.flush();os.fsync(target.fileno())
|
||||
if digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs')
|
||||
os.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001)
|
||||
print('{"all_checks_pass":true,"private_copy_verified":true}')
|
||||
""".replace('EXPECTED', repr(previous['snapshot_sha256']))
|
||||
with snapshot.open('rb') as source:
|
||||
argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET,
|
||||
'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',
|
||||
'--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN',
|
||||
'--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore',
|
||||
'--entrypoint', 'python', IMAGE, '-c', initializer]
|
||||
copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150)
|
||||
json_result(copied)
|
||||
options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',
|
||||
'--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges',
|
||||
'--mount', 'type=volume,src=' + VOLUME + ',dst=/restore']
|
||||
readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],
|
||||
(CASE / 'sqlite_readonly.py').read_text())
|
||||
require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store')
|
||||
checked = counts(json.loads(readonly.stdout))
|
||||
require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ')
|
||||
admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE,
|
||||
'inspect', '--db', '/restore/review.sqlite'])
|
||||
require(admin.returncode == 0, 'offline admin result uncertain')
|
||||
admin_counts = json.loads(admin.stdout)
|
||||
require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')},
|
||||
'offline admin changed frozen snapshot counters')
|
||||
return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked,
|
||||
'created_volume_identity': identity,
|
||||
'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False,
|
||||
'service_entrypoint_started': False, 'original_snapshot_retained': True}
|
||||
|
||||
|
||||
def cleanup_offline(journal):
|
||||
inspected = docker(['volume', 'inspect', VOLUME])
|
||||
require(inspected.returncode == 0, 'owned disposable volume identity unverified')
|
||||
value = json.loads(inspected.stdout)
|
||||
expected = journal.data['phases']['offline-verify']['result']['created_volume_identity']
|
||||
require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected
|
||||
and not value[0].get('Options'), 'volume ownership/recreation changed')
|
||||
removed = docker(['volume', 'rm', VOLUME])
|
||||
require(removed.returncode == 0 and removed.stdout.strip() == VOLUME
|
||||
and docker(['volume', 'inspect', VOLUME]).returncode != 0,
|
||||
'cleanup outcome ambiguous; do not retry')
|
||||
return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME,
|
||||
'native_and_offcluster_original_snapshots_retained': True}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--phase', choices=PHASES, required=True)
|
||||
parser.add_argument('--root-authority-receipt', type=Path, required=True)
|
||||
parser.add_argument('--root-native-outcome', type=Path, required=True)
|
||||
parser.add_argument('--source-revision', required=True)
|
||||
args = parser.parse_args()
|
||||
require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json')
|
||||
and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'),
|
||||
'fixed supervised receipt paths required')
|
||||
require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required')
|
||||
# Verify all prepared executor/input bytes before reading authority or dispatching.
|
||||
plan = json.loads((ROOT / 'execution-plan.json').read_text())
|
||||
require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'},
|
||||
'fixed executor sources required')
|
||||
require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json',
|
||||
'deploy/lifecycle/service.candidate.json',
|
||||
'deploy/lifecycle/kustomization.yaml',
|
||||
'deploy/lifecycle/registries.candidate.json'},
|
||||
'fixed owner image sources required')
|
||||
for relative, digest in plan['executor_files'].items():
|
||||
target = ROOT / relative
|
||||
require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed')
|
||||
for relative, digest in plan['case_files'].items():
|
||||
require(not Path(relative).is_absolute() and '..' not in Path(relative).parts,
|
||||
'case source path escaped')
|
||||
target = CASE / relative
|
||||
require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed')
|
||||
for relative, digest in plan['owner_source_files'].items():
|
||||
target = OWNER / relative
|
||||
require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed')
|
||||
committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative],
|
||||
capture_output=True)
|
||||
require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest,
|
||||
'committed owner render source differs from approved inputs')
|
||||
head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD'])
|
||||
require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs')
|
||||
from authority_journal import Journal, authority
|
||||
private(args.root_authority_receipt)
|
||||
private(args.root_native_outcome)
|
||||
receipt = json.loads(args.root_authority_receipt.read_text())
|
||||
require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed')
|
||||
require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'),
|
||||
'root verified executor plan differs')
|
||||
approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'),
|
||||
args.source_revision, args.phase)
|
||||
parent = CUSTODY.parent
|
||||
private(parent, directory=True)
|
||||
ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')])
|
||||
require(ignored.returncode == 0, 'offcluster custody is not ignored')
|
||||
if not CUSTODY.exists():
|
||||
require(args.phase == 'drill-backup', 'first approved phase must create unique private custody')
|
||||
os.mkdir(CUSTODY, 0o700)
|
||||
private(CUSTODY, directory=True)
|
||||
capacity = os.statvfs(CUSTODY)
|
||||
require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2,
|
||||
'independent protected custody headroom insufficient')
|
||||
os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True)
|
||||
private(CUSTODY / 'empty-docker-config', directory=True)
|
||||
require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty')
|
||||
journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision,
|
||||
'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json')})
|
||||
try:
|
||||
journal.start(args.phase, approved) # fsynced RUNNING before any phase effect.
|
||||
if args.phase in ('drill-copy', 'cutover-copy'):
|
||||
result = copy_snapshot(args.phase, args.source_revision, approved, journal)
|
||||
elif args.phase == 'offline-verify':
|
||||
result = offline_verify(journal)
|
||||
elif args.phase == 'cleanup-offline':
|
||||
result = cleanup_offline(journal)
|
||||
else:
|
||||
result = remote(args.phase, args.source_revision, approved)
|
||||
journal.finish(args.phase, result)
|
||||
print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes.
|
||||
except BaseException as error:
|
||||
safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__,
|
||||
'failure': 'fixed phase outcome uncertain; original evidence retained; no retry',
|
||||
'raw_output_withheld': True}
|
||||
if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING':
|
||||
journal.finish(args.phase, safe)
|
||||
print(json.dumps(safe))
|
||||
raise SystemExit(1) from None
|
||||
finally:
|
||||
journal.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception:
|
||||
raise SystemExit('supervised execution refused before phase; raw output withheld') from None
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
"""Supervised receipt bookkeeping, not an authenticated approval provider."""
|
||||
import datetime
|
||||
import fcntl
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
import stat
|
||||
import uuid
|
||||
|
||||
FOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}
|
||||
MEMO_ID = 'infd-20261011-purpose-overlay-r1'
|
||||
PROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1'
|
||||
PHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',
|
||||
'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback')
|
||||
|
||||
|
||||
def require(value, reason):
|
||||
if not value:
|
||||
raise ValueError(reason)
|
||||
|
||||
|
||||
def sha(path):
|
||||
digest = hashlib.sha256()
|
||||
with Path(path).open('rb') as stream:
|
||||
for block in iter(lambda: stream.read(1024**2), b''):
|
||||
digest.update(block)
|
||||
return digest.hexdigest()
|
||||
|
||||
|
||||
def private(path, directory=False):
|
||||
info = Path(path).lstat()
|
||||
require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))
|
||||
and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)
|
||||
and (directory or info.st_nlink == 1), 'private owned custody required')
|
||||
|
||||
|
||||
def authority(receipt, outcome, memo_sha, source_revision, phase, now=None):
|
||||
"""Root must freshly verify native outcome at fixed ORIGIN outside this helper.
|
||||
|
||||
Receipt files/flags are not signed grants. This function checks the exact
|
||||
supervised receipt relation; existing harness/founder authority remains the
|
||||
actual permission boundary. It never authenticates a caller as human.
|
||||
"""
|
||||
now = now or datetime.datetime.now(datetime.timezone.utc)
|
||||
require(phase in PHASES, 'fixed phase required')
|
||||
require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID
|
||||
and receipt.get('memo_version') == 1 and receipt.get('memo_sha256') == memo_sha
|
||||
and receipt.get('source_revision') == source_revision
|
||||
and receipt.get('activation') == 'APPROVED'
|
||||
and receipt.get('authority_mode') == 'ADMINISTER'
|
||||
and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision'
|
||||
and receipt.get('verification_method') == 'root-fixed-origin-native-readback'
|
||||
and receipt.get('runtime_authenticated_grant') is False,
|
||||
'exact externally verified supervised receipt required')
|
||||
verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00'))
|
||||
require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120,
|
||||
'fresh root native readback required before every phase')
|
||||
deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00')
|
||||
require(now < deadline, 'approved execution window expired')
|
||||
require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False
|
||||
and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current')
|
||||
review_id = outcome['review']['memo_id']
|
||||
require(review_id == receipt.get('review_memo_id'), 'native review identity changed')
|
||||
accepted = [x for x in outcome.get('dispositions', [])
|
||||
if x.get('submission_state') == 'confirmed'
|
||||
and x.get('disposition', {}).get('verb') == 'accept'
|
||||
and x['disposition'].get('memo_version') == 1]
|
||||
require(len(accepted) == 1, 'one confirmed founder acceptance required')
|
||||
accepted = accepted[0]['disposition']
|
||||
require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id
|
||||
and accepted.get('approval_id') == receipt.get('approval_id')
|
||||
and accepted.get('id') == receipt.get('disposition_id')
|
||||
and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch')
|
||||
require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None
|
||||
and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None
|
||||
and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None,
|
||||
'native disposition identifiers are malformed')
|
||||
accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00'))
|
||||
require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded')
|
||||
return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')}
|
||||
|
||||
|
||||
class Journal:
|
||||
def __init__(self, parent, identity):
|
||||
self.parent = Path(parent)
|
||||
private(self.parent, directory=True)
|
||||
self.path = self.parent / 'execution-journal.json'
|
||||
self.lock = os.open(self.parent / 'execution.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600)
|
||||
fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
private(self.parent / 'execution.lock')
|
||||
if self.path.exists():
|
||||
private(self.path)
|
||||
self.data = json.loads(self.path.read_text())
|
||||
require(self.data['identity'] == identity, 'journal case/source identity changed')
|
||||
else:
|
||||
self.data = {'identity': identity, 'phases': {}}
|
||||
self.save()
|
||||
|
||||
def save(self):
|
||||
temporary = self.parent / 'execution-journal.new'
|
||||
fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600)
|
||||
try:
|
||||
with os.fdopen(fd, 'w') as stream:
|
||||
json.dump(self.data, stream, indent=2)
|
||||
stream.write('\n')
|
||||
stream.flush()
|
||||
os.fsync(stream.fileno())
|
||||
os.replace(temporary, self.path)
|
||||
directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY)
|
||||
try:
|
||||
os.fsync(directory)
|
||||
finally:
|
||||
os.close(directory)
|
||||
except BaseException:
|
||||
# Retain evidence rather than overwriting an uncertain durable intent.
|
||||
raise
|
||||
|
||||
def start(self, phase, approval):
|
||||
require(phase not in self.data['phases'], 'already attempted phase; no retry')
|
||||
predecessors = dict(zip(PHASES[1:-1], PHASES[:-2]))
|
||||
if phase in predecessors:
|
||||
require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE',
|
||||
'preceding phase is not verified complete')
|
||||
if phase == 'rollback':
|
||||
require('release' in self.data['phases'], 'rollback requires a recorded release attempt')
|
||||
self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval,
|
||||
'attempt_id': str(uuid.uuid4()),
|
||||
'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()}
|
||||
self.save()
|
||||
|
||||
def note(self, phase, key, value):
|
||||
require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing')
|
||||
self.data['phases'][phase][key] = value
|
||||
self.save()
|
||||
|
||||
def finish(self, phase, result):
|
||||
entry = self.data['phases'][phase]
|
||||
require(entry['state'] == 'RUNNING', 'phase intent missing')
|
||||
entry['result'] = result
|
||||
entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN'
|
||||
self.save()
|
||||
|
||||
def close(self):
|
||||
os.close(self.lock)
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"kind": "informed-decision.supervised-mechanical-release-plan",
|
||||
"version": 1,
|
||||
"proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"trial_id": "infd-purpose-20261011-r1",
|
||||
"state": "prepared-unapproved",
|
||||
"executor_files": {
|
||||
"actuator.py": "faf019cd011dee1032d3f309e85b1f1b0bf5f333d6e279701c3f7e233d54fe23",
|
||||
"authority_journal.py": "55e441b1af7288540c31ea4733c3471559a2100a26fae8b6b0ed415e04d469a5",
|
||||
"native_program.py": "3ad4fe28d0556a001f6334f3f8267d1e21d76e17db9765d3cc35b679a9db9ec5",
|
||||
"receipt_safety.py": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b"
|
||||
},
|
||||
"case_files": {
|
||||
"change_guard.py": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be",
|
||||
"sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38",
|
||||
"preflight-inputs.json": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06",
|
||||
"sealed-live-deployment.json": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362",
|
||||
"sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369",
|
||||
"candidate-deployment.json": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e",
|
||||
"rollback-deployment.json": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121",
|
||||
"check_installed.py": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad",
|
||||
"published-verification.json": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2",
|
||||
"security-summary.json": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44"
|
||||
},
|
||||
"owner_source_files": {
|
||||
"deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55",
|
||||
"deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4",
|
||||
"deploy/lifecycle/kustomization.yaml": "1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47",
|
||||
"deploy/lifecycle/registries.candidate.json": "9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e"
|
||||
},
|
||||
"candidate_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"prior_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"source_revision": "must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs",
|
||||
"phases": [
|
||||
"drill-backup",
|
||||
"drill-copy",
|
||||
"offline-verify",
|
||||
"cleanup-offline",
|
||||
"cutover-backup",
|
||||
"cutover-copy",
|
||||
"release",
|
||||
"verify",
|
||||
"rollback"
|
||||
],
|
||||
"authorization": "fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant",
|
||||
"execute_by": "2026-10-12T23:59:59Z",
|
||||
"raw_output_withheld": true,
|
||||
"native_data_or_workload_action_executed": false
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"prior_reviewed_packet_manifest_sha256": "b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033",
|
||||
"kind": "mechanical-actuator-packet-refinement-required-before-first-human-post",
|
||||
"changes": [
|
||||
"Hash-bind all executor bytes/executionplan in amended20doc packet, preserve prior78path technical reviews as history",
|
||||
"Require fresh root fixed-origin confirmed founder receipt before each phase, no signed autonomous grant",
|
||||
"Bind all four committed owner Kustomize input blobs and reject Application source overrides or automated:{}",
|
||||
"Explicit new isolated offline volume UID0/CAP_CHOWN initializer, no host/livePVC/token/config mounts, bounded512MiB private snapshot stream and namedVolume nonce ownership",
|
||||
"Durable per-phase RUNNING before action; no same-phase retries after failures/crash, distinct supervised same-schema rollback retains latestDB",
|
||||
"Actual native pre-open readonlyschema5/integrity/count gate before backup/admin, actual Pod/CM/PVC/source seals, offline pre-open check before admininspect, nativeinstalled10syntheticpurpose checks+boundedlocalhosthealth aftercontrollercompletion"
|
||||
],
|
||||
"unchanged": [
|
||||
"immutable763c purposeonly image",
|
||||
"ConfigMap6c/runtime/policy pins/audiences/credentials",
|
||||
"Deployment-only manualArgo scoped operation/prunefalse",
|
||||
"existingPVC/singlewriter/Recreate/schema5",
|
||||
"explicit inherited1fixableMED ownerT05 follow-through"
|
||||
],
|
||||
"native_action_executed": false,
|
||||
"founder_approval": false
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
"""Only structural count/hash receipts can leave the private execution phase."""
|
||||
def counts(value):
|
||||
if (set(value) != {'schema_version', 'lifecycle', 'outbox', 'submissions', 'integrity',
|
||||
'read_only_pre_open', 'store_constructed'}
|
||||
or value['schema_version'] != 5 or value['integrity'] != 'ok'
|
||||
or value['read_only_pre_open'] is not True or value['store_constructed'] is not False
|
||||
or set(value['lifecycle']) != {'records', 'events', 'pending'}
|
||||
or not set(value['outbox']) <= {'pending', 'delivered', 'blocked'}
|
||||
or not set(value['submissions']) <= {'prepared', 'in_flight', 'confirmed', 'unresolved'}):
|
||||
raise ValueError('count-only receipt shape/state refused; values withheld')
|
||||
for group in ('lifecycle', 'outbox', 'submissions'):
|
||||
if any(type(number) is not int or number < 0 or number > 10**12
|
||||
for number in value[group].values()):
|
||||
raise ValueError('count-only receipt values refused')
|
||||
return value
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"memo_id": "infd-20261011-purpose-overlay-r1",
|
||||
"memo_version": 1,
|
||||
"memo_sha256": null,
|
||||
"source_revision": null,
|
||||
"activation": "PENDING",
|
||||
"authority_mode": "ADMINISTER",
|
||||
"target": "realm:kubernetes/railiance01/informed-decision",
|
||||
"verification_method": "root-fixed-origin-native-readback",
|
||||
"runtime_authenticated_grant": false,
|
||||
"verified_at": null,
|
||||
"accepted_at": null,
|
||||
"review_memo_id": null,
|
||||
"approval_id": null,
|
||||
"disposition_id": null,
|
||||
"native_outcome_sha256": null,
|
||||
"executor_plan_sha256": "4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85"
|
||||
}
|
||||
|
|
@ -0,0 +1,296 @@
|
|||
"""Synthetic custody/transport tests. No native data, Docker or cluster action."""
|
||||
import copy
|
||||
import datetime
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
from contextlib import redirect_stdout
|
||||
|
||||
import actuator
|
||||
from authority_journal import Journal, authority
|
||||
from native_program import PROGRAM
|
||||
from receipt_safety import counts
|
||||
|
||||
CASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release')
|
||||
NOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc)
|
||||
REVISION = 'e' * 40
|
||||
COUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False,
|
||||
'lifecycle': {'records': 3, 'events': 8, 'pending': 1},
|
||||
'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}}
|
||||
|
||||
|
||||
def accepted():
|
||||
approval = '11111111-1111-4111-8111-111111111111'
|
||||
review = 'review-22222222-2222-4222-8222-222222222222'
|
||||
disposition = 'disp-33333333-3333-4333-8333-333333333333'
|
||||
receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1',
|
||||
'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 1,
|
||||
'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED',
|
||||
'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision',
|
||||
'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False,
|
||||
'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z',
|
||||
'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition}
|
||||
outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'},
|
||||
'dispositions': [{'approval_id': None, 'submission_state': 'confirmed',
|
||||
'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review,
|
||||
'approval_id': approval, 'id': disposition,
|
||||
'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'},
|
||||
'at': receipt['accepted_at']}}]}
|
||||
return receipt, outcome
|
||||
|
||||
|
||||
class AuthorityAndCustody(unittest.TestCase):
|
||||
def test_exact_nested_founder_receipt_not_top_level_approval(self):
|
||||
receipt, outcome = accepted()
|
||||
result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-backup', NOW)
|
||||
self.assertEqual(result['approval_id'], receipt['approval_id'])
|
||||
|
||||
def test_pending_stale_wrong_actor_version_and_binding_refuse(self):
|
||||
mutations = [lambda r, o: r.update(activation='PENDING'),
|
||||
lambda r, o: r.update(memo_sha256='changed'),
|
||||
lambda r, o: r.update(source_revision='changed'),
|
||||
lambda r, o: r.update(target='other'),
|
||||
lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'),
|
||||
lambda r, o: r.update(verification_method='caller-asserted'),
|
||||
lambda r, o: r.update(runtime_authenticated_grant=True),
|
||||
lambda r, o: o['review'].update(stale=True),
|
||||
lambda r, o: o['review'].update(intake_state='pending'),
|
||||
lambda r, o: o['dispositions'][0].update(submission_state='unresolved'),
|
||||
lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=2),
|
||||
lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}),
|
||||
lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))]
|
||||
for mutate in mutations:
|
||||
with self.subTest(mutate=mutate):
|
||||
r, o = accepted()
|
||||
mutate(r, o)
|
||||
with self.assertRaises(ValueError):
|
||||
authority(r, o, 'a' * 64, REVISION, 'release', NOW)
|
||||
|
||||
def test_expired_window_and_unknown_phase_refuse(self):
|
||||
r, o = accepted()
|
||||
with self.assertRaises(ValueError):
|
||||
authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW)
|
||||
late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc)
|
||||
r['verified_at'] = late.isoformat()
|
||||
with self.assertRaises(ValueError):
|
||||
authority(r, o, 'a' * 64, REVISION, 'rollback', late)
|
||||
|
||||
def test_durable_intent_precedes_dispatch_and_never_retries(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
parent = Path(directory)
|
||||
os.chmod(parent, 0o700)
|
||||
journal = Journal(parent, {'case': 'fixture'})
|
||||
journal.start('drill-backup', {'approval_id': 'fixture'})
|
||||
self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-backup']['state'], 'RUNNING')
|
||||
journal.close() # simulated crash before result
|
||||
recovered = Journal(parent, {'case': 'fixture'})
|
||||
with self.assertRaises(ValueError):
|
||||
recovered.start('drill-backup', {})
|
||||
with self.assertRaises(ValueError):
|
||||
recovered.start('drill-copy', {})
|
||||
recovered.close()
|
||||
|
||||
def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
os.chmod(directory, 0o700)
|
||||
j = Journal(directory, {'case': 'fixture'})
|
||||
with self.assertRaises(ValueError):
|
||||
j.start('release', {})
|
||||
for phase in actuator.PHASES[:-3]:
|
||||
j.start(phase, {})
|
||||
j.finish(phase, {'all_checks_pass': True})
|
||||
j.start('release', {})
|
||||
j.finish('release', {'all_checks_pass': False})
|
||||
with self.assertRaises(ValueError):
|
||||
j.start('release', {})
|
||||
with self.assertRaises(ValueError):
|
||||
j.start('verify', {})
|
||||
j.start('rollback', {})
|
||||
j.finish('rollback', {'all_checks_pass': True})
|
||||
j.close()
|
||||
|
||||
def test_secret_or_unknown_child_output_is_withheld(self):
|
||||
for body in ('not-json', '{"all_checks_pass":true,"token":"private-value"}',
|
||||
'{"all_checks_pass":true,"snapshot_readonly":{"schema_version":5}}'):
|
||||
with self.assertRaises(ValueError):
|
||||
actuator.json_result(subprocess.CompletedProcess([], 0, body, ''))
|
||||
wrong = copy.deepcopy(COUNT)
|
||||
wrong['outbox'] = {'private-row-value': 1}
|
||||
with self.assertRaises(ValueError):
|
||||
counts(wrong)
|
||||
counts(COUNT) # blocked/unresolved counts are not required to be zero.
|
||||
|
||||
def test_binary_copy_is_bounded_private_and_never_echoed(self):
|
||||
blob = b'synthetic private fixture bytes'
|
||||
digest = __import__('hashlib').sha256(blob).hexdigest()
|
||||
metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob),
|
||||
'snapshot_sha256': digest, 'snapshot_readonly': COUNT,
|
||||
'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'}
|
||||
journal = type('FixtureJournal', (), {'data': {'phases': {'drill-backup': {'result': metadata}}}})()
|
||||
real_popen = subprocess.Popen
|
||||
for extra in (b'', b'oversized'):
|
||||
with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder:
|
||||
os.chmod(folder, 0o700)
|
||||
output = io.StringIO()
|
||||
|
||||
def child(*args, **kwargs):
|
||||
return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
|
||||
|
||||
with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \
|
||||
patch('subprocess.Popen', side_effect=child), redirect_stdout(output):
|
||||
if extra:
|
||||
with self.assertRaises(ValueError):
|
||||
actuator.copy_snapshot('drill-copy', REVISION, {}, journal)
|
||||
else:
|
||||
result = actuator.copy_snapshot('drill-copy', REVISION, {}, journal)
|
||||
self.assertTrue(result['off_cluster_private_copy_verified'])
|
||||
self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob)
|
||||
self.assertEqual(output.getvalue(), '')
|
||||
self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600)
|
||||
|
||||
def test_recreated_offline_volume_cannot_be_deleted(self):
|
||||
identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'}
|
||||
journal = type('FixtureJournal', (), {'data': {'phases': {
|
||||
'offline-verify': {'result': {'created_volume_identity': identity}}}}})()
|
||||
inspected = [{**identity, 'CreatedAt': 'recreated'}]
|
||||
with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked:
|
||||
with self.assertRaises(ValueError):
|
||||
actuator.cleanup_offline(journal)
|
||||
self.assertEqual(mocked.call_count, 1)
|
||||
|
||||
|
||||
class FixedNativeProgram(unittest.TestCase):
|
||||
def fixture(self):
|
||||
sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text())
|
||||
live = copy.deepcopy(sealed)
|
||||
live['metadata'].update(generation=42)
|
||||
live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42}
|
||||
dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text())
|
||||
cm = copy.deepcopy(dependencies['configmap'])
|
||||
cm.pop('canonical_data_sha256')
|
||||
service = json.loads((CASE / 'candidate-deployment.json').read_text())
|
||||
source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text())
|
||||
cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data']
|
||||
pvc = copy.deepcopy(dependencies['pvc'])
|
||||
pvc['status'] = {'phase': 'Bound'}
|
||||
app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'},
|
||||
'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git',
|
||||
'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'},
|
||||
'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}}
|
||||
objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app}
|
||||
payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed,
|
||||
'dependencies': dependencies, 'candidate': service,
|
||||
'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),
|
||||
'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(),
|
||||
'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()}
|
||||
return objects, payload
|
||||
|
||||
def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False):
|
||||
writes = []
|
||||
calls = []
|
||||
|
||||
def fake(argv, input=None, **kwargs):
|
||||
calls.append(argv)
|
||||
if argv[:2] == ['kubectl', 'get']:
|
||||
kind = argv[2]
|
||||
if kind in objects:
|
||||
body = objects[kind]
|
||||
elif kind == 'pods':
|
||||
body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid',
|
||||
'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]},
|
||||
'spec': objects['deployment']['spec']['template']['spec'],
|
||||
'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]}
|
||||
elif kind == 'replicaset':
|
||||
body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [
|
||||
{'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}}
|
||||
elif kind == 'nodes':
|
||||
body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': {
|
||||
'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'},
|
||||
'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'}
|
||||
for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]}
|
||||
else:
|
||||
raise AssertionError('unexpected fixed metadata route')
|
||||
return subprocess.CompletedProcess(argv, 0, json.dumps(body), '')
|
||||
if argv[:2] == ['kubectl', 'exec']:
|
||||
if schema_refused:
|
||||
return subprocess.CompletedProcess(argv, 1, '', 'withheld')
|
||||
return subprocess.CompletedProcess(argv, 0, json.dumps({
|
||||
'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '')
|
||||
if argv[:2] == ['kubectl', 'apply']:
|
||||
admitted = copy.deepcopy(payload['sealed'])
|
||||
admitted['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE
|
||||
return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '')
|
||||
if argv[:2] == ['kubectl', 'describe']:
|
||||
return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\n cpu 3460m (86%)\n', '')
|
||||
if argv[:2] == ['kubectl', 'diff']:
|
||||
return subprocess.CompletedProcess(argv, 1, '-image: base\n+image: candidate\n', '')
|
||||
if argv[:2] == ['kubectl', 'patch']:
|
||||
if '--dry-run=server' not in argv:
|
||||
writes.append(json.loads(input))
|
||||
if ambiguous:
|
||||
return subprocess.CompletedProcess(argv, 1, '', 'withheld')
|
||||
return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\n', '')
|
||||
raise AssertionError('unexpected command')
|
||||
|
||||
source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(
|
||||
'__GUARD__', repr((CASE / 'change_guard.py').read_text()))
|
||||
output = io.StringIO()
|
||||
with patch('subprocess.run', side_effect=fake), redirect_stdout(output):
|
||||
try:
|
||||
exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'})
|
||||
except (ValueError, SystemExit):
|
||||
pass
|
||||
receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False}
|
||||
return receipt, writes, calls
|
||||
|
||||
def test_only_existing_application_operation_and_deployment_are_requested(self):
|
||||
objects, payload = self.fixture()
|
||||
receipt, writes, calls = self.execute_fake(objects, payload)
|
||||
self.assertTrue(receipt['all_checks_pass'])
|
||||
self.assertFalse(receipt['rollout_verified'])
|
||||
self.assertEqual(len(writes), 1)
|
||||
operation = writes[0][-1]['value']
|
||||
self.assertFalse(operation['sync']['prune'])
|
||||
self.assertEqual(operation['sync']['resources'], [
|
||||
{'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}])
|
||||
self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls))
|
||||
self.assertEqual(writes[0][0]['path'], '/metadata/uid')
|
||||
|
||||
def test_source_overrides_automation_and_custody_drift_stop_before_write(self):
|
||||
mutations = [lambda o: o['application']['metadata'].update(uid='recreated'),
|
||||
lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}),
|
||||
lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}),
|
||||
lambda o: o['application']['spec'].update(sources=[{}]),
|
||||
lambda o: o['configmap']['metadata'].update(uid='recreated'),
|
||||
lambda o: o['pvc']['spec'].update(volumeName='replaced'),
|
||||
lambda o: o['deployment']['status'].update(readyReplicas=0)]
|
||||
for mutate in mutations:
|
||||
with self.subTest(mutate=mutate):
|
||||
objects, payload = self.fixture()
|
||||
mutate(objects)
|
||||
receipt, writes, calls = self.execute_fake(objects, payload)
|
||||
self.assertFalse(receipt['all_checks_pass'])
|
||||
self.assertEqual(writes, [])
|
||||
|
||||
def test_preopen_schema_refusal_prevents_image_operation(self):
|
||||
objects, payload = self.fixture()
|
||||
receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)
|
||||
self.assertFalse(receipt['all_checks_pass'])
|
||||
self.assertEqual(writes, [])
|
||||
|
||||
def test_ambiguous_patch_is_never_retried(self):
|
||||
objects, payload = self.fixture()
|
||||
receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True)
|
||||
self.assertFalse(receipt['all_checks_pass'])
|
||||
self.assertEqual(len(writes), 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"tests": 12,
|
||||
"result": "passed",
|
||||
"synthetic_transport_only": true,
|
||||
"real_native_data_read": false,
|
||||
"native_backup_export_restore_executed": false,
|
||||
"native_workload_changed": false,
|
||||
"actual_founder_approval": false,
|
||||
"local_read_only_capability_checks": [
|
||||
"argocdCLI absent, existingApplication.operation path retained",
|
||||
"Dockerunixsocket engineName bnt-lap001"
|
||||
],
|
||||
"case_source_commit_at_preparation": "e0359bc (owner original78source; final helpercommit mustbe explicitlypinned)"
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
[
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/execution/README.md",
|
||||
"staged_path": "/tmp/infd-purpose-execution-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/README.md",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "91d7b3c36498629bb4632b2a45cd75b67bf3a8ce8ab924d6a754a67410fadf6f"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py",
|
||||
"staged_path": "/tmp/infd-purpose-execution-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/actuator.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "faf019cd011dee1032d3f309e85b1f1b0bf5f333d6e279701c3f7e233d54fe23"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py",
|
||||
"staged_path": "/tmp/infd-purpose-execution-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/authority_journal.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "55e441b1af7288540c31ea4733c3471559a2100a26fae8b6b0ed415e04d469a5"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json",
|
||||
"staged_path": "/tmp/infd-purpose-execution-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/execution-plan.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py",
|
||||
"staged_path": "/tmp/infd-purpose-execution-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/native_program.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "3ad4fe28d0556a001f6334f3f8267d1e21d76e17db9765d3cc35b679a9db9ec5"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/execution/packet-refinement.json",
|
||||
"staged_path": "/tmp/infd-purpose-execution-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/packet-refinement.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "003f08e4ff4abe96478f1db9d5b13e4a49a16cdc724090ba0d40a9f7e8440624"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/execution/receipt_safety.py",
|
||||
"staged_path": "/tmp/infd-purpose-execution-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/receipt_safety.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/execution/root-authority-receipt-template.json",
|
||||
"staged_path": "/tmp/infd-purpose-execution-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/root-authority-receipt-template.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "15966b7c6f088a033baf1fef878ddb351de2fa2ae46b5bc710265ed172ab2813"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/execution/test_execution.py",
|
||||
"staged_path": "/tmp/infd-purpose-execution-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/test_execution.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "d4f20fba850f0303a87971d2498bccc894ab39b7584ce98756e1c536e517fb18"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/execution/validation.json",
|
||||
"staged_path": "/tmp/infd-purpose-execution-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution/validation.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "abefda88f48ae455205cf6c27033fa81f99e89baea9ffffb8c26749a53815a39"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json",
|
||||
"staged_path": "/tmp/infd-purpose-execution-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/execution-bundle.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "0a79eda40fe0954fd3828bf06fd6ccf149e294ac194bc6fe605e585b878fa8d3"
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# Supervised Informed Decision purpose release executor — unapproved preparation
|
||||
|
||||
No native database read, backup/export/restore or workload action has been run. This source implements the reviewed protocol; its additional mechanical details need peer review and an amended hash-bound packet before first human submission. The original78path packet/reviews remain historical technical agreement, not founder approval of this executor.
|
||||
|
||||
Run one phase at a time only after the coordinator has freshly authenticated the exact founder disposition at the existing fixed Informed Decision origin. Root writes the protected0600 fixed files `/tmp/security-infd-purpose-root-authority.json` and `/tmp/security-infd-purpose-native-outcome-latest.json`. The receipt template is PENDING and cannot authorize anything. The helper checks exact nested confirmed person/platform-root ACCEPT version1, original memo identity/current memo SHA, source commit, plan SHA and freshness120seconds. This is supervised receipt bookkeeping, not cryptographic provider verification, a signed grant or agent autonomy promotion. Root/harness supervision remains the authority boundary. Never synthesize an approval receipt from a technical review or caller assertion.
|
||||
|
||||
Invocation after actual approval: `python3 execution/actuator.py --phase <fixed-phase> --root-authority-receipt /tmp/security-infd-purpose-root-authority.json --root-native-outcome /tmp/security-infd-purpose-native-outcome-latest.json --source-revision <exact-final-owner-commit>`. Order: drill-backup → drill-copy → offline-verify → cleanup-offline → cutover-backup → cutover-copy → release → verify. Rollback is a distinct authorized recovery after a recorded release attempt, followed by rollback-verify. Rollback dispatch needs no Ready Pod or candidate database exec: sealed Deployment/CM/PVC/source/image pair and admission CAS remain mandatory. Its acknowledgment is not recovery completion; rollback-verify separately requires Ready1 of the old image, succeeded exact scoped operation and readonly schema5/integrity/count proof of the current retained database. Root refreshes actual native acceptance immediately before each phase.
|
||||
|
||||
The private ignored Custodian custody parent `.private-backups` must already exist,0700 owned by the workstation agent user; the exact case child20261011-infd-purpose-r1 is created only after authority checks. Native parent `/data/private/purpose-overlay-r1` is uniquely created by UID10001 for drill/cutover SQLite-consistent snapshots, each0600/nonsymlink/single-link. The attached stdlib readonly checker must report schema5/integrity/counts before any Store/admin on native source or offlineclone. Invalid states/count shapes and all raw child outputs are withheld. Main-only snapshot closure is verified before binary transfer; stdin/stdout snapshot bytes reach only private files or the isolated restore copy, never tool/chat/log output. Streams stop beyond frozen byte count/512MiB; failures retain partial private evidence.
|
||||
|
||||
New private offline volume `infd-purpose-r1-restore-20261011` is created only on the pinned local workstation Docker socket/engine bnt-lap001, with localdriver/nooptions and attemptnonce labels. One-time initializer runs exact763c as UID0 with only CAP_CHOWN, networknone/read-onlyroot/no-newprivileges, one NEW namedvolume mount, no host/livePVC/credential/config mounts. It receives only the protected snapshot on stdin, verifies bytes, sets folder0700/file0600 owned10001. Then UID10001 performs readonly pre-open validation, `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite`, never the service entrypoint. A second UID10001/network-none readonly integrity/schema/count check after admin must exactly equal the frozen snapshot proof, and the original protected snapshot SHA must remain unchanged. Cleanup compares exact nonce/creation identity and removes only this clone volume, retaining all native/offcluster originals. CPU1/memory128MiB; private offcluster capacity at least1GiB+16MiB and native estimated two/one-snapshot headroom required.
|
||||
|
||||
Every phase fsyncs RUNNING intent before dispatch. Any failure/interruption/ambiguous result remains UNCERTAIN; same-phase retry is refused. Separate operator diagnosis and any needed recovery are recorded; neither snapshots nor unresolved/new records are removed to make checks green. Frozen snapshot/clone counters must agree; live post-cutover/rollback counters can include legitimate concurrent commits/state transitions.
|
||||
|
||||
Existing Application UID and actual Deployment/Pod/CM/PVC custody/source are checked. All four owner render Git blobs must match; overrides/plugins/multiple sources and even automated:{} are rejected. The existing Application.operation API is used (native argocd CLI is absent), with server dry-run, resourceVersion/UID/source tests, one Deployment only, prune=false. Dispatch acknowledgment is not rollout completion. Verify requires exact succeeded operation/controller generation/Ready1, same schema5 DB, actual installed hash/mode/UID and10purpose checks plus bounded localhosthealth/readiness. Purpose transport remains synthetic and is explicitly not a native PDP authority test. Rollback pins prior7db/7f5 through the same scoped workflow and retains the current live database; it never restores an older snapshot over later writes.
|
||||
|
||||
Sixteen synthetic tests pass against frozen case metadata: authority/expiry/actor/ambiguity refusals, crash intent/no retry/order, credential-output withholding, private bounded binarycopy, volume recreation cleanup refusal, source/automation/CM/PVC/Ready drift, pre-open gate refusal and exact Deployment-only operation/dry-run. These are source tests, not native backup or release proof.
|
||||
|
||||
All phases, including recovery and verification, are bounded by 2026-10-12T23:59:59Z. This explicitly refines the earlier packet deadline wording for unstarted release: the helper does not extend authority past the deadline. Start sufficiently early to complete drill/cutover/recovery; after expiry stop and obtain a fresh founder decision. This may delay recovery if the window is exhausted, and must be disclosed before acceptance.
|
||||
|
||||
The initial 11-file helper freeze SHA653b68c3891c066f40d104bfc67a35da5e436605cd99afd52fbac4b47a9553fe and independent conditional findings remain archived under execution-history/initial-653b68c3. This refinement is the same proposal/trial; no native execution or human acceptance has occurred.
|
||||
|
|
@ -0,0 +1,353 @@
|
|||
"""One fixed supervised phase; never run this during source preparation."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import selectors
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
if sys.flags.optimize:
|
||||
raise SystemExit('optimized interpreter refused')
|
||||
|
||||
PHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',
|
||||
'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')
|
||||
|
||||
|
||||
def require(value, reason):
|
||||
if not value:
|
||||
raise ValueError(reason)
|
||||
|
||||
|
||||
def sha(path):
|
||||
digest = hashlib.sha256()
|
||||
with Path(path).open('rb') as stream:
|
||||
for block in iter(lambda: stream.read(1024**2), b''):
|
||||
digest.update(block)
|
||||
return digest.hexdigest()
|
||||
|
||||
|
||||
def private(path, directory=False):
|
||||
info = Path(path).lstat()
|
||||
require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))
|
||||
and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)
|
||||
and (directory or info.st_nlink == 1), 'private owned custody required')
|
||||
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
CASE = ROOT.parent
|
||||
OWNER = Path('/home/worsch/informed-decision')
|
||||
CUSTODIAN = Path('/home/worsch/the-custodian')
|
||||
CUSTODY = CUSTODIAN / '.private-backups/20261011-infd-purpose-r1'
|
||||
SOCKET = 'unix:///var/run/docker.sock'
|
||||
IMAGE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'
|
||||
VOLUME = 'infd-purpose-r1-restore-20261011'
|
||||
MAX_BYTES = 512 * 1024**2
|
||||
|
||||
|
||||
def run(argv, body=None, timeout=90):
|
||||
return subprocess.run(argv, input=body, text=True, capture_output=True, timeout=timeout)
|
||||
|
||||
|
||||
def json_result(result):
|
||||
try:
|
||||
value = json.loads(result.stdout)
|
||||
except (ValueError, TypeError):
|
||||
raise ValueError('safe phase receipt unavailable; outcome uncertain') from None
|
||||
require(result.returncode == 0 and isinstance(value, dict) and value.get('all_checks_pass') is True,
|
||||
'phase did not verify complete; raw output withheld; no retry')
|
||||
permitted = {'phase', 'all_checks_pass', 'raw_output_withheld', 'native_approval_verified_by_root',
|
||||
'native_authenticated_grant', 'source_readonly_baseline', 'snapshot_readonly',
|
||||
'snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'native_parent_private',
|
||||
'native_uid', 'pod_name', 'pod_uid', 'live_readonly_schema_integrity_counts',
|
||||
'live_counts_may_include_concurrent_commits', 'operation_requested', 'source_revision',
|
||||
'resources', 'prune', 'rollout_verified', 'latest_live_database_retained',
|
||||
'client_diff_sha256', 'native_rollout_verified', 'current_schema5_database_retained',
|
||||
'private_copy_verified', 'installed_purpose_checks', 'policy_sha256',
|
||||
'policy_mode', 'policy_uid', 'health_statuses', 'native_provider_probe', 'recovery_verification'}
|
||||
require(set(value) <= permitted, 'unexpected output fields withheld')
|
||||
from receipt_safety import counts
|
||||
for name in ('source_readonly_baseline', 'snapshot_readonly', 'live_readonly_schema_integrity_counts'):
|
||||
if name in value:
|
||||
counts(value[name])
|
||||
for name in ('snapshot_sha256', 'client_diff_sha256'):
|
||||
if name in value:
|
||||
require(re.fullmatch(r'[a-f0-9]{64}', value[name]) is not None, 'invalid output digest withheld')
|
||||
if 'snapshot_bytes' in value:
|
||||
require(type(value['snapshot_bytes']) is int and 0 < value['snapshot_bytes'] <= MAX_BYTES,
|
||||
'invalid output size withheld')
|
||||
if 'snapshot_file' in value:
|
||||
require(value['snapshot_file'] in ('drill.sqlite', 'cutover.sqlite'), 'invalid output file withheld')
|
||||
return value
|
||||
|
||||
|
||||
def docker(argv, body=None, timeout=120):
|
||||
return run(['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET] + argv,
|
||||
body=body, timeout=timeout)
|
||||
|
||||
|
||||
def remote(phase, revision, approved):
|
||||
# Fixed module imported only after main verifies every executor source hash.
|
||||
from native_program import PROGRAM
|
||||
payload = {'phase': phase, 'source_revision': revision, 'approval': approved,
|
||||
'sealed': json.loads((CASE / 'sealed-live-deployment.json').read_text()),
|
||||
'dependencies': json.loads((CASE / 'sealed-native-dependencies.json').read_text()),
|
||||
'candidate': json.loads((CASE / 'candidate-deployment.json').read_text()),
|
||||
'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),
|
||||
'receipt_safety': (ROOT / 'receipt_safety.py').read_text(),
|
||||
'purpose_checks': (CASE / 'check_installed.py').read_text(),
|
||||
'readonly': (CASE / 'sqlite_readonly.py').read_text()}
|
||||
script = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(
|
||||
'__GUARD__', repr((CASE / 'change_guard.py').read_text()))
|
||||
return json_result(run(['ssh', 'railiance01', 'python3 -'], script, timeout=200))
|
||||
|
||||
|
||||
def copy_snapshot(phase, revision, approved, journal):
|
||||
metadata = remote(phase, revision, approved)
|
||||
backup_phase = 'drill-backup' if phase == 'drill-copy' else 'cutover-backup'
|
||||
prior = journal.data['phases'][backup_phase]['result']
|
||||
for key in ('snapshot_sha256', 'snapshot_bytes', 'snapshot_file', 'snapshot_readonly'):
|
||||
require(metadata[key] == prior[key], 'closed frozen snapshot changed')
|
||||
name = metadata['snapshot_file']
|
||||
require(name in ('drill.sqlite', 'cutover.sqlite') and 0 < metadata['snapshot_bytes'] <= MAX_BYTES,
|
||||
'fixed bounded snapshot required')
|
||||
pod = metadata['pod_name']
|
||||
require(re.fullmatch(r'[a-z0-9]([-a-z0-9]*[a-z0-9])?', pod) is not None, 'fixed owner pod name required')
|
||||
local = CUSTODY / name
|
||||
fd = os.open(local, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)
|
||||
# Binary snapshot stdout goes only to a private file, never tool/chat/log output.
|
||||
# Snapshot schema/count metadata was validated before opening this destination.
|
||||
with os.fdopen(fd, 'wb') as destination:
|
||||
command = ('kubectl exec -n informed-decision ' + pod +
|
||||
' -c informed-decision -- cat /data/private/purpose-overlay-r1/' + name)
|
||||
transfer = subprocess.Popen(['ssh', 'railiance01', command], stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL)
|
||||
selector = selectors.DefaultSelector()
|
||||
selector.register(transfer.stdout, selectors.EVENT_READ)
|
||||
deadline = time.monotonic() + 150
|
||||
received = 0
|
||||
try:
|
||||
while True:
|
||||
remaining = deadline - time.monotonic()
|
||||
require(remaining > 0 and selector.select(remaining), 'private transfer timed out')
|
||||
block = os.read(transfer.stdout.fileno(), 1024**2)
|
||||
if not block:
|
||||
break
|
||||
received += len(block)
|
||||
require(received <= metadata['snapshot_bytes'] and received <= MAX_BYTES,
|
||||
'private copy exceeds frozen snapshot size')
|
||||
destination.write(block)
|
||||
transfer.wait(timeout=max(1, deadline - time.monotonic()))
|
||||
finally:
|
||||
selector.close()
|
||||
transfer.stdout.close()
|
||||
if transfer.poll() is None:
|
||||
transfer.kill()
|
||||
transfer.wait()
|
||||
destination.flush()
|
||||
os.fsync(destination.fileno())
|
||||
private(local)
|
||||
require(transfer.returncode == 0 and local.stat().st_size == metadata['snapshot_bytes']
|
||||
and sha(local) == metadata['snapshot_sha256'], 'private copy incomplete/uncertain; retain, no retry')
|
||||
# Re-read identity/hash after transfer. This is verification, not a write retry.
|
||||
after = remote(phase, revision, approved)
|
||||
require(after['pod_uid'] == metadata['pod_uid'] and after['snapshot_sha256'] == metadata['snapshot_sha256'],
|
||||
'source identity/snapshot changed during transfer')
|
||||
return {**metadata, 'off_cluster_private_copy_verified': True, 'snapshot_contents_output': False}
|
||||
|
||||
|
||||
def offline_verify(journal):
|
||||
from receipt_safety import counts
|
||||
snapshot = CUSTODY / 'drill.sqlite'
|
||||
private(snapshot)
|
||||
previous = journal.data['phases']['drill-copy']['result']
|
||||
require(sha(snapshot) == previous['snapshot_sha256'], 'protected snapshot bytes changed')
|
||||
identity = docker(['info', '--format', '{{json .Name}}'])
|
||||
require(identity.returncode == 0 and json.loads(identity.stdout) == 'bnt-lap001',
|
||||
'local offline Docker engine identity changed')
|
||||
listed = docker(['volume', 'ls', '--format', '{{.Name}}'])
|
||||
require(listed.returncode == 0 and VOLUME not in listed.stdout.splitlines(),
|
||||
'disposable volume absence not verified')
|
||||
nonce = journal.data['phases']['offline-verify']['attempt_id']
|
||||
labels = {'informed-decision.case': 'infd-purpose-20261011-r1',
|
||||
'informed-decision.use': 'offline-restore-only', 'informed-decision.attempt': nonce}
|
||||
created = docker(['volume', 'create', '--driver', 'local', '--label', 'informed-decision.case=infd-purpose-20261011-r1',
|
||||
'--label', 'informed-decision.attempt=' + nonce,
|
||||
'--label', 'informed-decision.use=offline-restore-only', VOLUME])
|
||||
require(created.returncode == 0 and created.stdout.strip() == VOLUME, 'volume creation uncertain; no retry')
|
||||
inspected = docker(['volume', 'inspect', VOLUME])
|
||||
require(inspected.returncode == 0, 'new volume identity unavailable')
|
||||
volume = json.loads(inspected.stdout)
|
||||
require(len(volume) == 1 and volume[0]['Name'] == VOLUME and volume[0].get('Labels') == labels
|
||||
and volume[0].get('Driver') == 'local' and not volume[0].get('Options')
|
||||
and volume[0].get('Scope') == 'local', 'new isolated volume identity changed')
|
||||
identity = {key: volume[0][key] for key in ('Name', 'Labels', 'Driver', 'Scope', 'CreatedAt')}
|
||||
journal.note('offline-verify', 'created_volume_identity', identity)
|
||||
# One-time UID0/CAP_CHOWN initialization is isolated to the NEW named volume.
|
||||
# No host/live PVC/config/token mount exists; this detail needs packet review.
|
||||
initializer = """import hashlib,os,stat,sys
|
||||
if sys.flags.optimize:raise RuntimeError('optimized interpreter refused')
|
||||
folder='/restore';expected=EXPECTED
|
||||
if os.listdir(folder):raise ValueError('new empty private volume required')
|
||||
os.chmod(folder,0o700)
|
||||
fd=os.open(folder+'/review.sqlite',os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW|os.O_WRONLY,0o600)
|
||||
digest=hashlib.sha256();size=0
|
||||
with os.fdopen(fd,'wb') as target:
|
||||
while True:
|
||||
block=sys.stdin.buffer.read(1024**2)
|
||||
if not block:break
|
||||
size+=len(block)
|
||||
if size>512*1024**2:raise ValueError('private restore size exceeds bound')
|
||||
target.write(block);digest.update(block)
|
||||
target.flush();os.fsync(target.fileno())
|
||||
if digest.hexdigest()!=expected:raise ValueError('private copied snapshot differs')
|
||||
os.chown(folder+'/review.sqlite',10001,10001);os.chown(folder,10001,10001)
|
||||
print('{"all_checks_pass":true,"private_copy_verified":true}')
|
||||
""".replace('EXPECTED', repr(previous['snapshot_sha256']))
|
||||
with snapshot.open('rb') as source:
|
||||
argv = ['docker', '--config', str(CUSTODY / 'empty-docker-config'), '--host', SOCKET,
|
||||
'run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',
|
||||
'--user', '0:0', '--cap-drop', 'ALL', '--cap-add', 'CHOWN',
|
||||
'--security-opt', 'no-new-privileges', '--mount', 'type=volume,src=' + VOLUME + ',dst=/restore',
|
||||
'--entrypoint', 'python', IMAGE, '-c', initializer]
|
||||
copied = subprocess.run(argv, stdin=source, text=True, capture_output=True, timeout=150)
|
||||
json_result(copied)
|
||||
options = ['run', '--rm', '-i', '--network', 'none', '--read-only', '--cpus', '1', '--memory', '128m',
|
||||
'--user', '10001:10001', '--cap-drop', 'ALL', '--security-opt', 'no-new-privileges',
|
||||
'--mount', 'type=volume,src=' + VOLUME + ',dst=/restore']
|
||||
readonly = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],
|
||||
(CASE / 'sqlite_readonly.py').read_text())
|
||||
require(readonly.returncode == 0, 'offline pre-open schema/integrity gate refused; never open Store')
|
||||
checked = counts(json.loads(readonly.stdout))
|
||||
require(checked == previous['snapshot_readonly'], 'frozen snapshot/clone readonly counts differ')
|
||||
admin = docker(options + ['--entrypoint', 'informed-decision-admin', IMAGE,
|
||||
'inspect', '--db', '/restore/review.sqlite'])
|
||||
require(admin.returncode == 0, 'offline admin result uncertain')
|
||||
admin_counts = json.loads(admin.stdout)
|
||||
require(admin_counts == {key: checked[key] for key in ('schema_version', 'lifecycle', 'outbox', 'submissions')},
|
||||
'offline admin changed frozen snapshot counters')
|
||||
# Admin Store construction must not silently alter schema/integrity/counters.
|
||||
post = docker(options + ['--entrypoint', 'python', IMAGE, '-', '--db', '/restore/review.sqlite'],
|
||||
(CASE / 'sqlite_readonly.py').read_text())
|
||||
require(post.returncode == 0, 'offline post-admin readonly integrity gate refused')
|
||||
post_checked = counts(json.loads(post.stdout))
|
||||
require(post_checked == checked == previous['snapshot_readonly'],
|
||||
'offline admin altered frozen snapshot proof')
|
||||
private(snapshot)
|
||||
require(sha(snapshot) == previous['snapshot_sha256'], 'original protected snapshot changed during drill')
|
||||
return {'all_checks_pass': True, 'offline_volume': VOLUME, 'offline_readonly': checked,
|
||||
'offline_post_admin_readonly': post_checked, 'original_snapshot_hash_unchanged': True,
|
||||
'created_volume_identity': identity,
|
||||
'admin_counts': admin_counts, 'network': 'none', 'runtime_tokens_or_config_mounted': False,
|
||||
'service_entrypoint_started': False, 'original_snapshot_retained': True}
|
||||
|
||||
|
||||
def cleanup_offline(journal):
|
||||
inspected = docker(['volume', 'inspect', VOLUME])
|
||||
require(inspected.returncode == 0, 'owned disposable volume identity unverified')
|
||||
value = json.loads(inspected.stdout)
|
||||
expected = journal.data['phases']['offline-verify']['result']['created_volume_identity']
|
||||
require(len(value) == 1 and {key: value[0].get(key) for key in expected} == expected
|
||||
and not value[0].get('Options'), 'volume ownership/recreation changed')
|
||||
removed = docker(['volume', 'rm', VOLUME])
|
||||
require(removed.returncode == 0 and removed.stdout.strip() == VOLUME
|
||||
and docker(['volume', 'inspect', VOLUME]).returncode != 0,
|
||||
'cleanup outcome ambiguous; do not retry')
|
||||
return {'all_checks_pass': True, 'only_disposable_offline_volume_removed': VOLUME,
|
||||
'native_and_offcluster_original_snapshots_retained': True}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--phase', choices=PHASES, required=True)
|
||||
parser.add_argument('--root-authority-receipt', type=Path, required=True)
|
||||
parser.add_argument('--root-native-outcome', type=Path, required=True)
|
||||
parser.add_argument('--source-revision', required=True)
|
||||
args = parser.parse_args()
|
||||
require(args.root_authority_receipt == Path('/tmp/security-infd-purpose-root-authority.json')
|
||||
and args.root_native_outcome == Path('/tmp/security-infd-purpose-native-outcome-latest.json'),
|
||||
'fixed supervised receipt paths required')
|
||||
require(re.fullmatch(r'[0-9a-f]{40}', args.source_revision) is not None, 'exact source commit required')
|
||||
# Verify all prepared executor/input bytes before reading authority or dispatching.
|
||||
plan = json.loads((ROOT / 'execution-plan.json').read_text())
|
||||
require(set(plan['executor_files']) == {'actuator.py', 'authority_journal.py', 'native_program.py', 'receipt_safety.py'},
|
||||
'fixed executor sources required')
|
||||
require(set(plan['owner_source_files']) == {'deploy/lifecycle/admission.candidate.json',
|
||||
'deploy/lifecycle/service.candidate.json',
|
||||
'deploy/lifecycle/kustomization.yaml',
|
||||
'deploy/lifecycle/registries.candidate.json'},
|
||||
'fixed owner image sources required')
|
||||
for relative, digest in plan['executor_files'].items():
|
||||
target = ROOT / relative
|
||||
require(not target.is_symlink() and sha(target) == digest, 'executor source bytes changed')
|
||||
for relative, digest in plan['case_files'].items():
|
||||
require(not Path(relative).is_absolute() and '..' not in Path(relative).parts,
|
||||
'case source path escaped')
|
||||
target = CASE / relative
|
||||
require(not target.is_symlink() and sha(target) == digest, 'case source bytes changed')
|
||||
for relative, digest in plan['owner_source_files'].items():
|
||||
target = OWNER / relative
|
||||
require(not target.is_symlink() and sha(target) == digest, 'owner image-only source changed')
|
||||
committed = subprocess.run(['git', '-C', str(OWNER), 'show', args.source_revision + ':' + relative],
|
||||
capture_output=True)
|
||||
require(committed.returncode == 0 and hashlib.sha256(committed.stdout).hexdigest() == digest,
|
||||
'committed owner render source differs from approved inputs')
|
||||
head = run(['git', '-C', str(OWNER), 'rev-parse', 'HEAD'])
|
||||
require(head.returncode == 0 and head.stdout.strip() == args.source_revision, 'owner source HEAD differs')
|
||||
from authority_journal import Journal, authority
|
||||
private(args.root_authority_receipt)
|
||||
private(args.root_native_outcome)
|
||||
receipt = json.loads(args.root_authority_receipt.read_text())
|
||||
require(receipt.get('native_outcome_sha256') == sha(args.root_native_outcome), 'native outcome bytes changed')
|
||||
require(receipt.get('executor_plan_sha256') == sha(ROOT / 'execution-plan.json'),
|
||||
'root verified executor plan differs')
|
||||
approved = authority(receipt, json.loads(args.root_native_outcome.read_text()), sha(CASE / 'memo.json'),
|
||||
args.source_revision, args.phase)
|
||||
parent = CUSTODY.parent
|
||||
private(parent, directory=True)
|
||||
ignored = run(['git', '-C', str(CUSTODIAN), 'check-ignore', '--no-index', str(CUSTODY / 'drill.sqlite')])
|
||||
require(ignored.returncode == 0, 'offcluster custody is not ignored')
|
||||
if not CUSTODY.exists():
|
||||
require(args.phase == 'drill-backup', 'first approved phase must create unique private custody')
|
||||
os.mkdir(CUSTODY, 0o700)
|
||||
private(CUSTODY, directory=True)
|
||||
capacity = os.statvfs(CUSTODY)
|
||||
require(capacity.f_bavail * capacity.f_frsize >= 2 * MAX_BYTES + 16 * 1024**2,
|
||||
'independent protected custody headroom insufficient')
|
||||
os.makedirs(CUSTODY / 'empty-docker-config', mode=0o700, exist_ok=True)
|
||||
private(CUSTODY / 'empty-docker-config', directory=True)
|
||||
require(not list((CUSTODY / 'empty-docker-config').iterdir()), 'public Docker read config must stay empty')
|
||||
journal = Journal(CUSTODY, {'proposal': plan['proposal_id'], 'source_revision': args.source_revision,
|
||||
'memo_sha256': sha(CASE / 'memo.json'), 'plan_sha256': sha(ROOT / 'execution-plan.json')})
|
||||
try:
|
||||
journal.start(args.phase, approved) # fsynced RUNNING before any phase effect.
|
||||
if args.phase in ('drill-copy', 'cutover-copy'):
|
||||
result = copy_snapshot(args.phase, args.source_revision, approved, journal)
|
||||
elif args.phase == 'offline-verify':
|
||||
result = offline_verify(journal)
|
||||
elif args.phase == 'cleanup-offline':
|
||||
result = cleanup_offline(journal)
|
||||
else:
|
||||
result = remote(args.phase, args.source_revision, approved)
|
||||
journal.finish(args.phase, result)
|
||||
print(json.dumps(result)) # Only count/hash/identity receipts, never snapshot bytes.
|
||||
except BaseException as error:
|
||||
safe = {'all_checks_pass': False, 'phase': args.phase, 'failure_class': type(error).__name__,
|
||||
'failure': 'fixed phase outcome uncertain; original evidence retained; no retry',
|
||||
'raw_output_withheld': True}
|
||||
if journal.data['phases'].get(args.phase, {}).get('state') == 'RUNNING':
|
||||
journal.finish(args.phase, safe)
|
||||
print(json.dumps(safe))
|
||||
raise SystemExit(1) from None
|
||||
finally:
|
||||
journal.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception:
|
||||
raise SystemExit('supervised execution refused before phase; raw output withheld') from None
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
"""Supervised receipt bookkeeping, not an authenticated approval provider."""
|
||||
import datetime
|
||||
import fcntl
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
import stat
|
||||
import uuid
|
||||
|
||||
FOUNDER = {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'}
|
||||
MEMO_ID = 'infd-20261011-purpose-overlay-r1'
|
||||
PROPOSAL = 'INFD-WP-0009-T04/purpose-overlay-v1'
|
||||
PHASES = ('drill-backup', 'drill-copy', 'offline-verify', 'cleanup-offline',
|
||||
'cutover-backup', 'cutover-copy', 'release', 'verify', 'rollback', 'rollback-verify')
|
||||
|
||||
|
||||
def require(value, reason):
|
||||
if not value:
|
||||
raise ValueError(reason)
|
||||
|
||||
|
||||
def sha(path):
|
||||
digest = hashlib.sha256()
|
||||
with Path(path).open('rb') as stream:
|
||||
for block in iter(lambda: stream.read(1024**2), b''):
|
||||
digest.update(block)
|
||||
return digest.hexdigest()
|
||||
|
||||
|
||||
def private(path, directory=False):
|
||||
info = Path(path).lstat()
|
||||
require((stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode))
|
||||
and info.st_uid == os.getuid() and stat.S_IMODE(info.st_mode) == (0o700 if directory else 0o600)
|
||||
and (directory or info.st_nlink == 1), 'private owned custody required')
|
||||
|
||||
|
||||
def authority(receipt, outcome, memo_sha, source_revision, phase, now=None):
|
||||
"""Root must freshly verify native outcome at fixed ORIGIN outside this helper.
|
||||
|
||||
Receipt files/flags are not signed grants. This function checks the exact
|
||||
supervised receipt relation; existing harness/founder authority remains the
|
||||
actual permission boundary. It never authenticates a caller as human.
|
||||
"""
|
||||
now = now or datetime.datetime.now(datetime.timezone.utc)
|
||||
require(phase in PHASES, 'fixed phase required')
|
||||
require(receipt.get('proposal_id') == PROPOSAL and receipt.get('memo_id') == MEMO_ID
|
||||
and receipt.get('memo_version') == 1 and receipt.get('memo_sha256') == memo_sha
|
||||
and receipt.get('source_revision') == source_revision
|
||||
and receipt.get('activation') == 'APPROVED'
|
||||
and receipt.get('authority_mode') == 'ADMINISTER'
|
||||
and receipt.get('target') == 'realm:kubernetes/railiance01/informed-decision'
|
||||
and receipt.get('verification_method') == 'root-fixed-origin-native-readback'
|
||||
and receipt.get('runtime_authenticated_grant') is False,
|
||||
'exact externally verified supervised receipt required')
|
||||
verified = datetime.datetime.fromisoformat(receipt['verified_at'].replace('Z', '+00:00'))
|
||||
require(verified.tzinfo is not None and 0 <= (now - verified).total_seconds() <= 120,
|
||||
'fresh root native readback required before every phase')
|
||||
deadline = datetime.datetime.fromisoformat('2026-10-12T23:59:59+00:00')
|
||||
require(now < deadline, 'approved execution window expired')
|
||||
require(outcome.get('memo_id') == MEMO_ID and outcome.get('review', {}).get('stale') is False
|
||||
and outcome['review'].get('intake_state') == 'ready', 'native review is not ready/current')
|
||||
review_id = outcome['review']['memo_id']
|
||||
require(review_id == receipt.get('review_memo_id'), 'native review identity changed')
|
||||
accepted = [x for x in outcome.get('dispositions', [])
|
||||
if x.get('submission_state') == 'confirmed'
|
||||
and x.get('disposition', {}).get('verb') == 'accept'
|
||||
and x['disposition'].get('memo_version') == 1]
|
||||
require(len(accepted) == 1, 'one confirmed founder acceptance required')
|
||||
accepted = accepted[0]['disposition']
|
||||
require(accepted.get('actor') == FOUNDER and accepted.get('memo_id') == review_id
|
||||
and accepted.get('approval_id') == receipt.get('approval_id')
|
||||
and accepted.get('id') == receipt.get('disposition_id')
|
||||
and accepted.get('at') == receipt.get('accepted_at'), 'exact founder disposition mismatch')
|
||||
require(re.fullmatch(r'[a-f0-9-]{36}', accepted['approval_id']) is not None
|
||||
and re.fullmatch(r'disp-[a-f0-9-]{36}', accepted['id']) is not None
|
||||
and re.fullmatch(r'review-[a-f0-9-]{36}', review_id) is not None,
|
||||
'native disposition identifiers are malformed')
|
||||
accepted_at = datetime.datetime.fromisoformat(accepted['at'].replace('Z', '+00:00'))
|
||||
require(accepted_at.tzinfo is not None and accepted_at <= verified, 'acceptance time not bounded')
|
||||
return {key: receipt[key] for key in ('approval_id', 'disposition_id', 'accepted_at', 'verified_at')}
|
||||
|
||||
|
||||
class Journal:
|
||||
def __init__(self, parent, identity):
|
||||
self.parent = Path(parent)
|
||||
private(self.parent, directory=True)
|
||||
self.path = self.parent / 'execution-journal.json'
|
||||
self.lock = os.open(self.parent / 'execution.lock', os.O_CREAT | os.O_NOFOLLOW | os.O_RDWR, 0o600)
|
||||
fcntl.flock(self.lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
private(self.parent / 'execution.lock')
|
||||
if self.path.exists():
|
||||
private(self.path)
|
||||
self.data = json.loads(self.path.read_text())
|
||||
require(self.data['identity'] == identity, 'journal case/source identity changed')
|
||||
else:
|
||||
self.data = {'identity': identity, 'phases': {}}
|
||||
self.save()
|
||||
|
||||
def save(self):
|
||||
temporary = self.parent / 'execution-journal.new'
|
||||
fd = os.open(temporary, os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW | os.O_WRONLY, 0o600)
|
||||
try:
|
||||
with os.fdopen(fd, 'w') as stream:
|
||||
json.dump(self.data, stream, indent=2)
|
||||
stream.write('\n')
|
||||
stream.flush()
|
||||
os.fsync(stream.fileno())
|
||||
os.replace(temporary, self.path)
|
||||
directory = os.open(self.parent, os.O_DIRECTORY | os.O_RDONLY)
|
||||
try:
|
||||
os.fsync(directory)
|
||||
finally:
|
||||
os.close(directory)
|
||||
except BaseException:
|
||||
# Retain evidence rather than overwriting an uncertain durable intent.
|
||||
raise
|
||||
|
||||
def start(self, phase, approval):
|
||||
require(phase not in self.data['phases'], 'already attempted phase; no retry')
|
||||
predecessors = dict(zip(PHASES[1:8], PHASES[:7]))
|
||||
predecessors['rollback-verify'] = 'rollback'
|
||||
if phase in predecessors:
|
||||
require(self.data['phases'].get(predecessors[phase], {}).get('state') == 'COMPLETE',
|
||||
'preceding phase is not verified complete')
|
||||
if phase == 'rollback':
|
||||
require('release' in self.data['phases'], 'rollback requires a recorded release attempt')
|
||||
self.data['phases'][phase] = {'state': 'RUNNING', 'approval': approval,
|
||||
'attempt_id': str(uuid.uuid4()),
|
||||
'started_at': datetime.datetime.now(datetime.timezone.utc).isoformat()}
|
||||
self.save()
|
||||
|
||||
def note(self, phase, key, value):
|
||||
require(self.data['phases'][phase]['state'] == 'RUNNING', 'phase intent missing')
|
||||
self.data['phases'][phase][key] = value
|
||||
self.save()
|
||||
|
||||
def finish(self, phase, result):
|
||||
entry = self.data['phases'][phase]
|
||||
require(entry['state'] == 'RUNNING', 'phase intent missing')
|
||||
entry['result'] = result
|
||||
entry['state'] = 'COMPLETE' if result.get('all_checks_pass') is True else 'UNCERTAIN'
|
||||
self.save()
|
||||
|
||||
def close(self):
|
||||
os.close(self.lock)
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
{
|
||||
"kind": "informed-decision.supervised-mechanical-release-plan",
|
||||
"version": 1,
|
||||
"proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"trial_id": "infd-purpose-20261011-r1",
|
||||
"state": "prepared-unapproved",
|
||||
"executor_files": {
|
||||
"actuator.py": "6b9d6439862454f261ee77f05b26519f8109599b1f67078bc4e1f7c7c4061ba5",
|
||||
"authority_journal.py": "74d6a91169296a99fa7dac2d0902567280f910af743580ec4b454f2abf8374aa",
|
||||
"native_program.py": "349f516a4e55f7fb47470144ce781a665fb003ebff380d054f642b22133d1cde",
|
||||
"receipt_safety.py": "5c54373f2dc4b064008225c186efb1d5afdeec36d15350bda0a12ded97602d1b"
|
||||
},
|
||||
"case_files": {
|
||||
"change_guard.py": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be",
|
||||
"sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38",
|
||||
"preflight-inputs.json": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06",
|
||||
"sealed-live-deployment.json": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362",
|
||||
"sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369",
|
||||
"candidate-deployment.json": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e",
|
||||
"rollback-deployment.json": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121",
|
||||
"check_installed.py": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad",
|
||||
"published-verification.json": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2",
|
||||
"security-summary.json": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44"
|
||||
},
|
||||
"owner_source_files": {
|
||||
"deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55",
|
||||
"deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4",
|
||||
"deploy/lifecycle/kustomization.yaml": "1bbce81bc6758434354157f8601534320c5d0290587908fd15a6d25e3fa57f47",
|
||||
"deploy/lifecycle/registries.candidate.json": "9bad6db5fbc2178d31b04120016a41830c3552fbb9e2517b718f9bbe87cf649e"
|
||||
},
|
||||
"candidate_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"prior_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"source_revision": "must-be-exact-final-owner-HEAD-with-approved-four-Git-blobs",
|
||||
"phases": [
|
||||
"drill-backup",
|
||||
"drill-copy",
|
||||
"offline-verify",
|
||||
"cleanup-offline",
|
||||
"cutover-backup",
|
||||
"cutover-copy",
|
||||
"release",
|
||||
"verify",
|
||||
"rollback",
|
||||
"rollback-verify"
|
||||
],
|
||||
"authorization": "fresh externally authenticated root fixed-origin native readback before each phase; exact confirmed platform-root disposition and current packet SHA/source commit; receipt bookkeeping is not an autonomous signed grant",
|
||||
"execute_by": "2026-10-12T23:59:59Z",
|
||||
"raw_output_withheld": true,
|
||||
"native_data_or_workload_action_executed": false,
|
||||
"deadline_semantics": "All phases including verification/recovery must begin before execute_by. No extension or automatic emergency grant; beyond deadline stop and obtain a fresh founder decision. Complete the bounded drill and rollout early enough to allow recovery within the window."
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"prior_reviewed_packet_manifest_sha256": "b1e3e66bc4023dc80c6ea59564c3557c7653fb3c307f46a049997b76198a9033",
|
||||
"kind": "mechanical-actuator-packet-refinement-required-before-first-human-post",
|
||||
"changes": [
|
||||
"Hash-bind all executor bytes/executionplan in amended20doc packet, preserve prior78path technical reviews as history",
|
||||
"Require fresh root fixed-origin confirmed founder receipt before each phase, no signed autonomous grant",
|
||||
"Bind all four committed owner Kustomize input blobs and reject Application source overrides or automated:{}",
|
||||
"Explicit new isolated offline volume UID0/CAP_CHOWN initializer, no host/livePVC/token/config mounts, bounded512MiB private snapshot stream and namedVolume nonce ownership",
|
||||
"Durable per-phase RUNNING before action; no same-phase retries after failures/crash, distinct supervised same-schema rollback retains latestDB",
|
||||
"Actual native pre-open readonlyschema5/integrity/count gate before backup/admin, actual Pod/CM/PVC/source seals, offline pre-open check before admininspect, nativeinstalled10syntheticpurpose checks+boundedlocalhosthealth aftercontrollercompletion"
|
||||
],
|
||||
"unchanged": [
|
||||
"immutable763c purposeonly image",
|
||||
"ConfigMap6c/runtime/policy pins/audiences/credentials",
|
||||
"Deployment-only manualArgo scoped operation/prunefalse",
|
||||
"existingPVC/singlewriter/Recreate/schema5",
|
||||
"explicit inherited1fixableMED ownerT05 follow-through"
|
||||
],
|
||||
"native_action_executed": false,
|
||||
"founder_approval": false,
|
||||
"mechanical_review_refinement": {
|
||||
"original_manifest_sha256": "653b68c3891c066f40d104bfc67a35da5e436605cd99afd52fbac4b47a9553fe",
|
||||
"archive": "execution-history/initial-653b68c3",
|
||||
"findings": [
|
||||
"rollback incorrectly depended on Ready candidate and database exec",
|
||||
"offline admin lacked post-open readonly full proof and original snapshot SHA check",
|
||||
"all-phase helper deadline was not disclosed by prior unstarted-release packet wording"
|
||||
],
|
||||
"resolved_by": [
|
||||
"rollback dispatch excludes Pod metadata/exec entirely; separate rollback-verify proves recovered old-image/schema5 DB",
|
||||
"post-admin UID10001 readonly integrity/schema/count proof equals frozen snapshot; retained original SHA unchanged",
|
||||
"explicit all-phase including recovery/verification deadline and fresh-founder-decision requirement beyond expiry"
|
||||
],
|
||||
"same_proposal_trial": true,
|
||||
"native_actions_executed": false,
|
||||
"human_acceptance": false
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
"""Only structural count/hash receipts can leave the private execution phase."""
|
||||
def counts(value):
|
||||
if (set(value) != {'schema_version', 'lifecycle', 'outbox', 'submissions', 'integrity',
|
||||
'read_only_pre_open', 'store_constructed'}
|
||||
or value['schema_version'] != 5 or value['integrity'] != 'ok'
|
||||
or value['read_only_pre_open'] is not True or value['store_constructed'] is not False
|
||||
or set(value['lifecycle']) != {'records', 'events', 'pending'}
|
||||
or not set(value['outbox']) <= {'pending', 'delivered', 'blocked'}
|
||||
or not set(value['submissions']) <= {'prepared', 'in_flight', 'confirmed', 'unresolved'}):
|
||||
raise ValueError('count-only receipt shape/state refused; values withheld')
|
||||
for group in ('lifecycle', 'outbox', 'submissions'):
|
||||
if any(type(number) is not int or number < 0 or number > 10**12
|
||||
for number in value[group].values()):
|
||||
raise ValueError('count-only receipt values refused')
|
||||
return value
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"memo_id": "infd-20261011-purpose-overlay-r1",
|
||||
"memo_version": 1,
|
||||
"memo_sha256": null,
|
||||
"source_revision": null,
|
||||
"activation": "PENDING",
|
||||
"authority_mode": "ADMINISTER",
|
||||
"target": "realm:kubernetes/railiance01/informed-decision",
|
||||
"verification_method": "root-fixed-origin-native-readback",
|
||||
"runtime_authenticated_grant": false,
|
||||
"verified_at": null,
|
||||
"accepted_at": null,
|
||||
"review_memo_id": null,
|
||||
"approval_id": null,
|
||||
"disposition_id": null,
|
||||
"native_outcome_sha256": null,
|
||||
"executor_plan_sha256": "4d5530e7418f638b10ccff0e0d9a0727adc64a7f3a45907f6deb5739ad2adc85"
|
||||
}
|
||||
|
|
@ -0,0 +1,367 @@
|
|||
"""Synthetic custody/transport tests. No native data, Docker or cluster action."""
|
||||
import copy
|
||||
import datetime
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
from contextlib import redirect_stdout
|
||||
|
||||
import actuator
|
||||
from authority_journal import Journal, authority
|
||||
from native_program import PROGRAM
|
||||
from receipt_safety import counts
|
||||
|
||||
CASE = Path('/home/worsch/informed-decision/docs/evidence/2026-10-11-purpose-image-release')
|
||||
NOW = datetime.datetime(2026, 10, 11, 2, 0, tzinfo=datetime.timezone.utc)
|
||||
REVISION = 'e' * 40
|
||||
COUNT = {'schema_version': 5, 'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False,
|
||||
'lifecycle': {'records': 3, 'events': 8, 'pending': 1},
|
||||
'outbox': {'pending': 2, 'delivered': 10}, 'submissions': {'confirmed': 1, 'unresolved': 1}}
|
||||
|
||||
|
||||
def accepted():
|
||||
approval = '11111111-1111-4111-8111-111111111111'
|
||||
review = 'review-22222222-2222-4222-8222-222222222222'
|
||||
disposition = 'disp-33333333-3333-4333-8333-333333333333'
|
||||
receipt = {'proposal_id': 'INFD-WP-0009-T04/purpose-overlay-v1',
|
||||
'memo_id': 'infd-20261011-purpose-overlay-r1', 'memo_version': 1,
|
||||
'memo_sha256': 'a' * 64, 'source_revision': REVISION, 'activation': 'APPROVED',
|
||||
'authority_mode': 'ADMINISTER', 'target': 'realm:kubernetes/railiance01/informed-decision',
|
||||
'verification_method': 'root-fixed-origin-native-readback', 'runtime_authenticated_grant': False,
|
||||
'verified_at': '2026-10-11T02:00:00Z', 'accepted_at': '2026-10-11T01:59:00Z',
|
||||
'review_memo_id': review, 'approval_id': approval, 'disposition_id': disposition}
|
||||
outcome = {'memo_id': receipt['memo_id'], 'review': {'memo_id': review, 'stale': False, 'intake_state': 'ready'},
|
||||
'dispositions': [{'approval_id': None, 'submission_state': 'confirmed',
|
||||
'disposition': {'verb': 'accept', 'memo_version': 1, 'memo_id': review,
|
||||
'approval_id': approval, 'id': disposition,
|
||||
'actor': {'kind': 'person', 'sub': 'uid=platform-root,ou=people,dc=netkingdom,dc=local'},
|
||||
'at': receipt['accepted_at']}}]}
|
||||
return receipt, outcome
|
||||
|
||||
|
||||
class AuthorityAndCustody(unittest.TestCase):
|
||||
def test_exact_nested_founder_receipt_not_top_level_approval(self):
|
||||
receipt, outcome = accepted()
|
||||
result = authority(receipt, outcome, 'a' * 64, REVISION, 'drill-backup', NOW)
|
||||
self.assertEqual(result['approval_id'], receipt['approval_id'])
|
||||
|
||||
def test_pending_stale_wrong_actor_version_and_binding_refuse(self):
|
||||
mutations = [lambda r, o: r.update(activation='PENDING'),
|
||||
lambda r, o: r.update(memo_sha256='changed'),
|
||||
lambda r, o: r.update(source_revision='changed'),
|
||||
lambda r, o: r.update(target='other'),
|
||||
lambda r, o: r.update(verified_at='2026-10-11T01:00:00Z'),
|
||||
lambda r, o: r.update(verification_method='caller-asserted'),
|
||||
lambda r, o: r.update(runtime_authenticated_grant=True),
|
||||
lambda r, o: o['review'].update(stale=True),
|
||||
lambda r, o: o['review'].update(intake_state='pending'),
|
||||
lambda r, o: o['dispositions'][0].update(submission_state='unresolved'),
|
||||
lambda r, o: o['dispositions'][0]['disposition'].update(memo_version=2),
|
||||
lambda r, o: o['dispositions'][0]['disposition'].update(actor={'kind': 'agent', 'sub': 'platform-root'}),
|
||||
lambda r, o: o['dispositions'].append(copy.deepcopy(o['dispositions'][0]))]
|
||||
for mutate in mutations:
|
||||
with self.subTest(mutate=mutate):
|
||||
r, o = accepted()
|
||||
mutate(r, o)
|
||||
with self.assertRaises(ValueError):
|
||||
authority(r, o, 'a' * 64, REVISION, 'release', NOW)
|
||||
|
||||
def test_expired_window_and_unknown_phase_refuse(self):
|
||||
r, o = accepted()
|
||||
with self.assertRaises(ValueError):
|
||||
authority(r, o, 'a' * 64, REVISION, 'arbitrary', NOW)
|
||||
late = datetime.datetime(2026, 10, 13, tzinfo=datetime.timezone.utc)
|
||||
r['verified_at'] = late.isoformat()
|
||||
with self.assertRaises(ValueError):
|
||||
authority(r, o, 'a' * 64, REVISION, 'rollback', late)
|
||||
|
||||
def test_durable_intent_precedes_dispatch_and_never_retries(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
parent = Path(directory)
|
||||
os.chmod(parent, 0o700)
|
||||
journal = Journal(parent, {'case': 'fixture'})
|
||||
journal.start('drill-backup', {'approval_id': 'fixture'})
|
||||
self.assertEqual(json.loads(journal.path.read_text())['phases']['drill-backup']['state'], 'RUNNING')
|
||||
journal.close() # simulated crash before result
|
||||
recovered = Journal(parent, {'case': 'fixture'})
|
||||
with self.assertRaises(ValueError):
|
||||
recovered.start('drill-backup', {})
|
||||
with self.assertRaises(ValueError):
|
||||
recovered.start('drill-copy', {})
|
||||
recovered.close()
|
||||
|
||||
def test_phase_order_and_uncertain_release_allows_only_distinct_recovery(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
os.chmod(directory, 0o700)
|
||||
j = Journal(directory, {'case': 'fixture'})
|
||||
with self.assertRaises(ValueError):
|
||||
j.start('release', {})
|
||||
for phase in actuator.PHASES[:6]:
|
||||
j.start(phase, {})
|
||||
j.finish(phase, {'all_checks_pass': True})
|
||||
j.start('release', {})
|
||||
j.finish('release', {'all_checks_pass': False})
|
||||
with self.assertRaises(ValueError):
|
||||
j.start('release', {})
|
||||
with self.assertRaises(ValueError):
|
||||
j.start('verify', {})
|
||||
j.start('rollback', {})
|
||||
j.finish('rollback', {'all_checks_pass': True})
|
||||
j.close()
|
||||
|
||||
def test_secret_or_unknown_child_output_is_withheld(self):
|
||||
for body in ('not-json', '{"all_checks_pass":true,"token":"private-value"}',
|
||||
'{"all_checks_pass":true,"snapshot_readonly":{"schema_version":5}}'):
|
||||
with self.assertRaises(ValueError):
|
||||
actuator.json_result(subprocess.CompletedProcess([], 0, body, ''))
|
||||
wrong = copy.deepcopy(COUNT)
|
||||
wrong['outbox'] = {'private-row-value': 1}
|
||||
with self.assertRaises(ValueError):
|
||||
counts(wrong)
|
||||
counts(COUNT) # blocked/unresolved counts are not required to be zero.
|
||||
|
||||
def test_binary_copy_is_bounded_private_and_never_echoed(self):
|
||||
blob = b'synthetic private fixture bytes'
|
||||
digest = __import__('hashlib').sha256(blob).hexdigest()
|
||||
metadata = {'all_checks_pass': True, 'snapshot_file': 'drill.sqlite', 'snapshot_bytes': len(blob),
|
||||
'snapshot_sha256': digest, 'snapshot_readonly': COUNT,
|
||||
'pod_name': 'fixture-pod', 'pod_uid': 'fixture-uid'}
|
||||
journal = type('FixtureJournal', (), {'data': {'phases': {'drill-backup': {'result': metadata}}}})()
|
||||
real_popen = subprocess.Popen
|
||||
for extra in (b'', b'oversized'):
|
||||
with self.subTest(extra=extra), tempfile.TemporaryDirectory() as folder:
|
||||
os.chmod(folder, 0o700)
|
||||
output = io.StringIO()
|
||||
|
||||
def child(*args, **kwargs):
|
||||
return real_popen([sys.executable, '-c', 'import sys;sys.stdout.buffer.write(' + repr(blob + extra) + ')'],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
|
||||
|
||||
with patch.object(actuator, 'CUSTODY', Path(folder)), patch.object(actuator, 'remote', return_value=metadata), \
|
||||
patch('subprocess.Popen', side_effect=child), redirect_stdout(output):
|
||||
if extra:
|
||||
with self.assertRaises(ValueError):
|
||||
actuator.copy_snapshot('drill-copy', REVISION, {}, journal)
|
||||
else:
|
||||
result = actuator.copy_snapshot('drill-copy', REVISION, {}, journal)
|
||||
self.assertTrue(result['off_cluster_private_copy_verified'])
|
||||
self.assertEqual((Path(folder) / 'drill.sqlite').read_bytes(), blob)
|
||||
self.assertEqual(output.getvalue(), '')
|
||||
self.assertEqual((Path(folder) / 'drill.sqlite').stat().st_mode & 0o777, 0o600)
|
||||
|
||||
def test_recreated_offline_volume_cannot_be_deleted(self):
|
||||
identity = {'Name': actuator.VOLUME, 'Labels': {'nonce': 'old'}, 'CreatedAt': 'old'}
|
||||
journal = type('FixtureJournal', (), {'data': {'phases': {
|
||||
'offline-verify': {'result': {'created_volume_identity': identity}}}}})()
|
||||
inspected = [{**identity, 'CreatedAt': 'recreated'}]
|
||||
with patch.object(actuator, 'docker', return_value=subprocess.CompletedProcess([], 0, json.dumps(inspected), '')) as mocked:
|
||||
with self.assertRaises(ValueError):
|
||||
actuator.cleanup_offline(journal)
|
||||
self.assertEqual(mocked.call_count, 1)
|
||||
|
||||
def test_offline_post_admin_integrity_and_original_hash_are_rechecked(self):
|
||||
for defect in ('none', 'post-integrity', 'original-hash'):
|
||||
with self.subTest(defect=defect), tempfile.TemporaryDirectory() as directory:
|
||||
folder=Path(directory);os.chmod(folder,0o700)
|
||||
snapshot=folder/'drill.sqlite';snapshot.write_bytes(b'private synthetic snapshot');os.chmod(snapshot,0o600)
|
||||
digest=actuator.sha(snapshot)
|
||||
prior={'snapshot_sha256':digest,'snapshot_readonly':COUNT}
|
||||
journal=type('FixtureJournal',(),{'data':{'phases':{'drill-copy':{'result':prior},'offline-verify':{'attempt_id':'nonce'}}},'note':lambda *args:None})()
|
||||
reads=[]
|
||||
volume={'Name':actuator.VOLUME,'Labels':{'informed-decision.case':'infd-purpose-20261011-r1','informed-decision.use':'offline-restore-only','informed-decision.attempt':'nonce'},'Driver':'local','Scope':'local','CreatedAt':'fixture','Options':None}
|
||||
def docker(argv, body=None, **kwargs):
|
||||
if argv[0]=='info':body=json.dumps('bnt-lap001')
|
||||
elif argv[:2]==['volume','ls']:body=''
|
||||
elif argv[:2]==['volume','create']:body=actuator.VOLUME
|
||||
elif argv[:2]==['volume','inspect']:body=json.dumps([volume])
|
||||
elif 'informed-decision-admin' in argv:
|
||||
body=json.dumps({key:COUNT[key] for key in ('schema_version','lifecycle','outbox','submissions')})
|
||||
if defect=='original-hash':snapshot.write_bytes(b'changed synthetic original')
|
||||
elif '--entrypoint' in argv and 'python' in argv:
|
||||
reads.append(argv);proof=copy.deepcopy(COUNT)
|
||||
if len(reads)==2 and defect=='post-integrity':proof['integrity']='corrupt'
|
||||
body=json.dumps(proof)
|
||||
else:raise AssertionError('unexpected offline command')
|
||||
return subprocess.CompletedProcess(argv,0,body,'')
|
||||
with patch.object(actuator,'CUSTODY',folder),patch.object(actuator,'CASE',CASE),patch.object(actuator,'docker',side_effect=docker),patch('subprocess.run',return_value=subprocess.CompletedProcess([],0,'{"all_checks_pass":true,"private_copy_verified":true}','')):
|
||||
if defect=='none':
|
||||
result=actuator.offline_verify(journal)
|
||||
self.assertEqual(result['offline_post_admin_readonly'],COUNT)
|
||||
self.assertTrue(result['original_snapshot_hash_unchanged'])
|
||||
else:
|
||||
with self.assertRaises(ValueError):actuator.offline_verify(journal)
|
||||
self.assertEqual(len(reads),2)
|
||||
|
||||
|
||||
class FixedNativeProgram(unittest.TestCase):
|
||||
def fixture(self):
|
||||
sealed = json.loads((CASE / 'sealed-live-deployment.json').read_text())
|
||||
live = copy.deepcopy(sealed)
|
||||
live['metadata'].update(generation=42)
|
||||
live['status'] = {'readyReplicas': 1, 'updatedReplicas': 1, 'observedGeneration': 42}
|
||||
dependencies = json.loads((CASE / 'sealed-native-dependencies.json').read_text())
|
||||
cm = copy.deepcopy(dependencies['configmap'])
|
||||
cm.pop('canonical_data_sha256')
|
||||
service = json.loads((CASE / 'candidate-deployment.json').read_text())
|
||||
source_service = json.loads((CASE.parents[2] / 'deploy/lifecycle/service.candidate.json').read_text())
|
||||
cm['data'] = next(x for x in source_service['items'] if x['kind'] == 'ConfigMap')['data']
|
||||
pvc = copy.deepcopy(dependencies['pvc'])
|
||||
pvc['status'] = {'phase': 'Bound'}
|
||||
app = {'metadata': {'uid': '499868f2-eabc-4df4-ae31-b89ce58d750d', 'resourceVersion': '17'},
|
||||
'spec': {'source': {'repoURL': 'https://forgejo.coulomb.social/coulomb/informed-decision.git',
|
||||
'path': 'deploy/lifecycle', 'targetRevision': '7db8485ffecdebfabd77a9daec085553c74bf0bf'},
|
||||
'destination': {'namespace': 'informed-decision', 'server': 'https://kubernetes.default.svc'}}}
|
||||
objects = {'deployment': live, 'configmap': cm, 'pvc': pvc, 'application': app}
|
||||
payload = {'phase': 'release', 'source_revision': REVISION, 'approval': {}, 'sealed': sealed,
|
||||
'dependencies': dependencies, 'candidate': service,
|
||||
'rollback': json.loads((CASE / 'rollback-deployment.json').read_text()),
|
||||
'readonly': (CASE / 'sqlite_readonly.py').read_text(),'purpose_checks':(CASE/'check_installed.py').read_text(),
|
||||
'receipt_safety': (Path(__file__).parent / 'receipt_safety.py').read_text()}
|
||||
return objects, payload
|
||||
|
||||
def execute_fake(self, objects, payload, ambiguous=False, schema_refused=False):
|
||||
writes = []
|
||||
calls = []
|
||||
|
||||
def fake(argv, input=None, **kwargs):
|
||||
calls.append(argv)
|
||||
if argv[:2] == ['kubectl', 'get']:
|
||||
kind = argv[2]
|
||||
if kind in objects:
|
||||
body = objects[kind]
|
||||
elif kind == 'pods':
|
||||
body = {'items': [{'metadata': {'name': 'fixture-pod', 'uid': 'pod-uid',
|
||||
'ownerReferences': [{'kind': 'ReplicaSet', 'name': 'fixture-rs', 'uid': 'rs-uid'}]},
|
||||
'spec': objects['deployment']['spec']['template']['spec'],
|
||||
'status': {'phase': 'Running', 'containerStatuses': [{'name':'informed-decision','ready': True}]}}]}
|
||||
elif kind == 'replicaset':
|
||||
body = {'metadata': {'uid': 'rs-uid', 'ownerReferences': [
|
||||
{'kind': 'Deployment', 'uid': payload['sealed']['metadata']['uid']}]}}
|
||||
elif kind == 'nodes':
|
||||
body = {'items': [{'metadata': {'name': 'fixture-node'}, 'status': {
|
||||
'addresses': [{'address': '92.205.62.239'}], 'allocatable': {'cpu': '4'},
|
||||
'conditions': [{'type': key, 'status': 'True' if key == 'Ready' else 'False'}
|
||||
for key in ('Ready', 'MemoryPressure', 'DiskPressure', 'PIDPressure')]}}]}
|
||||
else:
|
||||
raise AssertionError('unexpected fixed metadata route')
|
||||
return subprocess.CompletedProcess(argv, 0, json.dumps(body), '')
|
||||
if argv[:2] == ['kubectl', 'exec']:
|
||||
if schema_refused:
|
||||
return subprocess.CompletedProcess(argv, 1, '', 'withheld')
|
||||
return subprocess.CompletedProcess(argv, 0, json.dumps({
|
||||
'all_checks_pass': True, 'live_readonly_schema_integrity_counts': COUNT}), '')
|
||||
if argv[:2] == ['kubectl', 'apply']:
|
||||
admitted = copy.deepcopy(payload['sealed'])
|
||||
admitted['spec']['template']['spec']['containers'][0]['image'] = (actuator.IMAGE if payload['phase']=='release' else payload['sealed']['spec']['template']['spec']['containers'][0]['image'])
|
||||
return subprocess.CompletedProcess(argv, 0, json.dumps(admitted), '')
|
||||
if argv[:2] == ['kubectl', 'describe']:
|
||||
return subprocess.CompletedProcess(argv, 0, 'Allocated resources:\n cpu 3460m (86%)\n', '')
|
||||
if argv[:2] == ['kubectl', 'diff']:
|
||||
return subprocess.CompletedProcess(argv, 1, '-image: base\n+image: candidate\n', '')
|
||||
if argv[:2] == ['kubectl', 'patch']:
|
||||
if '--dry-run=server' not in argv:
|
||||
writes.append(json.loads(input))
|
||||
if ambiguous:
|
||||
return subprocess.CompletedProcess(argv, 1, '', 'withheld')
|
||||
return subprocess.CompletedProcess(argv, 0, 'application.argoproj.io/informed-decision\n', '')
|
||||
raise AssertionError('unexpected command')
|
||||
|
||||
source = PROGRAM.replace('__PAYLOAD__', repr(json.dumps(payload))).replace(
|
||||
'__GUARD__', repr((CASE / 'change_guard.py').read_text()))
|
||||
output = io.StringIO()
|
||||
with patch('subprocess.run', side_effect=fake), redirect_stdout(output):
|
||||
try:
|
||||
exec(compile(source, 'fixed-native-fixture', 'exec'), {'__name__': '__fixture__'})
|
||||
except (ValueError, SystemExit):
|
||||
pass
|
||||
receipt = json.loads(output.getvalue()) if output.getvalue() else {'all_checks_pass': False}
|
||||
return receipt, writes, calls
|
||||
|
||||
def test_only_existing_application_operation_and_deployment_are_requested(self):
|
||||
objects, payload = self.fixture()
|
||||
receipt, writes, calls = self.execute_fake(objects, payload)
|
||||
self.assertTrue(receipt['all_checks_pass'])
|
||||
self.assertFalse(receipt['rollout_verified'])
|
||||
self.assertEqual(len(writes), 1)
|
||||
operation = writes[0][-1]['value']
|
||||
self.assertFalse(operation['sync']['prune'])
|
||||
self.assertEqual(operation['sync']['resources'], [
|
||||
{'group': 'apps', 'kind': 'Deployment', 'name': 'informed-decision', 'namespace': 'informed-decision'}])
|
||||
self.assertTrue(any('--dry-run=server' in argv and argv[:2] == ['kubectl', 'patch'] for argv in calls))
|
||||
self.assertEqual(writes[0][0]['path'], '/metadata/uid')
|
||||
|
||||
def test_source_overrides_automation_and_custody_drift_stop_before_write(self):
|
||||
mutations = [lambda o: o['application']['metadata'].update(uid='recreated'),
|
||||
lambda o: o['application']['spec'].update(syncPolicy={'automated': {}}),
|
||||
lambda o: o['application']['spec']['source'].update(kustomize={'images': ['other']}),
|
||||
lambda o: o['application']['spec'].update(sources=[{}]),
|
||||
lambda o: o['configmap']['metadata'].update(uid='recreated'),
|
||||
lambda o: o['pvc']['spec'].update(volumeName='replaced'),
|
||||
lambda o: o['deployment']['status'].update(readyReplicas=0)]
|
||||
for mutate in mutations:
|
||||
with self.subTest(mutate=mutate):
|
||||
objects, payload = self.fixture()
|
||||
mutate(objects)
|
||||
receipt, writes, calls = self.execute_fake(objects, payload)
|
||||
self.assertFalse(receipt['all_checks_pass'])
|
||||
self.assertEqual(writes, [])
|
||||
|
||||
def test_preopen_schema_refusal_prevents_image_operation(self):
|
||||
objects, payload = self.fixture()
|
||||
receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)
|
||||
self.assertFalse(receipt['all_checks_pass'])
|
||||
self.assertEqual(writes, [])
|
||||
|
||||
|
||||
def test_rollback_unready_candidate_never_reads_pod_or_database(self):
|
||||
objects, payload = self.fixture()
|
||||
payload['phase'] = 'rollback'
|
||||
objects['deployment']['status'].update(readyReplicas=0, updatedReplicas=0)
|
||||
objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = actuator.IMAGE
|
||||
objects['application']['spec']['source']['targetRevision'] = REVISION
|
||||
receipt, writes, calls = self.execute_fake(objects, payload, schema_refused=True)
|
||||
self.assertTrue(receipt['all_checks_pass'])
|
||||
self.assertFalse(receipt['rollout_verified'])
|
||||
self.assertEqual(len(writes), 1)
|
||||
self.assertFalse(any(argv[:2] == ['kubectl', 'exec'] or argv[:3] == ['kubectl', 'get', 'pods'] for argv in calls))
|
||||
self.assertEqual(writes[0][-1]['value']['sync']['revision'], '7db8485ffecdebfabd77a9daec085553c74bf0bf')
|
||||
|
||||
def test_rollback_still_refuses_custody_or_nonpair_image_drift(self):
|
||||
for defect in ('cm', 'pvc', 'image'):
|
||||
with self.subTest(defect=defect):
|
||||
objects, payload = self.fixture();payload['phase'] = 'rollback'
|
||||
objects['deployment']['status']['readyReplicas'] = 0
|
||||
if defect == 'cm':objects['configmap']['metadata']['uid'] = 'recreated'
|
||||
elif defect == 'pvc':objects['pvc']['spec']['volumeName'] = 'replaced'
|
||||
else:objects['deployment']['spec']['template']['spec']['containers'][0]['image'] = 'foreign-image'
|
||||
receipt, writes, calls = self.execute_fake(objects, payload)
|
||||
self.assertFalse(receipt['all_checks_pass']);self.assertEqual(writes, [])
|
||||
|
||||
def test_recovery_verification_is_separate_ready_old_image_schema_proof(self):
|
||||
objects, payload = self.fixture();payload['phase'] = 'rollback-verify'
|
||||
objects['application']['status'] = {'operationState': {'phase': 'Succeeded', 'operation': {'sync': {
|
||||
'revision': '7db8485ffecdebfabd77a9daec085553c74bf0bf', 'prune': False,
|
||||
'resources': [{'group':'apps','kind':'Deployment','name':'informed-decision','namespace':'informed-decision'}]}}}}
|
||||
receipt, writes, calls = self.execute_fake(objects, payload)
|
||||
self.assertTrue(receipt['all_checks_pass']);self.assertTrue(receipt['recovery_verification'])
|
||||
self.assertEqual(writes, [])
|
||||
self.assertTrue(any(argv[:2]==['kubectl','exec'] for argv in calls))
|
||||
objects['deployment']['status']['readyReplicas'] = 0
|
||||
receipt, writes, calls = self.execute_fake(objects,payload)
|
||||
self.assertFalse(receipt['all_checks_pass'])
|
||||
|
||||
def test_ambiguous_patch_is_never_retried(self):
|
||||
objects, payload = self.fixture()
|
||||
receipt, writes, calls = self.execute_fake(objects, payload, ambiguous=True)
|
||||
self.assertFalse(receipt['all_checks_pass'])
|
||||
self.assertEqual(len(writes), 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"tests": 16,
|
||||
"result": "passed",
|
||||
"synthetic_transport_only": true,
|
||||
"real_native_data_read": false,
|
||||
"native_backup_export_restore_executed": false,
|
||||
"native_workload_changed": false,
|
||||
"actual_founder_approval": false,
|
||||
"local_read_only_capability_checks": [
|
||||
"argocdCLI absent, existingApplication.operation path retained",
|
||||
"Dockerunixsocket engineName bnt-lap001"
|
||||
],
|
||||
"case_source_commit_at_preparation": "e0359bc (owner original78source; final helpercommit mustbe explicitlypinned)",
|
||||
"additional_regressions": [
|
||||
"Ready0 candidate rollback dispatch has no Pod metadata/DB exec and one scoped CAS operation",
|
||||
"rollback still refuses CM/PVC or nonpair-image drift",
|
||||
"separate old-image Ready/schema5 recovery proof",
|
||||
"post-admin readonly integrity refusal and original snapshot tamper refusal"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,314 @@
|
|||
{
|
||||
"deploy/lifecycle/admission.candidate.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/deploy/lifecycle/admission.candidate.json",
|
||||
"sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
"deploy/lifecycle/service.candidate.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/deploy/lifecycle/service.candidate.json",
|
||||
"sha256": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/README.md": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md",
|
||||
"sha256": "ca2c34727a462c63f017700f703324d934f5fa3adc858c2756d62096b119c40c"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/base-image-config.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json",
|
||||
"sha256": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json",
|
||||
"sha256": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json",
|
||||
"sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json",
|
||||
"sha256": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/change_guard.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py",
|
||||
"sha256": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/check_installed.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py",
|
||||
"sha256": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/decision-packet.md": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md",
|
||||
"sha256": "23da78cf998a32af0481e68567db94bb40781cc18f147461f779d40ebd329fd1"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json",
|
||||
"sha256": "2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/image-config.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json",
|
||||
"sha256": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/image-manifest.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json",
|
||||
"sha256": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json",
|
||||
"sha256": "e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/original-packet-manifest.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/original-packet-manifest.json",
|
||||
"sha256": "7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/admission.candidate.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/admission.candidate.json",
|
||||
"sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/service.candidate.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/service.candidate.json",
|
||||
"sha256": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md",
|
||||
"sha256": "f88a79a93fff34a1b438e2dc0344cad88d6c7960dde04bc7f3c04ac1fbb992c7"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json",
|
||||
"sha256": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json",
|
||||
"sha256": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json",
|
||||
"sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json",
|
||||
"sha256": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py",
|
||||
"sha256": "830f7771b5c7d0a2851973aa65a01c6ab40b86570f0933d8aebb89f9665ca7e1"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py",
|
||||
"sha256": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md",
|
||||
"sha256": "7f6d8987f65dff479eeead67b7ca940ef44c22c1cdbdd6ca33fd732b824c8f02"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json",
|
||||
"sha256": "aa1d494e42491f0619f731a836c597df9178409887d734c166a8df81f8807a27"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json",
|
||||
"sha256": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json",
|
||||
"sha256": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json",
|
||||
"sha256": "e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json",
|
||||
"sha256": "9a39631362f20168da409cef74f7690f3aa1b8f841fc96ecd8770f73a1f954ac"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json",
|
||||
"sha256": "b6210dcd34e5485c94e35f4bdd3329fb72c1d40fa9357caf40ac42b4f8afa5c2"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json",
|
||||
"sha256": "06530425dd9634182f70a65dd2da56cbad3da967bc842b3c7b01c30542222128"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md",
|
||||
"sha256": "aa9758d4de587d14c6ce0fdaccd84002c5c5099425b9169ca7c972a86e9d3dec"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json",
|
||||
"sha256": "052fc57d2cda43b2e474f28a5ff70753f5fa673c77a9645a201d0e0e961792e4"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json",
|
||||
"sha256": "aaa77b406b201eb40a62f60182057e90b1baea06e03f85d7e06916b57f5f2de8"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json",
|
||||
"sha256": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json",
|
||||
"sha256": "0bbdaf56459aaef3c35d7b1bf3ad20be6260f047df6dd1c5eb60ac1797150944"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py",
|
||||
"sha256": "c206a1a9b9d232c656c6d57fb9247549eefa13b275a5da4d39b45a6c9902c834"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json",
|
||||
"sha256": "08c5573eaad05efd24b6df6737d33e7189543eb621f21704e38bab4326094914"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json",
|
||||
"sha256": "e304dd29571bf7d7b9f1db2ade0163dd39cfec012a5ce6986139f019f37e65a2"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json",
|
||||
"sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json",
|
||||
"sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json",
|
||||
"sha256": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json",
|
||||
"sha256": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json",
|
||||
"sha256": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json",
|
||||
"sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py",
|
||||
"sha256": "b7cd28b2ada33004c9264cb54c9749fa501f60166638f926e50e264ddebe037d"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json",
|
||||
"sha256": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json",
|
||||
"sha256": "3b57f525bbbb1db9dc46bcc6b0057a8dd9f45c461fad0a8dea5391ca78038c36"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py",
|
||||
"sha256": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md.source.txt": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md.source.txt",
|
||||
"sha256": "18205c0c7aa8f3460d78e3b7ad9dddd9e361395f9a28d93a7a384c29c9602d36"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/intake.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json",
|
||||
"sha256": "f61da7bf60e42728c2ef2f98838f310e9f97765096015492917ef8e9cab2d000"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json",
|
||||
"sha256": "c25d47a084401aafe4f17b9e9ac87bf099d7c9f423bd181509617314884bd28a"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/memo.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json",
|
||||
"sha256": "33a321fe0c276733034288e7395496cb52c8eaf7730da880637cfa379276978c"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md",
|
||||
"sha256": "2f8d4894c2861b34977ec020593b7515a8ee35a43ce2e6aef2d96a6d34a94ddc"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json",
|
||||
"sha256": "052fc57d2cda43b2e474f28a5ff70753f5fa673c77a9645a201d0e0e961792e4"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json",
|
||||
"sha256": "aaa77b406b201eb40a62f60182057e90b1baea06e03f85d7e06916b57f5f2de8"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/native-preflight.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json",
|
||||
"sha256": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json",
|
||||
"sha256": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/preflight.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py",
|
||||
"sha256": "6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/proposal.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json",
|
||||
"sha256": "a59bcddc6c79e3ba8265a95b4b68facda2683abda8e47e5bb48ce402b9e1fa82"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/published-verification.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json",
|
||||
"sha256": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/registry-proof.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json",
|
||||
"sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/review-refinement.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/review-refinement.json",
|
||||
"sha256": "ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json",
|
||||
"sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json",
|
||||
"sha256": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json",
|
||||
"sha256": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json",
|
||||
"sha256": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/sealed-native-dependencies.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-native-dependencies.json",
|
||||
"sha256": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/security-summary.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json",
|
||||
"sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py",
|
||||
"sha256": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py",
|
||||
"sha256": "da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/test_preflight_optimization.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_preflight_optimization.py",
|
||||
"sha256": "a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/test_sqlite_readonly.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_sqlite_readonly.py",
|
||||
"sha256": "c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/trivy-full.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json",
|
||||
"sha256": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/validation.json": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json",
|
||||
"sha256": "303490dd5a89da0ea2ea92149cfa7cd580e8f3270d3db42edae1c59e4aaf42ca"
|
||||
},
|
||||
"docs/evidence/2026-10-11-purpose-image-release/verify_registry.py": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py",
|
||||
"sha256": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4"
|
||||
},
|
||||
"workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md": {
|
||||
"archive_relative": "initial-b1e3e66b/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.source.txt",
|
||||
"sha256": "24e4b022f17ca041ccfbfb11d6de6373c90f4e790690e1cd4cf00e84fde6b838"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,548 @@
|
|||
[
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "deploy/lifecycle/admission.candidate.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/deploy/lifecycle/admission.candidate.json",
|
||||
"original_sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50",
|
||||
"staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "deploy/lifecycle/service.candidate.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/deploy/lifecycle/service.candidate.json",
|
||||
"original_sha256": "7a676532836affd6d75c7f1c41a5f937d8c8c809f63e3264ccce612730d5ba7b",
|
||||
"staged_sha256": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/README.md",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/README.md",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "ca2c34727a462c63f017700f703324d934f5fa3adc858c2756d62096b119c40c"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/base-image-config.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/change_guard.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/change_guard.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/check_installed.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/check_installed.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/decision-packet.md",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "23da78cf998a32af0481e68567db94bb40781cc18f147461f779d40ebd329fd1"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/image-config.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/image-config.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/image-manifest.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/original-packet-manifest.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/original-packet-manifest.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/admission.candidate.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/admission.candidate.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/service.candidate.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/deploy/lifecycle/service.candidate.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "f88a79a93fff34a1b438e2dc0344cad88d6c7960dde04bc7f3c04ac1fbb992c7"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "830f7771b5c7d0a2851973aa65a01c6ab40b86570f0933d8aebb89f9665ca7e1"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "7f6d8987f65dff479eeead67b7ca940ef44c22c1cdbdd6ca33fd732b824c8f02"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "aa1d494e42491f0619f731a836c597df9178409887d734c166a8df81f8807a27"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "9a39631362f20168da409cef74f7690f3aa1b8f841fc96ecd8770f73a1f954ac"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "b6210dcd34e5485c94e35f4bdd3329fb72c1d40fa9357caf40ac42b4f8afa5c2"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "06530425dd9634182f70a65dd2da56cbad3da967bc842b3c7b01c30542222128"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "aa9758d4de587d14c6ce0fdaccd84002c5c5099425b9169ca7c972a86e9d3dec"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "052fc57d2cda43b2e474f28a5ff70753f5fa673c77a9645a201d0e0e961792e4"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "aaa77b406b201eb40a62f60182057e90b1baea06e03f85d7e06916b57f5f2de8"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "0bbdaf56459aaef3c35d7b1bf3ad20be6260f047df6dd1c5eb60ac1797150944"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "c206a1a9b9d232c656c6d57fb9247549eefa13b275a5da4d39b45a6c9902c834"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "08c5573eaad05efd24b6df6737d33e7189543eb621f21704e38bab4326094914"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "e304dd29571bf7d7b9f1db2ade0163dd39cfec012a5ce6986139f019f37e65a2"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "b7cd28b2ada33004c9264cb54c9749fa501f60166638f926e50e264ddebe037d"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "3b57f525bbbb1db9dc46bcc6b0057a8dd9f45c461fad0a8dea5391ca78038c36"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md.source.txt",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/initial-7c6738b3/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md.source.txt",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "18205c0c7aa8f3460d78e3b7ad9dddd9e361395f9a28d93a7a384c29c9602d36"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/intake.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/intake.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "f61da7bf60e42728c2ef2f98838f310e9f97765096015492917ef8e9cab2d000"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "c25d47a084401aafe4f17b9e9ac87bf099d7c9f423bd181509617314884bd28a"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/memo.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/memo.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "33a321fe0c276733034288e7395496cb52c8eaf7730da880637cfa379276978c"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "2f8d4894c2861b34977ec020593b7515a8ee35a43ce2e6aef2d96a6d34a94ddc"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "052fc57d2cda43b2e474f28a5ff70753f5fa673c77a9645a201d0e0e961792e4"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "aaa77b406b201eb40a62f60182057e90b1baea06e03f85d7e06916b57f5f2de8"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/native-preflight.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/preflight.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/preflight.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/proposal.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/proposal.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "a59bcddc6c79e3ba8265a95b4b68facda2683abda8e47e5bb48ce402b9e1fa82"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/published-verification.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/published-verification.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/registry-proof.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/review-refinement.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/review-refinement.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/sealed-native-dependencies.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/sealed-native-dependencies.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/security-summary.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/security-summary.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/sqlite_readonly.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/test_preflight_optimization.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/test_preflight_optimization.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/test_sqlite_readonly.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/test_sqlite_readonly.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/trivy-full.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/validation.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/validation.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "303490dd5a89da0ea2ea92149cfa7cd580e8f3270d3db42edae1c59e4aaf42ca"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/verify_registry.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md",
|
||||
"original_sha256": "1544ece11a7a528a34b635b267b72e1c3fd4de99327200aded74864c64e64e77",
|
||||
"staged_sha256": "24e4b022f17ca041ccfbfb11d6de6373c90f4e790690e1cd4cf00e84fde6b838"
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"policy": {
|
||||
"origin": "http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080",
|
||||
"package": "informed-decision.compact-sitting",
|
||||
"version": "v13",
|
||||
"package_digest": "sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873",
|
||||
"pod_name": "flex-auth-informed-decision-sitting"
|
||||
},
|
||||
"keycape_egress_ips": [
|
||||
"92.205.62.239"
|
||||
],
|
||||
"storage_class": "local-path",
|
||||
"ordinary_approval_ids": [
|
||||
"2ce76d7f-01c3-4b63-8476-8d1230679769",
|
||||
"c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
|
||||
"dc22666a-d5d7-46bc-9490-ebe9fe09dc38"
|
||||
],
|
||||
"lifecycle_policy": {
|
||||
"package": "informed-decision.lifecycle",
|
||||
"version": "v2",
|
||||
"package_digest": "sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c",
|
||||
"origin": "http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080",
|
||||
"pod_name": "flex-auth-informed-decision-lifecycle"
|
||||
},
|
||||
"lifecycle_delivery": true,
|
||||
"intake_attributes": true,
|
||||
"intake_delivery": {
|
||||
"hub_origin": "http://state-hub.state-hub.svc.cluster.local:8000"
|
||||
},
|
||||
"workload_api": {
|
||||
"registries_configmap": "informed-decision-workload-registry",
|
||||
"peers": [
|
||||
{
|
||||
"namespace": "state-hub",
|
||||
"app": "state-hub"
|
||||
}
|
||||
],
|
||||
"api_egress": [
|
||||
{
|
||||
"ip": "10.43.0.1",
|
||||
"port": 443
|
||||
},
|
||||
{
|
||||
"ip": "92.205.62.239",
|
||||
"port": 6443
|
||||
}
|
||||
],
|
||||
"intake": true,
|
||||
"lifecycle": true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,800 @@
|
|||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "List",
|
||||
"items": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ServiceAccount",
|
||||
"metadata": {
|
||||
"name": "review",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"automountServiceAccountToken": false
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "PersistentVolumeClaim",
|
||||
"metadata": {
|
||||
"name": "informed-decision-data",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"accessModes": [
|
||||
"ReadWriteOnce"
|
||||
],
|
||||
"storageClassName": "local-path",
|
||||
"resources": {
|
||||
"requests": {
|
||||
"storage": "1Gi"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
"metadata": {
|
||||
"name": "informed-decision-runtime-6c221878d051",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"immutable": true,
|
||||
"data": {
|
||||
"runtime.json": "{\"approval_origin\":\"http://approval-engine.approval-engine.svc.cluster.local:8080\",\"audit\":{\"origin\":\"http://audit-core.audit-core.svc.cluster.local:8080\",\"sender_token_file\":\"/var/run/secrets/informed-decision/audit/token\"},\"evidence_db\":\"/data/private/review.sqlite\",\"intake_attributes\":true,\"intake_delivery\":{\"hub_origin\":\"http://state-hub.state-hub.svc.cluster.local:8000\"},\"lifecycle_delivery\":true,\"lifecycle_policy\":{\"caller_token_file\":\"/var/run/secrets/informed-decision/policy/token\",\"origin\":\"http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080\",\"package\":\"informed-decision.lifecycle\",\"package_digest\":\"sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c\",\"version\":\"v2\"},\"ordinary_approval_ids\":[\"2ce76d7f-01c3-4b63-8476-8d1230679769\",\"c2af4bcf-15b4-4305-aac1-acc7e4dcb099\",\"dc22666a-d5d7-46bc-9490-ebe9fe09dc38\"],\"policy\":{\"caller_token_file\":\"/var/run/secrets/informed-decision/policy/token\",\"origin\":\"http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080\",\"package\":\"informed-decision.compact-sitting\",\"package_digest\":\"sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873\",\"version\":\"v13\"},\"schema\":\"informed-decision.review-runtime.v1\",\"workload_api\":{\"intake\":{\"groups_file\":\"/workload-registry/review-groups.json\",\"secret_file\":\"/var/run/secrets/informed-decision/requester/client-secret\",\"submitters_file\":\"/workload-registry/intake-submitters.json\"},\"lifecycle_callers_file\":\"/workload-registry/lifecycle-callers.json\",\"token_review\":{\"ca_file\":\"/var/run/secrets/informed-decision/kubernetes/ca.crt\",\"origin\":\"https://kubernetes.default.svc:443\",\"token_file\":\"/var/run/secrets/informed-decision/kubernetes/token\"}}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"name": "informed-decision",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"replicas": 1,
|
||||
"strategy": {
|
||||
"type": "Recreate"
|
||||
},
|
||||
"progressDeadlineSeconds": 600,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"automountServiceAccountToken": false,
|
||||
"serviceAccountName": "review",
|
||||
"terminationGracePeriodSeconds": 45,
|
||||
"securityContext": {
|
||||
"runAsNonRoot": true,
|
||||
"runAsUser": 10001,
|
||||
"runAsGroup": 10001,
|
||||
"fsGroup": 10001,
|
||||
"fsGroupChangePolicy": "OnRootMismatch",
|
||||
"seccompProfile": {
|
||||
"type": "RuntimeDefault"
|
||||
}
|
||||
},
|
||||
"containers": [
|
||||
{
|
||||
"name": "informed-decision",
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"securityContext": {
|
||||
"allowPrivilegeEscalation": false,
|
||||
"readOnlyRootFilesystem": true,
|
||||
"capabilities": {
|
||||
"drop": [
|
||||
"ALL"
|
||||
]
|
||||
}
|
||||
},
|
||||
"env": [
|
||||
{
|
||||
"name": "INFD_KEYCAPE_ISSUER",
|
||||
"value": "https://kc.coulomb.social"
|
||||
},
|
||||
{
|
||||
"name": "INFD_CONTAINER_CONFIG",
|
||||
"value": "/configuration/runtime.json"
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"containerPort": 8080
|
||||
},
|
||||
{
|
||||
"name": "workload",
|
||||
"containerPort": 8081
|
||||
}
|
||||
],
|
||||
"startupProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2,
|
||||
"failureThreshold": 12
|
||||
},
|
||||
"readinessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"livenessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"resources": {
|
||||
"requests": {
|
||||
"cpu": "5m",
|
||||
"memory": "64Mi"
|
||||
},
|
||||
"limits": {
|
||||
"cpu": "500m",
|
||||
"memory": "256Mi"
|
||||
}
|
||||
},
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "data",
|
||||
"mountPath": "/data"
|
||||
},
|
||||
{
|
||||
"name": "runtime",
|
||||
"mountPath": "/run/informed-decision"
|
||||
},
|
||||
{
|
||||
"name": "tmp",
|
||||
"mountPath": "/tmp"
|
||||
},
|
||||
{
|
||||
"name": "configuration",
|
||||
"mountPath": "/configuration",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "caller",
|
||||
"mountPath": "/var/run/secrets/informed-decision/policy",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "audit",
|
||||
"mountPath": "/var/run/secrets/informed-decision/audit",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "kubernetes-api",
|
||||
"mountPath": "/var/run/secrets/informed-decision/kubernetes",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "workload-registry",
|
||||
"mountPath": "/workload-registry",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "sitting-requester",
|
||||
"mountPath": "/var/run/secrets/informed-decision/requester",
|
||||
"readOnly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"name": "data",
|
||||
"persistentVolumeClaim": {
|
||||
"claimName": "informed-decision-data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "runtime",
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tmp",
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "configuration",
|
||||
"configMap": {
|
||||
"name": "informed-decision-runtime-6c221878d051",
|
||||
"defaultMode": 292
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "caller",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"path": "token",
|
||||
"audience": "flex-auth",
|
||||
"expirationSeconds": 3600
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "audit",
|
||||
"secret": {
|
||||
"secretName": "informed-decision-audit",
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "token",
|
||||
"path": "token"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "kubernetes-api",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"path": "token",
|
||||
"expirationSeconds": 600
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"name": "kube-root-ca.crt",
|
||||
"items": [
|
||||
{
|
||||
"key": "ca.crt",
|
||||
"path": "ca.crt"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "workload-registry",
|
||||
"configMap": {
|
||||
"name": "informed-decision-workload-registry",
|
||||
"defaultMode": 292
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sitting-requester",
|
||||
"secret": {
|
||||
"secretName": "informed-decision-sitting-requester",
|
||||
"defaultMode": 288,
|
||||
"optional": false,
|
||||
"items": [
|
||||
{
|
||||
"key": "client-secret",
|
||||
"path": "client-secret"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "informed-decision",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 80,
|
||||
"targetPort": "http",
|
||||
"protocol": "TCP"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "networking.k8s.io/v1",
|
||||
"kind": "NetworkPolicy",
|
||||
"metadata": {
|
||||
"name": "informed-decision-review",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
}
|
||||
},
|
||||
"policyTypes": [
|
||||
"Ingress",
|
||||
"Egress"
|
||||
],
|
||||
"ingress": [
|
||||
{
|
||||
"from": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "kube-system"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "traefik"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8080
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "state-hub"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "state-hub"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8081
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"egress": [
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "kube-system"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"k8s-app": "kube-dns"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "UDP",
|
||||
"port": 53
|
||||
},
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 53
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "approval-engine"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "approval-engine"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "audit-core"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "audit-core"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "flex-auth"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "flex-auth-informed-decision-sitting"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "flex-auth"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "flex-auth-informed-decision-lifecycle"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8080
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "kube-system"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "traefik"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8443
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"ipBlock": {
|
||||
"cidr": "92.205.62.239/32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 443
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "state-hub"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "state-hub"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"ipBlock": {
|
||||
"cidr": "10.43.0.1/32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 443
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"ipBlock": {
|
||||
"cidr": "92.205.62.239/32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 6443
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "informed-decision-workload",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "workload",
|
||||
"port": 8081,
|
||||
"targetPort": "workload",
|
||||
"protocol": "TCP"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "rbac.authorization.k8s.io/v1",
|
||||
"kind": "ClusterRole",
|
||||
"metadata": {
|
||||
"name": "informed-decision-tokenreview",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "proposal; INFD-WP-0007/INFD-WP-0005 owner review required"
|
||||
}
|
||||
},
|
||||
"rules": [
|
||||
{
|
||||
"apiGroups": [
|
||||
"authentication.k8s.io"
|
||||
],
|
||||
"resources": [
|
||||
"tokenreviews"
|
||||
],
|
||||
"verbs": [
|
||||
"create"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiVersion": "rbac.authorization.k8s.io/v1",
|
||||
"kind": "ClusterRoleBinding",
|
||||
"metadata": {
|
||||
"name": "informed-decision-tokenreview",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "proposal; INFD-WP-0007/INFD-WP-0005 owner review required"
|
||||
}
|
||||
},
|
||||
"roleRef": {
|
||||
"apiGroup": "rbac.authorization.k8s.io",
|
||||
"kind": "ClusterRole",
|
||||
"name": "informed-decision-tokenreview"
|
||||
},
|
||||
"subjects": [
|
||||
{
|
||||
"kind": "ServiceAccount",
|
||||
"name": "review",
|
||||
"namespace": "informed-decision"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiVersion": "networking.k8s.io/v1",
|
||||
"kind": "NetworkPolicy",
|
||||
"metadata": {
|
||||
"name": "informed-decision-review-ingress",
|
||||
"namespace": "approval-engine",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08",
|
||||
"informed-decision.coulomb.social/owner-review": "APPROVAL-WP-0002-T01"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "approval-engine"
|
||||
}
|
||||
},
|
||||
"policyTypes": [
|
||||
"Ingress"
|
||||
],
|
||||
"ingress": [
|
||||
{
|
||||
"from": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8080
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "networking.k8s.io/v1",
|
||||
"kind": "NetworkPolicy",
|
||||
"metadata": {
|
||||
"name": "informed-decision-review-ingress",
|
||||
"namespace": "flex-auth",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08",
|
||||
"informed-decision.coulomb.social/owner-review": "INFD-WP-0001-T08 policy-owner return"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "flex-auth-informed-decision-sitting"
|
||||
}
|
||||
},
|
||||
"policyTypes": [
|
||||
"Ingress"
|
||||
],
|
||||
"ingress": [
|
||||
{
|
||||
"from": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8080
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "networking.k8s.io/v1",
|
||||
"kind": "NetworkPolicy",
|
||||
"metadata": {
|
||||
"name": "informed-decision-lifecycle-ingress",
|
||||
"namespace": "flex-auth",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08",
|
||||
"informed-decision.coulomb.social/owner-review": "INFD-WP-0007 lifecycle policy-owner return"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "flex-auth-informed-decision-lifecycle"
|
||||
}
|
||||
},
|
||||
"policyTypes": [
|
||||
"Ingress"
|
||||
],
|
||||
"ingress": [
|
||||
{
|
||||
"from": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8080
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Exact published purpose overlay and unapproved native release packet
|
||||
|
||||
Actual CI task11484/run3 at3e4bcb26 published immutable763c. The registry proof, installedUID/mode/purpose checks, full scan/SBOM and actualbase comparison are retained. The full scan contains1fixable inheritedMEDIUM,0HIGH/CRITICAL; see owner follow-through/T05. Legacy serialization differences are disclosed.
|
||||
|
||||
This stage prepares owner admission/service source candidates, protected native backup/restore protocol and20document offline-valid informed-decision memo. Native workload remains7f5/config6c. No native backup/export/restore, image change or human approval occurred. Initial failed CI/native preflight evidence remains in owner history. The original36path7c packet is fully archived and remains refinement-required, not approved. The amended gate adds pre-open stdlib readonlyschema5/integrity/count checks, explicitlocal/remote optimizationrefusal and actualCM/PVC UID/content/custody seals. The immutable original native capture stays sealed; future preflight requires unique output outside the sealed packet and owner source tree.
|
||||
|
||||
The memo's actual rawscan attachment plus hash-linked rawSBOM/base scan totalamended boundedpacketbytes (under256KiB); source/image receipt binds raw evidence filenames and hashes. Full owner source manifest includes all raw evidence and helper/tests. Source preparation or local checks do not approve native execution.
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
{
|
||||
"architecture": "amd64",
|
||||
"config": {
|
||||
"User": "10001:10001",
|
||||
"ExposedPorts": {
|
||||
"8080/tcp": {},
|
||||
"8081/tcp": {}
|
||||
},
|
||||
"Env": [
|
||||
"PATH=/opt/venv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"LANG=C.UTF-8",
|
||||
"GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305",
|
||||
"PYTHON_VERSION=3.12.14",
|
||||
"PYTHON_SHA256=5c8462af5790baf43a321a1559dbe0db06d1be4300fb85fb53c40060668e548a",
|
||||
"PYTHONDONTWRITEBYTECODE=1",
|
||||
"PYTHONUNBUFFERED=1"
|
||||
],
|
||||
"Entrypoint": [
|
||||
"informed-decision-container"
|
||||
],
|
||||
"WorkingDir": "/app"
|
||||
},
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"history": [
|
||||
{
|
||||
"created": "2026-06-16T00:01:29.967161902Z",
|
||||
"created_by": "ADD alpine-minirootfs-3.24.1-x86_64.tar.gz / # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-06-16T00:01:29.967161902Z",
|
||||
"created_by": "CMD [\"/bin/sh\"]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV LANG=C.UTF-8",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "RUN /bin/sh -c set -eux; \tapk add --no-cache \t\tca-certificates \t\ttzdata \t; # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV PYTHON_VERSION=3.12.14",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV PYTHON_SHA256=5c8462af5790baf43a321a1559dbe0db06d1be4300fb85fb53c40060668e548a",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:10:30.672225972Z",
|
||||
"created_by": "RUN /bin/sh -c set -eux; \t\tapk add --no-cache --virtual .build-deps \t\tbluez-dev \t\tbzip2-dev \t\tdpkg-dev dpkg \t\tfindutils \t\tg++ \t\tgcc \t\tgdbm-dev \t\tgnupg \t\tlibc-dev \t\tlibffi-dev \t\tlibnsl-dev \t\tlibtirpc-dev \t\tlinux-headers \t\tmake \t\tncurses-dev \t\topenssl-dev \t\tpax-utils \t\treadline-dev \t\tsqlite-dev \t\ttar \t\ttcl-dev \t\ttk \t\ttk-dev \t\tutil-linux-dev \t\txz \t\txz-dev \t\tzlib-dev \t; \t\twget -O python.tar.xz \"https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz\"; \techo \"$PYTHON_SHA256 *python.tar.xz\" | sha256sum -c -; \twget -O python.tar.xz.asc \"https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc\"; \tGNUPGHOME=\"$(mktemp -d)\"; export GNUPGHOME; \tgpg --batch --keyserver hkps://keys.openpgp.org --recv-keys \"$GPG_KEY\"; \tgpg --batch --verify python.tar.xz.asc python.tar.xz; \tgpgconf --kill all; \trm -rf \"$GNUPGHOME\" python.tar.xz.asc; \tmkdir -p /usr/src/python; \ttar --extract --directory /usr/src/python --strip-components=1 --file python.tar.xz; \trm python.tar.xz; \t\tcd /usr/src/python; \tgnuArch=\"$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)\"; \t./configure \t\t--build=\"$gnuArch\" \t\t--enable-loadable-sqlite-extensions \t\t--enable-option-checking=fatal \t\t--enable-shared \t\t$(test \"${gnuArch%%-*}\" != 'riscv64' && echo '--with-lto') \t\t--with-ensurepip \t; \tnproc=\"$(nproc)\"; \tEXTRA_CFLAGS=\"-DTHREAD_STACK_SIZE=0x100000\"; \tLDFLAGS=\"${LDFLAGS:-} -Wl,--strip-all\"; \tarch=\"$(apk --print-arch)\"; \tcase \"$arch\" in \t\tx86_64|aarch64) \t\t\tEXTRA_CFLAGS=\"${EXTRA_CFLAGS:-} -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer\"; \t\t\t;; \t\tx86) \t\t\t;; \t\t*) \t\t\tEXTRA_CFLAGS=\"${EXTRA_CFLAGS:-} -fno-omit-frame-pointer\"; \t\t\t;; \tesac; \tmake -j \"$nproc\" \t\t\"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}\" \t\t\"LDFLAGS=${LDFLAGS:-}\" \t; \trm python; \tmake -j \"$nproc\" \t\t\"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}\" \t\t\"LDFLAGS=${LDFLAGS:-} -Wl,-rpath='\\$\\$ORIGIN/../lib'\" \t\tpython \t; \tmake install; \t\tcd /; \trm -rf /usr/src/python; \t\tfind /usr/local -depth \t\t\\( \t\t\t\\( -type d -a \\( -name test -o -name tests -o -name idle_test \\) \\) \t\t\t-o \\( -type f -a \\( -name '*.pyc' -o -name '*.pyo' -o -name 'libpython*.a' \\) \\) \t\t\\) -exec rm -rf '{}' + \t; \t\tfind /usr/local -type f -executable -not \\( -name '*tkinter*' \\) -exec scanelf --needed --nobanner --format '%n#p' '{}' ';' \t\t| tr ',' '\\n' \t\t| sort -u \t\t| awk 'system(\"[ -e /usr/local/lib/\" $1 \" ]\") == 0 { next } { print \"so:\" $1 }' \t\t| xargs -rt apk add --no-network --virtual .python-rundeps \t; \tapk del --no-network .build-deps; \t\texport PYTHONDONTWRITEBYTECODE=1; \tpython3 --version; \tpip3 --version # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:10:30.782726003Z",
|
||||
"created_by": "RUN /bin/sh -c set -eux; \tfor src in idle3 pip3 pydoc3 python3 python3-config; do \t\tdst=\"$(echo \"$src\" | tr -d 3)\"; \t\t[ -s \"/usr/local/bin/$src\" ]; \t\t[ ! -e \"/usr/local/bin/$dst\" ]; \t\tln -svT \"$src\" \"/usr/local/bin/$dst\"; \tdone # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:10:30.782726003Z",
|
||||
"created_by": "CMD [\"python3\"]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-11T00:49:47.962156876+02:00",
|
||||
"created_by": "ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PATH=/opt/venv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-11T00:49:47.962156876+02:00",
|
||||
"created_by": "RUN /bin/sh -c apk add --no-cache 'libuuid>=2.42.3-r1' && addgroup -S -g 10001 informed && adduser -S -u 10001 -G informed -H informed # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:55.351944978+02:00",
|
||||
"created_by": "COPY /opt/venv /opt/venv # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.462092072+02:00",
|
||||
"created_by": "RUN /bin/sh -c rm -rf /usr/local/bin/pip* /usr/local/lib/python3.12/site-packages/pip* /usr/local/lib/python3.12/site-packages/setuptools* /usr/local/lib/python3.12/site-packages/pkg_resources /opt/venv/bin/pip* /opt/venv/lib/python3.12/site-packages/pip* /opt/venv/lib/python3.12/site-packages/setuptools* /opt/venv/lib/python3.12/site-packages/pkg_resources # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "WORKDIR /app",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "USER 10001:10001",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "EXPOSE [8080/tcp 8081/tcp]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "ENTRYPOINT [\"informed-decision-container\"]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
}
|
||||
],
|
||||
"os": "linux",
|
||||
"rootfs": {
|
||||
"type": "layers",
|
||||
"diff_ids": [
|
||||
"sha256:34884abbe92863fce933ed7c39c0e045631af0ed86d5cc0dfbdf9fdca426ce3c",
|
||||
"sha256:3ca4be2c6e9ac0223715355253725381000486c2b45bfcb22cf571b6a85a12dd",
|
||||
"sha256:e5ccda0fbf6b54d343e024156d876553ba57d3926d7196584b3a1ce4df016366",
|
||||
"sha256:4098ad033525263f92a8a9c51865596025d47018e078c0b1f7d9cd5663fc1ffe",
|
||||
"sha256:f9b4a8a412a0c07a489e46fb5db41f9d0dc84d4ec38a4e2c6ab9531f44e0d9f1",
|
||||
"sha256:648451a0dda84ad04681e32b5ecc7cd5d3a4f0ad84f783e9598d72bc69620d5c",
|
||||
"sha256:361430a1113969743b99e237b20f023d5497493bcf96fb91af99ac0a0dbc4a59",
|
||||
"sha256:cfc5939674d67f60b4411c24dfcde5622b712eeb7376cd0941a2751da80a6b02"
|
||||
]
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"policy": {
|
||||
"origin": "http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080",
|
||||
"package": "informed-decision.compact-sitting",
|
||||
"version": "v13",
|
||||
"package_digest": "sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873",
|
||||
"pod_name": "flex-auth-informed-decision-sitting"
|
||||
},
|
||||
"keycape_egress_ips": [
|
||||
"92.205.62.239"
|
||||
],
|
||||
"storage_class": "local-path",
|
||||
"ordinary_approval_ids": [
|
||||
"2ce76d7f-01c3-4b63-8476-8d1230679769",
|
||||
"c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
|
||||
"dc22666a-d5d7-46bc-9490-ebe9fe09dc38"
|
||||
],
|
||||
"lifecycle_policy": {
|
||||
"package": "informed-decision.lifecycle",
|
||||
"version": "v2",
|
||||
"package_digest": "sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c",
|
||||
"origin": "http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080",
|
||||
"pod_name": "flex-auth-informed-decision-lifecycle"
|
||||
},
|
||||
"lifecycle_delivery": true,
|
||||
"intake_attributes": true,
|
||||
"intake_delivery": {
|
||||
"hub_origin": "http://state-hub.state-hub.svc.cluster.local:8000"
|
||||
},
|
||||
"workload_api": {
|
||||
"registries_configmap": "informed-decision-workload-registry",
|
||||
"peers": [
|
||||
{
|
||||
"namespace": "state-hub",
|
||||
"app": "state-hub"
|
||||
}
|
||||
],
|
||||
"api_egress": [
|
||||
{
|
||||
"ip": "10.43.0.1",
|
||||
"port": 443
|
||||
},
|
||||
{
|
||||
"ip": "92.205.62.239",
|
||||
"port": 6443
|
||||
}
|
||||
],
|
||||
"intake": true,
|
||||
"lifecycle": true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover",
|
||||
"argocd.argoproj.io/tracking-id": "informed-decision:apps/Deployment:informed-decision/informed-decision"
|
||||
},
|
||||
"name": "informed-decision",
|
||||
"namespace": "informed-decision"
|
||||
},
|
||||
"spec": {
|
||||
"progressDeadlineSeconds": 600,
|
||||
"replicas": 1,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"strategy": {
|
||||
"type": "Recreate"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover"
|
||||
},
|
||||
"labels": {
|
||||
"app.kubernetes.io/component": "review",
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"automountServiceAccountToken": false,
|
||||
"containers": [
|
||||
{
|
||||
"env": [
|
||||
{
|
||||
"name": "INFD_KEYCAPE_ISSUER",
|
||||
"value": "https://kc.coulomb.social"
|
||||
},
|
||||
{
|
||||
"name": "INFD_CONTAINER_CONFIG",
|
||||
"value": "/configuration/runtime.json"
|
||||
}
|
||||
],
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"livenessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"name": "informed-decision",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 8080,
|
||||
"name": "http"
|
||||
},
|
||||
{
|
||||
"containerPort": 8081,
|
||||
"name": "workload"
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"resources": {
|
||||
"limits": {
|
||||
"cpu": "500m",
|
||||
"memory": "256Mi"
|
||||
},
|
||||
"requests": {
|
||||
"cpu": "5m",
|
||||
"memory": "64Mi"
|
||||
}
|
||||
},
|
||||
"securityContext": {
|
||||
"allowPrivilegeEscalation": false,
|
||||
"capabilities": {
|
||||
"drop": [
|
||||
"ALL"
|
||||
]
|
||||
},
|
||||
"readOnlyRootFilesystem": true
|
||||
},
|
||||
"startupProbe": {
|
||||
"failureThreshold": 12,
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/data",
|
||||
"name": "data"
|
||||
},
|
||||
{
|
||||
"mountPath": "/run/informed-decision",
|
||||
"name": "runtime"
|
||||
},
|
||||
{
|
||||
"mountPath": "/tmp",
|
||||
"name": "tmp"
|
||||
},
|
||||
{
|
||||
"mountPath": "/configuration",
|
||||
"name": "configuration",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/policy",
|
||||
"name": "caller",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/audit",
|
||||
"name": "audit",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/kubernetes",
|
||||
"name": "kubernetes-api",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/workload-registry",
|
||||
"name": "workload-registry",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/requester",
|
||||
"name": "sitting-requester",
|
||||
"readOnly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"securityContext": {
|
||||
"fsGroup": 10001,
|
||||
"fsGroupChangePolicy": "OnRootMismatch",
|
||||
"runAsGroup": 10001,
|
||||
"runAsNonRoot": true,
|
||||
"runAsUser": 10001,
|
||||
"seccompProfile": {
|
||||
"type": "RuntimeDefault"
|
||||
}
|
||||
},
|
||||
"serviceAccountName": "review",
|
||||
"terminationGracePeriodSeconds": 45,
|
||||
"volumes": [
|
||||
{
|
||||
"name": "data",
|
||||
"persistentVolumeClaim": {
|
||||
"claimName": "informed-decision-data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
},
|
||||
"name": "runtime"
|
||||
},
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
},
|
||||
"name": "tmp"
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 292,
|
||||
"name": "informed-decision-runtime-6c221878d051"
|
||||
},
|
||||
"name": "configuration"
|
||||
},
|
||||
{
|
||||
"name": "caller",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"audience": "flex-auth",
|
||||
"expirationSeconds": 3600,
|
||||
"path": "token"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "audit",
|
||||
"secret": {
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "token",
|
||||
"path": "token"
|
||||
}
|
||||
],
|
||||
"secretName": "informed-decision-audit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "kubernetes-api",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"expirationSeconds": 600,
|
||||
"path": "token"
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"items": [
|
||||
{
|
||||
"key": "ca.crt",
|
||||
"path": "ca.crt"
|
||||
}
|
||||
],
|
||||
"name": "kube-root-ca.crt"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 292,
|
||||
"name": "informed-decision-workload-registry"
|
||||
},
|
||||
"name": "workload-registry"
|
||||
},
|
||||
{
|
||||
"name": "sitting-requester",
|
||||
"secret": {
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "client-secret",
|
||||
"path": "client-secret"
|
||||
}
|
||||
],
|
||||
"optional": false,
|
||||
"secretName": "informed-decision-sitting-requester"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
"""Read-only exact Deployment and admission boundaries; no mutation authority."""
|
||||
import copy
|
||||
import hashlib
|
||||
import json
|
||||
|
||||
BASE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173'
|
||||
CANDIDATE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'
|
||||
|
||||
|
||||
def dependency_projection(configmap, pvc):
|
||||
if (configmap.get('kind') != 'ConfigMap' or configmap.get('immutable') is not True
|
||||
or configmap['metadata']['namespace'] != 'informed-decision'
|
||||
or configmap['metadata']['name'] != 'informed-decision-runtime-6c221878d051'
|
||||
or set(configmap.get('data', {})) != {'runtime.json'}
|
||||
or configmap.get('binaryData')):
|
||||
raise ValueError('unexpected immutable runtime config identity')
|
||||
if (pvc.get('kind') != 'PersistentVolumeClaim'
|
||||
or pvc['metadata']['namespace'] != 'informed-decision'
|
||||
or pvc['metadata']['name'] != 'informed-decision-data'
|
||||
or pvc.get('status', {}).get('phase') != 'Bound'
|
||||
or not pvc.get('spec', {}).get('volumeName')):
|
||||
raise ValueError('unexpected bound PVC custody')
|
||||
config = projection(configmap)
|
||||
config.pop('data')
|
||||
config['canonical_data_sha256'] = hashlib.sha256(json.dumps(
|
||||
configmap['data'], sort_keys=True, separators=(',', ':')).encode()).hexdigest()
|
||||
return {'configmap': config, 'pvc': projection(pvc), 'pvc_phase': 'Bound'}
|
||||
|
||||
|
||||
def check_dependencies(configmap, pvc, sealed):
|
||||
if dependency_projection(configmap, pvc) != sealed:
|
||||
raise ValueError('runtime config or PVC identity/custody changed')
|
||||
|
||||
|
||||
def projection(value):
|
||||
value = copy.deepcopy(value)
|
||||
value.pop('status', None)
|
||||
for key in ('resourceVersion', 'generation', 'creationTimestamp', 'managedFields'):
|
||||
value['metadata'].pop(key, None)
|
||||
for key in ('kubectl.kubernetes.io/last-applied-configuration', 'deployment.kubernetes.io/revision'):
|
||||
value['metadata'].get('annotations', {}).pop(key, None)
|
||||
return value
|
||||
|
||||
|
||||
def check_current(current, sealed):
|
||||
if projection(current) != sealed:
|
||||
raise ValueError('sealed live UID or configuration changed')
|
||||
|
||||
|
||||
def check_admitted(admitted, sealed):
|
||||
expected = copy.deepcopy(sealed)
|
||||
containers = expected['spec']['template']['spec']['containers']
|
||||
if len(containers) != 1 or containers[0]['name'] != 'informed-decision' or containers[0]['image'] != BASE:
|
||||
raise ValueError('unexpected baseline container identity')
|
||||
containers[0]['image'] = CANDIDATE
|
||||
if projection(admitted) != expected:
|
||||
raise ValueError('admission changed configuration beyond the sole image pin')
|
||||
|
||||
|
||||
def transport_result(exit_code, output):
|
||||
import json
|
||||
try:
|
||||
value = json.loads(output)
|
||||
except (ValueError, TypeError):
|
||||
return {'all_checks_pass': False, 'reason': 'invalid transport result'}
|
||||
if exit_code != 0 or not isinstance(value, dict) or value.get('all_checks_pass') is not True:
|
||||
return {'all_checks_pass': False, 'reason': 'read-only preflight refused'}
|
||||
return value
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import copy,json,time
|
||||
from datetime import datetime,timezone
|
||||
from informed_decision.policy import PolicyClient,CONTRACT,submitted_digest
|
||||
pin='sha256:'+'b'*64
|
||||
req={'id':'image-purpose-fixture','tenant':'tenant:platform','subject':{'id':'synthetic','type':'service','tenant':'tenant:platform'},'resource':{'id':'memo:fixture','type':'memo','system':'informed-decision','tenant':'tenant:platform'},'action':'register','context':{}}
|
||||
class Transport:
|
||||
def request(self,*args,**kwargs):
|
||||
now=time.time(); stamp=lambda t:datetime.fromtimestamp(t,timezone.utc).isoformat()
|
||||
b={**copy.deepcopy({k:req[k] for k in ('tenant','subject','action','resource','context')}),'request_digest':'sha256:'+'e'*64,'submitted_request_digest':submitted_digest(req)}
|
||||
if self.purpose!='ABSENT':b['purpose']=self.purpose
|
||||
d={'id':'synthetic-decision','contract_version':CONTRACT,'request_id':req['id'],'effect':'allow','matched_policy_version':'v1','subject':req['subject'],'resource':req['resource'],'binding':b,'lifetime':{'kind':'ttl','not_before':stamp(now-1),'expires_at':stamp(now+60)},'provenance':{'policy_package':'fixture','policy_version':'v1','policy_package_digest':pin,'registry_snapshot_digest':'sha256:'+'c'*64,'evaluator':'flex-auth/fixture','decision_time':stamp(now)}}
|
||||
return 200,d
|
||||
checks=[]
|
||||
for purpose in ('ABSENT','','readback','enforcement','unknown',None,False,0,[],{}):
|
||||
t=Transport();t.purpose=purpose
|
||||
c=PolicyClient('https://fixture.invalid',lambda:'synthetic-only',package='fixture',version='v1',package_digest=pin,transport=t)
|
||||
o=c.check(req)
|
||||
if purpose in ('ABSENT',''):assert o.outcome=='allow';o.require_current(time.time())
|
||||
else:assert o.outcome=='invalid_decision' and o.decision_json is None
|
||||
checks.append(str(purpose))
|
||||
print(json.dumps({'installed_image_purpose_variants':len(checks),'binding_forms_allowed':2,'advisory_or_malformed_refused':8,'synthetic_only':True,'native_provider':False}))
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# Informed Decision purpose overlay release
|
||||
|
||||
## Requested decision
|
||||
|
||||
Approve the exact purpose-only image rollout and protected real-data backup/restore protocol for the existing Informed Decision service on railiance01. This request is separate from the already approved config-only repair. Only the existing Deployment image changes through the owner's manual Argo workflow, with prune disabled. Runtime ConfigMap `informed-decision-runtime-6c221878d051`, schema5, PVC, credentials, audience, policies, registries, access, replica1 and Recreate strategy remain fixed. Execute by 2026-10-12T23:59:59Z, after refreshed sealed-source/UID/configuration checks and backup/restore gates. Expiry stops authorization for an unstarted release; it does not install a controller or automatically roll back an already released image.
|
||||
|
||||
## Artifact and known finding
|
||||
|
||||
Actual owner CI task11484/run3 published immutable image `sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a` from source `3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168`. Anonymous registry verification preserves all eight base compressed blobs/rootfs layers and adds only policy.py with exact source hash and mode0644. Legacy-builder media-type/default config serialization differences are recorded; the runtime semantics remain unchanged. Pulled published image executes as UID10001/GID10001 and passes ten installed checks: two supported binding forms, eight advisory/malformed refusals. Tests use synthetic transport and do not claim new native PDP authorization proof. The two failed CI attempts remain in the same trial history.
|
||||
|
||||
Actual unfiltered pinned scanner/DB evidence covers44packages: zero HIGH/CRITICAL, **one fixable MEDIUM**, CVE-2026-85091, zlib1.3.2-r0 fixed in1.3.2-r1. Actual current-base scan has the identical finding. Approving this packet explicitly permits this inherited finding during this narrow purpose release; it is not a RiskNexus estate risk grade or zero-CVE claim. Owner record INFD-RISK-20261011-ZLIB-85091 and live task INFD-WP-0009-T05 require separate base refresh and native approval, reviewed by2026-10-18. That review date is manual follow-through, with no auto-controller claim. Scanner notes Alpine3.24 absent EOL list; OS vulnerability detection ran against38OSpackages. Unknown vulnerabilities remain outside snapshot knowledge.
|
||||
|
||||
## Native baseline and gates
|
||||
|
||||
Original read-only capture01:25:38Z: existing Deployment UIDa588e10a, Ready1, image7f5c, unchanged runtime6c; native admission preserves the full configuration plus exactly the proposed image. Clientdiff returns1. Requests3460/4000mCPU86%, memory9472Mi59%; refresh before release. Existing Argo Application UID499868f2 is manual, target7db8485, Healthy with pre-existing OutOfSync status. Do not treat a scoped Deployment release as full-app reconciliation. Preserve its tracking-id; no unrelated resource sync/prune/adoption.
|
||||
|
||||
The refined read-only helper binds original source/helper/render/baseline hashes and actual immutable ConfigMap/PVC UIDs, runtime-data checksum and bound volume identity, explicitly refuses optimized interpreters, checks exact fresh live UID/configuration and admission, and writes a separate execution receipt outside this sealed packet. Failed initial raw Kustomize metadata check is retained: direct kubectl apply would drop Argo tracking-id. The reviewed selected Deployment explicitly retains that existing ID, matching Argo ownership. Any unrelated drift, different UID, altered admission, unavailable protected backup capacity, uncertain backup, restore mismatch or unhealthy baseline stops the release.
|
||||
|
||||
## Protected backup and release
|
||||
|
||||
Before **any** native source or offline-restored Store/admin open, use the attached stdlib SQLite mode=ro/query_only checker to require schema5, integrity=ok and count-only baseline. The admin automatically migrates oldschemas, so a post-open report alone cannot prove no migration. Refuse other schemas before admin. Then use the existing owner admin's SQLite backup API, not a raw copy of the live database/WAL. Protect directories0700/files0600, owned by10001. Retain independently protected off-cluster snapshot custody and only count/hash receipts. No database contents, caller tokens, requester Secret or runtime credential files enter Git, State Hub, logs or this packet. Native backup and offline real-data restore have not yet occurred. Use an isolated private disposable copy, networknone and no runtime config/token mounts, run the pre-open checker and exact offline `--entrypoint informed-decision-admin inspect --db /restore/review.sqlite` after it passes, comparing frozen snapshot counts without service startup, then clean only the disposable restored copy. Retain the original snapshot. The attached protocol binds case-specific paths and fail-closed capacity/custody checks.
|
||||
|
||||
Refresh a consistent online snapshot immediately before image-only cutover. This protocol does not assert traffic/dispatcher quiescence. Current and candidate share schema5 and unchanged store code; rollback retains the latest live database and all new/uncertain evidence. Stop the old writer before the new one with existing Recreate and single-writer lock. Do not restore an older snapshot over later writes, discard unresolved external effects, scale other workloads, change policies/identity/custody, or create human dispositions to make checks green.
|
||||
|
||||
Pin the existing Application to the exact owner commit containing the approved candidate source hashes, and manually sync only Deployment/informed-decision with prune=false. Verify actualimage/module/mode/UID, health/readiness and installed purpose refusals on the real placement; explicitly distinguish synthetic-transport checks from actual provider evidence. Existing native binding/lifecycle behavior must remain available. If unhealthy or verification fails, return Application source to7db8485 and scoped-sync prior same-schema image7f5c, preserving current evidence database; retain failed outcomes. Any data recovery beyond this same-schema image rollback is a separate founder decision.
|
||||
|
||||
## Alternatives and estimates
|
||||
|
||||
Proceed with this narrow release plus explicit inherited-medium follow-through, or defer and prepare a separate base/dependency refresh before any release. No additional recurring hosting is proposed: estimated incremental infrastructure EUR0, with private storage and attended engineering/recovery time unpriced. Risks include a brief Recreate interruption, private backup custody errors, caller refusal when advisory responses were improperly treated as binding, and the disclosed inherited finding. This decision does not promote agent autonomy or grant unrelated work.
|
||||
|
||||
## Independent review refinements
|
||||
|
||||
The initial36path/20document packet at manifest7c6738b3 and submissionac41c8ae is preserved in source preparation evidence, with the failed/conditional review. Independent Platform review identified admin auto-migration, optimization bypass, and actual same-name ConfigMap/PVC replacement gaps. The amended packet adds pre-open stdlib read-only schema/integrity/count gates, explicit local/remote optimization refusal, and independently sealed actual native config/PVC custody checks. These are refinements in the same proposal/trial, with no original or amended founder approval claimed.
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"node_allocatable_cpu_m": 4000,
|
||||
"node_requested_cpu_m": 3460,
|
||||
"captured_at": "2026-10-11T01:39:14.234277+00:00",
|
||||
"native_workload_changed": false,
|
||||
"native_backup_restore_executed": false,
|
||||
"argo": {
|
||||
"uid": "499868f2-eabc-4df4-ae31-b89ce58d750d",
|
||||
"repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git",
|
||||
"targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf",
|
||||
"path": "deploy/lifecycle",
|
||||
"destination": {
|
||||
"namespace": "informed-decision",
|
||||
"server": "https://kubernetes.default.svc"
|
||||
},
|
||||
"automated": false,
|
||||
"sync": {
|
||||
"comparedTo": {
|
||||
"destination": {
|
||||
"namespace": "informed-decision",
|
||||
"server": "https://kubernetes.default.svc"
|
||||
},
|
||||
"source": {
|
||||
"path": "deploy/lifecycle",
|
||||
"repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git",
|
||||
"targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf"
|
||||
}
|
||||
},
|
||||
"revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf",
|
||||
"status": "OutOfSync"
|
||||
},
|
||||
"health": {
|
||||
"lastTransitionTime": "2026-10-10T23:14:52Z",
|
||||
"status": "Healthy"
|
||||
}
|
||||
},
|
||||
"native_dependencies_checked": true,
|
||||
"configmap_uid": "90113d2d-54d9-4e82-b1d3-90b49ebed2b5",
|
||||
"pvc_uid": "d80b25b1-141a-441b-b205-98fa2fd98b7c",
|
||||
"live_ready_replicas": 1,
|
||||
"admitted_uid": "a588e10a-90d2-4883-975e-6dd8b8feca92",
|
||||
"server_dry_run_passed": true,
|
||||
"admitted_spec_exactly_live_plus_image": true,
|
||||
"client_diff_exit": 1,
|
||||
"client_diff_sha256": "840769c7d2a9c1655c40a3259f833d1fc8f69950ceb3bedb707a955fed711566",
|
||||
"node_allocated_resources": "(Total limits may be over 100 percent, i.e., overcommitted.)\n Resource Requests Limits\n -------- -------- ------\n cpu 3460m (86%) 36200m (905%)\n memory 9472Mi (59%) 32898Mi (205%)\n ephemeral-storage 0 (0%) 0 (0%)\n hugepages-1Gi 0 (0%) 0 (0%)\n hugepages-2Mi 0 (0%) 0 (0%)",
|
||||
"all_checks_pass": true,
|
||||
"sealed_preflight_inputs_sha256": "756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06",
|
||||
"fresh_execution_receipt": true
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
{
|
||||
"architecture": "amd64",
|
||||
"config": {
|
||||
"Hostname": "",
|
||||
"Domainname": "",
|
||||
"User": "10001:10001",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": false,
|
||||
"AttachStderr": false,
|
||||
"ExposedPorts": {
|
||||
"8080/tcp": {},
|
||||
"8081/tcp": {}
|
||||
},
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": [
|
||||
"PATH=/opt/venv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"LANG=C.UTF-8",
|
||||
"GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305",
|
||||
"PYTHON_VERSION=3.12.14",
|
||||
"PYTHON_SHA256=5c8462af5790baf43a321a1559dbe0db06d1be4300fb85fb53c40060668e548a",
|
||||
"PYTHONDONTWRITEBYTECODE=1",
|
||||
"PYTHONUNBUFFERED=1"
|
||||
],
|
||||
"Cmd": null,
|
||||
"Image": "sha256:90f1574f9eda35fa6cb972961beb27a7cb904c36560e381930b0e14065c23883",
|
||||
"Volumes": null,
|
||||
"WorkingDir": "/app",
|
||||
"Entrypoint": [
|
||||
"informed-decision-container"
|
||||
],
|
||||
"OnBuild": null,
|
||||
"Labels": {
|
||||
"org.opencontainers.image.base.digest": "sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"org.opencontainers.image.revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"social.coulomb.release.scope": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"social.coulomb.source.policy.sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62"
|
||||
}
|
||||
},
|
||||
"container_config": {
|
||||
"Hostname": "",
|
||||
"Domainname": "",
|
||||
"User": "10001:10001",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": false,
|
||||
"AttachStderr": false,
|
||||
"ExposedPorts": {
|
||||
"8080/tcp": {},
|
||||
"8081/tcp": {}
|
||||
},
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": [
|
||||
"PATH=/opt/venv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"LANG=C.UTF-8",
|
||||
"GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305",
|
||||
"PYTHON_VERSION=3.12.14",
|
||||
"PYTHON_SHA256=5c8462af5790baf43a321a1559dbe0db06d1be4300fb85fb53c40060668e548a",
|
||||
"PYTHONDONTWRITEBYTECODE=1",
|
||||
"PYTHONUNBUFFERED=1"
|
||||
],
|
||||
"Cmd": [
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
"#(nop) COPY file:2be9cb36e7253e15733673359cda8caa22986b6888822a008c1b360d909994e0 in /opt/venv/lib/python3.12/site-packages/informed_decision/policy.py "
|
||||
],
|
||||
"Image": "sha256:90f1574f9eda35fa6cb972961beb27a7cb904c36560e381930b0e14065c23883",
|
||||
"Volumes": null,
|
||||
"WorkingDir": "/app",
|
||||
"Entrypoint": [
|
||||
"informed-decision-container"
|
||||
],
|
||||
"OnBuild": null,
|
||||
"Labels": {
|
||||
"org.opencontainers.image.base.digest": "sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"org.opencontainers.image.revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"social.coulomb.release.scope": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"social.coulomb.source.policy.sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62"
|
||||
}
|
||||
},
|
||||
"created": "2026-10-11T01:21:04.787527697Z",
|
||||
"docker_version": "27.5.1",
|
||||
"history": [
|
||||
{
|
||||
"created": "2026-06-16T00:01:29.967161902Z",
|
||||
"created_by": "ADD alpine-minirootfs-3.24.1-x86_64.tar.gz / # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-06-16T00:01:29.967161902Z",
|
||||
"created_by": "CMD [\"/bin/sh\"]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV LANG=C.UTF-8",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "RUN /bin/sh -c set -eux; \tapk add --no-cache \t\tca-certificates \t\ttzdata \t; # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV PYTHON_VERSION=3.12.14",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV PYTHON_SHA256=5c8462af5790baf43a321a1559dbe0db06d1be4300fb85fb53c40060668e548a",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:10:30.672225972Z",
|
||||
"created_by": "RUN /bin/sh -c set -eux; \t\tapk add --no-cache --virtual .build-deps \t\tbluez-dev \t\tbzip2-dev \t\tdpkg-dev dpkg \t\tfindutils \t\tg++ \t\tgcc \t\tgdbm-dev \t\tgnupg \t\tlibc-dev \t\tlibffi-dev \t\tlibnsl-dev \t\tlibtirpc-dev \t\tlinux-headers \t\tmake \t\tncurses-dev \t\topenssl-dev \t\tpax-utils \t\treadline-dev \t\tsqlite-dev \t\ttar \t\ttcl-dev \t\ttk \t\ttk-dev \t\tutil-linux-dev \t\txz \t\txz-dev \t\tzlib-dev \t; \t\twget -O python.tar.xz \"https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz\"; \techo \"$PYTHON_SHA256 *python.tar.xz\" | sha256sum -c -; \twget -O python.tar.xz.asc \"https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc\"; \tGNUPGHOME=\"$(mktemp -d)\"; export GNUPGHOME; \tgpg --batch --keyserver hkps://keys.openpgp.org --recv-keys \"$GPG_KEY\"; \tgpg --batch --verify python.tar.xz.asc python.tar.xz; \tgpgconf --kill all; \trm -rf \"$GNUPGHOME\" python.tar.xz.asc; \tmkdir -p /usr/src/python; \ttar --extract --directory /usr/src/python --strip-components=1 --file python.tar.xz; \trm python.tar.xz; \t\tcd /usr/src/python; \tgnuArch=\"$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)\"; \t./configure \t\t--build=\"$gnuArch\" \t\t--enable-loadable-sqlite-extensions \t\t--enable-option-checking=fatal \t\t--enable-shared \t\t$(test \"${gnuArch%%-*}\" != 'riscv64' && echo '--with-lto') \t\t--with-ensurepip \t; \tnproc=\"$(nproc)\"; \tEXTRA_CFLAGS=\"-DTHREAD_STACK_SIZE=0x100000\"; \tLDFLAGS=\"${LDFLAGS:-} -Wl,--strip-all\"; \tarch=\"$(apk --print-arch)\"; \tcase \"$arch\" in \t\tx86_64|aarch64) \t\t\tEXTRA_CFLAGS=\"${EXTRA_CFLAGS:-} -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer\"; \t\t\t;; \t\tx86) \t\t\t;; \t\t*) \t\t\tEXTRA_CFLAGS=\"${EXTRA_CFLAGS:-} -fno-omit-frame-pointer\"; \t\t\t;; \tesac; \tmake -j \"$nproc\" \t\t\"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}\" \t\t\"LDFLAGS=${LDFLAGS:-}\" \t; \trm python; \tmake -j \"$nproc\" \t\t\"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}\" \t\t\"LDFLAGS=${LDFLAGS:-} -Wl,-rpath='\\$\\$ORIGIN/../lib'\" \t\tpython \t; \tmake install; \t\tcd /; \trm -rf /usr/src/python; \t\tfind /usr/local -depth \t\t\\( \t\t\t\\( -type d -a \\( -name test -o -name tests -o -name idle_test \\) \\) \t\t\t-o \\( -type f -a \\( -name '*.pyc' -o -name '*.pyo' -o -name 'libpython*.a' \\) \\) \t\t\\) -exec rm -rf '{}' + \t; \t\tfind /usr/local -type f -executable -not \\( -name '*tkinter*' \\) -exec scanelf --needed --nobanner --format '%n#p' '{}' ';' \t\t| tr ',' '\\n' \t\t| sort -u \t\t| awk 'system(\"[ -e /usr/local/lib/\" $1 \" ]\") == 0 { next } { print \"so:\" $1 }' \t\t| xargs -rt apk add --no-network --virtual .python-rundeps \t; \tapk del --no-network .build-deps; \t\texport PYTHONDONTWRITEBYTECODE=1; \tpython3 --version; \tpip3 --version # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:10:30.782726003Z",
|
||||
"created_by": "RUN /bin/sh -c set -eux; \tfor src in idle3 pip3 pydoc3 python3 python3-config; do \t\tdst=\"$(echo \"$src\" | tr -d 3)\"; \t\t[ -s \"/usr/local/bin/$src\" ]; \t\t[ ! -e \"/usr/local/bin/$dst\" ]; \t\tln -svT \"$src\" \"/usr/local/bin/$dst\"; \tdone # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:10:30.782726003Z",
|
||||
"created_by": "CMD [\"python3\"]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-11T00:49:47.962156876+02:00",
|
||||
"created_by": "ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PATH=/opt/venv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-11T00:49:47.962156876+02:00",
|
||||
"created_by": "RUN /bin/sh -c apk add --no-cache 'libuuid>=2.42.3-r1' && addgroup -S -g 10001 informed && adduser -S -u 10001 -G informed -H informed # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:55.351944978+02:00",
|
||||
"created_by": "COPY /opt/venv /opt/venv # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.462092072+02:00",
|
||||
"created_by": "RUN /bin/sh -c rm -rf /usr/local/bin/pip* /usr/local/lib/python3.12/site-packages/pip* /usr/local/lib/python3.12/site-packages/setuptools* /usr/local/lib/python3.12/site-packages/pkg_resources /opt/venv/bin/pip* /opt/venv/lib/python3.12/site-packages/pip* /opt/venv/lib/python3.12/site-packages/setuptools* /opt/venv/lib/python3.12/site-packages/pkg_resources # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "WORKDIR /app",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "USER 10001:10001",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "EXPOSE [8080/tcp 8081/tcp]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "ENTRYPOINT [\"informed-decision-container\"]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-11T01:15:11.991443676Z",
|
||||
"created_by": "/bin/sh -c #(nop) ARG SOURCE_REVISION",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-11T01:21:04.716126392Z",
|
||||
"created_by": "/bin/sh -c #(nop) LABEL org.opencontainers.image.revision=3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168 org.opencontainers.image.base.digest=sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173 social.coulomb.source.policy.sha256=9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62 social.coulomb.release.scope=INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-11T01:21:04.787527697Z",
|
||||
"created_by": "/bin/sh -c #(nop) COPY file:2be9cb36e7253e15733673359cda8caa22986b6888822a008c1b360d909994e0 in /opt/venv/lib/python3.12/site-packages/informed_decision/policy.py "
|
||||
}
|
||||
],
|
||||
"os": "linux",
|
||||
"rootfs": {
|
||||
"type": "layers",
|
||||
"diff_ids": [
|
||||
"sha256:34884abbe92863fce933ed7c39c0e045631af0ed86d5cc0dfbdf9fdca426ce3c",
|
||||
"sha256:3ca4be2c6e9ac0223715355253725381000486c2b45bfcb22cf571b6a85a12dd",
|
||||
"sha256:e5ccda0fbf6b54d343e024156d876553ba57d3926d7196584b3a1ce4df016366",
|
||||
"sha256:4098ad033525263f92a8a9c51865596025d47018e078c0b1f7d9cd5663fc1ffe",
|
||||
"sha256:f9b4a8a412a0c07a489e46fb5db41f9d0dc84d4ec38a4e2c6ab9531f44e0d9f1",
|
||||
"sha256:648451a0dda84ad04681e32b5ecc7cd5d3a4f0ad84f783e9598d72bc69620d5c",
|
||||
"sha256:361430a1113969743b99e237b20f023d5497493bcf96fb91af99ac0a0dbc4a59",
|
||||
"sha256:cfc5939674d67f60b4411c24dfcde5622b712eeb7376cd0941a2751da80a6b02",
|
||||
"sha256:21ff9188cb29ca95fe9be11355f70ab5586e8499e33b52a253d953fb3b75aea3"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"schemaVersion": 2,
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"config": {
|
||||
"mediaType": "application/vnd.docker.container.image.v1+json",
|
||||
"size": 10428,
|
||||
"digest": "sha256:f34de21379c4f50ea0361ca1d8296c8e72f989499ad288016b81204997ae4779"
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 3846391,
|
||||
"digest": "sha256:55afa1ecc21d2bb5e5045f32dafee56272ffd89860bac26f6c32123439af26a4"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 408093,
|
||||
"digest": "sha256:47393b668ce535d06e8967917d424c177e2ecccae83856d48b2e99164f8cc6cb"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 16346740,
|
||||
"digest": "sha256:2014fd3d47b2c2dd4dedc765822ac60ae269f3efa0e614f46ae29f540c7f1235"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 248,
|
||||
"digest": "sha256:ed62c91ccd94e36a928e96d704cfcf20861302590245cc12aa89a15a5d6be29b"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 49243,
|
||||
"digest": "sha256:f0fe3e08ab046c0c5e29d34ee73bc8c7e03398eb891e4498e0a67088a5ea3e86"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 10216362,
|
||||
"digest": "sha256:82ff17b555d91096dd328eb1e829daaeba9a48d7757143d0b97c35a721f6fb87"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 459,
|
||||
"digest": "sha256:16a3dba6b720d3059eab918cd3596f94145ac9cf4d456f925a21f0f72522863f"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 93,
|
||||
"digest": "sha256:e73dd464fbff5607cc62a1b2b66b0eefe737dfad4db8e7b58a48cda7c12d94d3"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 3586,
|
||||
"digest": "sha256:cfee29c2f8119d2a39714ecbe5095a2dc1c986054f2e1fe0a6565163242417e3"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"id": "INFD-RISK-20261011-ZLIB-85091",
|
||||
"kind": "owner-vulnerability-follow-through",
|
||||
"owner": "informed-decision",
|
||||
"task": "INFD-WP-0009-T05",
|
||||
"status": "open",
|
||||
"created": "2026-10-11",
|
||||
"review_due": "2026-10-18",
|
||||
"finding": "CVE-2026-85091",
|
||||
"scanner_severity": "MEDIUM",
|
||||
"estate_risk_grade": null,
|
||||
"affected_package": "zlib",
|
||||
"installed": "1.3.2-r0",
|
||||
"fixed": "1.3.2-r1",
|
||||
"actual_current_base_and_candidate_findings_identical": true,
|
||||
"source_evidence": "security-summary.json, trivy-full.json, base-trivy-full.json",
|
||||
"human_temporary_disposition": "pending",
|
||||
"follow_through": "Prepare a separately source-bound official-base/dependency refresh through normal owner CI, verify full scan and runtime compatibility, obtain distinct native release approval before updating this workload",
|
||||
"manual_review_expiry": "Due date requires owner review/escalation if unresolved; no automatic rollback/controller is installed",
|
||||
"close_condition": "Verified installed native fixed package and full unfiltered rescan; preserve original detection and any human disposition"
|
||||
}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
[
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "deploy/lifecycle/admission.candidate.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/deploy/lifecycle/admission.candidate.json",
|
||||
"original_sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50",
|
||||
"staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "deploy/lifecycle/service.candidate.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/deploy/lifecycle/service.candidate.json",
|
||||
"original_sha256": "7a676532836affd6d75c7f1c41a5f937d8c8c809f63e3264ccce612730d5ba7b",
|
||||
"staged_sha256": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/README.md",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/README.md",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "f88a79a93fff34a1b438e2dc0344cad88d6c7960dde04bc7f3c04ac1fbb992c7"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/base-image-config.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/change_guard.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/change_guard.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "830f7771b5c7d0a2851973aa65a01c6ab40b86570f0933d8aebb89f9665ca7e1"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/check_installed.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/check_installed.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/decision-packet.md",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "7f6d8987f65dff479eeead67b7ca940ef44c22c1cdbdd6ca33fd732b824c8f02"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "aa1d494e42491f0619f731a836c597df9178409887d734c166a8df81f8807a27"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/image-config.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/image-config.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/image-manifest.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/intake.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/intake.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "9a39631362f20168da409cef74f7690f3aa1b8f841fc96ecd8770f73a1f954ac"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "b6210dcd34e5485c94e35f4bdd3329fb72c1d40fa9357caf40ac42b4f8afa5c2"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/memo.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/memo.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "06530425dd9634182f70a65dd2da56cbad3da967bc842b3c7b01c30542222128"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "aa9758d4de587d14c6ce0fdaccd84002c5c5099425b9169ca7c972a86e9d3dec"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "052fc57d2cda43b2e474f28a5ff70753f5fa673c77a9645a201d0e0e961792e4"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "aaa77b406b201eb40a62f60182057e90b1baea06e03f85d7e06916b57f5f2de8"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/native-preflight.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "0bbdaf56459aaef3c35d7b1bf3ad20be6260f047df6dd1c5eb60ac1797150944"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/preflight.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/preflight.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "c206a1a9b9d232c656c6d57fb9247549eefa13b275a5da4d39b45a6c9902c834"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/proposal.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/proposal.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "08c5573eaad05efd24b6df6737d33e7189543eb621f21704e38bab4326094914"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/published-verification.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/published-verification.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "e304dd29571bf7d7b9f1db2ade0163dd39cfec012a5ce6986139f019f37e65a2"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/registry-proof.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/security-summary.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/security-summary.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "b7cd28b2ada33004c9264cb54c9749fa501f60166638f926e50e264ddebe037d"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/trivy-full.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/validation.json",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/validation.json",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "3b57f525bbbb1db9dc46bcc6b0057a8dd9f45c461fad0a8dea5391ca78038c36"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "docs/evidence/2026-10-11-purpose-image-release/verify_registry.py",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py",
|
||||
"original_sha256": null,
|
||||
"staged_sha256": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4"
|
||||
},
|
||||
{
|
||||
"repo": "informed-decision",
|
||||
"path": "workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md",
|
||||
"staged_path": "/tmp/infd-purpose-release-stage/informed-decision/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md",
|
||||
"original_sha256": "1544ece11a7a528a34b635b267b72e1c3fd4de99327200aded74864c64e64e77",
|
||||
"staged_sha256": "18205c0c7aa8f3460d78e3b7ad9dddd9e361395f9a28d93a7a384c29c9602d36"
|
||||
}
|
||||
]
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"policy": {
|
||||
"origin": "http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080",
|
||||
"package": "informed-decision.compact-sitting",
|
||||
"version": "v13",
|
||||
"package_digest": "sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873",
|
||||
"pod_name": "flex-auth-informed-decision-sitting"
|
||||
},
|
||||
"keycape_egress_ips": [
|
||||
"92.205.62.239"
|
||||
],
|
||||
"storage_class": "local-path",
|
||||
"ordinary_approval_ids": [
|
||||
"2ce76d7f-01c3-4b63-8476-8d1230679769",
|
||||
"c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
|
||||
"dc22666a-d5d7-46bc-9490-ebe9fe09dc38"
|
||||
],
|
||||
"lifecycle_policy": {
|
||||
"package": "informed-decision.lifecycle",
|
||||
"version": "v2",
|
||||
"package_digest": "sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c",
|
||||
"origin": "http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080",
|
||||
"pod_name": "flex-auth-informed-decision-lifecycle"
|
||||
},
|
||||
"lifecycle_delivery": true,
|
||||
"intake_attributes": true,
|
||||
"intake_delivery": {
|
||||
"hub_origin": "http://state-hub.state-hub.svc.cluster.local:8000"
|
||||
},
|
||||
"workload_api": {
|
||||
"registries_configmap": "informed-decision-workload-registry",
|
||||
"peers": [
|
||||
{
|
||||
"namespace": "state-hub",
|
||||
"app": "state-hub"
|
||||
}
|
||||
],
|
||||
"api_egress": [
|
||||
{
|
||||
"ip": "10.43.0.1",
|
||||
"port": 443
|
||||
},
|
||||
{
|
||||
"ip": "92.205.62.239",
|
||||
"port": 6443
|
||||
}
|
||||
],
|
||||
"intake": true,
|
||||
"lifecycle": true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,800 @@
|
|||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "List",
|
||||
"items": [
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ServiceAccount",
|
||||
"metadata": {
|
||||
"name": "review",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"automountServiceAccountToken": false
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "PersistentVolumeClaim",
|
||||
"metadata": {
|
||||
"name": "informed-decision-data",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"accessModes": [
|
||||
"ReadWriteOnce"
|
||||
],
|
||||
"storageClassName": "local-path",
|
||||
"resources": {
|
||||
"requests": {
|
||||
"storage": "1Gi"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
"metadata": {
|
||||
"name": "informed-decision-runtime-6c221878d051",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"immutable": true,
|
||||
"data": {
|
||||
"runtime.json": "{\"approval_origin\":\"http://approval-engine.approval-engine.svc.cluster.local:8080\",\"audit\":{\"origin\":\"http://audit-core.audit-core.svc.cluster.local:8080\",\"sender_token_file\":\"/var/run/secrets/informed-decision/audit/token\"},\"evidence_db\":\"/data/private/review.sqlite\",\"intake_attributes\":true,\"intake_delivery\":{\"hub_origin\":\"http://state-hub.state-hub.svc.cluster.local:8000\"},\"lifecycle_delivery\":true,\"lifecycle_policy\":{\"caller_token_file\":\"/var/run/secrets/informed-decision/policy/token\",\"origin\":\"http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080\",\"package\":\"informed-decision.lifecycle\",\"package_digest\":\"sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c\",\"version\":\"v2\"},\"ordinary_approval_ids\":[\"2ce76d7f-01c3-4b63-8476-8d1230679769\",\"c2af4bcf-15b4-4305-aac1-acc7e4dcb099\",\"dc22666a-d5d7-46bc-9490-ebe9fe09dc38\"],\"policy\":{\"caller_token_file\":\"/var/run/secrets/informed-decision/policy/token\",\"origin\":\"http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080\",\"package\":\"informed-decision.compact-sitting\",\"package_digest\":\"sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873\",\"version\":\"v13\"},\"schema\":\"informed-decision.review-runtime.v1\",\"workload_api\":{\"intake\":{\"groups_file\":\"/workload-registry/review-groups.json\",\"secret_file\":\"/var/run/secrets/informed-decision/requester/client-secret\",\"submitters_file\":\"/workload-registry/intake-submitters.json\"},\"lifecycle_callers_file\":\"/workload-registry/lifecycle-callers.json\",\"token_review\":{\"ca_file\":\"/var/run/secrets/informed-decision/kubernetes/ca.crt\",\"origin\":\"https://kubernetes.default.svc:443\",\"token_file\":\"/var/run/secrets/informed-decision/kubernetes/token\"}}}"
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"name": "informed-decision",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"replicas": 1,
|
||||
"strategy": {
|
||||
"type": "Recreate"
|
||||
},
|
||||
"progressDeadlineSeconds": 600,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"automountServiceAccountToken": false,
|
||||
"serviceAccountName": "review",
|
||||
"terminationGracePeriodSeconds": 45,
|
||||
"securityContext": {
|
||||
"runAsNonRoot": true,
|
||||
"runAsUser": 10001,
|
||||
"runAsGroup": 10001,
|
||||
"fsGroup": 10001,
|
||||
"fsGroupChangePolicy": "OnRootMismatch",
|
||||
"seccompProfile": {
|
||||
"type": "RuntimeDefault"
|
||||
}
|
||||
},
|
||||
"containers": [
|
||||
{
|
||||
"name": "informed-decision",
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"securityContext": {
|
||||
"allowPrivilegeEscalation": false,
|
||||
"readOnlyRootFilesystem": true,
|
||||
"capabilities": {
|
||||
"drop": [
|
||||
"ALL"
|
||||
]
|
||||
}
|
||||
},
|
||||
"env": [
|
||||
{
|
||||
"name": "INFD_KEYCAPE_ISSUER",
|
||||
"value": "https://kc.coulomb.social"
|
||||
},
|
||||
{
|
||||
"name": "INFD_CONTAINER_CONFIG",
|
||||
"value": "/configuration/runtime.json"
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"containerPort": 8080
|
||||
},
|
||||
{
|
||||
"name": "workload",
|
||||
"containerPort": 8081
|
||||
}
|
||||
],
|
||||
"startupProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2,
|
||||
"failureThreshold": 12
|
||||
},
|
||||
"readinessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"livenessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"resources": {
|
||||
"requests": {
|
||||
"cpu": "5m",
|
||||
"memory": "64Mi"
|
||||
},
|
||||
"limits": {
|
||||
"cpu": "500m",
|
||||
"memory": "256Mi"
|
||||
}
|
||||
},
|
||||
"volumeMounts": [
|
||||
{
|
||||
"name": "data",
|
||||
"mountPath": "/data"
|
||||
},
|
||||
{
|
||||
"name": "runtime",
|
||||
"mountPath": "/run/informed-decision"
|
||||
},
|
||||
{
|
||||
"name": "tmp",
|
||||
"mountPath": "/tmp"
|
||||
},
|
||||
{
|
||||
"name": "configuration",
|
||||
"mountPath": "/configuration",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "caller",
|
||||
"mountPath": "/var/run/secrets/informed-decision/policy",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "audit",
|
||||
"mountPath": "/var/run/secrets/informed-decision/audit",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "kubernetes-api",
|
||||
"mountPath": "/var/run/secrets/informed-decision/kubernetes",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "workload-registry",
|
||||
"mountPath": "/workload-registry",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"name": "sitting-requester",
|
||||
"mountPath": "/var/run/secrets/informed-decision/requester",
|
||||
"readOnly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"volumes": [
|
||||
{
|
||||
"name": "data",
|
||||
"persistentVolumeClaim": {
|
||||
"claimName": "informed-decision-data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "runtime",
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "tmp",
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "configuration",
|
||||
"configMap": {
|
||||
"name": "informed-decision-runtime-6c221878d051",
|
||||
"defaultMode": 292
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "caller",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"path": "token",
|
||||
"audience": "flex-auth",
|
||||
"expirationSeconds": 3600
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "audit",
|
||||
"secret": {
|
||||
"secretName": "informed-decision-audit",
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "token",
|
||||
"path": "token"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "kubernetes-api",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"path": "token",
|
||||
"expirationSeconds": 600
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"name": "kube-root-ca.crt",
|
||||
"items": [
|
||||
{
|
||||
"key": "ca.crt",
|
||||
"path": "ca.crt"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "workload-registry",
|
||||
"configMap": {
|
||||
"name": "informed-decision-workload-registry",
|
||||
"defaultMode": 292
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "sitting-requester",
|
||||
"secret": {
|
||||
"secretName": "informed-decision-sitting-requester",
|
||||
"defaultMode": 288,
|
||||
"optional": false,
|
||||
"items": [
|
||||
{
|
||||
"key": "client-secret",
|
||||
"path": "client-secret"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "informed-decision",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "http",
|
||||
"port": 80,
|
||||
"targetPort": "http",
|
||||
"protocol": "TCP"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "networking.k8s.io/v1",
|
||||
"kind": "NetworkPolicy",
|
||||
"metadata": {
|
||||
"name": "informed-decision-review",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
}
|
||||
},
|
||||
"policyTypes": [
|
||||
"Ingress",
|
||||
"Egress"
|
||||
],
|
||||
"ingress": [
|
||||
{
|
||||
"from": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "kube-system"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "traefik"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8080
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"from": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "state-hub"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "state-hub"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8081
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"egress": [
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "kube-system"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"k8s-app": "kube-dns"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "UDP",
|
||||
"port": 53
|
||||
},
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 53
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "approval-engine"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "approval-engine"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "audit-core"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "audit-core"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "flex-auth"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "flex-auth-informed-decision-sitting"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "flex-auth"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "flex-auth-informed-decision-lifecycle"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8080
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "kube-system"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "traefik"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8443
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"ipBlock": {
|
||||
"cidr": "92.205.62.239/32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 443
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "state-hub"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "state-hub"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8000
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"ipBlock": {
|
||||
"cidr": "10.43.0.1/32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 443
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"to": [
|
||||
{
|
||||
"ipBlock": {
|
||||
"cidr": "92.205.62.239/32"
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 6443
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "informed-decision-workload",
|
||||
"namespace": "informed-decision",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"type": "ClusterIP",
|
||||
"selector": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "workload",
|
||||
"port": 8081,
|
||||
"targetPort": "workload",
|
||||
"protocol": "TCP"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "rbac.authorization.k8s.io/v1",
|
||||
"kind": "ClusterRole",
|
||||
"metadata": {
|
||||
"name": "informed-decision-tokenreview",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "proposal; INFD-WP-0007/INFD-WP-0005 owner review required"
|
||||
}
|
||||
},
|
||||
"rules": [
|
||||
{
|
||||
"apiGroups": [
|
||||
"authentication.k8s.io"
|
||||
],
|
||||
"resources": [
|
||||
"tokenreviews"
|
||||
],
|
||||
"verbs": [
|
||||
"create"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiVersion": "rbac.authorization.k8s.io/v1",
|
||||
"kind": "ClusterRoleBinding",
|
||||
"metadata": {
|
||||
"name": "informed-decision-tokenreview",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "proposal; INFD-WP-0007/INFD-WP-0005 owner review required"
|
||||
}
|
||||
},
|
||||
"roleRef": {
|
||||
"apiGroup": "rbac.authorization.k8s.io",
|
||||
"kind": "ClusterRole",
|
||||
"name": "informed-decision-tokenreview"
|
||||
},
|
||||
"subjects": [
|
||||
{
|
||||
"kind": "ServiceAccount",
|
||||
"name": "review",
|
||||
"namespace": "informed-decision"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiVersion": "networking.k8s.io/v1",
|
||||
"kind": "NetworkPolicy",
|
||||
"metadata": {
|
||||
"name": "informed-decision-review-ingress",
|
||||
"namespace": "approval-engine",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08",
|
||||
"informed-decision.coulomb.social/owner-review": "APPROVAL-WP-0002-T01"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "approval-engine"
|
||||
}
|
||||
},
|
||||
"policyTypes": [
|
||||
"Ingress"
|
||||
],
|
||||
"ingress": [
|
||||
{
|
||||
"from": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8080
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "networking.k8s.io/v1",
|
||||
"kind": "NetworkPolicy",
|
||||
"metadata": {
|
||||
"name": "informed-decision-review-ingress",
|
||||
"namespace": "flex-auth",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08",
|
||||
"informed-decision.coulomb.social/owner-review": "INFD-WP-0001-T08 policy-owner return"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "flex-auth-informed-decision-sitting"
|
||||
}
|
||||
},
|
||||
"policyTypes": [
|
||||
"Ingress"
|
||||
],
|
||||
"ingress": [
|
||||
{
|
||||
"from": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8080
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"apiVersion": "networking.k8s.io/v1",
|
||||
"kind": "NetworkPolicy",
|
||||
"metadata": {
|
||||
"name": "informed-decision-lifecycle-ingress",
|
||||
"namespace": "flex-auth",
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "review-only; INFD-WP-0001-T08",
|
||||
"informed-decision.coulomb.social/owner-review": "INFD-WP-0007 lifecycle policy-owner return"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "flex-auth-informed-decision-lifecycle"
|
||||
}
|
||||
},
|
||||
"policyTypes": [
|
||||
"Ingress"
|
||||
],
|
||||
"ingress": [
|
||||
{
|
||||
"from": [
|
||||
{
|
||||
"namespaceSelector": {
|
||||
"matchLabels": {
|
||||
"kubernetes.io/metadata.name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"podSelector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision",
|
||||
"app.kubernetes.io/component": "review"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 8080
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Exact published purpose overlay and unapproved native release packet
|
||||
|
||||
Actual CI task11484/run3 at3e4bcb26 published immutable763c. The registry proof, installedUID/mode/purpose checks, full scan/SBOM and actualbase comparison are retained. The full scan contains1fixable inheritedMEDIUM,0HIGH/CRITICAL; see owner follow-through/T05. Legacy serialization differences are disclosed.
|
||||
|
||||
This stage prepares owner admission/service source candidates, protected native backup/restore protocol and20document offline-valid informed-decision memo. Native workload remains7f5/config6c. No native backup/export/restore, image change or human approval occurred. Initial failed CI/native preflight evidence remains in owner history. The immutable original native capture stays sealed; future preflight requires unique output outside the sealed packet and owner source tree.
|
||||
|
||||
The memo's actual rawscan/SBOM attachments plus hash-linked rawbase scan total249719packetbytes (under256KiB); source/image receipt binds raw evidence filenames and hashes. Full owner source manifest includes all raw evidence and helper/tests. Source preparation or local checks do not approve native execution.
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
{
|
||||
"architecture": "amd64",
|
||||
"config": {
|
||||
"User": "10001:10001",
|
||||
"ExposedPorts": {
|
||||
"8080/tcp": {},
|
||||
"8081/tcp": {}
|
||||
},
|
||||
"Env": [
|
||||
"PATH=/opt/venv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"LANG=C.UTF-8",
|
||||
"GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305",
|
||||
"PYTHON_VERSION=3.12.14",
|
||||
"PYTHON_SHA256=5c8462af5790baf43a321a1559dbe0db06d1be4300fb85fb53c40060668e548a",
|
||||
"PYTHONDONTWRITEBYTECODE=1",
|
||||
"PYTHONUNBUFFERED=1"
|
||||
],
|
||||
"Entrypoint": [
|
||||
"informed-decision-container"
|
||||
],
|
||||
"WorkingDir": "/app"
|
||||
},
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"history": [
|
||||
{
|
||||
"created": "2026-06-16T00:01:29.967161902Z",
|
||||
"created_by": "ADD alpine-minirootfs-3.24.1-x86_64.tar.gz / # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-06-16T00:01:29.967161902Z",
|
||||
"created_by": "CMD [\"/bin/sh\"]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV LANG=C.UTF-8",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "RUN /bin/sh -c set -eux; \tapk add --no-cache \t\tca-certificates \t\ttzdata \t; # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV PYTHON_VERSION=3.12.14",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV PYTHON_SHA256=5c8462af5790baf43a321a1559dbe0db06d1be4300fb85fb53c40060668e548a",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:10:30.672225972Z",
|
||||
"created_by": "RUN /bin/sh -c set -eux; \t\tapk add --no-cache --virtual .build-deps \t\tbluez-dev \t\tbzip2-dev \t\tdpkg-dev dpkg \t\tfindutils \t\tg++ \t\tgcc \t\tgdbm-dev \t\tgnupg \t\tlibc-dev \t\tlibffi-dev \t\tlibnsl-dev \t\tlibtirpc-dev \t\tlinux-headers \t\tmake \t\tncurses-dev \t\topenssl-dev \t\tpax-utils \t\treadline-dev \t\tsqlite-dev \t\ttar \t\ttcl-dev \t\ttk \t\ttk-dev \t\tutil-linux-dev \t\txz \t\txz-dev \t\tzlib-dev \t; \t\twget -O python.tar.xz \"https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz\"; \techo \"$PYTHON_SHA256 *python.tar.xz\" | sha256sum -c -; \twget -O python.tar.xz.asc \"https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc\"; \tGNUPGHOME=\"$(mktemp -d)\"; export GNUPGHOME; \tgpg --batch --keyserver hkps://keys.openpgp.org --recv-keys \"$GPG_KEY\"; \tgpg --batch --verify python.tar.xz.asc python.tar.xz; \tgpgconf --kill all; \trm -rf \"$GNUPGHOME\" python.tar.xz.asc; \tmkdir -p /usr/src/python; \ttar --extract --directory /usr/src/python --strip-components=1 --file python.tar.xz; \trm python.tar.xz; \t\tcd /usr/src/python; \tgnuArch=\"$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)\"; \t./configure \t\t--build=\"$gnuArch\" \t\t--enable-loadable-sqlite-extensions \t\t--enable-option-checking=fatal \t\t--enable-shared \t\t$(test \"${gnuArch%%-*}\" != 'riscv64' && echo '--with-lto') \t\t--with-ensurepip \t; \tnproc=\"$(nproc)\"; \tEXTRA_CFLAGS=\"-DTHREAD_STACK_SIZE=0x100000\"; \tLDFLAGS=\"${LDFLAGS:-} -Wl,--strip-all\"; \tarch=\"$(apk --print-arch)\"; \tcase \"$arch\" in \t\tx86_64|aarch64) \t\t\tEXTRA_CFLAGS=\"${EXTRA_CFLAGS:-} -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer\"; \t\t\t;; \t\tx86) \t\t\t;; \t\t*) \t\t\tEXTRA_CFLAGS=\"${EXTRA_CFLAGS:-} -fno-omit-frame-pointer\"; \t\t\t;; \tesac; \tmake -j \"$nproc\" \t\t\"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}\" \t\t\"LDFLAGS=${LDFLAGS:-}\" \t; \trm python; \tmake -j \"$nproc\" \t\t\"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}\" \t\t\"LDFLAGS=${LDFLAGS:-} -Wl,-rpath='\\$\\$ORIGIN/../lib'\" \t\tpython \t; \tmake install; \t\tcd /; \trm -rf /usr/src/python; \t\tfind /usr/local -depth \t\t\\( \t\t\t\\( -type d -a \\( -name test -o -name tests -o -name idle_test \\) \\) \t\t\t-o \\( -type f -a \\( -name '*.pyc' -o -name '*.pyo' -o -name 'libpython*.a' \\) \\) \t\t\\) -exec rm -rf '{}' + \t; \t\tfind /usr/local -type f -executable -not \\( -name '*tkinter*' \\) -exec scanelf --needed --nobanner --format '%n#p' '{}' ';' \t\t| tr ',' '\\n' \t\t| sort -u \t\t| awk 'system(\"[ -e /usr/local/lib/\" $1 \" ]\") == 0 { next } { print \"so:\" $1 }' \t\t| xargs -rt apk add --no-network --virtual .python-rundeps \t; \tapk del --no-network .build-deps; \t\texport PYTHONDONTWRITEBYTECODE=1; \tpython3 --version; \tpip3 --version # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:10:30.782726003Z",
|
||||
"created_by": "RUN /bin/sh -c set -eux; \tfor src in idle3 pip3 pydoc3 python3 python3-config; do \t\tdst=\"$(echo \"$src\" | tr -d 3)\"; \t\t[ -s \"/usr/local/bin/$src\" ]; \t\t[ ! -e \"/usr/local/bin/$dst\" ]; \t\tln -svT \"$src\" \"/usr/local/bin/$dst\"; \tdone # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:10:30.782726003Z",
|
||||
"created_by": "CMD [\"python3\"]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-11T00:49:47.962156876+02:00",
|
||||
"created_by": "ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PATH=/opt/venv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-11T00:49:47.962156876+02:00",
|
||||
"created_by": "RUN /bin/sh -c apk add --no-cache 'libuuid>=2.42.3-r1' && addgroup -S -g 10001 informed && adduser -S -u 10001 -G informed -H informed # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:55.351944978+02:00",
|
||||
"created_by": "COPY /opt/venv /opt/venv # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.462092072+02:00",
|
||||
"created_by": "RUN /bin/sh -c rm -rf /usr/local/bin/pip* /usr/local/lib/python3.12/site-packages/pip* /usr/local/lib/python3.12/site-packages/setuptools* /usr/local/lib/python3.12/site-packages/pkg_resources /opt/venv/bin/pip* /opt/venv/lib/python3.12/site-packages/pip* /opt/venv/lib/python3.12/site-packages/setuptools* /opt/venv/lib/python3.12/site-packages/pkg_resources # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "WORKDIR /app",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "USER 10001:10001",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "EXPOSE [8080/tcp 8081/tcp]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "ENTRYPOINT [\"informed-decision-container\"]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
}
|
||||
],
|
||||
"os": "linux",
|
||||
"rootfs": {
|
||||
"type": "layers",
|
||||
"diff_ids": [
|
||||
"sha256:34884abbe92863fce933ed7c39c0e045631af0ed86d5cc0dfbdf9fdca426ce3c",
|
||||
"sha256:3ca4be2c6e9ac0223715355253725381000486c2b45bfcb22cf571b6a85a12dd",
|
||||
"sha256:e5ccda0fbf6b54d343e024156d876553ba57d3926d7196584b3a1ce4df016366",
|
||||
"sha256:4098ad033525263f92a8a9c51865596025d47018e078c0b1f7d9cd5663fc1ffe",
|
||||
"sha256:f9b4a8a412a0c07a489e46fb5db41f9d0dc84d4ec38a4e2c6ab9531f44e0d9f1",
|
||||
"sha256:648451a0dda84ad04681e32b5ecc7cd5d3a4f0ad84f783e9598d72bc69620d5c",
|
||||
"sha256:361430a1113969743b99e237b20f023d5497493bcf96fb91af99ac0a0dbc4a59",
|
||||
"sha256:cfc5939674d67f60b4411c24dfcde5622b712eeb7376cd0941a2751da80a6b02"
|
||||
]
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"policy": {
|
||||
"origin": "http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080",
|
||||
"package": "informed-decision.compact-sitting",
|
||||
"version": "v13",
|
||||
"package_digest": "sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873",
|
||||
"pod_name": "flex-auth-informed-decision-sitting"
|
||||
},
|
||||
"keycape_egress_ips": [
|
||||
"92.205.62.239"
|
||||
],
|
||||
"storage_class": "local-path",
|
||||
"ordinary_approval_ids": [
|
||||
"2ce76d7f-01c3-4b63-8476-8d1230679769",
|
||||
"c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
|
||||
"dc22666a-d5d7-46bc-9490-ebe9fe09dc38"
|
||||
],
|
||||
"lifecycle_policy": {
|
||||
"package": "informed-decision.lifecycle",
|
||||
"version": "v2",
|
||||
"package_digest": "sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c",
|
||||
"origin": "http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080",
|
||||
"pod_name": "flex-auth-informed-decision-lifecycle"
|
||||
},
|
||||
"lifecycle_delivery": true,
|
||||
"intake_attributes": true,
|
||||
"intake_delivery": {
|
||||
"hub_origin": "http://state-hub.state-hub.svc.cluster.local:8000"
|
||||
},
|
||||
"workload_api": {
|
||||
"registries_configmap": "informed-decision-workload-registry",
|
||||
"peers": [
|
||||
{
|
||||
"namespace": "state-hub",
|
||||
"app": "state-hub"
|
||||
}
|
||||
],
|
||||
"api_egress": [
|
||||
{
|
||||
"ip": "10.43.0.1",
|
||||
"port": 443
|
||||
},
|
||||
{
|
||||
"ip": "92.205.62.239",
|
||||
"port": 6443
|
||||
}
|
||||
],
|
||||
"intake": true,
|
||||
"lifecycle": true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover",
|
||||
"argocd.argoproj.io/tracking-id": "informed-decision:apps/Deployment:informed-decision/informed-decision"
|
||||
},
|
||||
"name": "informed-decision",
|
||||
"namespace": "informed-decision"
|
||||
},
|
||||
"spec": {
|
||||
"progressDeadlineSeconds": 600,
|
||||
"replicas": 1,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"strategy": {
|
||||
"type": "Recreate"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover"
|
||||
},
|
||||
"labels": {
|
||||
"app.kubernetes.io/component": "review",
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"automountServiceAccountToken": false,
|
||||
"containers": [
|
||||
{
|
||||
"env": [
|
||||
{
|
||||
"name": "INFD_KEYCAPE_ISSUER",
|
||||
"value": "https://kc.coulomb.social"
|
||||
},
|
||||
{
|
||||
"name": "INFD_CONTAINER_CONFIG",
|
||||
"value": "/configuration/runtime.json"
|
||||
}
|
||||
],
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"livenessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"name": "informed-decision",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 8080,
|
||||
"name": "http"
|
||||
},
|
||||
{
|
||||
"containerPort": 8081,
|
||||
"name": "workload"
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"resources": {
|
||||
"limits": {
|
||||
"cpu": "500m",
|
||||
"memory": "256Mi"
|
||||
},
|
||||
"requests": {
|
||||
"cpu": "5m",
|
||||
"memory": "64Mi"
|
||||
}
|
||||
},
|
||||
"securityContext": {
|
||||
"allowPrivilegeEscalation": false,
|
||||
"capabilities": {
|
||||
"drop": [
|
||||
"ALL"
|
||||
]
|
||||
},
|
||||
"readOnlyRootFilesystem": true
|
||||
},
|
||||
"startupProbe": {
|
||||
"failureThreshold": 12,
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/data",
|
||||
"name": "data"
|
||||
},
|
||||
{
|
||||
"mountPath": "/run/informed-decision",
|
||||
"name": "runtime"
|
||||
},
|
||||
{
|
||||
"mountPath": "/tmp",
|
||||
"name": "tmp"
|
||||
},
|
||||
{
|
||||
"mountPath": "/configuration",
|
||||
"name": "configuration",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/policy",
|
||||
"name": "caller",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/audit",
|
||||
"name": "audit",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/kubernetes",
|
||||
"name": "kubernetes-api",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/workload-registry",
|
||||
"name": "workload-registry",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/requester",
|
||||
"name": "sitting-requester",
|
||||
"readOnly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"securityContext": {
|
||||
"fsGroup": 10001,
|
||||
"fsGroupChangePolicy": "OnRootMismatch",
|
||||
"runAsGroup": 10001,
|
||||
"runAsNonRoot": true,
|
||||
"runAsUser": 10001,
|
||||
"seccompProfile": {
|
||||
"type": "RuntimeDefault"
|
||||
}
|
||||
},
|
||||
"serviceAccountName": "review",
|
||||
"terminationGracePeriodSeconds": 45,
|
||||
"volumes": [
|
||||
{
|
||||
"name": "data",
|
||||
"persistentVolumeClaim": {
|
||||
"claimName": "informed-decision-data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
},
|
||||
"name": "runtime"
|
||||
},
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
},
|
||||
"name": "tmp"
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 292,
|
||||
"name": "informed-decision-runtime-6c221878d051"
|
||||
},
|
||||
"name": "configuration"
|
||||
},
|
||||
{
|
||||
"name": "caller",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"audience": "flex-auth",
|
||||
"expirationSeconds": 3600,
|
||||
"path": "token"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "audit",
|
||||
"secret": {
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "token",
|
||||
"path": "token"
|
||||
}
|
||||
],
|
||||
"secretName": "informed-decision-audit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "kubernetes-api",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"expirationSeconds": 600,
|
||||
"path": "token"
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"items": [
|
||||
{
|
||||
"key": "ca.crt",
|
||||
"path": "ca.crt"
|
||||
}
|
||||
],
|
||||
"name": "kube-root-ca.crt"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 292,
|
||||
"name": "informed-decision-workload-registry"
|
||||
},
|
||||
"name": "workload-registry"
|
||||
},
|
||||
{
|
||||
"name": "sitting-requester",
|
||||
"secret": {
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "client-secret",
|
||||
"path": "client-secret"
|
||||
}
|
||||
],
|
||||
"optional": false,
|
||||
"secretName": "informed-decision-sitting-requester"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
"""Read-only exact Deployment and admission boundaries; no mutation authority."""
|
||||
import copy
|
||||
|
||||
BASE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173'
|
||||
CANDIDATE = 'forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a'
|
||||
|
||||
|
||||
def projection(value):
|
||||
value = copy.deepcopy(value)
|
||||
value.pop('status', None)
|
||||
for key in ('resourceVersion', 'generation', 'creationTimestamp', 'managedFields'):
|
||||
value['metadata'].pop(key, None)
|
||||
for key in ('kubectl.kubernetes.io/last-applied-configuration', 'deployment.kubernetes.io/revision'):
|
||||
value['metadata'].get('annotations', {}).pop(key, None)
|
||||
return value
|
||||
|
||||
|
||||
def check_current(current, sealed):
|
||||
if projection(current) != sealed:
|
||||
raise ValueError('sealed live UID or configuration changed')
|
||||
|
||||
|
||||
def check_admitted(admitted, sealed):
|
||||
expected = copy.deepcopy(sealed)
|
||||
containers = expected['spec']['template']['spec']['containers']
|
||||
if len(containers) != 1 or containers[0]['name'] != 'informed-decision' or containers[0]['image'] != BASE:
|
||||
raise ValueError('unexpected baseline container identity')
|
||||
containers[0]['image'] = CANDIDATE
|
||||
if projection(admitted) != expected:
|
||||
raise ValueError('admission changed configuration beyond the sole image pin')
|
||||
|
||||
|
||||
def transport_result(exit_code, output):
|
||||
import json
|
||||
try:
|
||||
value = json.loads(output)
|
||||
except (ValueError, TypeError):
|
||||
return {'all_checks_pass': False, 'reason': 'invalid transport result'}
|
||||
if exit_code != 0 or not isinstance(value, dict) or value.get('all_checks_pass') is not True:
|
||||
return {'all_checks_pass': False, 'reason': 'read-only preflight refused'}
|
||||
return value
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import copy,json,time
|
||||
from datetime import datetime,timezone
|
||||
from informed_decision.policy import PolicyClient,CONTRACT,submitted_digest
|
||||
pin='sha256:'+'b'*64
|
||||
req={'id':'image-purpose-fixture','tenant':'tenant:platform','subject':{'id':'synthetic','type':'service','tenant':'tenant:platform'},'resource':{'id':'memo:fixture','type':'memo','system':'informed-decision','tenant':'tenant:platform'},'action':'register','context':{}}
|
||||
class Transport:
|
||||
def request(self,*args,**kwargs):
|
||||
now=time.time(); stamp=lambda t:datetime.fromtimestamp(t,timezone.utc).isoformat()
|
||||
b={**copy.deepcopy({k:req[k] for k in ('tenant','subject','action','resource','context')}),'request_digest':'sha256:'+'e'*64,'submitted_request_digest':submitted_digest(req)}
|
||||
if self.purpose!='ABSENT':b['purpose']=self.purpose
|
||||
d={'id':'synthetic-decision','contract_version':CONTRACT,'request_id':req['id'],'effect':'allow','matched_policy_version':'v1','subject':req['subject'],'resource':req['resource'],'binding':b,'lifetime':{'kind':'ttl','not_before':stamp(now-1),'expires_at':stamp(now+60)},'provenance':{'policy_package':'fixture','policy_version':'v1','policy_package_digest':pin,'registry_snapshot_digest':'sha256:'+'c'*64,'evaluator':'flex-auth/fixture','decision_time':stamp(now)}}
|
||||
return 200,d
|
||||
checks=[]
|
||||
for purpose in ('ABSENT','','readback','enforcement','unknown',None,False,0,[],{}):
|
||||
t=Transport();t.purpose=purpose
|
||||
c=PolicyClient('https://fixture.invalid',lambda:'synthetic-only',package='fixture',version='v1',package_digest=pin,transport=t)
|
||||
o=c.check(req)
|
||||
if purpose in ('ABSENT',''):assert o.outcome=='allow';o.require_current(time.time())
|
||||
else:assert o.outcome=='invalid_decision' and o.decision_json is None
|
||||
checks.append(str(purpose))
|
||||
print(json.dumps({'installed_image_purpose_variants':len(checks),'binding_forms_allowed':2,'advisory_or_malformed_refused':8,'synthetic_only':True,'native_provider':False}))
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# Informed Decision purpose overlay release
|
||||
|
||||
## Requested decision
|
||||
|
||||
Approve the exact purpose-only image rollout and protected real-data backup/restore protocol for the existing Informed Decision service on railiance01. This request is separate from the already approved config-only repair. Only the existing Deployment image changes through the owner's manual Argo workflow, with prune disabled. Runtime ConfigMap `informed-decision-runtime-6c221878d051`, schema5, PVC, credentials, audience, policies, registries, access, replica1 and Recreate strategy remain fixed. Execute by 2026-10-12T23:59:59Z, after refreshed sealed-source/UID/configuration checks and backup/restore gates. Expiry stops authorization for an unstarted release; it does not install a controller or automatically roll back an already released image.
|
||||
|
||||
## Artifact and known finding
|
||||
|
||||
Actual owner CI task11484/run3 published immutable image `sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a` from source `3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168`. Anonymous registry verification preserves all eight base compressed blobs/rootfs layers and adds only policy.py with exact source hash and mode0644. Legacy-builder media-type/default config serialization differences are recorded; the runtime semantics remain unchanged. Pulled published image executes as UID10001/GID10001 and passes ten installed checks: two supported binding forms, eight advisory/malformed refusals. Tests use synthetic transport and do not claim new native PDP authorization proof. The two failed CI attempts remain in the same trial history.
|
||||
|
||||
Actual unfiltered pinned scanner/DB evidence covers44packages: zero HIGH/CRITICAL, **one fixable MEDIUM**, CVE-2026-85091, zlib1.3.2-r0 fixed in1.3.2-r1. Actual current-base scan has the identical finding. Approving this packet explicitly permits this inherited finding during this narrow purpose release; it is not a RiskNexus estate risk grade or zero-CVE claim. Owner record INFD-RISK-20261011-ZLIB-85091 and live task INFD-WP-0009-T05 require separate base refresh and native approval, reviewed by2026-10-18. That review date is manual follow-through, with no auto-controller claim. Scanner notes Alpine3.24 absent EOL list; OS vulnerability detection ran against38OSpackages. Unknown vulnerabilities remain outside snapshot knowledge.
|
||||
|
||||
## Native baseline and gates
|
||||
|
||||
Fresh read-only capture01:25:38Z: existing Deployment UIDa588e10a, Ready1, image7f5c, unchanged runtime6c; native admission preserves the full configuration plus exactly the proposed image. Clientdiff returns1. Requests3460/4000mCPU86%, memory9472Mi59%; refresh before release. Existing Argo Application UID499868f2 is manual, target7db8485, Healthy with pre-existing OutOfSync status. Do not treat a scoped Deployment release as full-app reconciliation. Preserve its tracking-id; no unrelated resource sync/prune/adoption.
|
||||
|
||||
The read-only helper binds original source/helper/render/baseline hashes, checks exact fresh live UID/configuration and admission, and writes a separate execution receipt outside this sealed packet. Failed initial raw Kustomize metadata check is retained: direct kubectl apply would drop Argo tracking-id. The reviewed selected Deployment explicitly retains that existing ID, matching Argo ownership. Any unrelated drift, different UID, altered admission, unavailable protected backup capacity, uncertain backup, restore mismatch or unhealthy baseline stops the release.
|
||||
|
||||
## Protected backup and release
|
||||
|
||||
Use the existing owner admin's SQLite backup API, not a raw copy of the live database/WAL. Protect directories0700/files0600, owned by10001. Retain independently protected off-cluster snapshot custody and only count/hash receipts. No database contents, caller tokens, requester Secret or runtime credential files enter Git, State Hub, logs or this packet. Native backup and offline real-data restore have not yet occurred. Use an isolated private disposable copy, networknone and no runtime config/token mounts, validate schema5/integrity and frozen snapshot counts, then clean only the disposable restored copy. Retain the original snapshot. The attached protocol binds case-specific paths and fail-closed capacity/custody checks.
|
||||
|
||||
Refresh a consistent online snapshot immediately before image-only cutover. This protocol does not assert traffic/dispatcher quiescence. Current and candidate share schema5 and unchanged store code; rollback retains the latest live database and all new/uncertain evidence. Stop the old writer before the new one with existing Recreate and single-writer lock. Do not restore an older snapshot over later writes, discard unresolved external effects, scale other workloads, change policies/identity/custody, or create human dispositions to make checks green.
|
||||
|
||||
Pin the existing Application to the exact owner commit containing the approved candidate source hashes, and manually sync only Deployment/informed-decision with prune=false. Verify actualimage/module/mode/UID, health/readiness and installed purpose refusals on the real placement; explicitly distinguish synthetic-transport checks from actual provider evidence. Existing native binding/lifecycle behavior must remain available. If unhealthy or verification fails, return Application source to7db8485 and scoped-sync prior same-schema image7f5c, preserving current evidence database; retain failed outcomes. Any data recovery beyond this same-schema image rollback is a separate founder decision.
|
||||
|
||||
## Alternatives and estimates
|
||||
|
||||
Proceed with this narrow release plus explicit inherited-medium follow-through, or defer and prepare a separate base/dependency refresh before any release. No additional recurring hosting is proposed: estimated incremental infrastructure EUR0, with private storage and attended engineering/recovery time unpriced. Risks include a brief Recreate interruption, private backup custody errors, caller refusal when advisory responses were improperly treated as binding, and the disclosed inherited finding. This decision does not promote agent autonomy or grant unrelated work.
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"node_allocatable_cpu_m": 4000,
|
||||
"node_requested_cpu_m": 3460,
|
||||
"captured_at": "2026-10-11T01:30:33.674360+00:00",
|
||||
"native_workload_changed": false,
|
||||
"native_backup_restore_executed": false,
|
||||
"argo": {
|
||||
"uid": "499868f2-eabc-4df4-ae31-b89ce58d750d",
|
||||
"repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git",
|
||||
"targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf",
|
||||
"path": "deploy/lifecycle",
|
||||
"destination": {
|
||||
"namespace": "informed-decision",
|
||||
"server": "https://kubernetes.default.svc"
|
||||
},
|
||||
"automated": false,
|
||||
"sync": {
|
||||
"comparedTo": {
|
||||
"destination": {
|
||||
"namespace": "informed-decision",
|
||||
"server": "https://kubernetes.default.svc"
|
||||
},
|
||||
"source": {
|
||||
"path": "deploy/lifecycle",
|
||||
"repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git",
|
||||
"targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf"
|
||||
}
|
||||
},
|
||||
"revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf",
|
||||
"status": "OutOfSync"
|
||||
},
|
||||
"health": {
|
||||
"lastTransitionTime": "2026-10-10T23:14:52Z",
|
||||
"status": "Healthy"
|
||||
}
|
||||
},
|
||||
"live_ready_replicas": 1,
|
||||
"admitted_uid": "a588e10a-90d2-4883-975e-6dd8b8feca92",
|
||||
"server_dry_run_passed": true,
|
||||
"admitted_spec_exactly_live_plus_image": true,
|
||||
"client_diff_exit": 1,
|
||||
"client_diff_sha256": "0506825b408bb2c7b9dcb00a5ee655dc9ec23b09b308d42bb013d72672f8f415",
|
||||
"node_allocated_resources": "(Total limits may be over 100 percent, i.e., overcommitted.)\n Resource Requests Limits\n -------- -------- ------\n cpu 3460m (86%) 36200m (905%)\n memory 9472Mi (59%) 32898Mi (205%)\n ephemeral-storage 0 (0%) 0 (0%)\n hugepages-1Gi 0 (0%) 0 (0%)\n hugepages-2Mi 0 (0%) 0 (0%)",
|
||||
"all_checks_pass": true,
|
||||
"sealed_preflight_inputs_sha256": "0bbdaf56459aaef3c35d7b1bf3ad20be6260f047df6dd1c5eb60ac1797150944",
|
||||
"fresh_execution_receipt": true
|
||||
}
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
{
|
||||
"architecture": "amd64",
|
||||
"config": {
|
||||
"Hostname": "",
|
||||
"Domainname": "",
|
||||
"User": "10001:10001",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": false,
|
||||
"AttachStderr": false,
|
||||
"ExposedPorts": {
|
||||
"8080/tcp": {},
|
||||
"8081/tcp": {}
|
||||
},
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": [
|
||||
"PATH=/opt/venv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"LANG=C.UTF-8",
|
||||
"GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305",
|
||||
"PYTHON_VERSION=3.12.14",
|
||||
"PYTHON_SHA256=5c8462af5790baf43a321a1559dbe0db06d1be4300fb85fb53c40060668e548a",
|
||||
"PYTHONDONTWRITEBYTECODE=1",
|
||||
"PYTHONUNBUFFERED=1"
|
||||
],
|
||||
"Cmd": null,
|
||||
"Image": "sha256:90f1574f9eda35fa6cb972961beb27a7cb904c36560e381930b0e14065c23883",
|
||||
"Volumes": null,
|
||||
"WorkingDir": "/app",
|
||||
"Entrypoint": [
|
||||
"informed-decision-container"
|
||||
],
|
||||
"OnBuild": null,
|
||||
"Labels": {
|
||||
"org.opencontainers.image.base.digest": "sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"org.opencontainers.image.revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"social.coulomb.release.scope": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"social.coulomb.source.policy.sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62"
|
||||
}
|
||||
},
|
||||
"container_config": {
|
||||
"Hostname": "",
|
||||
"Domainname": "",
|
||||
"User": "10001:10001",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": false,
|
||||
"AttachStderr": false,
|
||||
"ExposedPorts": {
|
||||
"8080/tcp": {},
|
||||
"8081/tcp": {}
|
||||
},
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": [
|
||||
"PATH=/opt/venv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"LANG=C.UTF-8",
|
||||
"GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305",
|
||||
"PYTHON_VERSION=3.12.14",
|
||||
"PYTHON_SHA256=5c8462af5790baf43a321a1559dbe0db06d1be4300fb85fb53c40060668e548a",
|
||||
"PYTHONDONTWRITEBYTECODE=1",
|
||||
"PYTHONUNBUFFERED=1"
|
||||
],
|
||||
"Cmd": [
|
||||
"/bin/sh",
|
||||
"-c",
|
||||
"#(nop) COPY file:2be9cb36e7253e15733673359cda8caa22986b6888822a008c1b360d909994e0 in /opt/venv/lib/python3.12/site-packages/informed_decision/policy.py "
|
||||
],
|
||||
"Image": "sha256:90f1574f9eda35fa6cb972961beb27a7cb904c36560e381930b0e14065c23883",
|
||||
"Volumes": null,
|
||||
"WorkingDir": "/app",
|
||||
"Entrypoint": [
|
||||
"informed-decision-container"
|
||||
],
|
||||
"OnBuild": null,
|
||||
"Labels": {
|
||||
"org.opencontainers.image.base.digest": "sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"org.opencontainers.image.revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"social.coulomb.release.scope": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"social.coulomb.source.policy.sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62"
|
||||
}
|
||||
},
|
||||
"created": "2026-10-11T01:21:04.787527697Z",
|
||||
"docker_version": "27.5.1",
|
||||
"history": [
|
||||
{
|
||||
"created": "2026-06-16T00:01:29.967161902Z",
|
||||
"created_by": "ADD alpine-minirootfs-3.24.1-x86_64.tar.gz / # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-06-16T00:01:29.967161902Z",
|
||||
"created_by": "CMD [\"/bin/sh\"]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV LANG=C.UTF-8",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "RUN /bin/sh -c set -eux; \tapk add --no-cache \t\tca-certificates \t\ttzdata \t; # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV GPG_KEY=7169605F62C751356D054A26A821E680E5FA6305",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV PYTHON_VERSION=3.12.14",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:05:24.224544843Z",
|
||||
"created_by": "ENV PYTHON_SHA256=5c8462af5790baf43a321a1559dbe0db06d1be4300fb85fb53c40060668e548a",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:10:30.672225972Z",
|
||||
"created_by": "RUN /bin/sh -c set -eux; \t\tapk add --no-cache --virtual .build-deps \t\tbluez-dev \t\tbzip2-dev \t\tdpkg-dev dpkg \t\tfindutils \t\tg++ \t\tgcc \t\tgdbm-dev \t\tgnupg \t\tlibc-dev \t\tlibffi-dev \t\tlibnsl-dev \t\tlibtirpc-dev \t\tlinux-headers \t\tmake \t\tncurses-dev \t\topenssl-dev \t\tpax-utils \t\treadline-dev \t\tsqlite-dev \t\ttar \t\ttcl-dev \t\ttk \t\ttk-dev \t\tutil-linux-dev \t\txz \t\txz-dev \t\tzlib-dev \t; \t\twget -O python.tar.xz \"https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz\"; \techo \"$PYTHON_SHA256 *python.tar.xz\" | sha256sum -c -; \twget -O python.tar.xz.asc \"https://www.python.org/ftp/python/${PYTHON_VERSION%%[a-z]*}/Python-$PYTHON_VERSION.tar.xz.asc\"; \tGNUPGHOME=\"$(mktemp -d)\"; export GNUPGHOME; \tgpg --batch --keyserver hkps://keys.openpgp.org --recv-keys \"$GPG_KEY\"; \tgpg --batch --verify python.tar.xz.asc python.tar.xz; \tgpgconf --kill all; \trm -rf \"$GNUPGHOME\" python.tar.xz.asc; \tmkdir -p /usr/src/python; \ttar --extract --directory /usr/src/python --strip-components=1 --file python.tar.xz; \trm python.tar.xz; \t\tcd /usr/src/python; \tgnuArch=\"$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)\"; \t./configure \t\t--build=\"$gnuArch\" \t\t--enable-loadable-sqlite-extensions \t\t--enable-option-checking=fatal \t\t--enable-shared \t\t$(test \"${gnuArch%%-*}\" != 'riscv64' && echo '--with-lto') \t\t--with-ensurepip \t; \tnproc=\"$(nproc)\"; \tEXTRA_CFLAGS=\"-DTHREAD_STACK_SIZE=0x100000\"; \tLDFLAGS=\"${LDFLAGS:-} -Wl,--strip-all\"; \tarch=\"$(apk --print-arch)\"; \tcase \"$arch\" in \t\tx86_64|aarch64) \t\t\tEXTRA_CFLAGS=\"${EXTRA_CFLAGS:-} -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer\"; \t\t\t;; \t\tx86) \t\t\t;; \t\t*) \t\t\tEXTRA_CFLAGS=\"${EXTRA_CFLAGS:-} -fno-omit-frame-pointer\"; \t\t\t;; \tesac; \tmake -j \"$nproc\" \t\t\"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}\" \t\t\"LDFLAGS=${LDFLAGS:-}\" \t; \trm python; \tmake -j \"$nproc\" \t\t\"EXTRA_CFLAGS=${EXTRA_CFLAGS:-}\" \t\t\"LDFLAGS=${LDFLAGS:-} -Wl,-rpath='\\$\\$ORIGIN/../lib'\" \t\tpython \t; \tmake install; \t\tcd /; \trm -rf /usr/src/python; \t\tfind /usr/local -depth \t\t\\( \t\t\t\\( -type d -a \\( -name test -o -name tests -o -name idle_test \\) \\) \t\t\t-o \\( -type f -a \\( -name '*.pyc' -o -name '*.pyo' -o -name 'libpython*.a' \\) \\) \t\t\\) -exec rm -rf '{}' + \t; \t\tfind /usr/local -type f -executable -not \\( -name '*tkinter*' \\) -exec scanelf --needed --nobanner --format '%n#p' '{}' ';' \t\t| tr ',' '\\n' \t\t| sort -u \t\t| awk 'system(\"[ -e /usr/local/lib/\" $1 \" ]\") == 0 { next } { print \"so:\" $1 }' \t\t| xargs -rt apk add --no-network --virtual .python-rundeps \t; \tapk del --no-network .build-deps; \t\texport PYTHONDONTWRITEBYTECODE=1; \tpython3 --version; \tpip3 --version # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:10:30.782726003Z",
|
||||
"created_by": "RUN /bin/sh -c set -eux; \tfor src in idle3 pip3 pydoc3 python3 python3-config; do \t\tdst=\"$(echo \"$src\" | tr -d 3)\"; \t\t[ -s \"/usr/local/bin/$src\" ]; \t\t[ ! -e \"/usr/local/bin/$dst\" ]; \t\tln -svT \"$src\" \"/usr/local/bin/$dst\"; \tdone # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-09-01T00:10:30.782726003Z",
|
||||
"created_by": "CMD [\"python3\"]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-11T00:49:47.962156876+02:00",
|
||||
"created_by": "ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PATH=/opt/venv/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-09-11T00:49:47.962156876+02:00",
|
||||
"created_by": "RUN /bin/sh -c apk add --no-cache 'libuuid>=2.42.3-r1' && addgroup -S -g 10001 informed && adduser -S -u 10001 -G informed -H informed # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:55.351944978+02:00",
|
||||
"created_by": "COPY /opt/venv /opt/venv # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.462092072+02:00",
|
||||
"created_by": "RUN /bin/sh -c rm -rf /usr/local/bin/pip* /usr/local/lib/python3.12/site-packages/pip* /usr/local/lib/python3.12/site-packages/setuptools* /usr/local/lib/python3.12/site-packages/pkg_resources /opt/venv/bin/pip* /opt/venv/lib/python3.12/site-packages/pip* /opt/venv/lib/python3.12/site-packages/setuptools* /opt/venv/lib/python3.12/site-packages/pkg_resources # buildkit",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "WORKDIR /app",
|
||||
"comment": "buildkit.dockerfile.v0"
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "USER 10001:10001",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "EXPOSE [8080/tcp 8081/tcp]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-05T01:03:56.675216821+02:00",
|
||||
"created_by": "ENTRYPOINT [\"informed-decision-container\"]",
|
||||
"comment": "buildkit.dockerfile.v0",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-11T01:15:11.991443676Z",
|
||||
"created_by": "/bin/sh -c #(nop) ARG SOURCE_REVISION",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-11T01:21:04.716126392Z",
|
||||
"created_by": "/bin/sh -c #(nop) LABEL org.opencontainers.image.revision=3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168 org.opencontainers.image.base.digest=sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173 social.coulomb.source.policy.sha256=9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62 social.coulomb.release.scope=INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"empty_layer": true
|
||||
},
|
||||
{
|
||||
"created": "2026-10-11T01:21:04.787527697Z",
|
||||
"created_by": "/bin/sh -c #(nop) COPY file:2be9cb36e7253e15733673359cda8caa22986b6888822a008c1b360d909994e0 in /opt/venv/lib/python3.12/site-packages/informed_decision/policy.py "
|
||||
}
|
||||
],
|
||||
"os": "linux",
|
||||
"rootfs": {
|
||||
"type": "layers",
|
||||
"diff_ids": [
|
||||
"sha256:34884abbe92863fce933ed7c39c0e045631af0ed86d5cc0dfbdf9fdca426ce3c",
|
||||
"sha256:3ca4be2c6e9ac0223715355253725381000486c2b45bfcb22cf571b6a85a12dd",
|
||||
"sha256:e5ccda0fbf6b54d343e024156d876553ba57d3926d7196584b3a1ce4df016366",
|
||||
"sha256:4098ad033525263f92a8a9c51865596025d47018e078c0b1f7d9cd5663fc1ffe",
|
||||
"sha256:f9b4a8a412a0c07a489e46fb5db41f9d0dc84d4ec38a4e2c6ab9531f44e0d9f1",
|
||||
"sha256:648451a0dda84ad04681e32b5ecc7cd5d3a4f0ad84f783e9598d72bc69620d5c",
|
||||
"sha256:361430a1113969743b99e237b20f023d5497493bcf96fb91af99ac0a0dbc4a59",
|
||||
"sha256:cfc5939674d67f60b4411c24dfcde5622b712eeb7376cd0941a2751da80a6b02",
|
||||
"sha256:21ff9188cb29ca95fe9be11355f70ab5586e8499e33b52a253d953fb3b75aea3"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"schemaVersion": 2,
|
||||
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
|
||||
"config": {
|
||||
"mediaType": "application/vnd.docker.container.image.v1+json",
|
||||
"size": 10428,
|
||||
"digest": "sha256:f34de21379c4f50ea0361ca1d8296c8e72f989499ad288016b81204997ae4779"
|
||||
},
|
||||
"layers": [
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 3846391,
|
||||
"digest": "sha256:55afa1ecc21d2bb5e5045f32dafee56272ffd89860bac26f6c32123439af26a4"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 408093,
|
||||
"digest": "sha256:47393b668ce535d06e8967917d424c177e2ecccae83856d48b2e99164f8cc6cb"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 16346740,
|
||||
"digest": "sha256:2014fd3d47b2c2dd4dedc765822ac60ae269f3efa0e614f46ae29f540c7f1235"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 248,
|
||||
"digest": "sha256:ed62c91ccd94e36a928e96d704cfcf20861302590245cc12aa89a15a5d6be29b"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 49243,
|
||||
"digest": "sha256:f0fe3e08ab046c0c5e29d34ee73bc8c7e03398eb891e4498e0a67088a5ea3e86"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 10216362,
|
||||
"digest": "sha256:82ff17b555d91096dd328eb1e829daaeba9a48d7757143d0b97c35a721f6fb87"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 459,
|
||||
"digest": "sha256:16a3dba6b720d3059eab918cd3596f94145ac9cf4d456f925a21f0f72522863f"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 93,
|
||||
"digest": "sha256:e73dd464fbff5607cc62a1b2b66b0eefe737dfad4db8e7b58a48cda7c12d94d3"
|
||||
},
|
||||
{
|
||||
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
|
||||
"size": 3586,
|
||||
"digest": "sha256:cfee29c2f8119d2a39714ecbe5095a2dc1c986054f2e1fe0a6565163242417e3"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"id": "INFD-RISK-20261011-ZLIB-85091",
|
||||
"kind": "owner-vulnerability-follow-through",
|
||||
"owner": "informed-decision",
|
||||
"task": "INFD-WP-0009-T05",
|
||||
"status": "open",
|
||||
"created": "2026-10-11",
|
||||
"review_due": "2026-10-18",
|
||||
"finding": "CVE-2026-85091",
|
||||
"scanner_severity": "MEDIUM",
|
||||
"estate_risk_grade": null,
|
||||
"affected_package": "zlib",
|
||||
"installed": "1.3.2-r0",
|
||||
"fixed": "1.3.2-r1",
|
||||
"actual_current_base_and_candidate_findings_identical": true,
|
||||
"source_evidence": "security-summary.json, trivy-full.json, base-trivy-full.json",
|
||||
"human_temporary_disposition": "pending",
|
||||
"follow_through": "Prepare a separately source-bound official-base/dependency refresh through normal owner CI, verify full scan and runtime compatibility, obtain distinct native release approval before updating this workload",
|
||||
"manual_review_expiry": "Due date requires owner review/escalation if unresolved; no automatic rollback/controller is installed",
|
||||
"close_condition": "Verified installed native fixed package and full unfiltered rescan; preserve original detection and any human disposition"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,141 @@
|
|||
{
|
||||
"id": "infd-20261011-purpose-overlay-r1",
|
||||
"version": 1,
|
||||
"question": "Approve this exact Informed Decision purpose-only image release on railiance01, including protected native backup/restore gates and explicit temporary acceptance of the inherited fixable MEDIUM zlib finding with owner remediation follow-through?",
|
||||
"requested_act": "approve",
|
||||
"binding_level": "organizational",
|
||||
"brief": "Actual owner CI published763c from3e4bcb26; unchanged8base layers plus one policy.py, installedUID10001 and10purpose checks pass. Full44package scan0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib, identical actualbase scan. Only Deploymentimage changes; manualArgo prune=false, runtime6c/schema5/PVC/identity/policies unchanged. Protected real-data backup/restore and fresh sealed-source/UID/configuration gates required, not executed. Live owner riskrecord/T05 dueOct18; Recreate briefly interrupts service. No priorconfigapproval reused.",
|
||||
"binding": {
|
||||
"principal": {
|
||||
"id": "pending-human-session",
|
||||
"kind": "person",
|
||||
"display_name": "Founder review"
|
||||
},
|
||||
"target": {
|
||||
"kind": "environment",
|
||||
"id": "realm:kubernetes/railiance01/informed-decision",
|
||||
"label": "Informed Decision image-only purpose hardening on railiance01",
|
||||
"environment": "production"
|
||||
},
|
||||
"terms": "Only attached exact INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1: protected consistent snapshots/off-cluster custody/offline restore plus exact owner-source pin/manual Deployment-only image release763c, prune=false. ADMINISTER activationAPPROVED only upon actualdisposition, execute by2026-10-12T23:59:59Z afterfresh sealedpreflight+restoregates; rollbackprior7f5 retaining latestschema5DB. Explicit inheritedfixableMEDIUM permitted with INFD-WP-0009-T05 ownerreviewdue2026-10-18. No credential/policy/grant change, humanbinding, wholeAppsync or autonomygrant."
|
||||
},
|
||||
"step_kind": "approve",
|
||||
"packet": [
|
||||
{
|
||||
"item_id": "decision-packet-md",
|
||||
"label": "decision-packet.md",
|
||||
"hash": "sha256:7f6d8987f65dff479eeead67b7ca940ef44c22c1cdbdd6ca33fd732b824c8f02"
|
||||
},
|
||||
{
|
||||
"item_id": "proposal-json",
|
||||
"label": "proposal.json",
|
||||
"hash": "sha256:08c5573eaad05efd24b6df6737d33e7189543eb621f21704e38bab4326094914"
|
||||
},
|
||||
{
|
||||
"item_id": "candidate-admission-json",
|
||||
"label": "candidate-admission.json",
|
||||
"hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
{
|
||||
"item_id": "rollback-admission-json",
|
||||
"label": "rollback-admission.json",
|
||||
"hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50"
|
||||
},
|
||||
{
|
||||
"item_id": "candidate-deployment-json",
|
||||
"label": "candidate-deployment.json",
|
||||
"hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e"
|
||||
},
|
||||
{
|
||||
"item_id": "rollback-deployment-json",
|
||||
"label": "rollback-deployment.json",
|
||||
"hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121"
|
||||
},
|
||||
{
|
||||
"item_id": "published-verification-json",
|
||||
"label": "published-verification.json",
|
||||
"hash": "sha256:e304dd29571bf7d7b9f1db2ade0163dd39cfec012a5ce6986139f019f37e65a2"
|
||||
},
|
||||
{
|
||||
"item_id": "registry-proof-json",
|
||||
"label": "registry-proof.json",
|
||||
"hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213"
|
||||
},
|
||||
{
|
||||
"item_id": "security-summary-json",
|
||||
"label": "security-summary.json",
|
||||
"hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44"
|
||||
},
|
||||
{
|
||||
"item_id": "trivy-full-json",
|
||||
"label": "trivy-full.json",
|
||||
"hash": "sha256:f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e"
|
||||
},
|
||||
{
|
||||
"item_id": "sbom-cdx-json",
|
||||
"label": "sbom.cdx.json",
|
||||
"hash": "sha256:a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d"
|
||||
},
|
||||
{
|
||||
"item_id": "check-installed-py",
|
||||
"label": "check_installed.py",
|
||||
"hash": "sha256:a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad"
|
||||
},
|
||||
{
|
||||
"item_id": "native-backup-restore-protocol-md",
|
||||
"label": "native-backup-restore-protocol.md",
|
||||
"hash": "sha256:aa9758d4de587d14c6ce0fdaccd84002c5c5099425b9169ca7c972a86e9d3dec"
|
||||
},
|
||||
{
|
||||
"item_id": "inherited-vulnerability-follow-through-json",
|
||||
"label": "inherited-vulnerability-follow-through.json",
|
||||
"hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101"
|
||||
},
|
||||
{
|
||||
"item_id": "native-preflight-json",
|
||||
"label": "native-preflight.json",
|
||||
"hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262"
|
||||
},
|
||||
{
|
||||
"item_id": "sealed-live-deployment-json",
|
||||
"label": "sealed-live-deployment.json",
|
||||
"hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362"
|
||||
},
|
||||
{
|
||||
"item_id": "change-guard-py",
|
||||
"label": "change_guard.py",
|
||||
"hash": "sha256:830f7771b5c7d0a2851973aa65a01c6ab40b86570f0933d8aebb89f9665ca7e1"
|
||||
},
|
||||
{
|
||||
"item_id": "preflight-py",
|
||||
"label": "preflight.py",
|
||||
"hash": "sha256:c206a1a9b9d232c656c6d57fb9247549eefa13b275a5da4d39b45a6c9902c834"
|
||||
},
|
||||
{
|
||||
"item_id": "preflight-inputs-json",
|
||||
"label": "preflight-inputs.json",
|
||||
"hash": "sha256:0bbdaf56459aaef3c35d7b1bf3ad20be6260f047df6dd1c5eb60ac1797150944"
|
||||
},
|
||||
{
|
||||
"item_id": "fresh-preflight-validation-json",
|
||||
"label": "fresh-preflight-validation.json",
|
||||
"hash": "sha256:aa1d494e42491f0619f731a836c597df9178409887d734c166a8df81f8807a27"
|
||||
}
|
||||
],
|
||||
"highlights": [
|
||||
{
|
||||
"id": "native-custody-rollout-and-known-medium",
|
||||
"item_id": "decision-packet-md",
|
||||
"note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof.",
|
||||
"required_ack": true,
|
||||
"severity": "warning",
|
||||
"locator": {
|
||||
"kind": "section",
|
||||
"heading": "Requested decision"
|
||||
}
|
||||
}
|
||||
],
|
||||
"sealed": false,
|
||||
"approval_id": null,
|
||||
"approval_binding_digest": null
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# Protected native backup/restore and image-only release protocol
|
||||
|
||||
Prepared protocol for `INFD-WP-0009-T04/purpose-overlay-v1`. No actual native backup, data export, restore, workload change or approval is recorded here. Candidate registry image identity remains a prerequisite; only after actual artifact proof may the founder approve one exact conditional protocol/rollout packet. The config-only7db8485 approval is outside this scope.
|
||||
|
||||
## Preconditions and protected custody
|
||||
|
||||
Freeze exact candidate and prior7f5c6cb image digests, source/installed policy hashes, current manually managed Argo Application/revision, runtime ConfigMap6c221878d051, Deployment UID/template/spec, schema5, policy package pins, database path `/data/private/review.sqlite`, PVC binding, replicas1/Recreate and stable keys for intended verification. Confirm no concurrent writer or custody change. Use fixed metadata; never fetch Secret objects or token values. A changed image/config/schema/owner invalidates the packet. Fresh resources/headroom and exact source/native server-dry-run/diff remain required.
|
||||
|
||||
Backups are private evidence containing real decision records, not logs or packet attachments. Allocate a unique backup directory under existing protected PVC custody, owned10001, mode0700, snapshot file0600, no symlink/hardlink/reused output path. An off-cluster copy belongs only in the already established ignored `.private-backups/<unique-trial-directory>` custody with0700/0600 permissions; no Git, StateHub, public object store or terminal-content dump. Record only schema, integrity pass/fail, bounded table/state counts and protected receipt identifier; retain byte digests in protected custody if needed for internal copy identity. No credential, record payload or token fingerprint enters public evidence.
|
||||
|
||||
## Approved online compatibility drill
|
||||
|
||||
Within the explicit founder-approved action, run the existing base image's `informed-decision-admin backup --db /data/private/review.sqlite --output <new-private-snapshot>` in the actual serving workload. This uses SQLite's backup API for a transactionally consistent snapshot; copying a live main database while ignoring WAL is prohibited. Suppress raw failures/output and retain only sanitized status. Observe schema/integrity and count-only metadata from the resulting snapshot, not record content.
|
||||
|
||||
Transfer that consistent snapshot only into protected off-cluster custody through the existing authorized operator lane. The copy is real production data even in build mode. Verify private permissions, unique identity and protected internal digest agreement. Do not export mounted workload credentials or directory trees; copy only the exact snapshot.
|
||||
|
||||
Create a separate private disposable restore volume/directory; retain the original snapshot unchanged. Run the exact published candidate with network disabled, no production ConfigMap/token mounts, read-only image and only that isolated volume writable. Override the service entrypoint with the owner's count-only administrative inspection/integrity check; do not start HTTP listeners, audit delivery, requester exchanges or approval operations. The current candidate changes policy.py only and retains the schema/store module bytes; still prove schema5, SQLite integrity and exact bounded counts before/after opening the restored copy. Refuse any migration/downgrade, lost/changed counts, unexpected write class or unknown outcome. Keep pending/uncertain submission and outbox states; never replay, discard or mark them delivered to green the drill. Cleanup only the disposable copy/volume after verified receipt; retain the original protected backup for the approved recovery interval.
|
||||
|
||||
This step is actual native-data compatibility evidence once performed. Its previous synthetic fixture checks remain mechanism evidence and cannot be renamed native success. A failed drill stops rollout and remains a failed/unverified outcome in the same trial.
|
||||
|
||||
## Fresh cutover snapshot and single-writer rollout
|
||||
|
||||
After successful actual-data compatibility checks, create another unique SQLite-consistent online snapshot immediately before the image cutover, retaining its point-in-time schema/integrity/count receipt. This is an online transactional snapshot, not a claim that dispatchers or human writes were quiesced. Every later committed record remains in the live database; same-schema rollback retains that database and never restores the earlier snapshot over it. The narrow image-only update does not need dispatcher/configuration/PVC/temporary-pod changes or a schema cutover. If fresh verification shows a migration or any data-restoration requirement, stop and refine the proposal rather than applying this protocol.
|
||||
|
||||
The existing Recreate rollout drains/stops the single old writer before starting the new image on the same PVC; the inherited single-writer lock independently refuses concurrent serving processes. Do not add an admin pod, scale-to-zero, dispatcher stop, network-policy rewrite or snapshot overwrite as an improvised image-only step. The existing owner admin backup operation runs inside the admitted serving workload, and its separate protected restore drill runs off-cluster with network disabled and no workload credentials. Those exact custody operations must be enumerated in the founder packet alongside the one Deployment image change.
|
||||
|
||||
Once backup/compatibility/preflight gates pass, manually pin the existing Argo Application to the exact reviewed source revision and sync only Deployment/informed-decision with prune false, keeping the current immutable runtime ConfigMap and all other resources. The source patch changes only the image in admission/rendered Deployment; no Secret, PVC, policy, database or dispatcher change is included unless separately enumerated in the final proposal. Observe five-minute readiness and exact image/config/schema/pins. Verify native lifecycle binding using stable keys and an isolated installed-client probe based on a real provider response contaminated with advisory purpose; prove refusal before any write. Do not contaminate the live PDP, create human approvals, read credentials through CLI, or replay unknown external outcomes for testing.
|
||||
|
||||
## Same-schema rollback and evidence retention
|
||||
|
||||
On startup/readiness/binding/refusal failure, retain current database, cutover backup and every post-cutover evidence/uncertain outcome. Restore only the prior7f5c6cb image through the same manual Argo owner path, retaining schema5 and current DB/configuration; never restore an old snapshot over current live evidence just to roll the image back. Verify old image/Ready1, same schema/counts and prior behavior, and reconcile any external effects using existing lifecycle/audit ownership. The narrow overlay's identical store/schema/dependency bytes permit this image-only rollback; it is not permission for a schema downgrade or data loss.
|
||||
|
||||
Record original/approved/executed source and image revisions, backup/drill/cutover/rollout timestamps, exact disposition and sanitized outcomes in the existing supervised trial receipt. EUR0 incremental infrastructure estimate uses existing service/storage/operator lane; protected temporary copy/storage consumption and15–30minute recovery time remain operational costs. No EUR incident-loss cap or autonomy grant is inferred. TaskT04 cannot close until actual published image, approved native compatibility and release plus post-release refusal/binding evidence all exist.
|
||||
|
||||
## Exact release case identifiers
|
||||
|
||||
Proposal `INFD-WP-0009-T04/purpose-overlay-v1`, trial `infd-purpose-20261011-r1`.
|
||||
Protected native parent `/data/private/purpose-overlay-r1` must be unique/non-symlink, owned10001 and0700. The drill snapshot is `drill.sqlite`, the refreshed pre-cutover snapshot `cutover.sqlite`, each new0600 file; refuse any existing output. Off-cluster custody is the existing ignored Custodian `.private-backups/20261011-infd-purpose-r1` parent0700, files0600; no snapshot is an evidence attachment. Check owner UID, no symlinks, ignored status and free capacity for both native snapshots plus independently protected copies before making any snapshot.
|
||||
|
||||
The disposable offline restore volume is `infd-purpose-r1-restore-20261011`; refuse an existing volume, copy only the selected frozen snapshot, and run exact published candidate763c with networknone/read-only image,128MiB/core1 and no runtime config/token mounts. SQLite `PRAGMA integrity_check` must return `ok`, `PRAGMA user_version`/Store inspection must agree with actual schema5 semantics, and installed admin count-only inspection must match the frozen snapshot. Validate the actual schema representation rather than assume PRAGMA user_version is the schema authority. No synthetic restoration is reported as native restoration. Native original/off-cluster copies remain retained; only the disposable restore copy/volume may be removed under the exact approved cleanup scope.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"all_checks_pass": false,
|
||||
"transport_exit": 1,
|
||||
"stderr_sha256": "d9ea0351e38468c65d13bd68ece0c8e27acb654380ffee23111f76655edf8c49"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"all_checks_pass": false,
|
||||
"metadata_diff": {
|
||||
"category": "annotations",
|
||||
"changed_keys": [
|
||||
"argocd.argoproj.io/tracking-id"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"captured_at": "2026-10-11T01:25:38.793555+00:00",
|
||||
"native_workload_changed": false,
|
||||
"native_backup_restore_executed": false,
|
||||
"argo": {
|
||||
"uid": "499868f2-eabc-4df4-ae31-b89ce58d750d",
|
||||
"repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git",
|
||||
"targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf",
|
||||
"path": "deploy/lifecycle",
|
||||
"destination": {
|
||||
"namespace": "informed-decision",
|
||||
"server": "https://kubernetes.default.svc"
|
||||
},
|
||||
"automated": false,
|
||||
"sync": {
|
||||
"comparedTo": {
|
||||
"destination": {
|
||||
"namespace": "informed-decision",
|
||||
"server": "https://kubernetes.default.svc"
|
||||
},
|
||||
"source": {
|
||||
"path": "deploy/lifecycle",
|
||||
"repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git",
|
||||
"targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf"
|
||||
}
|
||||
},
|
||||
"revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf",
|
||||
"status": "OutOfSync"
|
||||
},
|
||||
"health": {
|
||||
"lastTransitionTime": "2026-10-10T23:14:52Z",
|
||||
"status": "Healthy"
|
||||
}
|
||||
},
|
||||
"live_ready_replicas": 1,
|
||||
"admitted_uid": "a588e10a-90d2-4883-975e-6dd8b8feca92",
|
||||
"server_dry_run_passed": true,
|
||||
"admitted_spec_exactly_live_plus_image": true,
|
||||
"client_diff_exit": 1,
|
||||
"client_diff_sha256": "a4bc024a8cec658f835285ed51964e2e084edbaf103d45a48b89c0950bcd3e7d",
|
||||
"node_allocated_resources": "(Total limits may be over 100 percent, i.e., overcommitted.)\n Resource Requests Limits\n -------- -------- ------\n cpu 3460m (86%) 36200m (905%)\n memory 9472Mi (59%) 32898Mi (205%)\n ephemeral-storage 0 (0%) 0 (0%)\n hugepages-1Gi 0 (0%) 0 (0%)\n hugepages-2Mi 0 (0%) 0 (0%)",
|
||||
"all_checks_pass": true
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"packet_files": {
|
||||
"change_guard.py": "830f7771b5c7d0a2851973aa65a01c6ab40b86570f0933d8aebb89f9665ca7e1",
|
||||
"preflight.py": "c206a1a9b9d232c656c6d57fb9247549eefa13b275a5da4d39b45a6c9902c834",
|
||||
"candidate-deployment.json": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e",
|
||||
"rollback-deployment.json": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121",
|
||||
"sealed-live-deployment.json": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362",
|
||||
"native-preflight.json": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262"
|
||||
},
|
||||
"owner_source_files": {
|
||||
"deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55",
|
||||
"deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
"""Read-only refresh; exact original capture remains immutable; never execute cutover."""
|
||||
import argparse,hashlib,json,subprocess,sys
|
||||
from pathlib import Path
|
||||
from change_guard import transport_result
|
||||
ROOT=Path(__file__).resolve().parent
|
||||
p=argparse.ArgumentParser();p.add_argument('--receipt-output',type=Path,required=True);p.add_argument('--source-root',type=Path,default=Path('/home/worsch/informed-decision'));a=p.parse_args()
|
||||
out=a.receipt_output.resolve()
|
||||
if not a.receipt_output.is_absolute() or out==ROOT or ROOT in out.parents or out==a.source_root.resolve() or a.source_root.resolve() in out.parents or out.exists():
|
||||
raise SystemExit('unique execution receipt must be outside the sealed packet')
|
||||
inputs=json.loads((ROOT/'preflight-inputs.json').read_text())
|
||||
for relative,digest in inputs['packet_files'].items():
|
||||
path=ROOT/relative
|
||||
if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('sealed helper/input bytes changed')
|
||||
for relative,digest in inputs['owner_source_files'].items():
|
||||
path=a.source_root/relative
|
||||
if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('owner source bytes changed')
|
||||
program="import subprocess,json,hashlib,datetime,sys,copy,re\ncandidate=json.loads(CANDIDATE_LITERAL)\nsealed_baseline=json.loads(SEALED_LITERAL)\nexec(GUARD_LITERAL)\ndef run(args,data=None):\n p=subprocess.run(args,input=data,text=True,capture_output=True)\n if p.returncode: raise ValueError('read-only command failed: '+args[1]+' '+args[2])\n return p.stdout\nlive=json.loads(run(['kubectl','get','deployment','informed-decision','-n','informed-decision','-o','json']))\ncheck_current(live,sealed_baseline)\nspec=live['spec']; cs=spec['template']['spec']['containers'];assert len(cs)==1 and cs[0]['name']=='informed-decision'\nexpected_env={'INFD_KEYCAPE_ISSUER':'https://kc.coulomb.social','INFD_CONTAINER_CONFIG':'/configuration/runtime.json'}\nassert cs[0].get('env')==[{'name':'INFD_KEYCAPE_ISSUER','value':expected_env['INFD_KEYCAPE_ISSUER']},{'name':'INFD_CONTAINER_CONFIG','value':expected_env['INFD_CONTAINER_CONFIG']}]\nassert cs[0]['image']=='forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173'\nassert spec['replicas']==1 and spec['strategy']=={'type':'Recreate'}\nassert next(v for v in spec['template']['spec']['volumes'] if v['name']=='configuration')['configMap']['name']=='informed-decision-runtime-6c221878d051'\nassert live['status'].get('readyReplicas')==1 and live['status'].get('updatedReplicas')==1\nsealed={'apiVersion':live['apiVersion'],'kind':live['kind'],'metadata':{k:copy.deepcopy(v) for k,v in live['metadata'].items() if k not in ('resourceVersion','generation','creationTimestamp','managedFields')},'spec':copy.deepcopy(spec)}\nfor key in ('kubectl.kubernetes.io/last-applied-configuration','deployment.kubernetes.io/revision'):sealed['metadata'].get('annotations',{}).pop(key,None)\nadmitted=json.loads(run(['kubectl','apply','--dry-run=server','-f','-','-o','json'],json.dumps(candidate)))\ncheck_admitted(admitted,sealed_baseline)\napp=json.loads(run(['kubectl','get','application','informed-decision','-n','argocd','-o','json']))\nassert app['spec']['source']['path']=='deploy/lifecycle' and not app['spec'].get('syncPolicy',{}).get('automated')\nargo={'uid':app['metadata']['uid'],'repoURL':app['spec']['source']['repoURL'],'targetRevision':app['spec']['source']['targetRevision'],'path':app['spec']['source']['path'],'destination':app['spec']['destination'],'automated':False,'sync':app.get('status',{}).get('sync'),'health':app.get('status',{}).get('health')}\nexpected_argo=json.loads(ARGO_LITERAL)\nfor key in ('uid','repoURL','targetRevision','path','destination','automated'):\n assert argo[key]==expected_argo[key]\nassert argo['health']['status']=='Healthy'\ndiff=subprocess.run(['kubectl','diff','-f','-'],input=json.dumps(candidate),text=True,capture_output=True);assert diff.returncode in (0,1)\n# Diff can contain only nonsecret Deployment references; preserve digest rather than raw stdout.\nnode=run(['kubectl','describe','node']);allocated=re.search(r'Allocated resources:.*?CPU Requests|Allocated resources:',node,re.S)\nsection=node.split('Allocated resources:')[1].split('Events:')[0] if 'Allocated resources:' in node else ''\nnodes=json.loads(run(['kubectl','get','nodes','-o','json']))['items'];assert len(nodes)==1\nalloc=nodes[0]['status']['allocatable'];cpu=alloc['cpu'];cpu_m=int(cpu[:-1]) if cpu.endswith('m') else int(cpu)*1000\nrequested=int(re.search(r'cpu\\s+(\\d+)m',section).group(1));assert requested<=cpu_m\nreceipt={'node_allocatable_cpu_m':cpu_m,'node_requested_cpu_m':requested,'captured_at':datetime.datetime.now(datetime.timezone.utc).isoformat(),'native_workload_changed':False,'native_backup_restore_executed':False,'argo':argo,'live_ready_replicas':1,'admitted_uid':admitted['metadata']['uid'],'server_dry_run_passed':True,'admitted_spec_exactly_live_plus_image':True,'client_diff_exit':diff.returncode,'client_diff_sha256':hashlib.sha256(diff.stdout.encode()).hexdigest(),'node_allocated_resources':section.strip(),'all_checks_pass':True}\nprint(json.dumps(receipt))\n"
|
||||
for marker,value in [('CANDIDATE_LITERAL',(ROOT/'candidate-deployment.json').read_text()),('SEALED_LITERAL',(ROOT/'sealed-live-deployment.json').read_text()),('GUARD_LITERAL',(ROOT/'change_guard.py').read_text()),('ARGO_LITERAL',json.dumps(json.loads((ROOT/'native-preflight.json').read_text())['argo']))]:
|
||||
program=program.replace(marker,repr(value))
|
||||
program='import traceback,json\ntry:\n'+''.join(' '+line+'\n' for line in program.splitlines())+"except Exception as error:\n print(json.dumps({'all_checks_pass':False,'exception_type':type(error).__name__,'exception_line':traceback.extract_tb(error.__traceback__)[-1].lineno}))\n"
|
||||
r=subprocess.run(['ssh','railiance01','python3 -'],input=program,text=True,capture_output=True)
|
||||
result=transport_result(r.returncode,r.stdout);result['sealed_preflight_inputs_sha256']=hashlib.sha256((ROOT/'preflight-inputs.json').read_bytes()).hexdigest();result['fresh_execution_receipt']=True
|
||||
out.write_text(json.dumps(result,indent=2)+'\n');print(json.dumps(result,indent=2));sys.exit(0 if result.get('all_checks_pass') is True else 1)
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"trial_id": "infd-purpose-20261011-r1",
|
||||
"state": "prepared-unapproved",
|
||||
"target": "realm:kubernetes/railiance01/informed-decision",
|
||||
"authority": "ADMINISTER; activation APPROVED only upon exact founder disposition",
|
||||
"candidate_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"published_source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"prior_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"prior_argo_revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf",
|
||||
"native_object": {
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"namespace": "informed-decision",
|
||||
"name": "informed-decision",
|
||||
"uid": "a588e10a-90d2-4883-975e-6dd8b8feca92"
|
||||
},
|
||||
"argo_application_uid": "499868f2-eabc-4df4-ae31-b89ce58d750d",
|
||||
"source_gate": "Exact committed owner source must contain the two approved candidate file hashes in preflight-inputs.json; source preparation is not native approval",
|
||||
"sync_scope": [
|
||||
"apps:Deployment:informed-decision"
|
||||
],
|
||||
"prune": false,
|
||||
"automated_sync": false,
|
||||
"runtime_configmap": "informed-decision-runtime-6c221878d051",
|
||||
"schema": 5,
|
||||
"requested_operations": [
|
||||
"Protected SQLite-consistent native backup and independently protected off-cluster custody",
|
||||
"Offline restore/integrity/count comparison on a private disposable volume with exact candidate, no runtime tokens/config/network",
|
||||
"Refresh a consistent pre-cutover snapshot, retain private copies and count-only/hash receipts",
|
||||
"Pin existing manual Argo Application to exact approved owner source and manually sync only existing Deployment image",
|
||||
"Verify health/readiness/image/module/installed fail-closed purpose checks and retained schema/count evidence; recover to prior same-schema image if needed"
|
||||
],
|
||||
"execute_by": "2026-10-12T23:59:59Z",
|
||||
"temporary_vulnerability_review_due": "2026-10-18",
|
||||
"known_scan_findings": "0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib, actual currentbase+candidate findings identical",
|
||||
"vulnerability_record": "INFD-RISK-20261011-ZLIB-85091 / INFD-WP-0009-T05",
|
||||
"cost_estimate_EUR": 0,
|
||||
"cost_limits": "No new recurring infrastructure; private backup storage and attended engineering/recovery time unpriced, not an autopilot cost grant",
|
||||
"risk_estimates": [
|
||||
"Brief Recreate service interruption; no concurrent new writer/surge",
|
||||
"Private evidence snapshot custody and disposal errors; no snapshots/tokens in public evidence",
|
||||
"Candidate purpose refusal may expose callers relying on advisory results as binding",
|
||||
"Inherited known fixable MEDIUM remains until separately approved owner remediation",
|
||||
"Existing Argo OutOfSync baseline is retained; no whole-app sync or unrelated repairs permitted"
|
||||
],
|
||||
"rollback": "Manual Argo source pin back to7db8485 and scoped Deployment-only sync to7f5c image; retain current schema5 database and all post-cutover evidence, never restore older snapshot over live writes",
|
||||
"native_executed": false,
|
||||
"human_approval": false
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"proposal": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"observed_at": "2026-10-11T01:24:01.985128+00:00",
|
||||
"native_owner_publication_job": {
|
||||
"id": 11484,
|
||||
"name": "publish-candidate",
|
||||
"head_branch": "main",
|
||||
"head_sha": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"run_number": 3,
|
||||
"event": "push",
|
||||
"display_title": "Prepare readable overlay context with the admitted legacy builder",
|
||||
"status": "success",
|
||||
"workflow_id": "purpose-overlay-image.yaml",
|
||||
"url": "https://forgejo.coulomb.social/coulomb/informed-decision/actions/runs/3",
|
||||
"created_at": "2026-10-11T01:20:59Z",
|
||||
"updated_at": "2026-10-11T01:21:08Z",
|
||||
"run_started_at": "2026-10-11T01:20:59Z"
|
||||
},
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"policy_sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62",
|
||||
"registry_proof_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213",
|
||||
"source_render_change_only": "Deployment/informed-decision spec.template.spec.containers[0].image",
|
||||
"runtime_configmap_unchanged": "informed-decision-runtime-6c221878d051",
|
||||
"installed_image_execution": {
|
||||
"immutable_registry_artifact_pulled_anonymously": true,
|
||||
"UID": 10001,
|
||||
"GID": 10001,
|
||||
"policy_file_UID": 0,
|
||||
"policy_file_mode": "0644",
|
||||
"purpose_variants": 10,
|
||||
"binding_forms_allowed": 2,
|
||||
"advisory_or_malformed_refused": 8,
|
||||
"network": "none",
|
||||
"read_only": true,
|
||||
"synthetic_transport": true,
|
||||
"native_PDP_test": false
|
||||
},
|
||||
"scan_summary_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44",
|
||||
"historical_failed_runs_retained": [
|
||||
"f66de505/task11482/run1",
|
||||
"acecad887/task11483/run2"
|
||||
],
|
||||
"native_hosting_changed": false,
|
||||
"native_backup_restore_executed": false,
|
||||
"human_approval": false,
|
||||
"evidence_file_sha256": {
|
||||
"image-manifest.json": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb",
|
||||
"image-config.json": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10",
|
||||
"base-image-config.json": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00",
|
||||
"registry-proof.json": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213",
|
||||
"trivy-full.json": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e",
|
||||
"sbom.cdx.json": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d",
|
||||
"base-trivy-full.json": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80",
|
||||
"check_installed.py": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad",
|
||||
"verify_registry.py": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"image_digest": "sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"base_image_digest": "sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"base_layer_bytes_identical": true,
|
||||
"layer_media_type_conversion": "OCI gzip to Docker gzip, same digest and size",
|
||||
"base_runtime_config_semantics_identical": true,
|
||||
"legacy_builder_config_additions": {
|
||||
"Hostname": "",
|
||||
"Domainname": "",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": false,
|
||||
"AttachStderr": false,
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Cmd": null,
|
||||
"Volumes": null,
|
||||
"OnBuild": null,
|
||||
"Image": "sha256:90f1574f9eda35fa6cb972961beb27a7cb904c36560e381930b0e14065c23883"
|
||||
},
|
||||
"base_rootfs_prefix_identical": true,
|
||||
"overlay_regular_files": [
|
||||
"opt/venv/lib/python3.12/site-packages/informed_decision/policy.py"
|
||||
],
|
||||
"overlay_directories": [
|
||||
"opt",
|
||||
"opt/venv",
|
||||
"opt/venv/lib",
|
||||
"opt/venv/lib/python3.12",
|
||||
"opt/venv/lib/python3.12/site-packages",
|
||||
"opt/venv/lib/python3.12/site-packages/informed_decision"
|
||||
],
|
||||
"policy_sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62",
|
||||
"policy_mode": "0644",
|
||||
"base_user": "10001:10001",
|
||||
"source_scope_labels": {
|
||||
"org.opencontainers.image.revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"org.opencontainers.image.base.digest": "sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"social.coulomb.source.policy.sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62",
|
||||
"social.coulomb.release.scope": "INFD-WP-0009-T04/purpose-overlay-v1"
|
||||
},
|
||||
"registry_read_route": "anonymous public scoped bearer challenge, no token retention",
|
||||
"image_executed": false,
|
||||
"native_workload_changed": false,
|
||||
"native_backup_restore_executed": false
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"policy": {
|
||||
"origin": "http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080",
|
||||
"package": "informed-decision.compact-sitting",
|
||||
"version": "v13",
|
||||
"package_digest": "sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873",
|
||||
"pod_name": "flex-auth-informed-decision-sitting"
|
||||
},
|
||||
"keycape_egress_ips": [
|
||||
"92.205.62.239"
|
||||
],
|
||||
"storage_class": "local-path",
|
||||
"ordinary_approval_ids": [
|
||||
"2ce76d7f-01c3-4b63-8476-8d1230679769",
|
||||
"c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
|
||||
"dc22666a-d5d7-46bc-9490-ebe9fe09dc38"
|
||||
],
|
||||
"lifecycle_policy": {
|
||||
"package": "informed-decision.lifecycle",
|
||||
"version": "v2",
|
||||
"package_digest": "sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c",
|
||||
"origin": "http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080",
|
||||
"pod_name": "flex-auth-informed-decision-lifecycle"
|
||||
},
|
||||
"lifecycle_delivery": true,
|
||||
"intake_attributes": true,
|
||||
"intake_delivery": {
|
||||
"hub_origin": "http://state-hub.state-hub.svc.cluster.local:8000"
|
||||
},
|
||||
"workload_api": {
|
||||
"registries_configmap": "informed-decision-workload-registry",
|
||||
"peers": [
|
||||
{
|
||||
"namespace": "state-hub",
|
||||
"app": "state-hub"
|
||||
}
|
||||
],
|
||||
"api_egress": [
|
||||
{
|
||||
"ip": "10.43.0.1",
|
||||
"port": 443
|
||||
},
|
||||
{
|
||||
"ip": "92.205.62.239",
|
||||
"port": 6443
|
||||
}
|
||||
],
|
||||
"intake": true,
|
||||
"lifecycle": true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover",
|
||||
"argocd.argoproj.io/tracking-id": "informed-decision:apps/Deployment:informed-decision/informed-decision"
|
||||
},
|
||||
"name": "informed-decision",
|
||||
"namespace": "informed-decision"
|
||||
},
|
||||
"spec": {
|
||||
"progressDeadlineSeconds": 600,
|
||||
"replicas": 1,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"strategy": {
|
||||
"type": "Recreate"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover"
|
||||
},
|
||||
"labels": {
|
||||
"app.kubernetes.io/component": "review",
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"automountServiceAccountToken": false,
|
||||
"containers": [
|
||||
{
|
||||
"env": [
|
||||
{
|
||||
"name": "INFD_KEYCAPE_ISSUER",
|
||||
"value": "https://kc.coulomb.social"
|
||||
},
|
||||
{
|
||||
"name": "INFD_CONTAINER_CONFIG",
|
||||
"value": "/configuration/runtime.json"
|
||||
}
|
||||
],
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"livenessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"name": "informed-decision",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 8080,
|
||||
"name": "http"
|
||||
},
|
||||
{
|
||||
"containerPort": 8081,
|
||||
"name": "workload"
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"resources": {
|
||||
"limits": {
|
||||
"cpu": "500m",
|
||||
"memory": "256Mi"
|
||||
},
|
||||
"requests": {
|
||||
"cpu": "5m",
|
||||
"memory": "64Mi"
|
||||
}
|
||||
},
|
||||
"securityContext": {
|
||||
"allowPrivilegeEscalation": false,
|
||||
"capabilities": {
|
||||
"drop": [
|
||||
"ALL"
|
||||
]
|
||||
},
|
||||
"readOnlyRootFilesystem": true
|
||||
},
|
||||
"startupProbe": {
|
||||
"failureThreshold": 12,
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/data",
|
||||
"name": "data"
|
||||
},
|
||||
{
|
||||
"mountPath": "/run/informed-decision",
|
||||
"name": "runtime"
|
||||
},
|
||||
{
|
||||
"mountPath": "/tmp",
|
||||
"name": "tmp"
|
||||
},
|
||||
{
|
||||
"mountPath": "/configuration",
|
||||
"name": "configuration",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/policy",
|
||||
"name": "caller",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/audit",
|
||||
"name": "audit",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/kubernetes",
|
||||
"name": "kubernetes-api",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/workload-registry",
|
||||
"name": "workload-registry",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/requester",
|
||||
"name": "sitting-requester",
|
||||
"readOnly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"securityContext": {
|
||||
"fsGroup": 10001,
|
||||
"fsGroupChangePolicy": "OnRootMismatch",
|
||||
"runAsGroup": 10001,
|
||||
"runAsNonRoot": true,
|
||||
"runAsUser": 10001,
|
||||
"seccompProfile": {
|
||||
"type": "RuntimeDefault"
|
||||
}
|
||||
},
|
||||
"serviceAccountName": "review",
|
||||
"terminationGracePeriodSeconds": 45,
|
||||
"volumes": [
|
||||
{
|
||||
"name": "data",
|
||||
"persistentVolumeClaim": {
|
||||
"claimName": "informed-decision-data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
},
|
||||
"name": "runtime"
|
||||
},
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
},
|
||||
"name": "tmp"
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 292,
|
||||
"name": "informed-decision-runtime-6c221878d051"
|
||||
},
|
||||
"name": "configuration"
|
||||
},
|
||||
{
|
||||
"name": "caller",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"audience": "flex-auth",
|
||||
"expirationSeconds": 3600,
|
||||
"path": "token"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "audit",
|
||||
"secret": {
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "token",
|
||||
"path": "token"
|
||||
}
|
||||
],
|
||||
"secretName": "informed-decision-audit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "kubernetes-api",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"expirationSeconds": 600,
|
||||
"path": "token"
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"items": [
|
||||
{
|
||||
"key": "ca.crt",
|
||||
"path": "ca.crt"
|
||||
}
|
||||
],
|
||||
"name": "kube-root-ca.crt"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 292,
|
||||
"name": "informed-decision-workload-registry"
|
||||
},
|
||||
"name": "workload-registry"
|
||||
},
|
||||
{
|
||||
"name": "sitting-requester",
|
||||
"secret": {
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "client-secret",
|
||||
"path": "client-secret"
|
||||
}
|
||||
],
|
||||
"optional": false,
|
||||
"secretName": "informed-decision-sitting-requester"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,286 @@
|
|||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"argocd.argoproj.io/tracking-id": "informed-decision:apps/Deployment:informed-decision/informed-decision",
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover"
|
||||
},
|
||||
"name": "informed-decision",
|
||||
"namespace": "informed-decision",
|
||||
"uid": "a588e10a-90d2-4883-975e-6dd8b8feca92"
|
||||
},
|
||||
"spec": {
|
||||
"progressDeadlineSeconds": 600,
|
||||
"replicas": 1,
|
||||
"revisionHistoryLimit": 10,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"strategy": {
|
||||
"type": "Recreate"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover"
|
||||
},
|
||||
"labels": {
|
||||
"app.kubernetes.io/component": "review",
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"automountServiceAccountToken": false,
|
||||
"containers": [
|
||||
{
|
||||
"env": [
|
||||
{
|
||||
"name": "INFD_KEYCAPE_ISSUER",
|
||||
"value": "https://kc.coulomb.social"
|
||||
},
|
||||
{
|
||||
"name": "INFD_CONTAINER_CONFIG",
|
||||
"value": "/configuration/runtime.json"
|
||||
}
|
||||
],
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"livenessProbe": {
|
||||
"failureThreshold": 3,
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http",
|
||||
"scheme": "HTTP"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"successThreshold": 1,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"name": "informed-decision",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 8080,
|
||||
"name": "http",
|
||||
"protocol": "TCP"
|
||||
},
|
||||
{
|
||||
"containerPort": 8081,
|
||||
"name": "workload",
|
||||
"protocol": "TCP"
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"failureThreshold": 3,
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http",
|
||||
"scheme": "HTTP"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"successThreshold": 1,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"resources": {
|
||||
"limits": {
|
||||
"cpu": "500m",
|
||||
"memory": "256Mi"
|
||||
},
|
||||
"requests": {
|
||||
"cpu": "5m",
|
||||
"memory": "64Mi"
|
||||
}
|
||||
},
|
||||
"securityContext": {
|
||||
"allowPrivilegeEscalation": false,
|
||||
"capabilities": {
|
||||
"drop": [
|
||||
"ALL"
|
||||
]
|
||||
},
|
||||
"readOnlyRootFilesystem": true
|
||||
},
|
||||
"startupProbe": {
|
||||
"failureThreshold": 12,
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http",
|
||||
"scheme": "HTTP"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"successThreshold": 1,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"terminationMessagePolicy": "File",
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/data",
|
||||
"name": "data"
|
||||
},
|
||||
{
|
||||
"mountPath": "/run/informed-decision",
|
||||
"name": "runtime"
|
||||
},
|
||||
{
|
||||
"mountPath": "/tmp",
|
||||
"name": "tmp"
|
||||
},
|
||||
{
|
||||
"mountPath": "/configuration",
|
||||
"name": "configuration",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/policy",
|
||||
"name": "caller",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/audit",
|
||||
"name": "audit",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/kubernetes",
|
||||
"name": "kubernetes-api",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/workload-registry",
|
||||
"name": "workload-registry",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/requester",
|
||||
"name": "sitting-requester",
|
||||
"readOnly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"dnsPolicy": "ClusterFirst",
|
||||
"restartPolicy": "Always",
|
||||
"schedulerName": "default-scheduler",
|
||||
"securityContext": {
|
||||
"fsGroup": 10001,
|
||||
"fsGroupChangePolicy": "OnRootMismatch",
|
||||
"runAsGroup": 10001,
|
||||
"runAsNonRoot": true,
|
||||
"runAsUser": 10001,
|
||||
"seccompProfile": {
|
||||
"type": "RuntimeDefault"
|
||||
}
|
||||
},
|
||||
"serviceAccount": "review",
|
||||
"serviceAccountName": "review",
|
||||
"terminationGracePeriodSeconds": 45,
|
||||
"volumes": [
|
||||
{
|
||||
"name": "data",
|
||||
"persistentVolumeClaim": {
|
||||
"claimName": "informed-decision-data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
},
|
||||
"name": "runtime"
|
||||
},
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
},
|
||||
"name": "tmp"
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 292,
|
||||
"name": "informed-decision-runtime-6c221878d051"
|
||||
},
|
||||
"name": "configuration"
|
||||
},
|
||||
{
|
||||
"name": "caller",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"audience": "flex-auth",
|
||||
"expirationSeconds": 3600,
|
||||
"path": "token"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "audit",
|
||||
"secret": {
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "token",
|
||||
"path": "token"
|
||||
}
|
||||
],
|
||||
"secretName": "informed-decision-audit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "kubernetes-api",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"expirationSeconds": 600,
|
||||
"path": "token"
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"items": [
|
||||
{
|
||||
"key": "ca.crt",
|
||||
"path": "ca.crt"
|
||||
}
|
||||
],
|
||||
"name": "kube-root-ca.crt"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 292,
|
||||
"name": "informed-decision-workload-registry"
|
||||
},
|
||||
"name": "workload-registry"
|
||||
},
|
||||
{
|
||||
"name": "sitting-requester",
|
||||
"secret": {
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "client-secret",
|
||||
"path": "client-secret"
|
||||
}
|
||||
],
|
||||
"optional": false,
|
||||
"secretName": "informed-decision-sitting-requester"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"scanner": "aquasec/trivy@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969",
|
||||
"version": "0.74.0",
|
||||
"db_metadata": {
|
||||
"Version": 2,
|
||||
"NextUpdate": "2026-10-11T18:59:50.889010572Z",
|
||||
"UpdatedAt": "2026-10-10T18:59:50.889010923Z",
|
||||
"DownloadedAt": "2026-10-10T23:32:32.380033131Z"
|
||||
},
|
||||
"suppression": false,
|
||||
"ignore_unfixed": false,
|
||||
"severity_filter": null,
|
||||
"package_count": 44,
|
||||
"findings_by_severity": {
|
||||
"MEDIUM": 1
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"id": "CVE-2026-85091",
|
||||
"package": "zlib",
|
||||
"installed": "1.3.2-r0",
|
||||
"fixed": "1.3.2-r1",
|
||||
"severity": "MEDIUM"
|
||||
}
|
||||
],
|
||||
"coverage_limits": [
|
||||
"Alpine3.24 absent scanner EOL list; OS detector ran against Alpine3.24 repository on38OS packages",
|
||||
"Known findings asof pinnedDB, not claim absence of unknown vulnerabilities"
|
||||
],
|
||||
"high_critical": 0,
|
||||
"same_scanner_actual_base_scan_findings_identical": true,
|
||||
"base_scan_file": "base-trivy-full.json"
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import copy
|
||||
import json
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
from change_guard import CANDIDATE, check_current, check_admitted, transport_result
|
||||
|
||||
ROOT = Path(__file__).parent
|
||||
|
||||
|
||||
class ExactDeploymentBoundary(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.sealed = json.loads((ROOT / 'sealed-live-deployment.json').read_text())
|
||||
self.admitted = copy.deepcopy(self.sealed)
|
||||
self.admitted['spec']['template']['spec']['containers'][0]['image'] = CANDIDATE
|
||||
|
||||
def test_only_expected_image_is_accepted(self):
|
||||
check_current(self.sealed, self.sealed)
|
||||
check_admitted(self.admitted, self.sealed)
|
||||
|
||||
def test_bookkeeping_is_ignored(self):
|
||||
value = copy.deepcopy(self.admitted)
|
||||
value['status'] = {'readyReplicas': 0}
|
||||
value['metadata']['generation'] = 100
|
||||
value['metadata']['resourceVersion'] = 'changed'
|
||||
value['metadata']['annotations']['kubectl.kubernetes.io/last-applied-configuration'] = 'server bookkeeping'
|
||||
check_admitted(value, self.sealed)
|
||||
|
||||
def test_unrelated_drift_and_recreated_uid_are_refused(self):
|
||||
mutators = [
|
||||
lambda v: v['metadata'].update(uid='recreated'),
|
||||
lambda v: v['metadata'].update(finalizers=['new']),
|
||||
lambda v: v['metadata'].update(ownerReferences=[{'uid': 'new'}]),
|
||||
lambda v: v['spec']['template']['spec'].update(hostNetwork=True),
|
||||
lambda v: v['spec']['template']['spec'].update(serviceAccountName='other'),
|
||||
lambda v: v['spec']['template']['spec'].update(automountServiceAccountToken=True),
|
||||
lambda v: v['spec']['template']['spec']['containers'][0].update(env=[]),
|
||||
lambda v: v['spec']['template']['spec']['containers'][0]['securityContext'].update(privileged=True),
|
||||
lambda v: v['spec'].update(replicas=2),
|
||||
lambda v: v['spec'].update(strategy={'type': 'RollingUpdate'}),
|
||||
]
|
||||
for mutate in mutators:
|
||||
with self.subTest(mutate=mutate):
|
||||
current = copy.deepcopy(self.sealed)
|
||||
mutate(current)
|
||||
with self.assertRaises(ValueError):
|
||||
check_current(current, self.sealed)
|
||||
admitted = copy.deepcopy(self.admitted)
|
||||
mutate(admitted)
|
||||
with self.assertRaises(ValueError):
|
||||
check_admitted(admitted, self.sealed)
|
||||
|
||||
def test_unexpected_image_is_refused(self):
|
||||
value = copy.deepcopy(self.admitted)
|
||||
value['spec']['template']['spec']['containers'][0]['image'] = 'other'
|
||||
with self.assertRaises(ValueError):
|
||||
check_admitted(value, self.sealed)
|
||||
|
||||
def test_malformed_successful_transport_is_refused(self):
|
||||
for output in ('banner', '{}', '[]', '{"all_checks_pass": "true"}', '{"all_checks_pass": false}'):
|
||||
self.assertIs(transport_result(0, output)['all_checks_pass'], False)
|
||||
self.assertIs(transport_result(1, '{"all_checks_pass":true}')['all_checks_pass'], False)
|
||||
self.assertIs(transport_result(0, '{"all_checks_pass":true}')['all_checks_pass'], True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"intake_valid_offline": true,
|
||||
"typed_memo_valid": true,
|
||||
"lifecycle_documents_valid": 20,
|
||||
"packet_actual_file_bytes_verified": true,
|
||||
"submission_digest": "sha256:ac41c8aea7bb008e17f50dc0bab4aad584aef1e461222967ac98d74c7bd28af7",
|
||||
"offline_constructed_grant": "state-hub/decision-record/net-kingdom-admins",
|
||||
"deployed_submitter_admission_verified": false,
|
||||
"human_approval": false,
|
||||
"live_submitted": false,
|
||||
"native_backup_restore_executed": false,
|
||||
"native_workload_changed": false,
|
||||
"packet_bytes_total": 249719,
|
||||
"guard_tests": 5,
|
||||
"guard_drift_negative_assertions": 20,
|
||||
"transport_negative_cases": 6,
|
||||
"fresh_readonly_preflight_all_checks_pass": true,
|
||||
"fresh_readonly_capture": "2026-10-11T01:30:33Z",
|
||||
"original_capture_bytes_preserved": true
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
"""Read a public policy image without executing it or retaining registry tokens."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
from pathlib import Path, PurePosixPath
|
||||
import re
|
||||
import tarfile
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
ORIGIN = 'https://forgejo.coulomb.social'
|
||||
BASE = ORIGIN + '/v2/coulomb/informed-decision/'
|
||||
LIMIT = 300 * 1024 * 1024
|
||||
class NoRedirect(urllib.request.HTTPRedirectHandler):
|
||||
def redirect_request(self, request, response, code, message, headers, new_url):
|
||||
raise ValueError('registry redirects refused')
|
||||
OPENER = urllib.request.build_opener(NoRedirect())
|
||||
|
||||
|
||||
def fetch(url, accept=None):
|
||||
parsed_url = urllib.parse.urlparse(url)
|
||||
if parsed_url.scheme != 'https' or parsed_url.netloc != 'forgejo.coulomb.social':
|
||||
raise ValueError('unexpected registry origin')
|
||||
headers = {'Accept': accept} if accept else {}
|
||||
try:
|
||||
response = OPENER.open(urllib.request.Request(url, headers=headers), timeout=30)
|
||||
except urllib.error.HTTPError as error:
|
||||
if error.code != 401:
|
||||
raise
|
||||
fields = dict(re.findall(r'(\w+)="([^"]*)"', error.headers.get('WWW-Authenticate', '')))
|
||||
realm = fields['realm']
|
||||
parsed = urllib.parse.urlparse(realm)
|
||||
if parsed.scheme != 'https' or parsed.netloc != 'forgejo.coulomb.social':
|
||||
raise ValueError('unexpected registry challenge origin')
|
||||
query = urllib.parse.urlencode({k: fields[k] for k in ('service', 'scope') if k in fields})
|
||||
with OPENER.open(realm + '?' + query, timeout=30) as auth:
|
||||
token = json.load(auth)['token']
|
||||
headers['Authorization'] = 'Bearer ' + token
|
||||
response = OPENER.open(urllib.request.Request(url, headers=headers), timeout=60)
|
||||
with response:
|
||||
body = response.read(LIMIT + 1)
|
||||
if len(body) > LIMIT:
|
||||
raise ValueError('registry artifact exceeds local verification bound')
|
||||
return body
|
||||
|
||||
|
||||
def sha(data):
|
||||
return hashlib.sha256(data).hexdigest()
|
||||
|
||||
|
||||
def blob(descriptor):
|
||||
digest = descriptor['digest']
|
||||
if not re.fullmatch(r'sha256:[a-f0-9]{64}', digest):
|
||||
raise ValueError('unknown image digest')
|
||||
data = fetch(BASE + 'blobs/' + digest)
|
||||
if 'sha256:' + sha(data) != digest or len(data) != descriptor['size']:
|
||||
raise ValueError('image blob hash or size mismatch')
|
||||
return data
|
||||
|
||||
|
||||
def manifest(digest):
|
||||
raw = fetch(BASE + 'manifests/' + digest, 'application/vnd.oci.image.index.v1+json, application/vnd.docker.distribution.manifest.list.v2+json, application/vnd.oci.image.manifest.v1+json, application/vnd.docker.distribution.manifest.v2+json')
|
||||
if 'sha256:' + sha(raw) != digest:
|
||||
raise ValueError('manifest digest mismatch')
|
||||
value = json.loads(raw)
|
||||
if 'manifests' in value:
|
||||
selected = [d for d in value['manifests'] if d.get('platform',{}).get('os') == 'linux' and d.get('platform',{}).get('architecture') == 'amd64']
|
||||
if len(selected) != 1:
|
||||
raise ValueError('one linux/amd64 platform required')
|
||||
child, config, layerlist = manifest(selected[0]['digest'])
|
||||
return child, config, layerlist
|
||||
return value, json.loads(blob(value['config'])), value['layers']
|
||||
|
||||
def main():
|
||||
p = argparse.ArgumentParser(); p.add_argument('--digest',required=True);p.add_argument('--revision',required=True);p.add_argument('--output',type=Path,required=True);a=p.parse_args()
|
||||
if not re.fullmatch(r'sha256:[a-f0-9]{64}',a.digest) or not re.fullmatch(r'[a-f0-9]{40}',a.revision):
|
||||
raise ValueError('exact immutable revision and image required')
|
||||
base_digest='sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173'
|
||||
m,c,l=manifest(a.digest);bm,bc,bl=manifest(base_digest)
|
||||
allowed_media={'application/vnd.docker.image.rootfs.diff.tar.gzip','application/vnd.oci.image.layer.v1.tar+gzip'}
|
||||
if any(d['mediaType'] not in allowed_media for d in l+bl): raise ValueError('unsupported layer encoding')
|
||||
if [(d['digest'],d['size']) for d in l[:-1]] != [(d['digest'],d['size']) for d in bl] or len(l) != len(bl)+1:
|
||||
raise ValueError('candidate must retain all base descriptors plus exactly one layer')
|
||||
for key in ('architecture','os'):
|
||||
if c[key] != bc[key]: raise ValueError('platform changed')
|
||||
if c['rootfs']['diff_ids'][:-1] != bc['rootfs']['diff_ids'] or len(c['rootfs']['diff_ids']) != len(bc['rootfs']['diff_ids'])+1:
|
||||
raise ValueError('base rootfs changed')
|
||||
defaults={'Hostname':'','Domainname':'','AttachStdin':False,'AttachStdout':False,'AttachStderr':False,'Tty':False,'OpenStdin':False,'StdinOnce':False,'Cmd':None,'Volumes':None,'OnBuild':None}
|
||||
extra_defaults={}
|
||||
for key,value in defaults.items():
|
||||
if key not in bc['config'] and key in c['config']:
|
||||
if c['config'][key] != value: raise ValueError('legacy builder runtime default changed')
|
||||
extra_defaults[key]=value
|
||||
if 'Image' in c['config'] and 'Image' not in bc['config']:
|
||||
if not re.fullmatch(r'sha256:[a-f0-9]{64}',c['config']['Image']):raise ValueError('unexpected legacy builder parent-image metadata')
|
||||
extra_defaults['Image']=c['config']['Image']
|
||||
actual_config={k:v for k,v in c['config'].items() if k != 'Labels' and k not in extra_defaults}
|
||||
base_config={k:v for k,v in bc['config'].items() if k != 'Labels'}
|
||||
if actual_config != base_config: raise ValueError('runtime image config changed')
|
||||
labels=c['config']['Labels']; expected={'org.opencontainers.image.revision':a.revision,'org.opencontainers.image.base.digest':base_digest,'social.coulomb.source.policy.sha256':'9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62','social.coulomb.release.scope':'INFD-WP-0009-T04/purpose-overlay-v1'}
|
||||
for k,v in expected.items():
|
||||
if labels.get(k)!=v:raise ValueError('exact source/scope label mismatch')
|
||||
if {k:v for k,v in labels.items() if k not in expected} != {k:v for k,v in bc['config'].get('Labels',{}).items() if k not in expected}:
|
||||
raise ValueError('unrelated labels changed')
|
||||
files=[]; dirs=[];content=None
|
||||
with tarfile.open(fileobj=io.BytesIO(blob(l[-1])),mode='r:*') as archive:
|
||||
for item in archive:
|
||||
path=PurePosixPath(item.name.removeprefix('./'))
|
||||
if path.is_absolute() or '..' in path.parts or any(p.startswith('.wh.') for p in path.parts):raise ValueError('unsafe overlay entry')
|
||||
if item.isdir():
|
||||
allowed_dirs={'opt','opt/venv','opt/venv/lib','opt/venv/lib/python3.12','opt/venv/lib/python3.12/site-packages','opt/venv/lib/python3.12/site-packages/informed_decision'}
|
||||
if str(path) not in allowed_dirs: raise ValueError('unexpected overlay directory')
|
||||
dirs.append(str(path));continue
|
||||
if not item.isfile():raise ValueError('unexpected overlay link or device')
|
||||
files.append(str(path))
|
||||
if str(path)!='opt/venv/lib/python3.12/site-packages/informed_decision/policy.py' or item.mode!=0o644 or item.uid!=0 or item.gid!=0 or item.size>100000:raise ValueError('unexpected overlay file metadata')
|
||||
content=archive.extractfile(item).read()
|
||||
if len(files)!=1 or sha(content)!=expected['social.coulomb.source.policy.sha256']:raise ValueError('single installed source file not exact')
|
||||
a.output.mkdir(parents=True,exist_ok=True)
|
||||
(a.output/'image-manifest.json').write_text(json.dumps(m,indent=2)+'\n');(a.output/'image-config.json').write_text(json.dumps(c,indent=2)+'\n');(a.output/'base-image-config.json').write_text(json.dumps(bc,indent=2)+'\n')
|
||||
receipt={'image_digest':a.digest,'source_revision':a.revision,'base_image_digest':base_digest,'base_layer_bytes_identical':True,'layer_media_type_conversion':'OCI gzip to Docker gzip, same digest and size','base_runtime_config_semantics_identical':True,'legacy_builder_config_additions':extra_defaults,'base_rootfs_prefix_identical':True,'overlay_regular_files':files,'overlay_directories':dirs,'policy_sha256':sha(content),'policy_mode':'0644','base_user':bc['config'].get('User'),'source_scope_labels':expected,'registry_read_route':'anonymous public scoped bearer challenge, no token retention','image_executed':False,'native_workload_changed':False,'native_backup_restore_executed':False}
|
||||
(a.output/'registry-proof.json').write_text(json.dumps(receipt,indent=2)+'\n');print(json.dumps(receipt,sort_keys=True))
|
||||
if __name__=='__main__': main()
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
---
|
||||
id: INFD-WP-0009
|
||||
type: workplan
|
||||
title: "Repair lifecycle consumer pin after Access Engine v2 policy release"
|
||||
domain: infotech
|
||||
repo: informed-decision
|
||||
status: active
|
||||
owner: codex
|
||||
topic_slug: netkingdom
|
||||
created: "2026-10-10"
|
||||
updated: "2026-10-11"
|
||||
flavor: implementation
|
||||
depends_on: []
|
||||
related:
|
||||
- FLEX-WP-0035
|
||||
- INFD-WP-0007
|
||||
state_hub_workstream_id: "77eaeabf-0644-595f-b3d5-1168e6a294c4"
|
||||
---
|
||||
|
||||
## Diagnose and prepare exact config repair
|
||||
|
||||
```task
|
||||
id: INFD-WP-0009-T01
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "5c30c308-8fe2-5956-b0c1-66c80bcb07e9"
|
||||
```
|
||||
|
||||
Native State Hub lifecycle submission returns HTTP 503 `invalid_decision`.
|
||||
The service remains Ready but its configured lifecycle package is v1/cee6a79;
|
||||
Access Engine lifecycle provider now runs v2/da01e045 after FLEX-WP-0035.
|
||||
The envelope contract remains `flex-auth.decision-record.v1`; this is a policy
|
||||
pin mismatch, not an envelope compatibility migration. Keep exact package,
|
||||
version and digest enforcement. Source preparation and regression evidence are
|
||||
in `docs/evidence/2026-10-10-lifecycle-consumer-pin-repair.md`.
|
||||
|
||||
## Release and verify the config-only repair
|
||||
|
||||
```task
|
||||
id: INFD-WP-0009-T02
|
||||
status: done
|
||||
priority: high
|
||||
needs_human: false
|
||||
state_hub_task_id: "1e6684d7-7676-5c70-b701-9dad124b4f07"
|
||||
```
|
||||
|
||||
Apply only the reviewed immutable runtime ConfigMap and Deployment reference
|
||||
through the existing owner GitOps path after exact scoped supervisor approval.
|
||||
Image, schema, credentials, audience and review policy remain pinned. Retain
|
||||
server dry-run/diff, readiness and native State Hub register/publish receipts;
|
||||
retry with stable write keys, do not infer success from readiness. Root agent
|
||||
owns live evidence and approval recording. This is a repair of the shipped
|
||||
initial lifecycle, separate from INFD-WP-0008 expansion.
|
||||
|
||||
**Verified 2026-10-11:** founder approved exact config-only revision
|
||||
`7db8485ffecdebfabd77a9daec085553c74bf0bf`. Manual Argo Application operation
|
||||
synced only `informed-decision-runtime-6c221878d051` and Deployment, prune false.
|
||||
Application Succeeded/Healthy; generation24 observed24 Ready1; `/readyz`200;
|
||||
consumer v2/da01e045 and unchanged image7f5c6cb verified. Native lifecycle
|
||||
registration and publication succeeded (events28/29). A later review request
|
||||
rejected packet validation; this separate caller error does not undo verified
|
||||
authoring. Custodian evidence records original approval, execution and rollback:
|
||||
`docs/evidence/2026-10-10-security-consolidation/infd-pin-repair-preflight.json`.
|
||||
|
||||
## Explicitly reject advisory purpose at consumer boundary
|
||||
|
||||
```task
|
||||
id: INFD-WP-0009-T03
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "ee798d7d-5e60-5247-9c9b-285a7f65cf11"
|
||||
```
|
||||
|
||||
PolicyClient now validates binding purpose: absent or exact empty string only;
|
||||
readback and malformed purposes are refused. Nine purpose variants and a real
|
||||
provider response contamination test preserve the binding, pin, expiry and
|
||||
obligations gates. This task covers source implementation and regression tests.
|
||||
The current runtime image lacks this patch. Service build/native release belongs
|
||||
to T04, separate from the config-only T02 repair.
|
||||
|
||||
|
||||
## Release the advisory-purpose source correction
|
||||
|
||||
```task
|
||||
id: INFD-WP-0009-T04
|
||||
status: progress
|
||||
priority: medium
|
||||
state_hub_task_id: "0e1bb868-7bc2-5d4d-953c-e0edaf660ad0"
|
||||
```
|
||||
|
||||
Build and scan a new service image including T03, retain provenance and backup
|
||||
compatibility evidence, prepare a separate scoped image proposal, and verify
|
||||
native binding/refusal after the owner's approved release. Do not fold an image
|
||||
change into the config-only T02 proposal. Current runtime 7f5c6cb remains exact.
|
||||
|
||||
**Historical local preparation 2026-10-11:** narrow single-module image overlay on immutable running
|
||||
7f5c6cb; exact source policy SHA-256 9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62.
|
||||
Local image/index b8b58944786015a5375304241c149d1dab885eb539d6d8945f56b01a3c2bc821
|
||||
is built and retained, unpublished and undeployed. Base layer prefix and runtime
|
||||
configuration are preserved; installed-image 10 purpose variants pass; 13
|
||||
container checks include restart and synthetic consistent backup/restore. A
|
||||
fresh Trivy database scan has zero HIGH/CRITICAL findings, with its Alpine EOL
|
||||
warning retained. See `docs/evidence/2026-10-11-purpose-hardening/README.md`.
|
||||
Remaining gates: source-bound registry publication and exact digest verification,
|
||||
fresh native snapshot/restore compatibility, owner GitOps server dry-run/diff,
|
||||
separate scoped supervisor approval and native post-release binding/refusal.
|
||||
No release approval or actual production-data restore is inferred from fixtures.
|
||||
|
||||
**Publication and release preparation 2026-10-11:** actual owner CI
|
||||
task11484/run3 succeeds at source3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168,
|
||||
publishing immutable image763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a.
|
||||
The failed run1/f66 and run2/ace are retained as refinements in the same trial.
|
||||
Anonymous registry readback proves all8base compressed blobs/rootfs unchanged
|
||||
plus only policy.py; legacy media-type/default-config serialization differences
|
||||
are explicit. Pulled published artifact UID10001/GID10001, installed mode0644
|
||||
and exactpolicy hash, all10purpose forms pass. Full pinned scanner/DB covers
|
||||
44packages: 0HIGH/CRITICAL, 1fixableMEDIUM CVE-2026-85091 in zlib1.3.2-r0,
|
||||
identical actual current-base scan. This is not a zero-CVE release or estate
|
||||
risk grade. T05 and INFD-RISK-20261011-ZLIB-85091 are live owner follow-through.
|
||||
|
||||
The exact separate20document informed-decision packet is prepared and
|
||||
offline typed/intake validated, with no submission or founder disposition
|
||||
claimed. Source candidates differ solely in Deploymentimage and retain
|
||||
ConfigMap6c221878d051/schema5/PVC/identity/policy pins. Fresh read-only
|
||||
serverdryrun/clientdiff pass with sealedUID/fullconfiguration; existingmanual
|
||||
Argo remains Healthy/OutOfSync at7db8485, not whole-app reconciled.
|
||||
Remaining gates: independent owner review, actual founder native approval,
|
||||
fresh protected native consistent snapshot/off-cluster custody/offline restore,
|
||||
refresh preflight, exact owner-source pin/Deployment-only manual sync and
|
||||
verified native installed purpose/refusal/lifecycle behavior. Synthetic native
|
||||
placement checks are not new provider authorization evidence. Runtime remains7f5c.
|
||||
|
||||
Evidence: `docs/evidence/2026-10-11-purpose-image-release/`.
|
||||
|
||||
## Resolve inherited published-image zlib finding
|
||||
|
||||
```task
|
||||
id: INFD-WP-0009-T05
|
||||
status: todo
|
||||
priority: medium
|
||||
```
|
||||
|
||||
Owner follow-through `INFD-RISK-20261011-ZLIB-85091` tracks actual published
|
||||
base and purpose-overlay scan finding CVE-2026-85091: zlib 1.3.2-r0, fixed
|
||||
1.3.2-r1, scanner MEDIUM; this is not an estate risk grade. Prepare and verify a
|
||||
separate source-bound base/dependency refresh, then obtain distinct native
|
||||
release approval before changing the workload. Review due 2026-10-18; the date
|
||||
is a manual owner follow-up, with no automatic expiry/rollback controller.
|
||||
T04 cannot be treated as a zero-CVE release or silently include the base fix.
|
||||
Preserve the original detection, pending founder disposition and remediation
|
||||
evidence. Close only after actual installed-package proof and full rescan.
|
||||
|
||||
Evidence: `docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json`.
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,141 @@
|
|||
{
|
||||
"id": "infd-20261011-purpose-overlay-r1",
|
||||
"version": 1,
|
||||
"question": "Approve this exact Informed Decision purpose-only image release on railiance01, including protected native backup/restore gates and explicit temporary acceptance of the inherited fixable MEDIUM zlib finding with owner remediation follow-through?",
|
||||
"requested_act": "approve",
|
||||
"binding_level": "organizational",
|
||||
"brief": "Actual owner CI published763c from3e4bcb26; unchanged8base layers plus one policy.py, installedUID10001 and10purpose checks pass. Full44package scan0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib, identical actualbase scan. Only Deploymentimage changes; manualArgo prune=false, runtime6c/schema5/PVC/identity/policies unchanged. Before ANY admin/Store, readonly schema5/integrity/count gate; protected backup/restore, sealedDeployment+actualCM/PVC identities and unoptimizedpreflight required, not executed. Live owner riskrecord/T05 dueOct18; Recreate briefly interrupts service. No priorconfigapproval reused.",
|
||||
"binding": {
|
||||
"principal": {
|
||||
"id": "pending-human-session",
|
||||
"kind": "person",
|
||||
"display_name": "Founder review"
|
||||
},
|
||||
"target": {
|
||||
"kind": "environment",
|
||||
"id": "realm:kubernetes/railiance01/informed-decision",
|
||||
"label": "Informed Decision image-only purpose hardening on railiance01",
|
||||
"environment": "production"
|
||||
},
|
||||
"terms": "Only attached exact INFD-WP-0009-T04/purpose-overlay-v1 trialinfd-purpose-20261011-r1: protected consistent snapshots/off-cluster custody/offline restore plus exact owner-source pin/manual Deployment-only image release763c, prune=false. ADMINISTER activationAPPROVED only upon actualdisposition, execute by2026-10-12T23:59:59Z afterfresh sealedCM/PVC/Deploymentpreflight+pre-openreadonlyschema5+restoregates; rollbackprior7f5 retaining latestschema5DB. Explicit inheritedfixableMEDIUM permitted with INFD-WP-0009-T05 ownerreviewdue2026-10-18. No credential/policy/grant change, humanbinding, wholeAppsync or autonomygrant."
|
||||
},
|
||||
"step_kind": "approve",
|
||||
"packet": [
|
||||
{
|
||||
"item_id": "decision-packet-md",
|
||||
"label": "decision-packet.md",
|
||||
"hash": "sha256:23da78cf998a32af0481e68567db94bb40781cc18f147461f779d40ebd329fd1"
|
||||
},
|
||||
{
|
||||
"item_id": "proposal-json",
|
||||
"label": "proposal.json",
|
||||
"hash": "sha256:a59bcddc6c79e3ba8265a95b4b68facda2683abda8e47e5bb48ce402b9e1fa82"
|
||||
},
|
||||
{
|
||||
"item_id": "candidate-admission-json",
|
||||
"label": "candidate-admission.json",
|
||||
"hash": "sha256:92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
{
|
||||
"item_id": "rollback-admission-json",
|
||||
"label": "rollback-admission.json",
|
||||
"hash": "sha256:22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50"
|
||||
},
|
||||
{
|
||||
"item_id": "candidate-deployment-json",
|
||||
"label": "candidate-deployment.json",
|
||||
"hash": "sha256:722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e"
|
||||
},
|
||||
{
|
||||
"item_id": "rollback-deployment-json",
|
||||
"label": "rollback-deployment.json",
|
||||
"hash": "sha256:39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121"
|
||||
},
|
||||
{
|
||||
"item_id": "published-verification-json",
|
||||
"label": "published-verification.json",
|
||||
"hash": "sha256:8a676c38f89f9ca762b8ebe945b5acb90d47a4cb350692687abb985bbb2d8ae2"
|
||||
},
|
||||
{
|
||||
"item_id": "registry-proof-json",
|
||||
"label": "registry-proof.json",
|
||||
"hash": "sha256:5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213"
|
||||
},
|
||||
{
|
||||
"item_id": "security-summary-json",
|
||||
"label": "security-summary.json",
|
||||
"hash": "sha256:0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44"
|
||||
},
|
||||
{
|
||||
"item_id": "trivy-full-json",
|
||||
"label": "trivy-full.json",
|
||||
"hash": "sha256:f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e"
|
||||
},
|
||||
{
|
||||
"item_id": "sqlite-readonly-py",
|
||||
"label": "sqlite_readonly.py",
|
||||
"hash": "sha256:eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38"
|
||||
},
|
||||
{
|
||||
"item_id": "sealed-native-dependencies-json",
|
||||
"label": "sealed-native-dependencies.json",
|
||||
"hash": "sha256:042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369"
|
||||
},
|
||||
{
|
||||
"item_id": "native-backup-restore-protocol-md",
|
||||
"label": "native-backup-restore-protocol.md",
|
||||
"hash": "sha256:2f8d4894c2861b34977ec020593b7515a8ee35a43ce2e6aef2d96a6d34a94ddc"
|
||||
},
|
||||
{
|
||||
"item_id": "inherited-vulnerability-follow-through-json",
|
||||
"label": "inherited-vulnerability-follow-through.json",
|
||||
"hash": "sha256:e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101"
|
||||
},
|
||||
{
|
||||
"item_id": "native-preflight-json",
|
||||
"label": "native-preflight.json",
|
||||
"hash": "sha256:eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262"
|
||||
},
|
||||
{
|
||||
"item_id": "sealed-live-deployment-json",
|
||||
"label": "sealed-live-deployment.json",
|
||||
"hash": "sha256:d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362"
|
||||
},
|
||||
{
|
||||
"item_id": "change-guard-py",
|
||||
"label": "change_guard.py",
|
||||
"hash": "sha256:f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be"
|
||||
},
|
||||
{
|
||||
"item_id": "preflight-py",
|
||||
"label": "preflight.py",
|
||||
"hash": "sha256:6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd"
|
||||
},
|
||||
{
|
||||
"item_id": "preflight-inputs-json",
|
||||
"label": "preflight-inputs.json",
|
||||
"hash": "sha256:756e72da9ec36572242421bea8b6d2285394e334f991db5e90e9b409563b5f06"
|
||||
},
|
||||
{
|
||||
"item_id": "fresh-preflight-validation-json",
|
||||
"label": "fresh-preflight-validation.json",
|
||||
"hash": "sha256:2ec324aa8e3f97753b3ed87bca80820feb5e542dc0a4799aa848ec77ea92feb7"
|
||||
}
|
||||
],
|
||||
"highlights": [
|
||||
{
|
||||
"id": "native-custody-rollout-and-known-medium",
|
||||
"item_id": "decision-packet-md",
|
||||
"note": "Protected real-data snapshot/restore and a brief Recreate restart require this separate native approval. Actual scan has one fixable inherited MEDIUM, not zero CVEs; exact owner follow-through due2026-10-18 is manual, with no automatic controller. Rollback preserves latestschema5DB and allnew/uncertain evidence. Synthetic transport tests are not native PDP authority proof. Admin can migrate oldschemas: readonlyschema5/integrity/count check must precede every native/offline Store/admin open. ActualCM/PVC UID/custody drift and optimizedPython stop the operation.",
|
||||
"required_ack": true,
|
||||
"severity": "warning",
|
||||
"locator": {
|
||||
"kind": "section",
|
||||
"heading": "Requested decision"
|
||||
}
|
||||
}
|
||||
],
|
||||
"sealed": false,
|
||||
"approval_id": null,
|
||||
"approval_binding_digest": null
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
# Protected native backup/restore and image-only release protocol
|
||||
|
||||
Prepared protocol for `INFD-WP-0009-T04/purpose-overlay-v1`. No actual native backup, data export, restore, workload change or approval is recorded here. Candidate registry image identity remains a prerequisite; only after actual artifact proof may the founder approve one exact conditional protocol/rollout packet. The config-only7db8485 approval is outside this scope.
|
||||
|
||||
## Preconditions and protected custody
|
||||
|
||||
Freeze exact candidate and prior7f5c6cb image digests, source/installed policy hashes, current manually managed Argo Application/revision, runtime ConfigMap6c221878d051, Deployment UID/template/spec, schema5, policy package pins, database path `/data/private/review.sqlite`, PVC binding, replicas1/Recreate and stable keys for intended verification. Confirm no concurrent writer or custody change. Use fixed metadata; never fetch Secret objects or token values. A changed image/config/schema/owner invalidates the packet. Fresh resources/headroom and exact source/native server-dry-run/diff remain required.
|
||||
|
||||
Backups are private evidence containing real decision records, not logs or packet attachments. Allocate a unique backup directory under existing protected PVC custody, owned10001, mode0700, snapshot file0600, no symlink/hardlink/reused output path. An off-cluster copy belongs only in the already established ignored `.private-backups/<unique-trial-directory>` custody with0700/0600 permissions; no Git, StateHub, public object store or terminal-content dump. Record only schema, integrity pass/fail, bounded table/state counts and protected receipt identifier; retain byte digests in protected custody if needed for internal copy identity. No credential, record payload or token fingerprint enters public evidence.
|
||||
|
||||
## Approved online compatibility drill
|
||||
|
||||
Within the explicit founder-approved action, run the existing base image's `informed-decision-admin backup --db /data/private/review.sqlite --output <new-private-snapshot>` in the actual serving workload. This uses SQLite's backup API for a transactionally consistent snapshot; copying a live main database while ignoring WAL is prohibited. Suppress raw failures/output and retain only sanitized status. Observe schema/integrity and count-only metadata from the resulting snapshot, not record content.
|
||||
|
||||
Transfer that consistent snapshot only into protected off-cluster custody through the existing authorized operator lane. The copy is real production data even in build mode. Verify private permissions, unique identity and protected internal digest agreement. Do not export mounted workload credentials or directory trees; copy only the exact snapshot.
|
||||
|
||||
Create a separate private disposable restore volume/directory; retain the original snapshot unchanged. Run the exact published candidate with network disabled, no production ConfigMap/token mounts, read-only image and only that isolated volume writable. Override the service entrypoint with the owner's count-only administrative inspection/integrity check; do not start HTTP listeners, audit delivery, requester exchanges or approval operations. The current candidate changes policy.py only and retains the schema/store module bytes; still prove schema5, SQLite integrity and exact bounded counts before/after opening the restored copy. Refuse any migration/downgrade, lost/changed counts, unexpected write class or unknown outcome. Keep pending/uncertain submission and outbox states; never replay, discard or mark them delivered to green the drill. Cleanup only the disposable copy/volume after verified receipt; retain the original protected backup for the approved recovery interval.
|
||||
|
||||
This step is actual native-data compatibility evidence once performed. Its previous synthetic fixture checks remain mechanism evidence and cannot be renamed native success. A failed drill stops rollout and remains a failed/unverified outcome in the same trial.
|
||||
|
||||
## Fresh cutover snapshot and single-writer rollout
|
||||
|
||||
After successful actual-data compatibility checks, create another unique SQLite-consistent online snapshot immediately before the image cutover, retaining its point-in-time schema/integrity/count receipt. This is an online transactional snapshot, not a claim that dispatchers or human writes were quiesced. Every later committed record remains in the live database; same-schema rollback retains that database and never restores the earlier snapshot over it. The narrow image-only update does not need dispatcher/configuration/PVC/temporary-pod changes or a schema cutover. If fresh verification shows a migration or any data-restoration requirement, stop and refine the proposal rather than applying this protocol.
|
||||
|
||||
The existing Recreate rollout drains/stops the single old writer before starting the new image on the same PVC; the inherited single-writer lock independently refuses concurrent serving processes. Do not add an admin pod, scale-to-zero, dispatcher stop, network-policy rewrite or snapshot overwrite as an improvised image-only step. The existing owner admin backup operation runs inside the admitted serving workload, and its separate protected restore drill runs off-cluster with network disabled and no workload credentials. Those exact custody operations must be enumerated in the founder packet alongside the one Deployment image change.
|
||||
|
||||
Once backup/compatibility/preflight gates pass, manually pin the existing Argo Application to the exact reviewed source revision and sync only Deployment/informed-decision with prune false, keeping the current immutable runtime ConfigMap and all other resources. The source patch changes only the image in admission/rendered Deployment; no Secret, PVC, policy, database or dispatcher change is included unless separately enumerated in the final proposal. Observe five-minute readiness and exact image/config/schema/pins. Verify native lifecycle binding using stable keys and an isolated installed-client probe based on a real provider response contaminated with advisory purpose; prove refusal before any write. Do not contaminate the live PDP, create human approvals, read credentials through CLI, or replay unknown external outcomes for testing.
|
||||
|
||||
## Same-schema rollback and evidence retention
|
||||
|
||||
On startup/readiness/binding/refusal failure, retain current database, cutover backup and every post-cutover evidence/uncertain outcome. Restore only the prior7f5c6cb image through the same manual Argo owner path, retaining schema5 and current DB/configuration; never restore an old snapshot over current live evidence just to roll the image back. Verify old image/Ready1, same schema/counts and prior behavior, and reconcile any external effects using existing lifecycle/audit ownership. The narrow overlay's identical store/schema/dependency bytes permit this image-only rollback; it is not permission for a schema downgrade or data loss.
|
||||
|
||||
Record original/approved/executed source and image revisions, backup/drill/cutover/rollout timestamps, exact disposition and sanitized outcomes in the existing supervised trial receipt. EUR0 incremental infrastructure estimate uses existing service/storage/operator lane; protected temporary copy/storage consumption and15–30minute recovery time remain operational costs. No EUR incident-loss cap or autonomy grant is inferred. TaskT04 cannot close until actual published image, approved native compatibility and release plus post-release refusal/binding evidence all exist.
|
||||
|
||||
## Exact release case identifiers
|
||||
|
||||
Proposal `INFD-WP-0009-T04/purpose-overlay-v1`, trial `infd-purpose-20261011-r1`.
|
||||
Protected native parent `/data/private/purpose-overlay-r1` must be unique/non-symlink, owned10001 and0700. The drill snapshot is `drill.sqlite`, the refreshed pre-cutover snapshot `cutover.sqlite`, each new0600 file; refuse any existing output. Off-cluster custody is the existing ignored Custodian `.private-backups/20261011-infd-purpose-r1` parent0700, files0600; no snapshot is an evidence attachment. Check owner UID, no symlinks, ignored status and free capacity for both native snapshots plus independently protected copies before making any snapshot.
|
||||
|
||||
The disposable offline restore volume is `infd-purpose-r1-restore-20261011`; refuse an existing volume, copy only the selected frozen snapshot, and run exact published candidate763c with networknone/read-only image,128MiB/core1 and no runtime config/token mounts. SQLite `PRAGMA integrity_check` must return `ok`, `PRAGMA user_version`/Store inspection must agree with actual schema5 semantics, and installed admin count-only inspection must match the frozen snapshot. Validate the actual schema representation rather than assume PRAGMA user_version is the schema authority. No synthetic restoration is reported as native restoration. Native original/off-cluster copies remain retained; only the disposable restore copy/volume may be removed under the exact approved cleanup scope.
|
||||
|
||||
## Mandatory pre-open schema gate and offline command
|
||||
|
||||
`informed-decision-admin inspect` and `backup` construct Store, which can migrate schemas1–4 to5. Therefore **before any Store/admin open**, run the exact attached stdlib-only `sqlite_readonly.py` against the native source database using SQLite URI mode=ro, query_only and one read transaction. Require PRAGMA user_version5, integrity_check=ok and retain count-only baseline. Refuse any other/unknown schema or incomplete integrity/count check before constructing Store; do not infer no migration from a post-open admin report. This native gate has not been executed in this source-preparation stage. Repeat before each native backup/admin operation.
|
||||
|
||||
After copying the selected consistent snapshot to the isolated restored private path `/restore/review.sqlite`, run the same read-only checker **before** any offline candidate admin/Store opens that copy. Frozen snapshot and restored-copy schema/integrity/count reports must agree exactly; the copied main-file digest must match the selected closed snapshot. Reject oldschema fixtures rather than allow migration. Only after this pre-open gate may the offline candidate admin inspect run.
|
||||
|
||||
Offline command vectors use exactimage `forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a`, `--network none --read-only --cpus 1 --memory 128m`, private restored volume mounted at `/restore`, and **no runtime config/credential/token mounts**. First override entrypoint to `python`, arguments `- --db /restore/review.sqlite`, streaming only the verified attached checker on stdin. Then override entrypoint to **`informed-decision-admin`**, arguments **`inspect --db /restore/review.sqlite`**. This does not start `informed-decision-container`, the HTTP service, dispatcher or delivery workers. Compare the admin's schema/lifecycle/outbox/submission counters to the frozen pre-open snapshot report; integrity and migration-free pre-open proof come from the stdlib checker, not admin output alone.
|
||||
|
||||
Live reads and online snapshots may legitimately differ because reviews, intake and delivery can commit concurrently. Exact counter equality is required between the frozen selected snapshot and its offline restored clone; it is **not** required between a running post-cutover/rollback database and an earlier snapshot. Live count changes must be accounted for as legitimate committed records/state transitions; preserve all current and uncertain entries. Do not discard new commits or restore the old snapshot to force equality. Same-schema image rollback keeps the current live DB, followed by read-only schema5/integrity and count-only health checks; any unexplained evidence loss or required data recovery stops and requires a separate founder decision.
|
||||
|
||||
The fresh preflight also independently reads the actual immutable nonsecret ConfigMap and bound PVC: compares sealed UIDs/fullmetadata/PVCspec+volumeName and canonical runtime data checksum, returning no raw runtime data. Same-name deletion/recreation or content/custody drift stops before admission. Secret values remain excluded. Both local and remote optimized Python interpreters are explicitly refused before assertion-based gates.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"all_checks_pass": false,
|
||||
"transport_exit": 1,
|
||||
"stderr_sha256": "d9ea0351e38468c65d13bd68ece0c8e27acb654380ffee23111f76655edf8c49"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"all_checks_pass": false,
|
||||
"metadata_diff": {
|
||||
"category": "annotations",
|
||||
"changed_keys": [
|
||||
"argocd.argoproj.io/tracking-id"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"captured_at": "2026-10-11T01:25:38.793555+00:00",
|
||||
"native_workload_changed": false,
|
||||
"native_backup_restore_executed": false,
|
||||
"argo": {
|
||||
"uid": "499868f2-eabc-4df4-ae31-b89ce58d750d",
|
||||
"repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git",
|
||||
"targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf",
|
||||
"path": "deploy/lifecycle",
|
||||
"destination": {
|
||||
"namespace": "informed-decision",
|
||||
"server": "https://kubernetes.default.svc"
|
||||
},
|
||||
"automated": false,
|
||||
"sync": {
|
||||
"comparedTo": {
|
||||
"destination": {
|
||||
"namespace": "informed-decision",
|
||||
"server": "https://kubernetes.default.svc"
|
||||
},
|
||||
"source": {
|
||||
"path": "deploy/lifecycle",
|
||||
"repoURL": "https://forgejo.coulomb.social/coulomb/informed-decision.git",
|
||||
"targetRevision": "7db8485ffecdebfabd77a9daec085553c74bf0bf"
|
||||
}
|
||||
},
|
||||
"revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf",
|
||||
"status": "OutOfSync"
|
||||
},
|
||||
"health": {
|
||||
"lastTransitionTime": "2026-10-10T23:14:52Z",
|
||||
"status": "Healthy"
|
||||
}
|
||||
},
|
||||
"live_ready_replicas": 1,
|
||||
"admitted_uid": "a588e10a-90d2-4883-975e-6dd8b8feca92",
|
||||
"server_dry_run_passed": true,
|
||||
"admitted_spec_exactly_live_plus_image": true,
|
||||
"client_diff_exit": 1,
|
||||
"client_diff_sha256": "a4bc024a8cec658f835285ed51964e2e084edbaf103d45a48b89c0950bcd3e7d",
|
||||
"node_allocated_resources": "(Total limits may be over 100 percent, i.e., overcommitted.)\n Resource Requests Limits\n -------- -------- ------\n cpu 3460m (86%) 36200m (905%)\n memory 9472Mi (59%) 32898Mi (205%)\n ephemeral-storage 0 (0%) 0 (0%)\n hugepages-1Gi 0 (0%) 0 (0%)\n hugepages-2Mi 0 (0%) 0 (0%)",
|
||||
"all_checks_pass": true
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"packet_files": {
|
||||
"change_guard.py": "f348e449c49f4d9e49af9e82e01764e7197837fd3df9d756f5891d9b8d9b38be",
|
||||
"preflight.py": "6b4c65f708238c9a9d17fd065876c7a00e1f1745926f990a1dd5e667298340cd",
|
||||
"candidate-deployment.json": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e",
|
||||
"rollback-deployment.json": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121",
|
||||
"sealed-live-deployment.json": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362",
|
||||
"native-preflight.json": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262",
|
||||
"sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369",
|
||||
"sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38"
|
||||
},
|
||||
"owner_source_files": {
|
||||
"deploy/lifecycle/admission.candidate.json": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55",
|
||||
"deploy/lifecycle/service.candidate.json": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
"""Read-only refresh; exact original capture remains immutable; never execute cutover."""
|
||||
import argparse,hashlib,json,subprocess,sys
|
||||
from pathlib import Path
|
||||
if sys.flags.optimize:
|
||||
raise SystemExit("optimized interpreter refused before source/transport execution")
|
||||
ROOT=Path(__file__).resolve().parent
|
||||
p=argparse.ArgumentParser();p.add_argument('--receipt-output',type=Path,required=True);p.add_argument('--source-root',type=Path,default=Path('/home/worsch/informed-decision'));a=p.parse_args()
|
||||
out=a.receipt_output.resolve()
|
||||
if not a.receipt_output.is_absolute() or out==ROOT or ROOT in out.parents or out==a.source_root.resolve() or a.source_root.resolve() in out.parents or out.exists():
|
||||
raise SystemExit('unique execution receipt must be outside the sealed packet')
|
||||
inputs=json.loads((ROOT/'preflight-inputs.json').read_text())
|
||||
for relative,digest in inputs['packet_files'].items():
|
||||
path=ROOT/relative
|
||||
if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('sealed helper/input bytes changed')
|
||||
for relative,digest in inputs['owner_source_files'].items():
|
||||
path=a.source_root/relative
|
||||
if path.is_symlink() or hashlib.sha256(path.read_bytes()).hexdigest()!=digest:raise SystemExit('owner source bytes changed')
|
||||
from change_guard import transport_result
|
||||
program='import subprocess,json,hashlib,datetime,sys,copy,re\nif sys.flags.optimize:raise RuntimeError("optimized interpreter refused")\ncandidate=json.loads(CANDIDATE_LITERAL)\nsealed_dependencies=json.loads(DEPENDENCIES_LITERAL)\nsealed_baseline=json.loads(SEALED_LITERAL)\nexec(GUARD_LITERAL)\ndef run(args,data=None):\n p=subprocess.run(args,input=data,text=True,capture_output=True)\n if p.returncode: raise ValueError(\'read-only command failed: \'+args[1]+\' \'+args[2])\n return p.stdout\nlive=json.loads(run([\'kubectl\',\'get\',\'deployment\',\'informed-decision\',\'-n\',\'informed-decision\',\'-o\',\'json\']))\ncm=json.loads(run([\'kubectl\',\'get\',\'configmap\',\'informed-decision-runtime-6c221878d051\',\'-n\',\'informed-decision\',\'-o\',\'json\']))\npvc=json.loads(run([\'kubectl\',\'get\',\'pvc\',\'informed-decision-data\',\'-n\',\'informed-decision\',\'-o\',\'json\']))\ncheck_dependencies(cm,pvc,sealed_dependencies)\ncheck_current(live,sealed_baseline)\nspec=live[\'spec\']; cs=spec[\'template\'][\'spec\'][\'containers\'];assert len(cs)==1 and cs[0][\'name\']==\'informed-decision\'\nexpected_env={\'INFD_KEYCAPE_ISSUER\':\'https://kc.coulomb.social\',\'INFD_CONTAINER_CONFIG\':\'/configuration/runtime.json\'}\nassert cs[0].get(\'env\')==[{\'name\':\'INFD_KEYCAPE_ISSUER\',\'value\':expected_env[\'INFD_KEYCAPE_ISSUER\']},{\'name\':\'INFD_CONTAINER_CONFIG\',\'value\':expected_env[\'INFD_CONTAINER_CONFIG\']}]\nassert cs[0][\'image\']==\'forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173\'\nassert spec[\'replicas\']==1 and spec[\'strategy\']=={\'type\':\'Recreate\'}\nassert next(v for v in spec[\'template\'][\'spec\'][\'volumes\'] if v[\'name\']==\'configuration\')[\'configMap\'][\'name\']==\'informed-decision-runtime-6c221878d051\'\nassert live[\'status\'].get(\'readyReplicas\')==1 and live[\'status\'].get(\'updatedReplicas\')==1\nsealed={\'apiVersion\':live[\'apiVersion\'],\'kind\':live[\'kind\'],\'metadata\':{k:copy.deepcopy(v) for k,v in live[\'metadata\'].items() if k not in (\'resourceVersion\',\'generation\',\'creationTimestamp\',\'managedFields\')},\'spec\':copy.deepcopy(spec)}\nfor key in (\'kubectl.kubernetes.io/last-applied-configuration\',\'deployment.kubernetes.io/revision\'):sealed[\'metadata\'].get(\'annotations\',{}).pop(key,None)\nadmitted=json.loads(run([\'kubectl\',\'apply\',\'--dry-run=server\',\'-f\',\'-\',\'-o\',\'json\'],json.dumps(candidate)))\ncheck_admitted(admitted,sealed_baseline)\napp=json.loads(run([\'kubectl\',\'get\',\'application\',\'informed-decision\',\'-n\',\'argocd\',\'-o\',\'json\']))\nassert app[\'spec\'][\'source\'][\'path\']==\'deploy/lifecycle\' and not app[\'spec\'].get(\'syncPolicy\',{}).get(\'automated\')\nargo={\'uid\':app[\'metadata\'][\'uid\'],\'repoURL\':app[\'spec\'][\'source\'][\'repoURL\'],\'targetRevision\':app[\'spec\'][\'source\'][\'targetRevision\'],\'path\':app[\'spec\'][\'source\'][\'path\'],\'destination\':app[\'spec\'][\'destination\'],\'automated\':False,\'sync\':app.get(\'status\',{}).get(\'sync\'),\'health\':app.get(\'status\',{}).get(\'health\')}\nexpected_argo=json.loads(ARGO_LITERAL)\nfor key in (\'uid\',\'repoURL\',\'targetRevision\',\'path\',\'destination\',\'automated\'):\n assert argo[key]==expected_argo[key]\nassert argo[\'health\'][\'status\']==\'Healthy\'\ndiff=subprocess.run([\'kubectl\',\'diff\',\'-f\',\'-\'],input=json.dumps(candidate),text=True,capture_output=True);assert diff.returncode in (0,1)\n# Diff can contain only nonsecret Deployment references; preserve digest rather than raw stdout.\nnode=run([\'kubectl\',\'describe\',\'node\']);allocated=re.search(r\'Allocated resources:.*?CPU Requests|Allocated resources:\',node,re.S)\nsection=node.split(\'Allocated resources:\')[1].split(\'Events:\')[0] if \'Allocated resources:\' in node else \'\'\nnodes=json.loads(run([\'kubectl\',\'get\',\'nodes\',\'-o\',\'json\']))[\'items\'];assert len(nodes)==1\nalloc=nodes[0][\'status\'][\'allocatable\'];cpu=alloc[\'cpu\'];cpu_m=int(cpu[:-1]) if cpu.endswith(\'m\') else int(cpu)*1000\nrequested=int(re.search(r\'cpu\\s+(\\d+)m\',section).group(1));assert requested<=cpu_m\nreceipt={\'node_allocatable_cpu_m\':cpu_m,\'node_requested_cpu_m\':requested,\'captured_at\':datetime.datetime.now(datetime.timezone.utc).isoformat(),\'native_workload_changed\':False,\'native_backup_restore_executed\':False,\'argo\':argo,\'native_dependencies_checked\':True,\'configmap_uid\':cm[\'metadata\'][\'uid\'],\'pvc_uid\':pvc[\'metadata\'][\'uid\'],\'live_ready_replicas\':1,\'admitted_uid\':admitted[\'metadata\'][\'uid\'],\'server_dry_run_passed\':True,\'admitted_spec_exactly_live_plus_image\':True,\'client_diff_exit\':diff.returncode,\'client_diff_sha256\':hashlib.sha256(diff.stdout.encode()).hexdigest(),\'node_allocated_resources\':section.strip(),\'all_checks_pass\':True}\nprint(json.dumps(receipt))\n'
|
||||
for marker,value in [('DEPENDENCIES_LITERAL',(ROOT/'sealed-native-dependencies.json').read_text()),('CANDIDATE_LITERAL',(ROOT/'candidate-deployment.json').read_text()),('SEALED_LITERAL',(ROOT/'sealed-live-deployment.json').read_text()),('GUARD_LITERAL',(ROOT/'change_guard.py').read_text()),('ARGO_LITERAL',json.dumps(json.loads((ROOT/'native-preflight.json').read_text())['argo']))]:
|
||||
program=program.replace(marker,repr(value))
|
||||
program='import traceback,json\ntry:\n'+''.join(' '+line+'\n' for line in program.splitlines())+"except Exception as error:\n print(json.dumps({'all_checks_pass':False,'exception_type':type(error).__name__,'exception_line':traceback.extract_tb(error.__traceback__)[-1].lineno}))\n"
|
||||
r=subprocess.run(['ssh','railiance01','python3 -'],input=program,text=True,capture_output=True)
|
||||
result=transport_result(r.returncode,r.stdout);result['sealed_preflight_inputs_sha256']=hashlib.sha256((ROOT/'preflight-inputs.json').read_bytes()).hexdigest();result['fresh_execution_receipt']=True
|
||||
out.write_text(json.dumps(result,indent=2)+'\n');print(json.dumps(result,indent=2));sys.exit(0 if result.get('all_checks_pass') is True else 1)
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"trial_id": "infd-purpose-20261011-r1",
|
||||
"state": "prepared-unapproved",
|
||||
"target": "realm:kubernetes/railiance01/informed-decision",
|
||||
"authority": "ADMINISTER; activation APPROVED only upon exact founder disposition",
|
||||
"candidate_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"published_source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"prior_image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"prior_argo_revision": "7db8485ffecdebfabd77a9daec085553c74bf0bf",
|
||||
"native_object": {
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"namespace": "informed-decision",
|
||||
"name": "informed-decision",
|
||||
"uid": "a588e10a-90d2-4883-975e-6dd8b8feca92"
|
||||
},
|
||||
"argo_application_uid": "499868f2-eabc-4df4-ae31-b89ce58d750d",
|
||||
"source_gate": "Exact committed owner source must contain the two approved candidate file hashes in preflight-inputs.json; source preparation is not native approval",
|
||||
"sync_scope": [
|
||||
"apps:Deployment:informed-decision"
|
||||
],
|
||||
"prune": false,
|
||||
"automated_sync": false,
|
||||
"runtime_configmap": "informed-decision-runtime-6c221878d051",
|
||||
"schema": 5,
|
||||
"requested_operations": [
|
||||
"Protected SQLite-consistent native backup and independently protected off-cluster custody",
|
||||
"Offline restore/integrity/count comparison on a private disposable volume with exact candidate, no runtime tokens/config/network",
|
||||
"Refresh a consistent pre-cutover snapshot, retain private copies and count-only/hash receipts",
|
||||
"Pin existing manual Argo Application to exact approved owner source and manually sync only existing Deployment image",
|
||||
"Verify health/readiness/image/module/installed fail-closed purpose checks and retained schema/count evidence; recover to prior same-schema image if needed"
|
||||
],
|
||||
"execute_by": "2026-10-12T23:59:59Z",
|
||||
"temporary_vulnerability_review_due": "2026-10-18",
|
||||
"known_scan_findings": "0HIGH/CRITICAL,1fixable inheritedMEDIUM zlib, actual currentbase+candidate findings identical",
|
||||
"vulnerability_record": "INFD-RISK-20261011-ZLIB-85091 / INFD-WP-0009-T05",
|
||||
"cost_estimate_EUR": 0,
|
||||
"cost_limits": "No new recurring infrastructure; private backup storage and attended engineering/recovery time unpriced, not an autopilot cost grant",
|
||||
"risk_estimates": [
|
||||
"Brief Recreate service interruption; no concurrent new writer/surge",
|
||||
"Private evidence snapshot custody and disposal errors; no snapshots/tokens in public evidence",
|
||||
"Candidate purpose refusal may expose callers relying on advisory results as binding",
|
||||
"Inherited known fixable MEDIUM remains until separately approved owner remediation",
|
||||
"Existing Argo OutOfSync baseline is retained; no whole-app sync or unrelated repairs permitted"
|
||||
],
|
||||
"rollback": "Manual Argo source pin back to7db8485 and scoped Deployment-only sync to7f5c image; retain current schema5 database and all post-cutover evidence, never restore older snapshot over live writes",
|
||||
"native_executed": false,
|
||||
"human_approval": false,
|
||||
"refinement_of_manifest": "7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300",
|
||||
"mandatory_pre_open_gate": "stdlibSQLite mode=ro/query_only: schema5+integrity+count baseline before ANY Store/admin on native source or restoredcopy; refuseoldschemas without migration",
|
||||
"optimized_interpreters": "local+remote explicitlyrefused beforeassert gates",
|
||||
"native_dependency_gate": "sealed actualCM UID/immutable/canonicaldatahash+PVC UID/fullspec/Bound/volumeName, no rawCMdata orSecret reads",
|
||||
"live_counts": "Frozen snapshot/clone exactcounter equality; postcutover/rollback livecounterchanges may reflect legitimate concurrentcommits/state transitions, latestDB alwaysretained"
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"proposal": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"observed_at": "2026-10-11T01:24:01.985128+00:00",
|
||||
"native_owner_publication_job": {
|
||||
"id": 11484,
|
||||
"name": "publish-candidate",
|
||||
"head_branch": "main",
|
||||
"head_sha": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"run_number": 3,
|
||||
"event": "push",
|
||||
"display_title": "Prepare readable overlay context with the admitted legacy builder",
|
||||
"status": "success",
|
||||
"workflow_id": "purpose-overlay-image.yaml",
|
||||
"url": "https://forgejo.coulomb.social/coulomb/informed-decision/actions/runs/3",
|
||||
"created_at": "2026-10-11T01:20:59Z",
|
||||
"updated_at": "2026-10-11T01:21:08Z",
|
||||
"run_started_at": "2026-10-11T01:20:59Z"
|
||||
},
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"policy_sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62",
|
||||
"registry_proof_sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213",
|
||||
"source_render_change_only": "Deployment/informed-decision spec.template.spec.containers[0].image",
|
||||
"runtime_configmap_unchanged": "informed-decision-runtime-6c221878d051",
|
||||
"installed_image_execution": {
|
||||
"immutable_registry_artifact_pulled_anonymously": true,
|
||||
"UID": 10001,
|
||||
"GID": 10001,
|
||||
"policy_file_UID": 0,
|
||||
"policy_file_mode": "0644",
|
||||
"purpose_variants": 10,
|
||||
"binding_forms_allowed": 2,
|
||||
"advisory_or_malformed_refused": 8,
|
||||
"network": "none",
|
||||
"read_only": true,
|
||||
"synthetic_transport": true,
|
||||
"native_PDP_test": false
|
||||
},
|
||||
"scan_summary_sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44",
|
||||
"historical_failed_runs_retained": [
|
||||
"f66de505/task11482/run1",
|
||||
"acecad887/task11483/run2"
|
||||
],
|
||||
"native_hosting_changed": false,
|
||||
"native_backup_restore_executed": false,
|
||||
"human_approval": false,
|
||||
"evidence_file_sha256": {
|
||||
"image-manifest.json": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb",
|
||||
"image-config.json": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10",
|
||||
"base-image-config.json": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00",
|
||||
"registry-proof.json": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213",
|
||||
"trivy-full.json": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e",
|
||||
"sbom.cdx.json": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d",
|
||||
"base-trivy-full.json": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80",
|
||||
"check_installed.py": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad",
|
||||
"verify_registry.py": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4",
|
||||
"sqlite_readonly.py": "eef53dd233eee74c17f20823bd7f5787c60cad79ac648021c9479643c6ce9e38",
|
||||
"sealed-native-dependencies.json": "042327a036ed254cf95dbeb0c056ac25b03a6a844b95a332c992df2943691369",
|
||||
"review-refinement.json": "ea62845cee5ee6f4f6cb7f5dcd0af601ba29a21c8ff80efbbc02ad16e35bea75",
|
||||
"test_change_guard.py": "da5350437357ba329236cc137610c03856f38f836ddf2856025bc12011fad07f",
|
||||
"test_sqlite_readonly.py": "c7a91d0c6a373d738c88bb817d9bfb2ff8a179bc61b93063b89677b566520323",
|
||||
"test_preflight_optimization.py": "a0c4fa18c5d6c21476a06c6d05fe7656259d204299138851599e9214d911206d"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"image_digest": "sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"base_image_digest": "sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"base_layer_bytes_identical": true,
|
||||
"layer_media_type_conversion": "OCI gzip to Docker gzip, same digest and size",
|
||||
"base_runtime_config_semantics_identical": true,
|
||||
"legacy_builder_config_additions": {
|
||||
"Hostname": "",
|
||||
"Domainname": "",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": false,
|
||||
"AttachStderr": false,
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Cmd": null,
|
||||
"Volumes": null,
|
||||
"OnBuild": null,
|
||||
"Image": "sha256:90f1574f9eda35fa6cb972961beb27a7cb904c36560e381930b0e14065c23883"
|
||||
},
|
||||
"base_rootfs_prefix_identical": true,
|
||||
"overlay_regular_files": [
|
||||
"opt/venv/lib/python3.12/site-packages/informed_decision/policy.py"
|
||||
],
|
||||
"overlay_directories": [
|
||||
"opt",
|
||||
"opt/venv",
|
||||
"opt/venv/lib",
|
||||
"opt/venv/lib/python3.12",
|
||||
"opt/venv/lib/python3.12/site-packages",
|
||||
"opt/venv/lib/python3.12/site-packages/informed_decision"
|
||||
],
|
||||
"policy_sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62",
|
||||
"policy_mode": "0644",
|
||||
"base_user": "10001:10001",
|
||||
"source_scope_labels": {
|
||||
"org.opencontainers.image.revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"org.opencontainers.image.base.digest": "sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"social.coulomb.source.policy.sha256": "9d7c1be4cb6199d14ef0aaead5f85951f45b0ccbd7c800a7fde922a253566b62",
|
||||
"social.coulomb.release.scope": "INFD-WP-0009-T04/purpose-overlay-v1"
|
||||
},
|
||||
"registry_read_route": "anonymous public scoped bearer challenge, no token retention",
|
||||
"image_executed": false,
|
||||
"native_workload_changed": false,
|
||||
"native_backup_restore_executed": false
|
||||
}
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
{
|
||||
"proposal_id": "INFD-WP-0009-T04/purpose-overlay-v1",
|
||||
"trial_id": "infd-purpose-20261011-r1",
|
||||
"original_manifest_sha256": "7c6738b39ea8e54e61c8ed625e94ad0b2755e672e1576efcdf84a1d665ac3300",
|
||||
"original_submission_sha256": "sha256:ac41c8aea7bb008e17f50dc0bab4aad584aef1e461222967ac98d74c7bd28af7",
|
||||
"original36files_preserved": [
|
||||
{
|
||||
"original_owner_path": "deploy/lifecycle/admission.candidate.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/deploy/lifecycle/admission.candidate.json",
|
||||
"sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "deploy/lifecycle/service.candidate.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/deploy/lifecycle/service.candidate.json",
|
||||
"sha256": "38b78b9cbee5ade7750a58d5156ca4c5773352e947acb304ee714b59e749ceb4"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/README.md",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/README.md",
|
||||
"sha256": "f88a79a93fff34a1b438e2dc0344cad88d6c7960dde04bc7f3c04ac1fbb992c7"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/base-image-config.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-image-config.json",
|
||||
"sha256": "b706c9209e324f39a86ffcda2a3e9d94c92649739ad5b21fe4611006e36f6f00"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/base-trivy-full.json",
|
||||
"sha256": "d44c555aecbb1a4518f4127d48015ea459325c93e8b0371910a55de47293ca80"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-admission.json",
|
||||
"sha256": "92382a56b349c3b895e5806e975082527bb99d1a001140e69d857e5b0391fa55"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/candidate-deployment.json",
|
||||
"sha256": "722a8e2dc52bec217bf960e23b2fddfc7ac27d343ac8743790e3183db81a6a0e"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/change_guard.py",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/change_guard.py",
|
||||
"sha256": "830f7771b5c7d0a2851973aa65a01c6ab40b86570f0933d8aebb89f9665ca7e1"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/check_installed.py",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/check_installed.py",
|
||||
"sha256": "a34a51be9c9f2b16a06a88173b5c6c492c9957fe021cf412a86a1737730640ad"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/decision-packet.md",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/decision-packet.md",
|
||||
"sha256": "7f6d8987f65dff479eeead67b7ca940ef44c22c1cdbdd6ca33fd732b824c8f02"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/fresh-preflight-validation.json",
|
||||
"sha256": "aa1d494e42491f0619f731a836c597df9178409887d734c166a8df81f8807a27"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/image-config.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-config.json",
|
||||
"sha256": "4ad7249c75fd9fc039ceb186772419e1cba5fd9759c404556459c80a2d285d10"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/image-manifest.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/image-manifest.json",
|
||||
"sha256": "978c575d3c7bf0de39dbe4e9567c39cd36f70b7e55bc17357bdb03fb3b96b0fb"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/inherited-vulnerability-follow-through.json",
|
||||
"sha256": "e8da413bf985ef2cb66c71a093ba7fc0636ab884f428e40a18b40ccff8e3b101"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/intake.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/intake.json",
|
||||
"sha256": "9a39631362f20168da409cef74f7690f3aa1b8f841fc96ecd8770f73a1f954ac"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/lifecycle-commands.json",
|
||||
"sha256": "b6210dcd34e5485c94e35f4bdd3329fb72c1d40fa9357caf40ac42b4f8afa5c2"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/memo.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/memo.json",
|
||||
"sha256": "06530425dd9634182f70a65dd2da56cbad3da967bc842b3c7b01c30542222128"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-backup-restore-protocol.md",
|
||||
"sha256": "aa9758d4de587d14c6ce0fdaccd84002c5c5099425b9169ca7c972a86e9d3dec"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-initial-refusal.json",
|
||||
"sha256": "052fc57d2cda43b2e474f28a5ff70753f5fa673c77a9645a201d0e0e961792e4"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight-tracking-id-refusal.json",
|
||||
"sha256": "aaa77b406b201eb40a62f60182057e90b1baea06e03f85d7e06916b57f5f2de8"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/native-preflight.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/native-preflight.json",
|
||||
"sha256": "eb5f41aefb97666bb0c1279617e95a7c05017a609415624daee724c48b90d262"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight-inputs.json",
|
||||
"sha256": "0bbdaf56459aaef3c35d7b1bf3ad20be6260f047df6dd1c5eb60ac1797150944"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/preflight.py",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/preflight.py",
|
||||
"sha256": "c206a1a9b9d232c656c6d57fb9247549eefa13b275a5da4d39b45a6c9902c834"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/proposal.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/proposal.json",
|
||||
"sha256": "08c5573eaad05efd24b6df6737d33e7189543eb621f21704e38bab4326094914"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/published-verification.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/published-verification.json",
|
||||
"sha256": "e304dd29571bf7d7b9f1db2ade0163dd39cfec012a5ce6986139f019f37e65a2"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/registry-proof.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/registry-proof.json",
|
||||
"sha256": "5aa2c1f780c47f62fa9b59da9543d82c07afa02b1d946e6144b8a042ef86f213"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-admission.json",
|
||||
"sha256": "22f830736ee56f6ed9b62f47d243e4e24a1b68263b261e78e2f1cfcb85adbd50"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/rollback-deployment.json",
|
||||
"sha256": "39b3f43bb84ef4921cc3a1fbcdc444610741ed8809149d8f8f17ed805f262121"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sbom.cdx.json",
|
||||
"sha256": "a4252951e2027472c26d8679cb543e30983180809d6dd3c7c94b883d62803e5d"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/sealed-live-deployment.json",
|
||||
"sha256": "d18d27063d06f535ae884ea01f96747fe301685518ab94b1cba072a1e1519362"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/security-summary.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/security-summary.json",
|
||||
"sha256": "0ee56400dc703f7c9968c2a0a3ea0390d8362f8d0bbf8002a2bd7fa58f19cb44"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/test_change_guard.py",
|
||||
"sha256": "b7cd28b2ada33004c9264cb54c9749fa501f60166638f926e50e264ddebe037d"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/trivy-full.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/trivy-full.json",
|
||||
"sha256": "f38a8f7e6c419eed9154d7762f932b9deb6680a622247b08196b7458b893434e"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/validation.json",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/validation.json",
|
||||
"sha256": "3b57f525bbbb1db9dc46bcc6b0057a8dd9f45c461fad0a8dea5391ca78038c36"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "docs/evidence/2026-10-11-purpose-image-release/verify_registry.py",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/docs/evidence/2026-10-11-purpose-image-release/verify_registry.py",
|
||||
"sha256": "413f575c21a2bd18a3696f8f2d939eeadc52d76f282c42813f76bb0e3ee8a2a4"
|
||||
},
|
||||
{
|
||||
"original_owner_path": "workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md",
|
||||
"archive_path": "initial-7c6738b3/owner-snapshot/workplans/INFD-WP-0009-lifecycle-consumer-pin-repair.md.source.txt",
|
||||
"sha256": "18205c0c7aa8f3460d78e3b7ad9dddd9e361395f9a28d93a7a384c29c9602d36"
|
||||
}
|
||||
],
|
||||
"review_result": "initial conditional/refinement-required; no human disposition",
|
||||
"identified_gates": [
|
||||
"Store/admin automatically migrate oldschema; readonly pre-open schema5 required",
|
||||
"Python optimization bypasses asserts; explicit local/remote optimized interpreter refusal",
|
||||
"Actual immutableCM and boundPVC identities/content/custody must be sealed",
|
||||
"Snapshotclone counts exact; livecounts may include legitimate concurrentcommits"
|
||||
],
|
||||
"amended_scope": "same763cimage, same source2image-only candidates, no native data orworkload operation",
|
||||
"human_approval": false,
|
||||
"native_backup_restore_executed": false,
|
||||
"native_workload_changed": false
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"policy": {
|
||||
"origin": "http://flex-auth-informed-decision-sitting.flex-auth.svc.cluster.local:8080",
|
||||
"package": "informed-decision.compact-sitting",
|
||||
"version": "v13",
|
||||
"package_digest": "sha256:31be5985c0c1e6b0c3a039ed7310d1e94daf523a94f6d926e6e8d759d3711873",
|
||||
"pod_name": "flex-auth-informed-decision-sitting"
|
||||
},
|
||||
"keycape_egress_ips": [
|
||||
"92.205.62.239"
|
||||
],
|
||||
"storage_class": "local-path",
|
||||
"ordinary_approval_ids": [
|
||||
"2ce76d7f-01c3-4b63-8476-8d1230679769",
|
||||
"c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
|
||||
"dc22666a-d5d7-46bc-9490-ebe9fe09dc38"
|
||||
],
|
||||
"lifecycle_policy": {
|
||||
"package": "informed-decision.lifecycle",
|
||||
"version": "v2",
|
||||
"package_digest": "sha256:da01e045fc108adec6b489e5d51f7e57366793016c5a64776963780a6aae457c",
|
||||
"origin": "http://flex-auth-informed-decision-lifecycle.flex-auth.svc.cluster.local:8080",
|
||||
"pod_name": "flex-auth-informed-decision-lifecycle"
|
||||
},
|
||||
"lifecycle_delivery": true,
|
||||
"intake_attributes": true,
|
||||
"intake_delivery": {
|
||||
"hub_origin": "http://state-hub.state-hub.svc.cluster.local:8000"
|
||||
},
|
||||
"workload_api": {
|
||||
"registries_configmap": "informed-decision-workload-registry",
|
||||
"peers": [
|
||||
{
|
||||
"namespace": "state-hub",
|
||||
"app": "state-hub"
|
||||
}
|
||||
],
|
||||
"api_egress": [
|
||||
{
|
||||
"ip": "10.43.0.1",
|
||||
"port": 443
|
||||
},
|
||||
{
|
||||
"ip": "92.205.62.239",
|
||||
"port": 6443
|
||||
}
|
||||
],
|
||||
"intake": true,
|
||||
"lifecycle": true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover",
|
||||
"argocd.argoproj.io/tracking-id": "informed-decision:apps/Deployment:informed-decision/informed-decision"
|
||||
},
|
||||
"name": "informed-decision",
|
||||
"namespace": "informed-decision"
|
||||
},
|
||||
"spec": {
|
||||
"progressDeadlineSeconds": 600,
|
||||
"replicas": 1,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"strategy": {
|
||||
"type": "Recreate"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover"
|
||||
},
|
||||
"labels": {
|
||||
"app.kubernetes.io/component": "review",
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"automountServiceAccountToken": false,
|
||||
"containers": [
|
||||
{
|
||||
"env": [
|
||||
{
|
||||
"name": "INFD_KEYCAPE_ISSUER",
|
||||
"value": "https://kc.coulomb.social"
|
||||
},
|
||||
{
|
||||
"name": "INFD_CONTAINER_CONFIG",
|
||||
"value": "/configuration/runtime.json"
|
||||
}
|
||||
],
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"livenessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"name": "informed-decision",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 8080,
|
||||
"name": "http"
|
||||
},
|
||||
{
|
||||
"containerPort": 8081,
|
||||
"name": "workload"
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"resources": {
|
||||
"limits": {
|
||||
"cpu": "500m",
|
||||
"memory": "256Mi"
|
||||
},
|
||||
"requests": {
|
||||
"cpu": "5m",
|
||||
"memory": "64Mi"
|
||||
}
|
||||
},
|
||||
"securityContext": {
|
||||
"allowPrivilegeEscalation": false,
|
||||
"capabilities": {
|
||||
"drop": [
|
||||
"ALL"
|
||||
]
|
||||
},
|
||||
"readOnlyRootFilesystem": true
|
||||
},
|
||||
"startupProbe": {
|
||||
"failureThreshold": 12,
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/data",
|
||||
"name": "data"
|
||||
},
|
||||
{
|
||||
"mountPath": "/run/informed-decision",
|
||||
"name": "runtime"
|
||||
},
|
||||
{
|
||||
"mountPath": "/tmp",
|
||||
"name": "tmp"
|
||||
},
|
||||
{
|
||||
"mountPath": "/configuration",
|
||||
"name": "configuration",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/policy",
|
||||
"name": "caller",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/audit",
|
||||
"name": "audit",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/kubernetes",
|
||||
"name": "kubernetes-api",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/workload-registry",
|
||||
"name": "workload-registry",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/requester",
|
||||
"name": "sitting-requester",
|
||||
"readOnly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"securityContext": {
|
||||
"fsGroup": 10001,
|
||||
"fsGroupChangePolicy": "OnRootMismatch",
|
||||
"runAsGroup": 10001,
|
||||
"runAsNonRoot": true,
|
||||
"runAsUser": 10001,
|
||||
"seccompProfile": {
|
||||
"type": "RuntimeDefault"
|
||||
}
|
||||
},
|
||||
"serviceAccountName": "review",
|
||||
"terminationGracePeriodSeconds": 45,
|
||||
"volumes": [
|
||||
{
|
||||
"name": "data",
|
||||
"persistentVolumeClaim": {
|
||||
"claimName": "informed-decision-data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
},
|
||||
"name": "runtime"
|
||||
},
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
},
|
||||
"name": "tmp"
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 292,
|
||||
"name": "informed-decision-runtime-6c221878d051"
|
||||
},
|
||||
"name": "configuration"
|
||||
},
|
||||
{
|
||||
"name": "caller",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"audience": "flex-auth",
|
||||
"expirationSeconds": 3600,
|
||||
"path": "token"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "audit",
|
||||
"secret": {
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "token",
|
||||
"path": "token"
|
||||
}
|
||||
],
|
||||
"secretName": "informed-decision-audit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "kubernetes-api",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"expirationSeconds": 600,
|
||||
"path": "token"
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"items": [
|
||||
{
|
||||
"key": "ca.crt",
|
||||
"path": "ca.crt"
|
||||
}
|
||||
],
|
||||
"name": "kube-root-ca.crt"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 292,
|
||||
"name": "informed-decision-workload-registry"
|
||||
},
|
||||
"name": "workload-registry"
|
||||
},
|
||||
{
|
||||
"name": "sitting-requester",
|
||||
"secret": {
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "client-secret",
|
||||
"path": "client-secret"
|
||||
}
|
||||
],
|
||||
"optional": false,
|
||||
"secretName": "informed-decision-sitting-requester"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,286 @@
|
|||
{
|
||||
"apiVersion": "apps/v1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"argocd.argoproj.io/tracking-id": "informed-decision:apps/Deployment:informed-decision/informed-decision",
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover"
|
||||
},
|
||||
"name": "informed-decision",
|
||||
"namespace": "informed-decision",
|
||||
"uid": "a588e10a-90d2-4883-975e-6dd8b8feca92"
|
||||
},
|
||||
"spec": {
|
||||
"progressDeadlineSeconds": 600,
|
||||
"replicas": 1,
|
||||
"revisionHistoryLimit": 10,
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"strategy": {
|
||||
"type": "Recreate"
|
||||
},
|
||||
"template": {
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover"
|
||||
},
|
||||
"labels": {
|
||||
"app.kubernetes.io/component": "review",
|
||||
"app.kubernetes.io/name": "informed-decision"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"automountServiceAccountToken": false,
|
||||
"containers": [
|
||||
{
|
||||
"env": [
|
||||
{
|
||||
"name": "INFD_KEYCAPE_ISSUER",
|
||||
"value": "https://kc.coulomb.social"
|
||||
},
|
||||
{
|
||||
"name": "INFD_CONTAINER_CONFIG",
|
||||
"value": "/configuration/runtime.json"
|
||||
}
|
||||
],
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:7f5c6cb29c9f70a026bfe30e72934274ddc69261676cf6d476f81dd32812d173",
|
||||
"imagePullPolicy": "IfNotPresent",
|
||||
"livenessProbe": {
|
||||
"failureThreshold": 3,
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http",
|
||||
"scheme": "HTTP"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"successThreshold": 1,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"name": "informed-decision",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 8080,
|
||||
"name": "http",
|
||||
"protocol": "TCP"
|
||||
},
|
||||
{
|
||||
"containerPort": 8081,
|
||||
"name": "workload",
|
||||
"protocol": "TCP"
|
||||
}
|
||||
],
|
||||
"readinessProbe": {
|
||||
"failureThreshold": 3,
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http",
|
||||
"scheme": "HTTP"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"successThreshold": 1,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"resources": {
|
||||
"limits": {
|
||||
"cpu": "500m",
|
||||
"memory": "256Mi"
|
||||
},
|
||||
"requests": {
|
||||
"cpu": "5m",
|
||||
"memory": "64Mi"
|
||||
}
|
||||
},
|
||||
"securityContext": {
|
||||
"allowPrivilegeEscalation": false,
|
||||
"capabilities": {
|
||||
"drop": [
|
||||
"ALL"
|
||||
]
|
||||
},
|
||||
"readOnlyRootFilesystem": true
|
||||
},
|
||||
"startupProbe": {
|
||||
"failureThreshold": 12,
|
||||
"httpGet": {
|
||||
"path": "/healthz",
|
||||
"port": "http",
|
||||
"scheme": "HTTP"
|
||||
},
|
||||
"periodSeconds": 10,
|
||||
"successThreshold": 1,
|
||||
"timeoutSeconds": 2
|
||||
},
|
||||
"terminationMessagePath": "/dev/termination-log",
|
||||
"terminationMessagePolicy": "File",
|
||||
"volumeMounts": [
|
||||
{
|
||||
"mountPath": "/data",
|
||||
"name": "data"
|
||||
},
|
||||
{
|
||||
"mountPath": "/run/informed-decision",
|
||||
"name": "runtime"
|
||||
},
|
||||
{
|
||||
"mountPath": "/tmp",
|
||||
"name": "tmp"
|
||||
},
|
||||
{
|
||||
"mountPath": "/configuration",
|
||||
"name": "configuration",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/policy",
|
||||
"name": "caller",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/audit",
|
||||
"name": "audit",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/kubernetes",
|
||||
"name": "kubernetes-api",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/workload-registry",
|
||||
"name": "workload-registry",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"mountPath": "/var/run/secrets/informed-decision/requester",
|
||||
"name": "sitting-requester",
|
||||
"readOnly": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"dnsPolicy": "ClusterFirst",
|
||||
"restartPolicy": "Always",
|
||||
"schedulerName": "default-scheduler",
|
||||
"securityContext": {
|
||||
"fsGroup": 10001,
|
||||
"fsGroupChangePolicy": "OnRootMismatch",
|
||||
"runAsGroup": 10001,
|
||||
"runAsNonRoot": true,
|
||||
"runAsUser": 10001,
|
||||
"seccompProfile": {
|
||||
"type": "RuntimeDefault"
|
||||
}
|
||||
},
|
||||
"serviceAccount": "review",
|
||||
"serviceAccountName": "review",
|
||||
"terminationGracePeriodSeconds": 45,
|
||||
"volumes": [
|
||||
{
|
||||
"name": "data",
|
||||
"persistentVolumeClaim": {
|
||||
"claimName": "informed-decision-data"
|
||||
}
|
||||
},
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
},
|
||||
"name": "runtime"
|
||||
},
|
||||
{
|
||||
"emptyDir": {
|
||||
"medium": "Memory",
|
||||
"sizeLimit": "16Mi"
|
||||
},
|
||||
"name": "tmp"
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 292,
|
||||
"name": "informed-decision-runtime-6c221878d051"
|
||||
},
|
||||
"name": "configuration"
|
||||
},
|
||||
{
|
||||
"name": "caller",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"audience": "flex-auth",
|
||||
"expirationSeconds": 3600,
|
||||
"path": "token"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "audit",
|
||||
"secret": {
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "token",
|
||||
"path": "token"
|
||||
}
|
||||
],
|
||||
"secretName": "informed-decision-audit"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "kubernetes-api",
|
||||
"projected": {
|
||||
"defaultMode": 288,
|
||||
"sources": [
|
||||
{
|
||||
"serviceAccountToken": {
|
||||
"expirationSeconds": 600,
|
||||
"path": "token"
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"items": [
|
||||
{
|
||||
"key": "ca.crt",
|
||||
"path": "ca.crt"
|
||||
}
|
||||
],
|
||||
"name": "kube-root-ca.crt"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"configMap": {
|
||||
"defaultMode": 292,
|
||||
"name": "informed-decision-workload-registry"
|
||||
},
|
||||
"name": "workload-registry"
|
||||
},
|
||||
{
|
||||
"name": "sitting-requester",
|
||||
"secret": {
|
||||
"defaultMode": 288,
|
||||
"items": [
|
||||
{
|
||||
"key": "client-secret",
|
||||
"path": "client-secret"
|
||||
}
|
||||
],
|
||||
"optional": false,
|
||||
"secretName": "informed-decision-sitting-requester"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"configmap": {
|
||||
"apiVersion": "v1",
|
||||
"immutable": true,
|
||||
"kind": "ConfigMap",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"argocd.argoproj.io/tracking-id": "informed-decision:/ConfigMap:informed-decision/informed-decision-runtime-6c221878d051",
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover"
|
||||
},
|
||||
"name": "informed-decision-runtime-6c221878d051",
|
||||
"namespace": "informed-decision",
|
||||
"uid": "90113d2d-54d9-4e82-b1d3-90b49ebed2b5"
|
||||
},
|
||||
"canonical_data_sha256": "8ec462d12347548f506eeebf1e3c7cc47648019c8a783804d09bcc79b0f22af6"
|
||||
},
|
||||
"pvc": {
|
||||
"apiVersion": "v1",
|
||||
"kind": "PersistentVolumeClaim",
|
||||
"metadata": {
|
||||
"annotations": {
|
||||
"argocd.argoproj.io/tracking-id": "informed-decision:/PersistentVolumeClaim:informed-decision/informed-decision-data",
|
||||
"informed-decision.coulomb.social/admission": "approved; INFD-WP-0007 cutover",
|
||||
"pv.kubernetes.io/bind-completed": "yes",
|
||||
"pv.kubernetes.io/bound-by-controller": "yes",
|
||||
"volume.beta.kubernetes.io/storage-provisioner": "rancher.io/local-path",
|
||||
"volume.kubernetes.io/selected-node": "239.62.205.92.host.secureserver.net",
|
||||
"volume.kubernetes.io/storage-provisioner": "rancher.io/local-path"
|
||||
},
|
||||
"finalizers": [
|
||||
"kubernetes.io/pvc-protection"
|
||||
],
|
||||
"name": "informed-decision-data",
|
||||
"namespace": "informed-decision",
|
||||
"uid": "d80b25b1-141a-441b-b205-98fa2fd98b7c"
|
||||
},
|
||||
"spec": {
|
||||
"accessModes": [
|
||||
"ReadWriteOnce"
|
||||
],
|
||||
"resources": {
|
||||
"requests": {
|
||||
"storage": "1Gi"
|
||||
}
|
||||
},
|
||||
"storageClassName": "local-path",
|
||||
"volumeMode": "Filesystem",
|
||||
"volumeName": "pvc-d80b25b1-141a-441b-b205-98fa2fd98b7c"
|
||||
}
|
||||
},
|
||||
"pvc_phase": "Bound"
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"image": "forgejo.coulomb.social/coulomb/informed-decision@sha256:763c36402c8be7cc4c1bd1a61623d1aff9116d52241877425b45a7018cc0883a",
|
||||
"source_revision": "3e4bcb26f8eeaa8c64345c565477b5ac8ccbb168",
|
||||
"scanner": "aquasec/trivy@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969",
|
||||
"version": "0.74.0",
|
||||
"db_metadata": {
|
||||
"Version": 2,
|
||||
"NextUpdate": "2026-10-11T18:59:50.889010572Z",
|
||||
"UpdatedAt": "2026-10-10T18:59:50.889010923Z",
|
||||
"DownloadedAt": "2026-10-10T23:32:32.380033131Z"
|
||||
},
|
||||
"suppression": false,
|
||||
"ignore_unfixed": false,
|
||||
"severity_filter": null,
|
||||
"package_count": 44,
|
||||
"findings_by_severity": {
|
||||
"MEDIUM": 1
|
||||
},
|
||||
"findings": [
|
||||
{
|
||||
"id": "CVE-2026-85091",
|
||||
"package": "zlib",
|
||||
"installed": "1.3.2-r0",
|
||||
"fixed": "1.3.2-r1",
|
||||
"severity": "MEDIUM"
|
||||
}
|
||||
],
|
||||
"coverage_limits": [
|
||||
"Alpine3.24 absent scanner EOL list; OS detector ran against Alpine3.24 repository on38OS packages",
|
||||
"Known findings asof pinnedDB, not claim absence of unknown vulnerabilities"
|
||||
],
|
||||
"high_critical": 0,
|
||||
"same_scanner_actual_base_scan_findings_identical": true,
|
||||
"base_scan_file": "base-trivy-full.json"
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
"""Pre-open schema/integrity/count proof; stdlib only, never constructs Store."""
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
import sqlite3
|
||||
|
||||
|
||||
def inspect_readonly(path):
|
||||
path = Path(path)
|
||||
if not path.is_file() or path.is_symlink():
|
||||
raise ValueError('existing nonsymlink private database required')
|
||||
with sqlite3.connect(path.resolve().as_uri() + '?mode=ro', uri=True, timeout=5) as db:
|
||||
db.execute('PRAGMA query_only=ON')
|
||||
db.execute('BEGIN')
|
||||
version = db.execute('PRAGMA user_version').fetchone()[0]
|
||||
if version != 5:
|
||||
raise ValueError('pre-open database is not schema5; refuse migration')
|
||||
if db.execute('PRAGMA integrity_check').fetchall() != [('ok',)]:
|
||||
raise ValueError('read-only integrity check refused')
|
||||
lifecycle = {name: db.execute('SELECT COUNT(*) FROM ' + table).fetchone()[0]
|
||||
for name, table in (('records', 'lifecycle_records'),
|
||||
('events', 'lifecycle_events'),
|
||||
('pending', 'lifecycle_pending'))}
|
||||
result = {'schema_version': version, 'lifecycle': lifecycle,
|
||||
'outbox': dict(db.execute('SELECT state,COUNT(*) FROM outbox GROUP BY state')),
|
||||
'submissions': dict(db.execute('SELECT state,COUNT(*) FROM submissions GROUP BY state')),
|
||||
'integrity': 'ok', 'read_only_pre_open': True, 'store_constructed': False}
|
||||
db.rollback()
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--db', type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
print(json.dumps(inspect_readonly(args.db), sort_keys=True))
|
||||
except Exception:
|
||||
raise SystemExit('read-only schema5/integrity/count gate refused; no Store/admin open') from None
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue