Compare commits
3 commits
main
...
csoc-wp001
| Author | SHA1 | Date | |
|---|---|---|---|
| 31eaa581a6 | |||
| 1139a6d30e | |||
| d308a28662 |
139 changed files with 116 additions and 9781 deletions
|
|
@ -92,35 +92,31 @@
|
|||
| task | CSOC-WP-0012-T04 | progress | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T05 | done | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T06 | done | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T07 | done | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T08 | done | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T07 | wait | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T08 | wait | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T09 | todo | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T10 | todo | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T11 | progress | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T12 | progress | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T11 | todo | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T12 | todo | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T13 | done | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T14 | done | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0012-T15 | done | — | workplans/CSOC-WP-0012-durable-recovery-service-readiness.md |
|
||||
| task | CSOC-WP-0013-T01 | done | — | workplans/CSOC-WP-0013-sharing-content-hardening.md |
|
||||
| task | CSOC-WP-0013-T02 | progress | — | workplans/CSOC-WP-0013-sharing-content-hardening.md |
|
||||
| task | CSOC-WP-0013-T03 | progress | — | workplans/CSOC-WP-0013-sharing-content-hardening.md |
|
||||
| task | CSOC-WP-0013-T03 | todo | — | workplans/CSOC-WP-0013-sharing-content-hardening.md |
|
||||
| task | CSOC-WP-0013-T04 | done | — | workplans/CSOC-WP-0013-sharing-content-hardening.md |
|
||||
| task | CSOC-WP-0013-T05 | progress | — | workplans/CSOC-WP-0013-sharing-content-hardening.md |
|
||||
| task | CSOC-WP-0013-T06 | progress | — | workplans/CSOC-WP-0013-sharing-content-hardening.md |
|
||||
| task | CSOC-WP-0013-T05 | todo | — | workplans/CSOC-WP-0013-sharing-content-hardening.md |
|
||||
| task | CSOC-WP-0014-T01 | progress | — | workplans/CSOC-WP-0014-cohort-transfer-bubble-offramp.md |
|
||||
| task | CSOC-WP-0014-T02 | todo | — | workplans/CSOC-WP-0014-cohort-transfer-bubble-offramp.md |
|
||||
| task | CSOC-WP-0014-T03 | wait | — | workplans/CSOC-WP-0014-cohort-transfer-bubble-offramp.md |
|
||||
| task | CSOC-WP-0014-T04 | done | — | workplans/CSOC-WP-0014-cohort-transfer-bubble-offramp.md |
|
||||
| task | CSOC-WP-0014-T05 | done | — | workplans/CSOC-WP-0014-cohort-transfer-bubble-offramp.md |
|
||||
| task | CSOC-WP-0014-T06 | progress | — | workplans/CSOC-WP-0014-cohort-transfer-bubble-offramp.md |
|
||||
| task | CSOC-WP-0014-T07 | progress | — | workplans/CSOC-WP-0014-cohort-transfer-bubble-offramp.md |
|
||||
| task | CSOC-WP-0014-T08 | done | — | workplans/CSOC-WP-0014-cohort-transfer-bubble-offramp.md |
|
||||
| task | CSOC-WP-0014-T07 | todo | — | workplans/CSOC-WP-0014-cohort-transfer-bubble-offramp.md |
|
||||
| task | CSOC-WP-0015-T01 | done | — | workplans/CSOC-WP-0015-communication-runtime-acceptance.md |
|
||||
| task | CSOC-WP-0015-T02 | progress | — | workplans/CSOC-WP-0015-communication-runtime-acceptance.md |
|
||||
| task | CSOC-WP-0015-T03 | done | — | workplans/CSOC-WP-0015-communication-runtime-acceptance.md |
|
||||
| task | CSOC-WP-0015-T04 | done | — | workplans/CSOC-WP-0015-communication-runtime-acceptance.md |
|
||||
| task | CSOC-WP-0015-T05 | todo | — | workplans/CSOC-WP-0015-communication-runtime-acceptance.md |
|
||||
| task | CSOC-WP-0015-T06 | progress | — | workplans/CSOC-WP-0015-communication-runtime-acceptance.md |
|
||||
| task | CSOC-WP-0015-T06 | todo | — | workplans/CSOC-WP-0015-communication-runtime-acceptance.md |
|
||||
| task | CSOC-WP-0016-T01 | done | — | workplans/CSOC-WP-0016-mfa-setup-link.md |
|
||||
| task | CSOC-WP-0017-T01 | done | — | workplans/CSOC-WP-0017-wave2-resource-right-sizing.md |
|
||||
| intake | CSOC-IN-0001 | closed | blue | docs/intakes/csoc-residuals.md |
|
||||
|
|
|
|||
|
|
@ -143,18 +143,6 @@ def prepare_bundle(spaces, articles, *, inventory_spaces=None):
|
|||
detail["relations"]["context_custom_article"] = normalize_ref(parent) if parent else None
|
||||
if article.get("hasattachments_boolean"):
|
||||
detail["review_flags"].append("attachment_records_require_capture")
|
||||
if "_list_custom_scrap" in article:
|
||||
# Bubble may return a deferred LOOKUP string instead of the actual
|
||||
# list. Preserve it privately; it is not a captured scrap record or
|
||||
# an article ID that may be traversed as a chunk.
|
||||
raw_scraps = article["_list_custom_scrap"]
|
||||
detail["scrap_relation"] = {
|
||||
"raw": raw_scraps,
|
||||
"state": "observed_empty_list" if raw_scraps == [] else "unresolved",
|
||||
"records_captured": False,
|
||||
}
|
||||
if raw_scraps != []:
|
||||
detail["review_flags"].append("scrap_relation_records_require_capture")
|
||||
article_details[identity] = detail
|
||||
|
||||
for entry in plan["spaces"]:
|
||||
|
|
|
|||
|
|
@ -1,181 +0,0 @@
|
|||
"""Read-only classification of uncertain corpus imports; never repairs a store."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import fcntl
|
||||
import hashlib
|
||||
import os
|
||||
import uuid
|
||||
from contextlib import contextmanager
|
||||
|
||||
from django.db import connection, transaction
|
||||
|
||||
from . import pageops
|
||||
from .import_receipts import digest, private_path, tree_digest
|
||||
from .import_tree import _metadata, _source_dates
|
||||
from .models import Space, SpaceMembership
|
||||
|
||||
|
||||
@contextmanager
|
||||
def existing_lock(path):
|
||||
private_path(path)
|
||||
# Inspection never creates a lock, journal, content root or receipt directory.
|
||||
fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW)
|
||||
try:
|
||||
try:
|
||||
fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except BlockingIOError as exc:
|
||||
raise ValueError("Import or content writer is active; inspect after it stops") from exc
|
||||
yield
|
||||
finally:
|
||||
os.close(fd)
|
||||
|
||||
|
||||
def expected_metadata(tree, tenant, slug, grants):
|
||||
title, description, visual = _metadata(tree, slug)
|
||||
values = {
|
||||
"tenant_id": tenant,
|
||||
"slug": slug,
|
||||
"title": title,
|
||||
"description": description,
|
||||
"visual": visual,
|
||||
"is_active": True,
|
||||
"content_root": "pages",
|
||||
"default_branch": "main",
|
||||
"forgejo_owner": "",
|
||||
"forgejo_repo": "",
|
||||
"created_by_id": next(m.pk for m, role in grants if role == SpaceMembership.Role.OWNER),
|
||||
}
|
||||
index = tree / "pages/index.md"
|
||||
if index.is_file():
|
||||
meta, _ = pageops.parse_frontmatter(index.read_text(encoding="utf-8"))
|
||||
values.update(_source_dates(meta))
|
||||
return values
|
||||
|
||||
|
||||
def observe_unit(receipts, index, unit):
|
||||
tree, tenant, slug, grants = receipts.plan[index]
|
||||
rows = list(Space.objects.filter(slug=slug).values())
|
||||
destination = pageops.space_dir(slug)
|
||||
if destination.is_symlink() or any(p.is_symlink() for p in destination.parents):
|
||||
raise ValueError("Destination must not contain symlinks")
|
||||
files_hash = tree_digest(destination) if destination.is_dir() else None
|
||||
grant_rows = sorted(
|
||||
(str(member), role)
|
||||
for member, role in SpaceMembership.objects.filter(space__slug=slug).values_list(
|
||||
"member_id", "role"
|
||||
)
|
||||
)
|
||||
result = {
|
||||
"index": index,
|
||||
"checkpoint_state": unit.get("state"),
|
||||
"sql_rows": len(rows),
|
||||
"published_tree_present": destination.exists(),
|
||||
"files_sha256": files_hash,
|
||||
"space_sha256": digest(rows),
|
||||
"grants_sha256": digest(grant_rows),
|
||||
}
|
||||
state = unit.get("state")
|
||||
if state == "completed":
|
||||
result["classification"] = (
|
||||
"completed_identity_present"
|
||||
if len(rows) == 1
|
||||
and str(rows[0]["id"]) == unit.get("space_id")
|
||||
and rows[0]["tenant_id"] == tenant
|
||||
else "completed_identity_changed"
|
||||
)
|
||||
return result
|
||||
if state not in {"pending", "started"}:
|
||||
raise ValueError("Invalid checkpoint state")
|
||||
if state == "pending":
|
||||
result["classification"] = (
|
||||
"pending_destination_occupied" if rows or destination.exists() else "pending"
|
||||
)
|
||||
return result
|
||||
try:
|
||||
reserved = uuid.UUID(unit["space_id"])
|
||||
except (KeyError, ValueError, TypeError, AttributeError):
|
||||
result["classification"] = "started_identity_unbound"
|
||||
return result
|
||||
if not rows and not destination.exists():
|
||||
result["classification"] = "no_sql_or_published_tree"
|
||||
return result
|
||||
if not rows:
|
||||
result["classification"] = "files_without_sql"
|
||||
return result
|
||||
if len(rows) != 1 or rows[0]["id"] != reserved or rows[0]["tenant_id"] != tenant:
|
||||
result["classification"] = "foreign_destination_identity"
|
||||
return result
|
||||
if not destination.exists():
|
||||
result["classification"] = "sql_without_files"
|
||||
return result
|
||||
wanted = expected_metadata(tree, tenant, slug, grants)
|
||||
metadata_match = all(rows[0][key] == value for key, value in wanted.items())
|
||||
grants_match = grant_rows == sorted((str(m.pk), role) for m, role in grants)
|
||||
# The importer copies root Markdown pages and the assets subtree. Extra
|
||||
# source files, or a synthesized index, cannot be called byte-exact here.
|
||||
files_match = files_hash == receipts.source_hashes[index]
|
||||
result.update(
|
||||
metadata_matches=metadata_match,
|
||||
grants_match=grants_match,
|
||||
source_files_match=files_match,
|
||||
original_space_date_checked="created_at" in wanted,
|
||||
)
|
||||
result["classification"] = (
|
||||
"reserved_destination_matches_source"
|
||||
if metadata_match and grants_match and files_match
|
||||
else "reserved_destination_differs"
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
@contextmanager
|
||||
def inspection_session(receipts):
|
||||
if connection.in_atomic_block or not connection.get_autocommit():
|
||||
raise ValueError("Inspection requires an independent read transaction")
|
||||
private_path(receipts.path)
|
||||
if not receipts.path.is_file():
|
||||
raise ValueError("An existing checkpoint is required for inspection")
|
||||
with (
|
||||
existing_lock(receipts.directory / ".lock"),
|
||||
existing_lock(pageops.content_root() / ".writer.lock"),
|
||||
):
|
||||
checkpoint = receipts.path.read_bytes()
|
||||
data = receipts.read()
|
||||
if any(not isinstance(unit, dict) for unit in data["spaces"]):
|
||||
raise ValueError("Invalid space checkpoint")
|
||||
with transaction.atomic():
|
||||
if connection.vendor == "postgresql":
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute("SET TRANSACTION ISOLATION LEVEL REPEATABLE READ, READ ONLY")
|
||||
first = [observe_unit(receipts, i, unit) for i, unit in enumerate(data["spaces"])]
|
||||
second = [observe_unit(receipts, i, unit) for i, unit in enumerate(data["spaces"])]
|
||||
if first != second or checkpoint != receipts.path.read_bytes():
|
||||
raise ValueError("Destination or checkpoint changed during inspection")
|
||||
if any(
|
||||
tree_digest(tree) != checksum
|
||||
for (tree, _, _, _), checksum in zip(
|
||||
receipts.plan, receipts.source_hashes, strict=True
|
||||
)
|
||||
):
|
||||
raise ValueError("Source changed during inspection")
|
||||
staging = list((pageops.content_root() / "spaces").glob(".import-*"))
|
||||
result = {
|
||||
"schema": "coulomb.corpus-import-inspection.v1",
|
||||
"binding": receipts.binding,
|
||||
"checkpoint_sha256": hashlib.sha256(checkpoint).hexdigest(),
|
||||
"spaces": first,
|
||||
"unattributed_staging_entries": len(staging),
|
||||
"read_only": True,
|
||||
"external_writer_fence_verified": False,
|
||||
"checkpoint_completed": False,
|
||||
"retry_authorized": False,
|
||||
"data_restored": False,
|
||||
}
|
||||
result["inspection_sha256"] = digest(result)
|
||||
yield result, data
|
||||
|
||||
|
||||
def inspect(receipts):
|
||||
with inspection_session(receipts) as (result, _):
|
||||
return result
|
||||
|
|
@ -1,235 +0,0 @@
|
|||
"""Opt-in corpus checkpoints; no automatic repair of uncertain DB/file commits.
|
||||
|
||||
The caller still owns source freezing, external writer fencing, paired backups
|
||||
and admission. A started receipt survives a crash and stops automatic retries.
|
||||
Completed receipts skip their space, preserving any subsequent local edits.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import fcntl
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import stat
|
||||
import tempfile
|
||||
import uuid
|
||||
from contextlib import contextmanager
|
||||
from pathlib import Path
|
||||
|
||||
from django.db import connection
|
||||
|
||||
from . import pageops
|
||||
from .import_tree import import_space_tree
|
||||
from .models import Space, SpaceMembership
|
||||
|
||||
SCHEMA = "coulomb.corpus-import-checkpoint.v1"
|
||||
|
||||
|
||||
def digest(value):
|
||||
return hashlib.sha256(json.dumps(value, sort_keys=True, default=str).encode()).hexdigest()
|
||||
|
||||
|
||||
def tree_digest(tree):
|
||||
files = []
|
||||
for path in sorted(tree.rglob("*")):
|
||||
mode = path.lstat().st_mode
|
||||
if stat.S_ISDIR(mode):
|
||||
continue
|
||||
if not stat.S_ISREG(mode):
|
||||
raise ValueError("Import tree must contain only real files and directories")
|
||||
with path.open("rb") as stream:
|
||||
checksum = hashlib.file_digest(stream, "sha256").hexdigest()
|
||||
files.append([path.relative_to(tree).as_posix(), checksum])
|
||||
return digest(files)
|
||||
|
||||
|
||||
def private_path(path, *, directory=False):
|
||||
if any(p.is_symlink() for p in (path, *path.parents)):
|
||||
raise ValueError("Receipt path must not contain symlinks")
|
||||
if path.exists():
|
||||
info = path.stat()
|
||||
expected = stat.S_ISDIR if directory else stat.S_ISREG
|
||||
if (not expected(info.st_mode) or info.st_uid != os.getuid()
|
||||
or info.st_mode & 0o077 or (not directory and info.st_nlink != 1)):
|
||||
raise ValueError("Receipt path must be private and owned by this operator")
|
||||
|
||||
|
||||
def sync_directory(path):
|
||||
fd = os.open(path, os.O_RDONLY | os.O_DIRECTORY | os.O_NOFOLLOW)
|
||||
try:
|
||||
os.fsync(fd)
|
||||
finally:
|
||||
os.close(fd)
|
||||
|
||||
|
||||
def sync_tree(tree):
|
||||
# Content must be durable before its completed receipt. The underlying
|
||||
# importer commits SQL first; a crash before this finishes remains started.
|
||||
directories = [tree]
|
||||
for path in tree.rglob("*"):
|
||||
mode = path.lstat().st_mode
|
||||
if stat.S_ISDIR(mode):
|
||||
directories.append(path)
|
||||
elif stat.S_ISREG(mode):
|
||||
fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW)
|
||||
try:
|
||||
os.fsync(fd)
|
||||
finally:
|
||||
os.close(fd)
|
||||
else:
|
||||
raise ValueError("Imported tree contains an unsupported file")
|
||||
for directory in sorted(directories, key=lambda p: len(p.parts), reverse=True):
|
||||
sync_directory(directory)
|
||||
sync_directory(tree.parent)
|
||||
sync_directory(tree.parent.parent)
|
||||
|
||||
|
||||
class CorpusReceipts:
|
||||
def __init__(self, directory, manifest, plan):
|
||||
self.directory = Path(directory).expanduser().absolute()
|
||||
private_path(self.directory, directory=True)
|
||||
self.directory = self.directory.resolve()
|
||||
root = pageops.content_root().resolve()
|
||||
for protected in (root, *(tree for tree, _, _, _ in plan)):
|
||||
if (self.directory.is_relative_to(protected)
|
||||
or protected.is_relative_to(self.directory)):
|
||||
raise ValueError("Receipt directory must be separate from source and content")
|
||||
self.path = self.directory / "checkpoint.json"
|
||||
self.plan = plan
|
||||
self.source_hashes = [tree_digest(tree) for tree, _, _, _ in plan]
|
||||
self.binding = digest({
|
||||
"manifest": hashlib.sha256(Path(manifest).read_bytes()).hexdigest(),
|
||||
"content_root": str(root),
|
||||
"database": {key: connection.settings_dict.get(key)
|
||||
for key in ("ENGINE", "HOST", "PORT", "NAME", "USER")},
|
||||
"units": [
|
||||
[str(tree), tenant, slug, source_hash,
|
||||
[[str(member.pk), role] for member, role in grants]]
|
||||
for (tree, tenant, slug, grants), source_hash
|
||||
in zip(plan, self.source_hashes, strict=True)
|
||||
],
|
||||
})
|
||||
|
||||
def read(self):
|
||||
private_path(self.directory, directory=True)
|
||||
private_path(self.path)
|
||||
if not self.path.exists():
|
||||
return {"schema": SCHEMA, "binding": self.binding,
|
||||
"spaces": [{"state": "pending"} for _ in self.plan]}
|
||||
data = json.loads(self.path.read_bytes())
|
||||
if (not isinstance(data, dict) or data.get("schema") != SCHEMA
|
||||
or data.get("binding") != self.binding
|
||||
or not isinstance(data.get("spaces"), list)
|
||||
or len(data["spaces"]) != len(self.plan)):
|
||||
raise ValueError("Receipt does not match this corpus, mapping or destination")
|
||||
return data
|
||||
|
||||
def validate(self, data):
|
||||
for unit, (_, tenant, slug, _) in zip(data["spaces"], self.plan, strict=True):
|
||||
if not isinstance(unit, dict):
|
||||
raise ValueError("Invalid space checkpoint")
|
||||
state = unit.get("state")
|
||||
if state == "completed":
|
||||
try:
|
||||
uuid.UUID(unit["space_id"])
|
||||
if any(not re.fullmatch(r"[a-f0-9]{64}", unit[key])
|
||||
for key in ("files_sha256", "space_sha256", "grants_sha256")):
|
||||
raise ValueError
|
||||
if any(type(unit[key]) is not int or unit[key] < 0
|
||||
for key in ("pages", "assets")):
|
||||
raise ValueError
|
||||
except (KeyError, TypeError, ValueError, AttributeError) as exc:
|
||||
raise ValueError("Invalid completed space checkpoint") from exc
|
||||
# Never recreate an independently deleted/replaced space or infer
|
||||
# that a later edit or grant change should be reversed.
|
||||
if not Space.objects.filter(pk=unit.get("space_id"), tenant_id=tenant,
|
||||
slug=slug).exists():
|
||||
raise ValueError("Completed space identity changed; reconciliation required")
|
||||
elif state == "pending":
|
||||
if (Space.objects.filter(slug=slug).exists()
|
||||
or pageops.space_dir(slug).exists()):
|
||||
raise ValueError("Unreceipted destination exists; reconciliation required")
|
||||
else:
|
||||
raise ValueError(
|
||||
"Uncertain space import; reconcile the started receipt before retry")
|
||||
|
||||
def save(self, data):
|
||||
private_path(self.path)
|
||||
fd, temporary = tempfile.mkstemp(prefix=".checkpoint-", dir=self.directory)
|
||||
try:
|
||||
with os.fdopen(fd, "w") as stream:
|
||||
json.dump(data, stream, sort_keys=True)
|
||||
stream.flush()
|
||||
os.fsync(stream.fileno())
|
||||
os.replace(temporary, self.path)
|
||||
sync_directory(self.directory)
|
||||
finally:
|
||||
if os.path.exists(temporary):
|
||||
os.unlink(temporary)
|
||||
|
||||
@contextmanager
|
||||
def lock(self):
|
||||
# Parent must already exist; do not chmod an operator's existing path.
|
||||
self.directory.mkdir(mode=0o700, exist_ok=True)
|
||||
private_path(self.directory, directory=True)
|
||||
sync_directory(self.directory.parent)
|
||||
lock = self.directory / ".lock"
|
||||
private_path(lock)
|
||||
fd = os.open(lock, os.O_CREAT | os.O_RDWR | os.O_NOFOLLOW, 0o600)
|
||||
try:
|
||||
try:
|
||||
fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except BlockingIOError as exc:
|
||||
raise ValueError("Another importer owns this receipt directory") from exc
|
||||
yield
|
||||
finally:
|
||||
os.close(fd)
|
||||
|
||||
def run(self):
|
||||
if connection.in_atomic_block or not connection.get_autocommit():
|
||||
raise ValueError("Receipted import requires independent database commits")
|
||||
self.validate(self.read()) # Invalid inputs remain write-free.
|
||||
with self.lock(), pageops.content_write_lock():
|
||||
data = self.read()
|
||||
self.validate(data)
|
||||
pageops.recover_interrupted_content()
|
||||
self.save(data)
|
||||
imported = skipped = 0
|
||||
for index, (tree, tenant, slug, grants) in enumerate(self.plan):
|
||||
if data["spaces"][index]["state"] == "completed":
|
||||
skipped += 1
|
||||
continue
|
||||
if tree_digest(tree) != self.source_hashes[index]:
|
||||
raise ValueError("Source changed after preflight")
|
||||
# Persist uncertainty BEFORE the first import write. Any failure,
|
||||
# including a lost commit reply or receipt fsync, stays uncertain.
|
||||
space_id = uuid.uuid4()
|
||||
data["spaces"][index] = {"state": "started", "space_id": str(space_id)}
|
||||
self.save(data)
|
||||
report = import_space_tree(tree, tenant_id=tenant, slug=slug,
|
||||
memberships=grants, replace=False,
|
||||
new_space_id=space_id)
|
||||
if tree_digest(tree) != self.source_hashes[index]:
|
||||
raise ValueError("Source changed during import; reconciliation required")
|
||||
space = Space.objects.get(tenant_id=tenant, slug=slug)
|
||||
if space.pk != space_id:
|
||||
raise ValueError("Imported space identity changed; reconciliation required")
|
||||
observed_grants = sorted((str(m), role) for m, role in
|
||||
SpaceMembership.objects.filter(space=space).values_list("member_id", "role"))
|
||||
if observed_grants != sorted((str(m.pk), role) for m, role in grants):
|
||||
raise ValueError("Imported grants differ from the reviewed mapping")
|
||||
sync_tree(pageops.space_dir(slug))
|
||||
# A fingerprint records the committed return, not acceptance of
|
||||
# source fidelity or authorization to import more cohorts.
|
||||
data["spaces"][index] = {
|
||||
"state": "completed", "space_id": str(space.pk),
|
||||
"files_sha256": tree_digest(pageops.space_dir(slug)),
|
||||
"space_sha256": digest(Space.objects.filter(pk=space.pk).values().get()),
|
||||
"grants_sha256": digest(observed_grants),
|
||||
"pages": report.pages_copied, "assets": report.assets_copied,
|
||||
}
|
||||
self.save(data)
|
||||
imported += 1
|
||||
return imported, skipped
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
"""Explicit checkpoint completion for an exactly observed, already committed import.
|
||||
|
||||
No SQL/content repair or automatic retry. The deployment owner still supplies
|
||||
admission, a paired backup and an external writer fence before invoking this.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import re
|
||||
|
||||
from . import pageops
|
||||
from .import_inspection import inspection_session, observe_unit
|
||||
from .import_receipts import digest, sync_tree, tree_digest
|
||||
from .models import Space
|
||||
|
||||
|
||||
def complete_matching_commit(receipts, *, index, expected_inspection):
|
||||
if (type(index) is not int or not 0 <= index < len(receipts.plan)
|
||||
or not isinstance(expected_inspection, str)
|
||||
or not re.fullmatch(r"[a-f0-9]{64}", expected_inspection)):
|
||||
raise ValueError("An exact inspection digest and valid unit index are required")
|
||||
with inspection_session(receipts) as (inspection, data):
|
||||
if inspection["inspection_sha256"] != expected_inspection:
|
||||
raise ValueError("Inspection changed; retain evidence and review again")
|
||||
observed = inspection["spaces"][index]
|
||||
if observed["classification"] != "reserved_destination_matches_source":
|
||||
raise ValueError("Only an exact reserved committed import can be completed")
|
||||
if inspection["unattributed_staging_entries"]:
|
||||
raise ValueError("Unattributed staging requires owner reconciliation first")
|
||||
tree, _, slug, _ = receipts.plan[index]
|
||||
prior_unit = data["spaces"][index]
|
||||
row = Space.objects.filter(pk=prior_unit["space_id"]).values().get()
|
||||
if digest([row]) != observed["space_sha256"]:
|
||||
raise ValueError("Observed SQL identity changed")
|
||||
# The original importer can die before fsync or its completed checkpoint.
|
||||
# Make the matching published tree durable before acknowledging it.
|
||||
sync_tree(pageops.space_dir(slug))
|
||||
if (observe_unit(receipts, index, prior_unit) != observed
|
||||
or tree_digest(tree) != receipts.source_hashes[index]
|
||||
or hashlib.sha256(receipts.path.read_bytes()).hexdigest()
|
||||
!= inspection["checkpoint_sha256"]):
|
||||
raise ValueError("State changed before checkpoint completion")
|
||||
data["spaces"][index] = {
|
||||
"state": "completed",
|
||||
"space_id": prior_unit["space_id"],
|
||||
"files_sha256": observed["files_sha256"],
|
||||
"space_sha256": digest(row),
|
||||
"grants_sha256": observed["grants_sha256"],
|
||||
"pages": len(list((tree / "pages").glob("*.md"))),
|
||||
"assets": sum(p.is_file() for p in (tree / "assets").rglob("*")),
|
||||
"reconciliation": {
|
||||
"schema": "coulomb.corpus-matching-commit-reconciliation.v1",
|
||||
"prior_unit": prior_unit,
|
||||
"inspection": inspection,
|
||||
},
|
||||
}
|
||||
# Existing atomic replacement + fsync keeps the prior started checkpoint
|
||||
# or the completed one with its evidence. Lost output requires readback;
|
||||
# replay of the old inspection cannot acknowledge a different state.
|
||||
receipts.save(data)
|
||||
return {
|
||||
"schema": "coulomb.corpus-matching-commit-return.v1",
|
||||
"status": "matching_commit_checkpoint_completed",
|
||||
"index": index,
|
||||
"inspection_sha256": expected_inspection,
|
||||
"checkpoint_sha256": hashlib.sha256(receipts.path.read_bytes()).hexdigest(),
|
||||
"checkpoint_completed": True,
|
||||
"sql_modified": False,
|
||||
"content_modified": False,
|
||||
"data_restored": False,
|
||||
"external_writer_fence_verified": False,
|
||||
"remaining_import_authorized": False,
|
||||
}
|
||||
|
|
@ -4,7 +4,6 @@ from __future__ import annotations
|
|||
|
||||
import shutil
|
||||
import tempfile
|
||||
import uuid
|
||||
from dataclasses import dataclass, field
|
||||
from pathlib import Path
|
||||
|
||||
|
|
@ -64,15 +63,11 @@ def _metadata(tree: Path, slug: str, title: str | None = None) -> tuple[str, str
|
|||
def validate_space_tree(
|
||||
tree: Path, *, tenant_id: str, slug: str | None = None,
|
||||
member: Member | None = None, replace: bool = False, title: str | None = None,
|
||||
check_existing: bool = True,
|
||||
) -> tuple[Path, str]:
|
||||
"""Preflight used by dry-run and execution, before any content writes.
|
||||
|
||||
CONTENT_ROOT is instance-local and keyed by slug, so importing a slug
|
||||
already owned by another tenant is unsupported and must fail closed.
|
||||
Receipt-aware preflight may set check_existing=False to inspect sources for
|
||||
completed units; it must validate destination identities separately. The
|
||||
actual importer always performs the default destination checks again.
|
||||
"""
|
||||
tree = tree.expanduser()
|
||||
if tree.is_symlink():
|
||||
|
|
@ -120,9 +115,9 @@ def validate_space_tree(
|
|||
for path in (root, root / "spaces", dest):
|
||||
if path.is_symlink():
|
||||
raise pageops.PageOpsError("Destination must not be a symlink")
|
||||
if check_existing and dest.exists() and not replace:
|
||||
if dest.exists() and not replace:
|
||||
raise pageops.PageOpsError("Destination already exists; pass replace=True to overwrite")
|
||||
if check_existing and dest.exists() and pageops.page_aliases(space_slug):
|
||||
if dest.exists() and pageops.page_aliases(space_slug):
|
||||
raise pageops.PageOpsError(
|
||||
"Retained page addresses need reconciliation before replacing content"
|
||||
)
|
||||
|
|
@ -133,13 +128,7 @@ def import_space_tree(
|
|||
tree: Path, *, tenant_id: str, slug: str | None = None,
|
||||
member: Member | None = None, title: str | None = None,
|
||||
replace: bool = False, memberships: list[tuple[Member, str]] | None = None,
|
||||
new_space_id: uuid.UUID | None = None,
|
||||
) -> ImportReport:
|
||||
if new_space_id is not None:
|
||||
if replace or not isinstance(new_space_id, uuid.UUID):
|
||||
raise pageops.PageOpsError("Reserved import identity requires a new UUID space")
|
||||
if Space.objects.filter(pk=new_space_id).exists():
|
||||
raise pageops.PageOpsError("Reserved import identity already exists")
|
||||
# Invalid proposals remain write-free, including lock-file creation.
|
||||
validate_space_tree(tree, tenant_id=tenant_id, slug=slug, member=member,
|
||||
replace=replace, title=title)
|
||||
|
|
@ -147,8 +136,7 @@ def import_space_tree(
|
|||
if mapped.tenant_id != tenant_id or role not in SpaceMembership.Role.values:
|
||||
raise pageops.PageOpsError("Invalid membership tenant or role")
|
||||
return _import_space_tree(tree, tenant_id=tenant_id, slug=slug, member=member,
|
||||
title=title, replace=replace, memberships=memberships,
|
||||
new_space_id=new_space_id)
|
||||
title=title, replace=replace, memberships=memberships)
|
||||
|
||||
|
||||
@pageops.content_writer
|
||||
|
|
@ -156,7 +144,6 @@ def _import_space_tree(
|
|||
tree: Path, *, tenant_id: str, slug: str | None = None,
|
||||
member: Member | None = None, title: str | None = None,
|
||||
replace: bool = False, memberships: list[tuple[Member, str]] | None = None,
|
||||
new_space_id: uuid.UUID | None = None,
|
||||
) -> ImportReport:
|
||||
"""Stage content, then publish with DB writes; restore on ordinary errors.
|
||||
|
||||
|
|
@ -203,22 +190,15 @@ def _import_space_tree(
|
|||
try:
|
||||
with transaction.atomic():
|
||||
try:
|
||||
defaults = {"title": display_title, "description": abstractor,
|
||||
"visual": visual, "is_active": True,
|
||||
"content_root": "pages", "default_branch": "main"}
|
||||
if new_space_id is not None:
|
||||
# A receipted attempt owns only its pre-recorded UUID.
|
||||
# Never update a row created concurrently at this slug.
|
||||
space = Space.objects.create(id=new_space_id, tenant_id=tenant_id,
|
||||
slug=space_slug, **defaults)
|
||||
created = True
|
||||
else:
|
||||
space, created = Space.objects.update_or_create(
|
||||
tenant_id=tenant_id, slug=space_slug, defaults=defaults)
|
||||
space, created = Space.objects.update_or_create(
|
||||
tenant_id=tenant_id, slug=space_slug,
|
||||
defaults={"title": display_title, "description": abstractor,
|
||||
"visual": visual, "is_active": True,
|
||||
"content_root": "pages", "default_branch": "main"},
|
||||
)
|
||||
except IntegrityError as exc:
|
||||
raise pageops.PageOpsError(
|
||||
"Reserved import identity or destination already exists"
|
||||
if new_space_id is not None else "Content slug belongs to another tenant"
|
||||
"Content slug belongs to another tenant"
|
||||
) from exc
|
||||
report.space_created = created
|
||||
report.space_updated = not created
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ from django.core.management.base import BaseCommand, CommandError
|
|||
|
||||
from coulomb_social.apps.members.models import Member
|
||||
from coulomb_social.apps.spaces import pageops
|
||||
from coulomb_social.apps.spaces.import_receipts import CorpusReceipts
|
||||
from coulomb_social.apps.spaces.import_tree import import_space_tree, validate_space_tree
|
||||
from coulomb_social.apps.spaces.models import SpaceMembership
|
||||
|
||||
|
|
@ -21,18 +20,10 @@ class Command(BaseCommand):
|
|||
parser.add_argument("manifest")
|
||||
parser.add_argument("--dry-run", action="store_true")
|
||||
parser.add_argument("--replace", action="store_true")
|
||||
parser.add_argument("--receipt-dir", help="Private durable checkpoints for new spaces only")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
if options["receipt_dir"] and options["replace"]:
|
||||
raise CommandError("Receipted imports cannot replace existing spaces")
|
||||
try:
|
||||
plan = self.preflight(Path(options["manifest"]), replace=options["replace"],
|
||||
check_existing=not options["receipt_dir"])
|
||||
receipts = None
|
||||
if options["receipt_dir"]:
|
||||
receipts = CorpusReceipts(options["receipt_dir"], options["manifest"], plan)
|
||||
receipts.validate(receipts.read())
|
||||
plan = self.preflight(Path(options["manifest"]), replace=options["replace"])
|
||||
except (ValueError, KeyError, TypeError, OSError, pageops.PageOpsError) as exc:
|
||||
raise CommandError(f"Manifest preflight failed: {exc}") from exc
|
||||
pages = sum(len(list((tree / "pages").glob("*.md"))) for tree, _, _, _ in plan)
|
||||
|
|
@ -40,17 +31,6 @@ class Command(BaseCommand):
|
|||
if options["dry_run"]:
|
||||
self.stdout.write("Dry run — no writes")
|
||||
return
|
||||
if receipts is not None:
|
||||
try:
|
||||
imported, skipped = receipts.run()
|
||||
except Exception as exc:
|
||||
raise CommandError(
|
||||
"Receipted import stopped; inspect the private checkpoint before retrying. "
|
||||
"A started space has an uncertain outcome and must be reconciled."
|
||||
) from exc
|
||||
self.stdout.write(self.style.SUCCESS(
|
||||
f"Imported {imported} space(s); skipped {skipped} completed space(s)"))
|
||||
return
|
||||
completed = 0
|
||||
for tree, tenant, slug, grants in plan:
|
||||
try:
|
||||
|
|
@ -72,7 +52,7 @@ class Command(BaseCommand):
|
|||
)
|
||||
self.stdout.write(self.style.SUCCESS(f"Imported {completed} space(s)"))
|
||||
|
||||
def preflight(self, manifest: Path, *, replace: bool, check_existing: bool = True):
|
||||
def preflight(self, manifest: Path, *, replace: bool):
|
||||
manifest = manifest.expanduser().resolve()
|
||||
data = json.loads(manifest.read_text(encoding="utf-8"))
|
||||
if (not isinstance(data, dict) or data.get("version") != 1
|
||||
|
|
@ -91,7 +71,6 @@ class Command(BaseCommand):
|
|||
tree = manifest.parent / tree
|
||||
tree, slug = validate_space_tree(
|
||||
tree, tenant_id=tenant, slug=entry.get("slug"), replace=replace,
|
||||
check_existing=check_existing,
|
||||
)
|
||||
if slug in slugs:
|
||||
raise ValueError("Duplicate destination content slug")
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
"""Inspect uncertain receipt-backed imports without changing content or checkpoints."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from coulomb_social.apps.spaces import pageops
|
||||
from coulomb_social.apps.spaces.import_inspection import inspect
|
||||
from coulomb_social.apps.spaces.import_receipts import CorpusReceipts
|
||||
from coulomb_social.apps.spaces.management.commands.import_content_corpus import (
|
||||
Command as ImportCommand,
|
||||
)
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Classify an existing corpus checkpoint; never repair or authorize a retry"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("manifest")
|
||||
parser.add_argument("--receipt-dir", required=True)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
try:
|
||||
manifest = Path(options["manifest"])
|
||||
plan = ImportCommand().preflight(manifest, replace=False, check_existing=False)
|
||||
receipts = CorpusReceipts(options["receipt_dir"], manifest, plan)
|
||||
result = inspect(receipts)
|
||||
except (ValueError, KeyError, TypeError, OSError, pageops.PageOpsError) as exc:
|
||||
# Do not disclose source paths, identities or row contents in diagnostics.
|
||||
raise CommandError(
|
||||
"Corpus inspection refused; retain the checkpoint and inspect privately"
|
||||
) from exc
|
||||
self.stdout.write(json.dumps(result, sort_keys=True))
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
"""Record one matching committed import; never restore or delete application data."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from coulomb_social.apps.spaces.import_receipts import CorpusReceipts
|
||||
from coulomb_social.apps.spaces.import_reconciliation import complete_matching_commit
|
||||
from coulomb_social.apps.spaces.management.commands.import_content_corpus import (
|
||||
Command as ImportCommand,
|
||||
)
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Complete one exact matching import checkpoint after owner reconciliation review"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument("manifest")
|
||||
parser.add_argument("--receipt-dir", required=True)
|
||||
parser.add_argument("--unit-index", type=int, required=True)
|
||||
parser.add_argument("--expect-inspection", required=True)
|
||||
parser.add_argument("--complete-matching-commit", action="store_true", required=True)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
if not options["complete_matching_commit"]:
|
||||
raise CommandError("Explicit matching-commit completion is required")
|
||||
try:
|
||||
manifest = Path(options["manifest"])
|
||||
plan = ImportCommand().preflight(manifest, replace=False, check_existing=False)
|
||||
receipts = CorpusReceipts(options["receipt_dir"], manifest, plan)
|
||||
result = complete_matching_commit(
|
||||
receipts, index=options["unit_index"],
|
||||
expected_inspection=options["expect_inspection"],
|
||||
)
|
||||
except Exception as exc:
|
||||
# Failure can follow durable checkpoint replacement. Never advise replay
|
||||
# or disclose source paths, identities or SQL values in the error.
|
||||
raise CommandError(
|
||||
"Reconciliation stopped; inspect the retained checkpoint before further action"
|
||||
) from exc
|
||||
self.stdout.write(json.dumps(result, sort_keys=True))
|
||||
|
|
@ -34,11 +34,6 @@ def audit_body(body: str):
|
|||
rendered = render_markdown(body)
|
||||
before, after = _Structure(raw), _Structure(rendered)
|
||||
removed_attrs = before.attributes - after.attributes
|
||||
reference_attributes = {"href", "src", "poster", "data", "action"}
|
||||
before_refs = Counter({key: count for key, count in before.attributes.items()
|
||||
if key[1] in reference_attributes})
|
||||
after_refs = Counter({key: count for key, count in after.attributes.items()
|
||||
if key[1] in reference_attributes})
|
||||
text_changed = " ".join("".join(before.text).split()) != (
|
||||
" ".join("".join(after.text).split()))
|
||||
markup_changed = before.tags != after.tags or before.attributes != after.attributes
|
||||
|
|
@ -48,11 +43,6 @@ def audit_body(body: str):
|
|||
"sanitization_changed_html": raw != rendered,
|
||||
"markup_changed_by_sanitization": markup_changed,
|
||||
"serialization_only_change": raw != rendered and not markup_changed and not text_changed,
|
||||
"reference_occurrences_before": sum(before_refs.values()),
|
||||
"reference_occurrences_after": sum(after_refs.values()),
|
||||
"reference_attributes_preserved": before_refs == after_refs,
|
||||
"removed_reference_occurrences": sum((before_refs - after_refs).values()),
|
||||
"added_reference_occurrences": sum((after_refs - before_refs).values()),
|
||||
"removed_tag_counts": dict(sorted((before.tags - after.tags).items())),
|
||||
"added_tag_counts": dict(sorted((after.tags - before.tags).items())),
|
||||
"removed_attributes": [
|
||||
|
|
|
|||
|
|
@ -142,101 +142,3 @@ Set COULOMB_SOCIAL_CORPUS_DIR to a private directory if needed. Do not put raw
|
|||
exports in the checkout. Default target route is /vw_pages; override via
|
||||
COULOMB_SOCIAL_CAPTURE_ROUTE only after confirming the actual authenticated
|
||||
protocol surface. A successful public-route load is not authentication proof.
|
||||
|
||||
|
||||
## Retained Visual capture and review bundle
|
||||
|
||||
The October31 all-space bundle now has a separate private Visual preparation at
|
||||
`~/.config/coulomb-social/auth/exports/visual-bundle-20261031`. The original
|
||||
`review-bundle-20261031` remains unchanged.242Visual references were captured from
|
||||
108URLs on the one recorded Bubble CDN, producing90distinct images.236draft
|
||||
article pages and67space indexes link local hashed assets. All90images decode in
|
||||
an offline browser; this is not a source/product appearance verdict or an import.
|
||||
|
||||
The reusable collector is `scripts/capture-bubble-visuals.py ORIGINAL --output NEW`.
|
||||
It requires a complete hash-bound original bundle, a new private directory outside
|
||||
repositories, and the exact known CDN over HTTPS. It refuses redirects, alternate
|
||||
origins, credentials in URLs, active/unknown image formats, source drift, oversized
|
||||
responses and existing output. No stored browser credentials are read or sent.
|
||||
A missing final reconciliation.json means partial output, which must be retained
|
||||
for review rather than used as an import bundle. Original body/date bytes are not
|
||||
rewritten; only the compiler's empty Visual metadata is replaced.
|
||||
|
||||
Verification for the completed bundle (read-only):
|
||||
|
||||
```bash
|
||||
python3 scripts/verify-bubble-visual-preservation.py \
|
||||
~/.config/coulomb-social/auth/exports/review-bundle-20261031 \
|
||||
~/.config/coulomb-social/auth/exports/visual-bundle-20261031
|
||||
node scripts/verify-bubble-visuals.mjs \
|
||||
~/.config/coulomb-social/auth/exports/visual-bundle-20261031
|
||||
```
|
||||
|
||||
Only aggregate results belong in Git/chat. Images, titles, source URLs and original
|
||||
records remain private. The new bundle retains all71spaces and the existing
|
||||
graph/grant/fidelity gates.18body links and one attachment flag are still
|
||||
unreconciled. Captured Visual bytes do not authorize copying memberships or
|
||||
productive import. Public proof: docs/release/bubble-visual-preparation-2026-10-31.json.
|
||||
|
||||
## Private access reconciliation
|
||||
|
||||
`scripts/audit-bubble-access.py ORIGINAL NEW_PRIVATE_DIRECTORY` inventories the
|
||||
retained source ownership, membership and visibility fields without proposing
|
||||
target grants. It requires private, hash-bound source snapshots and refuses
|
||||
source drift, symlinks, public files, hard links, existing output and output
|
||||
inside the original bundle or this repository. The JSON and escaped, network-free
|
||||
HTML review are private; stdout contains aggregate counts and hashes only.
|
||||
|
||||
The October 31 review is at
|
||||
`~/.config/coulomb-social/auth/exports/access-review-20261031/index.html`.
|
||||
It covers 70 fresh spaces, 245 article records and one inventory-only space.
|
||||
Three distinct source account references remain to be linked through authoritative
|
||||
identity evidence. Nine creator references are unresolved. A missing source
|
||||
membership field is unknown, not an empty list. Source role names and visibility
|
||||
values are preserved for review; no equivalence with target owner/member/viewer
|
||||
permissions is assumed. The accepted ReichelAG owner grant remains evidence for
|
||||
that cohort alone. See `docs/release/bubble-access-audit-2026-10-31.json`.
|
||||
|
||||
## Body links and deferred scrap relations
|
||||
|
||||
`scripts/verify-bubble-body-resources.py ORIGINAL VISUAL --output PRIVATE_JSON`
|
||||
checks source hashes, recompiles original draft bytes, checks prepared bodies and
|
||||
compares reference attributes before and after the product sanitizer. It neither
|
||||
fetches destinations nor changes source files. Its stdout receipt contains only
|
||||
aggregate counts and hashes. Raw references and deferred scrap descriptors belong
|
||||
in the separate private report, outside both bundles and the checkout.
|
||||
|
||||
The October 31 proof verifies 18 distinct body-link entries with 28 occurrences,
|
||||
all preserved by the product renderer. It also verifies 242 source bodies and 236
|
||||
prepared pages. This does not prove remote availability or Bubble appearance.
|
||||
Four `_list_custom_scrap` values are deferred strings, not captured record lists;
|
||||
the compiler now preserves them as unresolved review flags instead of silently
|
||||
omitting them. Explicit empty lists remain distinct from missing or deferred data.
|
||||
These four records and the separate attachment-flagged article still need source
|
||||
recovery or disposition. Do not interpret the strings as article IDs or infer
|
||||
that the attachment flag enumerates all resources. The supplemental report is
|
||||
`~/.config/coulomb-social/auth/exports/body-resources-20261031.json`; the existing
|
||||
original and Visual bundle receipts remain unchanged. Public proof:
|
||||
`docs/release/bubble-body-resources-2026-10-31.json`.
|
||||
|
||||
### Native resource follow-up
|
||||
|
||||
The separate `resources-20261031` private directory records a bounded source
|
||||
observation of the five affected articles. Their fresh parent records match the
|
||||
retained capture, but the page visits returned no typed scrap/attachment records.
|
||||
Two response reads failed, so zero captured records must not be read as zero
|
||||
existing resources. No prior capture was overwritten. The private `index.html`
|
||||
links all five original pages for the operator to identify the existing-resource
|
||||
view/download path. Add attachment controls were observed but not activated.
|
||||
|
||||
The collector is `scripts/capture-bubble-resources.mjs`, taking `--articles`,
|
||||
`--expect-articles-sha256` and a new private `--output` directory. It visits at
|
||||
most ten explicit affected article IDs, selects only typed scrap/attachment
|
||||
content envelopes from the existing same-origin read responses, and excludes
|
||||
user/session envelopes. Multiple observed resource versions remain separate;
|
||||
empty initialization envelopes remain unresolved. It does not decode or invent
|
||||
provider query payloads, click controls, submit forms, fetch arbitrary attachment
|
||||
URLs or create an import manifest. `completed_bounded_observation` describes only
|
||||
the terminal visit pass; completeness remains false. Source hashes, response
|
||||
failures and private checkpoint hashes are in
|
||||
`docs/release/bubble-resource-capture-2026-10-31.json`.
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.attachment-menu-source-validation.v1",
|
||||
"product_decision": "78175c34-58e1-4ad6-944d-0662c0462ae6",
|
||||
"full_main_gate": {
|
||||
"command": "TMPDIR=/var/tmp make check",
|
||||
"passed": 670,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"log_sha256": "357547d34f7d73f750721338cff3e07439e8c710d0f1cf838541c1b175268335"
|
||||
},
|
||||
"isolated_release_gate": {
|
||||
"source": "1139a6d30eee4f75317b46bd45120a15d818455f",
|
||||
"command": "make check",
|
||||
"passed": 568,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"log_sha256": "d9a9c8883f0d4021918c8600f9b5055cac24ca6b9943ee89db067f55d65ccdb1"
|
||||
},
|
||||
"checks": [
|
||||
"Author upload/remove; authorized reader download; foreign-tenant, outsider, revoked, archived and anonymous denial",
|
||||
"Stale page and CSRF refusal; immutable file names; 16 MiB limit; traversal and symlink denial",
|
||||
"Retained body/source dates and associations through edit/rename; removal keeps historical revision bytes",
|
||||
"Independent copy/move associations and managed files through 14 abrupt process deaths",
|
||||
"Upload recovery at partial bytes, complete bytes, stored revision and published page",
|
||||
"Real loopback browser upload/download/copy/move/remove and permission checks; no external requests"
|
||||
],
|
||||
"synthetic_fixtures_only": true,
|
||||
"production_deployed": false,
|
||||
"productive_user_acceptance": false
|
||||
}
|
||||
|
|
@ -1,280 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.completed-evidence-custody-independent-return.v1",
|
||||
"verified_at": "2026-10-31T16:37:46.139987+00:00",
|
||||
"proposal_digest": "sha256:fa2763d1dcbe92fe638a29c9a7a7d51c03d30849c4232f2d43f81ef705bae611",
|
||||
"receipt_sha256": "b79b26b1572faff0e2f2257e39e438bc065a4d2c71f92d879749e0e8b4b03493",
|
||||
"receipt": {
|
||||
"bytes_modified": false,
|
||||
"capture_executed": false,
|
||||
"changes": [
|
||||
{
|
||||
"after": {
|
||||
"bytes": 4096,
|
||||
"device": 2049,
|
||||
"gid": 0,
|
||||
"hash_kind": "directory-entry-names",
|
||||
"inode": 543834,
|
||||
"kind": "directory",
|
||||
"mode": "0o700",
|
||||
"mtime_ns": 1793430825511133103,
|
||||
"nlink": 4,
|
||||
"relative_path": "releases",
|
||||
"sha256": "3190439b978096a16c28aa0dd6b372735594808217b59a01dadbbe744d4110c8",
|
||||
"uid": 0
|
||||
},
|
||||
"before": {
|
||||
"bytes": 4096,
|
||||
"device": 2049,
|
||||
"gid": 0,
|
||||
"hash_kind": "directory-entry-names",
|
||||
"inode": 543834,
|
||||
"kind": "directory",
|
||||
"mode": "0o755",
|
||||
"mtime_ns": 1793430825511133103,
|
||||
"nlink": 4,
|
||||
"relative_path": "releases",
|
||||
"sha256": "3190439b978096a16c28aa0dd6b372735594808217b59a01dadbbe744d4110c8",
|
||||
"uid": 0
|
||||
},
|
||||
"path": "releases"
|
||||
},
|
||||
{
|
||||
"after": {
|
||||
"bytes": 4096,
|
||||
"device": 2049,
|
||||
"gid": 0,
|
||||
"hash_kind": "directory-entry-names",
|
||||
"inode": 549330,
|
||||
"kind": "directory",
|
||||
"mode": "0o700",
|
||||
"mtime_ns": 1793430825511133103,
|
||||
"nlink": 3,
|
||||
"relative_path": "releases/9f1daf6c5fb56b2b4fc9817f28f5ad090c884b0295f7d6f4469e42d48fa8d59f/capsule/charts",
|
||||
"sha256": "6b8295661773cb5820c305091679383b09fb0d7dcdde4412eeae48bfabab28b5",
|
||||
"uid": 0
|
||||
},
|
||||
"before": {
|
||||
"bytes": 4096,
|
||||
"device": 2049,
|
||||
"gid": 0,
|
||||
"hash_kind": "directory-entry-names",
|
||||
"inode": 549330,
|
||||
"kind": "directory",
|
||||
"mode": "0o755",
|
||||
"mtime_ns": 1793430825511133103,
|
||||
"nlink": 3,
|
||||
"relative_path": "releases/9f1daf6c5fb56b2b4fc9817f28f5ad090c884b0295f7d6f4469e42d48fa8d59f/capsule/charts",
|
||||
"sha256": "6b8295661773cb5820c305091679383b09fb0d7dcdde4412eeae48bfabab28b5",
|
||||
"uid": 0
|
||||
},
|
||||
"path": "releases/9f1daf6c5fb56b2b4fc9817f28f5ad090c884b0295f7d6f4469e42d48fa8d59f/capsule/charts"
|
||||
},
|
||||
{
|
||||
"after": {
|
||||
"bytes": 4096,
|
||||
"device": 2049,
|
||||
"gid": 0,
|
||||
"hash_kind": "directory-entry-names",
|
||||
"inode": 549341,
|
||||
"kind": "directory",
|
||||
"mode": "0o700",
|
||||
"mtime_ns": 1793430825512133101,
|
||||
"nlink": 3,
|
||||
"relative_path": "releases/9f1daf6c5fb56b2b4fc9817f28f5ad090c884b0295f7d6f4469e42d48fa8d59f/capsule/release",
|
||||
"sha256": "25a35515bc386a0c0a1a91b5fa3c966fffad64e2ce1d8bde35959bc164b11d79",
|
||||
"uid": 0
|
||||
},
|
||||
"before": {
|
||||
"bytes": 4096,
|
||||
"device": 2049,
|
||||
"gid": 0,
|
||||
"hash_kind": "directory-entry-names",
|
||||
"inode": 549341,
|
||||
"kind": "directory",
|
||||
"mode": "0o755",
|
||||
"mtime_ns": 1793430825512133101,
|
||||
"nlink": 3,
|
||||
"relative_path": "releases/9f1daf6c5fb56b2b4fc9817f28f5ad090c884b0295f7d6f4469e42d48fa8d59f/capsule/release",
|
||||
"sha256": "25a35515bc386a0c0a1a91b5fa3c966fffad64e2ce1d8bde35959bc164b11d79",
|
||||
"uid": 0
|
||||
},
|
||||
"path": "releases/9f1daf6c5fb56b2b4fc9817f28f5ad090c884b0295f7d6f4469e42d48fa8d59f/capsule/release"
|
||||
},
|
||||
{
|
||||
"after": {
|
||||
"bytes": 4096,
|
||||
"device": 2049,
|
||||
"gid": 0,
|
||||
"hash_kind": "directory-entry-names",
|
||||
"inode": 549219,
|
||||
"kind": "directory",
|
||||
"mode": "0o700",
|
||||
"mtime_ns": 1793406468579820277,
|
||||
"nlink": 3,
|
||||
"relative_path": "releases/5fd7ccd8f68057346367d81efb82b48280a16dd31d87683a5bd83e60e3d1837e/capsule/charts",
|
||||
"sha256": "6b8295661773cb5820c305091679383b09fb0d7dcdde4412eeae48bfabab28b5",
|
||||
"uid": 0
|
||||
},
|
||||
"before": {
|
||||
"bytes": 4096,
|
||||
"device": 2049,
|
||||
"gid": 0,
|
||||
"hash_kind": "directory-entry-names",
|
||||
"inode": 549219,
|
||||
"kind": "directory",
|
||||
"mode": "0o755",
|
||||
"mtime_ns": 1793406468579820277,
|
||||
"nlink": 3,
|
||||
"relative_path": "releases/5fd7ccd8f68057346367d81efb82b48280a16dd31d87683a5bd83e60e3d1837e/capsule/charts",
|
||||
"sha256": "6b8295661773cb5820c305091679383b09fb0d7dcdde4412eeae48bfabab28b5",
|
||||
"uid": 0
|
||||
},
|
||||
"path": "releases/5fd7ccd8f68057346367d81efb82b48280a16dd31d87683a5bd83e60e3d1837e/capsule/charts"
|
||||
},
|
||||
{
|
||||
"after": {
|
||||
"bytes": 4096,
|
||||
"device": 2049,
|
||||
"gid": 0,
|
||||
"hash_kind": "directory-entry-names",
|
||||
"inode": 549263,
|
||||
"kind": "directory",
|
||||
"mode": "0o700",
|
||||
"mtime_ns": 1793412565567095985,
|
||||
"nlink": 2,
|
||||
"relative_path": "date-operations/47829c7ac2e6fd2c81fde1c914aec7c6e433098fa66985db6cfb9b34069942dc/private",
|
||||
"sha256": "384eaf76c1a05ea25236c7a0d7bee390638b68fc89186604def37028364992fb",
|
||||
"uid": 0
|
||||
},
|
||||
"before": {
|
||||
"bytes": 4096,
|
||||
"device": 2049,
|
||||
"gid": 10001,
|
||||
"hash_kind": "directory-entry-names",
|
||||
"inode": 549263,
|
||||
"kind": "directory",
|
||||
"mode": "0o700",
|
||||
"mtime_ns": 1793412565567095985,
|
||||
"nlink": 2,
|
||||
"relative_path": "date-operations/47829c7ac2e6fd2c81fde1c914aec7c6e433098fa66985db6cfb9b34069942dc/private",
|
||||
"sha256": "384eaf76c1a05ea25236c7a0d7bee390638b68fc89186604def37028364992fb",
|
||||
"uid": 10001
|
||||
},
|
||||
"path": "date-operations/47829c7ac2e6fd2c81fde1c914aec7c6e433098fa66985db6cfb9b34069942dc/private"
|
||||
},
|
||||
{
|
||||
"after": {
|
||||
"bytes": 455,
|
||||
"device": 2049,
|
||||
"gid": 0,
|
||||
"hash_kind": "file-bytes",
|
||||
"inode": 549311,
|
||||
"kind": "regular",
|
||||
"mode": "0o600",
|
||||
"mtime_ns": 1793412565564096058,
|
||||
"nlink": 1,
|
||||
"relative_path": "date-operations/47829c7ac2e6fd2c81fde1c914aec7c6e433098fa66985db6cfb9b34069942dc/private/result.json",
|
||||
"sha256": "859e5a80442ad77b5eff61b68e5062a167d51f5db1b6c2d1ee064db977beb022",
|
||||
"uid": 0
|
||||
},
|
||||
"before": {
|
||||
"bytes": 455,
|
||||
"device": 2049,
|
||||
"gid": 10001,
|
||||
"hash_kind": "file-bytes",
|
||||
"inode": 549311,
|
||||
"kind": "regular",
|
||||
"mode": "0o600",
|
||||
"mtime_ns": 1793412565564096058,
|
||||
"nlink": 1,
|
||||
"relative_path": "date-operations/47829c7ac2e6fd2c81fde1c914aec7c6e433098fa66985db6cfb9b34069942dc/private/result.json",
|
||||
"sha256": "859e5a80442ad77b5eff61b68e5062a167d51f5db1b6c2d1ee064db977beb022",
|
||||
"uid": 10001
|
||||
},
|
||||
"path": "date-operations/47829c7ac2e6fd2c81fde1c914aec7c6e433098fa66985db6cfb9b34069942dc/private/result.json"
|
||||
},
|
||||
{
|
||||
"after": {
|
||||
"bytes": 12930,
|
||||
"device": 2049,
|
||||
"gid": 0,
|
||||
"hash_kind": "file-bytes",
|
||||
"inode": 549315,
|
||||
"kind": "regular",
|
||||
"mode": "0o600",
|
||||
"mtime_ns": 1793412565062108322,
|
||||
"nlink": 1,
|
||||
"relative_path": "date-operations/47829c7ac2e6fd2c81fde1c914aec7c6e433098fa66985db6cfb9b34069942dc/private/journal.json",
|
||||
"sha256": "fef62ad9317066d5d82eccbea0317eceb2f883e07f50935104e47113855fe0dd",
|
||||
"uid": 0
|
||||
},
|
||||
"before": {
|
||||
"bytes": 12930,
|
||||
"device": 2049,
|
||||
"gid": 10001,
|
||||
"hash_kind": "file-bytes",
|
||||
"inode": 549315,
|
||||
"kind": "regular",
|
||||
"mode": "0o600",
|
||||
"mtime_ns": 1793412565062108322,
|
||||
"nlink": 1,
|
||||
"relative_path": "date-operations/47829c7ac2e6fd2c81fde1c914aec7c6e433098fa66985db6cfb9b34069942dc/private/journal.json",
|
||||
"sha256": "fef62ad9317066d5d82eccbea0317eceb2f883e07f50935104e47113855fe0dd",
|
||||
"uid": 10001
|
||||
},
|
||||
"path": "date-operations/47829c7ac2e6fd2c81fde1c914aec7c6e433098fa66985db6cfb9b34069942dc/private/journal.json"
|
||||
},
|
||||
{
|
||||
"after": {
|
||||
"bytes": 0,
|
||||
"device": 2049,
|
||||
"gid": 0,
|
||||
"hash_kind": "file-bytes",
|
||||
"inode": 549310,
|
||||
"kind": "regular",
|
||||
"mode": "0o600",
|
||||
"mtime_ns": 1793412563167160722,
|
||||
"nlink": 1,
|
||||
"relative_path": "date-operations/47829c7ac2e6fd2c81fde1c914aec7c6e433098fa66985db6cfb9b34069942dc/private/execute.lock",
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"uid": 0
|
||||
},
|
||||
"before": {
|
||||
"bytes": 0,
|
||||
"device": 2049,
|
||||
"gid": 10001,
|
||||
"hash_kind": "file-bytes",
|
||||
"inode": 549310,
|
||||
"kind": "regular",
|
||||
"mode": "0o600",
|
||||
"mtime_ns": 1793412563167160722,
|
||||
"nlink": 1,
|
||||
"relative_path": "date-operations/47829c7ac2e6fd2c81fde1c914aec7c6e433098fa66985db6cfb9b34069942dc/private/execute.lock",
|
||||
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
|
||||
"uid": 10001
|
||||
},
|
||||
"path": "date-operations/47829c7ac2e6fd2c81fde1c914aec7c6e433098fa66985db6cfb9b34069942dc/private/execute.lock"
|
||||
}
|
||||
],
|
||||
"data_deleted": false,
|
||||
"paths_moved": false,
|
||||
"postflight": {
|
||||
"historical_operations_still_terminal": true,
|
||||
"state_bytes": 11259904,
|
||||
"whole_state_custody_guard_passed": true
|
||||
},
|
||||
"proposal_digest": "sha256:fa2763d1dcbe92fe638a29c9a7a7d51c03d30849c4232f2d43f81ef705bae611",
|
||||
"schema": "coulomb.completed-evidence-custody.v1",
|
||||
"started_at": "2026-10-31T16:36:38.149305+00:00",
|
||||
"status": "completed_evidence_private_root_custody_verified",
|
||||
"timers_activated": false,
|
||||
"updated_at": "2026-10-31T16:36:38.939513+00:00",
|
||||
"verified_entries": 8
|
||||
},
|
||||
"native_entries_verified": 8,
|
||||
"all_historical_hashes_inodes_paths_mtimes_preserved": true,
|
||||
"whole_state_custody_guard_passed": true,
|
||||
"state_bytes": 11259904,
|
||||
"verification_read_only": true,
|
||||
"verifier_source_sha256": "27fb56bb621ab9141f6b7ae205790e8a7eeb1618e2628940b3b6bc5525b4393d"
|
||||
}
|
||||
|
|
@ -1,19 +1,11 @@
|
|||
# Completed backup evidence custody repair
|
||||
|
||||
This is the exact proposed repair for the eight historical metadata exceptions
|
||||
recorded in CSOC-WP-0012-T04. **Founder execution and independent postflight are
|
||||
complete, under T15. Do not rerun the seal command.**
|
||||
recorded in CSOC-WP-0012-T04. Native preflight passes. **Nothing has been changed.**
|
||||
|
||||
Proposal:
|
||||
`sha256:fa2763d1dcbe92fe638a29c9a7a7d51c03d30849c4232f2d43f81ef705bae611`.
|
||||
|
||||
State Hub decision `3ec2f98e-9db3-47d9-bc1a-0387f980b81c` is resolved from the
|
||||
founder's actual execution at16:36:38Z. Independent read-only verification at
|
||||
16:37:46Z confirms all eight intended deltas and unchanged hashes, paths, inodes
|
||||
and mtimes. The whole-state custody guard passes at11,259,904bytes. Evidence:
|
||||
`backup-completed-evidence-custody-return-2026-10-31.json`.
|
||||
`operator-handoff-check-2026-10-31.json` retains the earlier pre-execution check.
|
||||
|
||||
## Exact change
|
||||
|
||||
Within `/var/lib/coulomb-social-backup/`, change:
|
||||
|
|
@ -41,9 +33,9 @@ The strict backup capacity guard is unchanged. Successful execution also runs it
|
|||
existing state-usage/custody check over the entire state tree. This is neither a
|
||||
blanket chmod/chown nor an exception that omits historical data from accounting.
|
||||
|
||||
## Historical founder terminal command — completed
|
||||
## Founder terminal command
|
||||
|
||||
Retained for provenance; do not run again:
|
||||
Run this from the workstation after reviewing the scope above:
|
||||
|
||||
```bash
|
||||
python3 /home/worsch/coulomb-social/scripts/seal-backup-evidence.py \
|
||||
|
|
@ -56,9 +48,9 @@ At the prompt, enter:
|
|||
SEAL sha256:fa2763d1dcbe92fe638a29c9a7a7d51c03d30849c4232f2d43f81ef705bae611
|
||||
```
|
||||
|
||||
Recorded status: `completed_evidence_private_root_custody_verified`, eight entries
|
||||
verified and `postflight.whole_state_custody_guard_passed: true`. Independent
|
||||
readback is complete. The private durable receipt is:
|
||||
Expected status: `completed_evidence_private_root_custody_verified`, eight entries
|
||||
verified and `postflight.whole_state_custody_guard_passed: true`. Paste the result
|
||||
back for independent readback. The private durable receipt is:
|
||||
|
||||
`/var/lib/coulomb-social-backup-custody/fa2763d1dcbe92fe638a29c9a7a7d51c03d30849c4232f2d43f81ef705bae611/receipt.json`.
|
||||
|
||||
|
|
@ -114,12 +106,12 @@ Nineteen dedicated cases exercise real metadata/lock IO, preserved bytes/paths,
|
|||
explicit/partial rollback, interference refusal, source/digest boundaries,
|
||||
nonterminal refusal, and native receipt/process/helper/mount/cluster/timer guards.
|
||||
|
||||
The verified attended execution resolves the historical custody mismatch. T04 still
|
||||
This resolves only the current custody mismatch after attended success. T04 still
|
||||
owns retention/capacity admission and historical-copy disposition. Preventing
|
||||
future release/date producers from reintroducing these metadata mismatches is also
|
||||
required before recurring service acceptance. That source correction is now
|
||||
completed under T13/RAPPS-WP-0015-T06; it does not repair the historical entries
|
||||
listed here or change frozen capsules.
|
||||
live T04 work before recurring service acceptance: nested release directory
|
||||
creation currently uses default intermediate modes, and date helper journals
|
||||
retain the execution UID after completion. Do not silently change frozen capsules.
|
||||
T07 still needs the existing route execution; T08 then needs inactive installation
|
||||
and independent readback. No native backup-operation or migration acceptance is
|
||||
inferred from this repair.
|
||||
|
|
|
|||
|
|
@ -1,371 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.backup-installation-independent-postflight.v1",
|
||||
"verified_at": "2026-10-31T17:30:18.219708+00:00",
|
||||
"status": "installed_files_and_inactive_units_verified",
|
||||
"proposal_digest": "sha256:8f442bf0ebed8bbf3b7f227b52081df52613f3f5f6874c4a59511cfc2ba06d42",
|
||||
"receipt_sha256": "96329afbd5662f71bf6d6b05c003f0810be12c10036f9cadb41cc373d3a1108b",
|
||||
"receipt": {
|
||||
"schema": "coulomb.backup-source-supervised-installation.v1",
|
||||
"proposal_digest": "sha256:8f442bf0ebed8bbf3b7f227b52081df52613f3f5f6874c4a59511cfc2ba06d42",
|
||||
"status": "sources_installed_units_inactive_verified",
|
||||
"preflight": {
|
||||
"units": {
|
||||
"coulomb-social-paired-backup.service": {
|
||||
"LoadState": "not-found",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "",
|
||||
"UnitFileState": ""
|
||||
},
|
||||
"coulomb-social-paired-backup.timer": {
|
||||
"LoadState": "not-found",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "",
|
||||
"UnitFileState": ""
|
||||
},
|
||||
"coulomb-social-backup-freshness.service": {
|
||||
"LoadState": "not-found",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "",
|
||||
"UnitFileState": ""
|
||||
},
|
||||
"coulomb-social-backup-freshness.timer": {
|
||||
"LoadState": "not-found",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "",
|
||||
"UnitFileState": ""
|
||||
},
|
||||
"coulomb-social-backup-alert@coulomb-social-paired-backup.service.service": {
|
||||
"LoadState": "not-found",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "",
|
||||
"UnitFileState": ""
|
||||
}
|
||||
},
|
||||
"capacity": {
|
||||
"state_bytes": 11259904,
|
||||
"state_reserve_bytes": 7532969984,
|
||||
"disk_reserve_bytes": 8606711808,
|
||||
"free_bytes": 115579949056,
|
||||
"free_inodes": 24523113,
|
||||
"filesystem_blocks_reserved": false
|
||||
},
|
||||
"sdk": {
|
||||
"boto3": "1.40.18",
|
||||
"botocore": "1.40.76"
|
||||
},
|
||||
"route": {
|
||||
"helm_revision": 6,
|
||||
"runtime_and_complete_resources_verified": true
|
||||
}
|
||||
},
|
||||
"timers_activated": false,
|
||||
"capture_executed": false,
|
||||
"email_sent": false,
|
||||
"retained_data_deleted": false,
|
||||
"started_at": "2026-10-31T17:22:48.757530+00:00",
|
||||
"capacity_profile": {
|
||||
"maximum_new_file_bytes": 1073741824,
|
||||
"state_budget_bytes": 8589934592,
|
||||
"minimum_free_bytes": 8589934592,
|
||||
"minimum_free_inodes": 1024,
|
||||
"control_margin_bytes": 16777216
|
||||
},
|
||||
"founder_confirmed_profile_and_installation": true,
|
||||
"route_postflight": {
|
||||
"helm_revision": 6,
|
||||
"runtime_and_complete_resources_verified": true
|
||||
},
|
||||
"verified_targets": 19,
|
||||
"units": {
|
||||
"coulomb-social-paired-backup.service": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-paired-backup.service",
|
||||
"UnitFileState": "static"
|
||||
},
|
||||
"coulomb-social-paired-backup.timer": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-paired-backup.timer",
|
||||
"UnitFileState": "disabled"
|
||||
},
|
||||
"coulomb-social-backup-freshness.service": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-backup-freshness.service",
|
||||
"UnitFileState": "static"
|
||||
},
|
||||
"coulomb-social-backup-freshness.timer": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-backup-freshness.timer",
|
||||
"UnitFileState": "disabled"
|
||||
},
|
||||
"coulomb-social-backup-alert@coulomb-social-paired-backup.service.service": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-backup-alert@.service",
|
||||
"UnitFileState": "static"
|
||||
}
|
||||
},
|
||||
"updated_at": "2026-10-31T17:22:54.560675+00:00"
|
||||
},
|
||||
"nested_receipt_sha256": "795d9eb672b24495c77ad636a210c5d2022c8c3124d276920db7eda02257e519",
|
||||
"verified_targets": 19,
|
||||
"installed_fingerprints": {
|
||||
"/opt/coulomb-social-backup/paired-backup.py": {
|
||||
"exists": true,
|
||||
"sha256": "d161c742d1a6a182460a57d0a1719591ab58fc94006f55169ad3d74442a93630",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 534009,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368826077309
|
||||
},
|
||||
"/opt/coulomb-social-backup/snapshot-content-and-db.py": {
|
||||
"exists": true,
|
||||
"sha256": "dcc8dd2a3989f279597595f9260b31b24fcc9b6dc787f04c17ef0491c53d830d",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549255,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793430923413704430
|
||||
},
|
||||
"/opt/coulomb-social-backup/mirror-paired-backup.py": {
|
||||
"exists": true,
|
||||
"sha256": "9ceb26d9083af016c4b787907e4dce7bdf437c782fb2d15eb28d9e334e6e431c",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549201,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368831077393
|
||||
},
|
||||
"/opt/coulomb-social-backup/check-paired-backup-health.py": {
|
||||
"exists": true,
|
||||
"sha256": "2d40ec6e4c59ea7fe1d46065d197b9a87ca6811f023cc6f3e20e4184a3490566",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549309,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368836077477
|
||||
},
|
||||
"/opt/coulomb-social-backup/backup_capacity.py": {
|
||||
"exists": true,
|
||||
"sha256": "cb699a79e67b129239b5aa5d6f3b0d4ffaa9773a8b073227ad17fdecb5b9d893",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549354,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368843077594
|
||||
},
|
||||
"/opt/coulomb-social-backup/mirror-platform-runtime.json": {
|
||||
"exists": true,
|
||||
"sha256": "9253c5f6e956b67f499d3e12d2851be7fabd3bc56b00496b8810bbd0be8209f1",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549355,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368847077662
|
||||
},
|
||||
"/opt/coulomb-social-backup/backup_alerts.py": {
|
||||
"exists": true,
|
||||
"sha256": "07522437d4276b92f0a44149adc6c9e81bb18dbe59ce0f1f9e58a48347700d0e",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549359,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368887078332
|
||||
},
|
||||
"/opt/coulomb-social-backup/notify-backup-alert.py": {
|
||||
"exists": true,
|
||||
"sha256": "0bd53bc5ad22d8bcb0326fb18a17737744b06416fe785dad077308e45f051d5a",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549360,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368891078399
|
||||
},
|
||||
"/opt/coulomb-social-backup/observe-backup-alerts.py": {
|
||||
"exists": true,
|
||||
"sha256": "17caf4fa65283242f618b039ff1d018801c9890ea2a9178912cbdd4b50ee2664",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549361,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368895078466
|
||||
},
|
||||
"/opt/railiance-platform/scripts/application_recovery_identities.py": {
|
||||
"exists": true,
|
||||
"sha256": "20f56255ed6eeec4aafe33f142bc3ee03f623d4957a7b0cabb741d340f15f79d",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549356,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368852077745
|
||||
},
|
||||
"/opt/railiance-platform/scripts/application_recovery_mirror.py": {
|
||||
"exists": true,
|
||||
"sha256": "d48ab95e89b9eeae36269d853ebe4c44c22e1f57d4e14224f03d0b9aeeb34178",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549357,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368857077829
|
||||
},
|
||||
"/opt/railiance-platform/scripts/application_recovery_resources.py": {
|
||||
"exists": true,
|
||||
"sha256": "ab70ec341e738272730eb0daf76840d0bca807caeb3c4e4c2357f162fbed4498",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 549358,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368862077913
|
||||
},
|
||||
"/opt/railiance-platform/scripts/primary_application_archive.py": {
|
||||
"exists": true,
|
||||
"sha256": "a3f0a61e869a6012edb4b5288be14e3b0c4a9a1273b090320ab146d12e5aa94d",
|
||||
"mode": 420,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 540610,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1791537447437616251
|
||||
},
|
||||
"/etc/systemd/system/coulomb-social-backup-freshness.service": {
|
||||
"exists": true,
|
||||
"sha256": "8d6278c2cbca7f48b659c239c1d1e181fa4b9cf023fe7429850e294c6cd84d0e",
|
||||
"mode": 420,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 19366,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368868078014
|
||||
},
|
||||
"/etc/systemd/system/coulomb-social-paired-backup.service": {
|
||||
"exists": true,
|
||||
"sha256": "8b01b788bb08f453fdd4807104185c89411e0b0b4dedee9240f14f110ceb5513",
|
||||
"mode": 420,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 14867,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368873078098
|
||||
},
|
||||
"/etc/systemd/system/coulomb-social-backup-freshness.timer": {
|
||||
"exists": true,
|
||||
"sha256": "75d1d0721c07fdd0703910c06bb8a678396440e7d95411a37ee7de4938f3ac31",
|
||||
"mode": 420,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 19367,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368878078181
|
||||
},
|
||||
"/etc/systemd/system/coulomb-social-paired-backup.timer": {
|
||||
"exists": true,
|
||||
"sha256": "5e87235e66f89a64a972562d6f163f62420628fc44fb7fd8d603a96c347dfbb9",
|
||||
"mode": 420,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 19368,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368882078248
|
||||
},
|
||||
"/etc/systemd/system/coulomb-social-backup-alert@.service": {
|
||||
"exists": true,
|
||||
"sha256": "4bfa019d29b1d0de278f03553602a5e824de50ed99ebcf3b5035cf4d5b06fe98",
|
||||
"mode": 420,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 19370,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368899078533
|
||||
},
|
||||
"/etc/coulomb-social-backup/alerting.env": {
|
||||
"exists": true,
|
||||
"sha256": "509844b5c8ef618b812d52f32e19c3c559623636dca62f7b16f437aa90cc0458",
|
||||
"mode": 384,
|
||||
"uid": 0,
|
||||
"gid": 0,
|
||||
"inode": 19369,
|
||||
"device": 2049,
|
||||
"mtime_ns": 1793467368904078617
|
||||
}
|
||||
},
|
||||
"units": {
|
||||
"coulomb-social-paired-backup.service": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-paired-backup.service",
|
||||
"UnitFileState": "static"
|
||||
},
|
||||
"coulomb-social-paired-backup.timer": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-paired-backup.timer",
|
||||
"UnitFileState": "disabled"
|
||||
},
|
||||
"coulomb-social-backup-freshness.service": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-backup-freshness.service",
|
||||
"UnitFileState": "static"
|
||||
},
|
||||
"coulomb-social-backup-freshness.timer": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-backup-freshness.timer",
|
||||
"UnitFileState": "disabled"
|
||||
},
|
||||
"coulomb-social-backup-alert@coulomb-social-paired-backup.service.service": {
|
||||
"LoadState": "loaded",
|
||||
"ActiveState": "inactive",
|
||||
"SubState": "dead",
|
||||
"FragmentPath": "/etc/systemd/system/coulomb-social-backup-alert@.service",
|
||||
"UnitFileState": "static"
|
||||
}
|
||||
},
|
||||
"route": {
|
||||
"helm_revision": 6,
|
||||
"runtime_and_complete_resources_verified": true
|
||||
},
|
||||
"capacity": {
|
||||
"state_bytes": 11259904,
|
||||
"state_reserve_bytes": 7532969984,
|
||||
"disk_reserve_bytes": 8606711808,
|
||||
"free_bytes": 115555618816,
|
||||
"free_inodes": 24523041,
|
||||
"filesystem_blocks_reserved": false
|
||||
},
|
||||
"sdk": {
|
||||
"boto3": "1.40.18",
|
||||
"botocore": "1.40.76"
|
||||
},
|
||||
"runtime_modified_by_verification": false
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.backup-route-independent-postflight.v1",
|
||||
"verified_at": "2026-10-31T17:19:36.926769+00:00",
|
||||
"status": "durable_receipt_and_live_route_verified",
|
||||
"execution_digest": "sha256:4d8481061dc9ce6835169defc96887945052332a0db8d4234ae84032d63cc328",
|
||||
"receipt": {
|
||||
"schema": "rapp-telemetry.backup-route-execution.v1",
|
||||
"execution_digest": "sha256:4d8481061dc9ce6835169defc96887945052332a0db8d4234ae84032d63cc328",
|
||||
"proposal_digest": "sha256:4bcad54f7b8e1e77b94112e452cbb58eaf8e882dc10305129c5f9ca69f014a66",
|
||||
"status": "backup_email_route_deployed_verified",
|
||||
"timers_activated": false,
|
||||
"notification_sent_by_helper": false,
|
||||
"production_data_restored": false,
|
||||
"started_at": "2026-10-31T17:17:13.743344+00:00",
|
||||
"helm_revision": 6,
|
||||
"verified_resource_count": 87,
|
||||
"after_resources_sha256": "600c4998e54b8e11845849c7d8e4c6b6699556c21f5df6ca79bb86b2e8d1683f",
|
||||
"live_desired_fields_verified": true,
|
||||
"runtime_config_verified": true,
|
||||
"existing_image_and_pvc_preserved": true,
|
||||
"completed_at": "2026-10-31T17:17:31.488654+00:00"
|
||||
},
|
||||
"receipt_sha256": "c26d636f59109956f281ad46f4885c4db800a9553cf05cac324aa3155ef7ac40",
|
||||
"original_execution_packet_matches": true,
|
||||
"live_desired_fields_verified": true,
|
||||
"runtime_config_verified": true,
|
||||
"existing_image_and_pvc_preserved": true,
|
||||
"runtime_modified_by_verification": false
|
||||
}
|
||||
|
|
@ -3,9 +3,7 @@
|
|||
The final wrapper is prepared for CSOC-WP-0012-T08. It installs the previously
|
||||
sealed22-member archive into its exact19 target paths, using the existing
|
||||
transaction library. It neither captures data nor starts/enables a service or
|
||||
timer. The earlier custody refusal was resolved by verified T15 execution at
|
||||
16:36:38Z. T07's route return and a fresh installer preflight remain required;
|
||||
do not execute this packet yet.
|
||||
timer. Current native preflight **refuses**; do not execute this packet yet.
|
||||
|
||||
Proposal:
|
||||
`sha256:8f442bf0ebed8bbf3b7f227b52081df52613f3f5f6874c4a59511cfc2ba06d42`.
|
||||
|
|
@ -107,7 +105,7 @@ corrected. The sender preparer's embedded remote Python AST is unchanged, and
|
|||
the send-free return-mail rehearsal passed again. Historical evidence keeps its
|
||||
original source hashes; the new validation binds the current formatted sources.
|
||||
|
||||
T08 remains wait until actual installation and independent inactive-state
|
||||
T08 remains progress until actual installation and independent inactive-state
|
||||
readback. T09 still needs native service/failure/retry/stale/producer-death proof;
|
||||
T10 still needs activation and observation after its existing prerequisites.
|
||||
No full service acceptance, mail delivery or migration verdict follows from
|
||||
|
|
|
|||
|
|
@ -1,131 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.bubble-access-audit-result.v1",
|
||||
"spaces": {
|
||||
"records": 70,
|
||||
"field_states": {
|
||||
"Created By": {
|
||||
"unresolved_reference": 5,
|
||||
"observed": 64,
|
||||
"missing": 1
|
||||
},
|
||||
"crew_list_user": {
|
||||
"observed": 69,
|
||||
"missing": 1
|
||||
},
|
||||
"members_list_user": {
|
||||
"observed": 47,
|
||||
"missing": 23
|
||||
},
|
||||
"guests_list_user": {
|
||||
"missing": 69,
|
||||
"observed": 1
|
||||
}
|
||||
},
|
||||
"option_fields": {
|
||||
"isprivate_boolean": {
|
||||
"present": 69,
|
||||
"missing": 1,
|
||||
"distinct_observed_values": 2
|
||||
},
|
||||
"addnewusersasmember_boolean": {
|
||||
"present": 20,
|
||||
"missing": 50,
|
||||
"distinct_observed_values": 2
|
||||
},
|
||||
"addnewusersasguest_boolean": {
|
||||
"present": 21,
|
||||
"missing": 49,
|
||||
"distinct_observed_values": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"articles": {
|
||||
"records": 245,
|
||||
"field_states": {
|
||||
"Created By": {
|
||||
"observed": 239,
|
||||
"unresolved_reference": 4,
|
||||
"missing": 2
|
||||
},
|
||||
"_creator_user": {
|
||||
"missing": 10,
|
||||
"observed": 235
|
||||
},
|
||||
"_owner_user": {
|
||||
"observed": 243,
|
||||
"missing": 2
|
||||
},
|
||||
"moders_list_user": {
|
||||
"missing": 71,
|
||||
"observed": 174
|
||||
}
|
||||
},
|
||||
"option_fields": {
|
||||
"access_option_visibility": {
|
||||
"present": 243,
|
||||
"missing": 2,
|
||||
"distinct_observed_values": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
"known_spaces": 71,
|
||||
"fresh_space_records": 70,
|
||||
"inventory_only_spaces": 1,
|
||||
"distinct_source_principals": 3,
|
||||
"target_identity_mappings_established": 0,
|
||||
"target_grants_proposed": 0,
|
||||
"production_changed": false,
|
||||
"source_visibility_semantics_verified": false,
|
||||
"source_sha256": {
|
||||
"spaces": "ae20b0cfd1705f486c0b67ef48ac84b396f953cbcef09f9a8f07d07a66f1bf71",
|
||||
"articles": "f33967c79c0f8a60a7d504f5d5e4082f8bc9e3c34f6a3160cb200fd380831d62",
|
||||
"retained_spaces": "92038249ec2e4eed4c8d61ffcdbe030232cebc52e59ba005baee506a16930550"
|
||||
},
|
||||
"source_report_sha256": "75fcd87d17ea0c5042e903efd60e65839da7716e5399ff431a345486ddd10f01",
|
||||
"recorded_at": "2026-10-31T14:05:30.738728+00:00",
|
||||
"workplan_task": "CSOC-WP-0014-T01",
|
||||
"task_status": "progress",
|
||||
"accepted_mapping_scope_evidence": "docs/release/reichelag-imported-2026-10-06.md",
|
||||
"validation": {
|
||||
"focused_tests_passed": 13,
|
||||
"full_gate": "make check passed",
|
||||
"junit": {
|
||||
"tests": 583,
|
||||
"errors": 0,
|
||||
"failures": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"source_snapshots_unchanged": true,
|
||||
"private_output_hashes_verified": true,
|
||||
"output_modes_verified": true
|
||||
},
|
||||
"statehub_readback": {
|
||||
"task_id": "0002882d-f156-5a5d-b524-d04793f4684d",
|
||||
"status": "progress",
|
||||
"access_audit_description_synced": true,
|
||||
"fix_consistency_exit_code": 0,
|
||||
"automation_errors": 0,
|
||||
"assessment_failures": 0,
|
||||
"warnings": 6
|
||||
},
|
||||
"output_files": [
|
||||
{
|
||||
"path": "access-inventory.json",
|
||||
"sha256": "d4f97ccc55867361048325f7227721a50a59bcf70ea1af4dfa3db48e8e703cb2"
|
||||
},
|
||||
{
|
||||
"path": "index.html",
|
||||
"sha256": "6c175577f8a34c7bda78f86461d68d2c2167708970517f417bc89d1fde37436b"
|
||||
}
|
||||
],
|
||||
"implementation_files": [
|
||||
{
|
||||
"path": "scripts/audit-bubble-access.py",
|
||||
"sha256": "6590a19e54b77521e31455944b085f92e784e2b85737579cb14caaeb8538807b"
|
||||
},
|
||||
{
|
||||
"path": "tests/test_bubble_access_audit.py",
|
||||
"sha256": "392a799d62828c7508a1b25133d9c1c8de01959b7f1fec90ae737a7cefce7883"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.bubble-attachment-recovery.v1",
|
||||
"completed_at": "2026-10-31T19:35:10.719868+00:00",
|
||||
"source_articles_sha256": "f33967c79c0f8a60a7d504f5d5e4082f8bc9e3c34f6a3160cb200fd380831d62",
|
||||
"capture_sha256": "995fa2558bdfab1035e538152948843977e66e096b286cc762b45a232b0c0052",
|
||||
"visited_pages": 6,
|
||||
"previously_flagged_pages": 5,
|
||||
"attachment_relations": 2,
|
||||
"retained_files": 2,
|
||||
"retained_bytes": 17529,
|
||||
"all_ui_and_independent_download_bytes_match": true,
|
||||
"original_five_parent_bodies_and_dates_unchanged": true,
|
||||
"source_attachment_dates_retained": true,
|
||||
"mapped_draft_pages": 1,
|
||||
"example_parents_outside_original_capture": 1,
|
||||
"new_attachment_child_records": 2,
|
||||
"four_scrap_relations_resolved": false,
|
||||
"original_bundle_files_preserved_in_place": 739,
|
||||
"draft_body_and_existing_metadata_unchanged": true,
|
||||
"source_resource_blockers_removed": false,
|
||||
"resource_completeness_verified": false,
|
||||
"production_imported": false,
|
||||
"source_mutation_controls_activated": false,
|
||||
"private_review_path": "/home/worsch/.config/coulomb-social/auth/exports/attachment-bundle-20261031/attachments-index.html",
|
||||
"preparation_manifest_sha256": "f61f4dc48c4dcc66aa967df1bbf274f1027630a4417a82d249d04bb6b6b73184",
|
||||
"validation": {
|
||||
"full_gate": "TMPDIR=/var/tmp make check",
|
||||
"passed": 670,
|
||||
"errors": 0,
|
||||
"failures": 0,
|
||||
"skipped": 0,
|
||||
"synthetic_resource_guards": 7,
|
||||
"full_gate_log_sha256": "6195e8cd91bb2dca72e240159a51d4ced15c979f89f3909c9495b4b8874f6876"
|
||||
},
|
||||
"implementation_sha256": {
|
||||
"scripts/capture-bubble-attachments.mjs": "cf8cba78d3a80f07f3448a50fb74d9502a01b84ff8be880c4d9e2a697af22812",
|
||||
"scripts/bubble-resource-utils.mjs": "4f4e125f4d48ea5d8fb6421fb570d04a09fd2668e42c4c4857d4ac3a211e89b0",
|
||||
"scripts/tests/bubble-resource-utils.test.mjs": "e434f56d9c586195f11ec1c642ef3f4da41d7cd2d4c01fc44f066bd3f76db192"
|
||||
},
|
||||
"private_preparation_driver_sha256": "e74d9571a6962e095bd299f15c47aa7a19f3223183f722a98a34a10450c29861"
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.bubble-body-resource-proof.v1",
|
||||
"source_report_sha256": "75fcd87d17ea0c5042e903efd60e65839da7716e5399ff431a345486ddd10f01",
|
||||
"visual_report_sha256": "a255df2237d95588b21a5db059487ca0178d1df28c810ebaaf744c5e6491267a",
|
||||
"source_sha256": {
|
||||
"articles": "f33967c79c0f8a60a7d504f5d5e4082f8bc9e3c34f6a3160cb200fd380831d62",
|
||||
"retained_spaces": "92038249ec2e4eed4c8d61ffcdbe030232cebc52e59ba005baee506a16930550",
|
||||
"spaces": "ae20b0cfd1705f486c0b67ef48ac84b396f953cbcef09f9a8f07d07a66f1bf71"
|
||||
},
|
||||
"captured_articles": 245,
|
||||
"source_bodies_verified": 242,
|
||||
"missing_bodies": 3,
|
||||
"prepared_pages_verified": 236,
|
||||
"original_draft_files_recompiled_unchanged": 545,
|
||||
"body_reference_inventory_entries": 18,
|
||||
"body_reference_records": 1,
|
||||
"body_reference_classifications": {
|
||||
"external": 18
|
||||
},
|
||||
"reference_occurrences_before": 28,
|
||||
"reference_occurrences_after": 28,
|
||||
"records_with_changed_reference_attributes": 0,
|
||||
"unresolved_scrap_relation_records": 4,
|
||||
"attachment_flag_records": 1,
|
||||
"live_destinations_checked": false,
|
||||
"original_bubble_render_compared": false,
|
||||
"productive_fidelity_accepted": false,
|
||||
"production_imported": false,
|
||||
"network_requests": 0,
|
||||
"private_report_sha256": "4caec573982dafc82e7228d9221c941f585522e235d64d1f6edac3b43913cf26",
|
||||
"recorded_at": "2026-10-31T14:11:42.653868+00:00",
|
||||
"tasks": [
|
||||
"CSOC-WP-0014-T01",
|
||||
"CSOC-WP-0013-T02"
|
||||
],
|
||||
"task_statuses_changed": false,
|
||||
"implementation_files": [
|
||||
{
|
||||
"path": "scripts/verify-bubble-body-resources.py",
|
||||
"sha256": "8c9a56964ea59422830481d5aacb668e8589f6096ca5130fb6d541edc0ab4d8d"
|
||||
},
|
||||
{
|
||||
"path": "scripts/verify-bubble-visual-preservation.py",
|
||||
"sha256": "9fbc212bd668126a0f6ce6a458b1ca3fba1e14d4b44438c0697f63dc34b5bc3d"
|
||||
},
|
||||
{
|
||||
"path": "coulomb_social/apps/spaces/rendering_audit.py",
|
||||
"sha256": "093f293f6651a759d77ce7d444ba83fdfaead016b353a167693b2e36c5807894"
|
||||
},
|
||||
{
|
||||
"path": "coulomb_social/apps/spaces/bubble_bundle.py",
|
||||
"sha256": "fa928e049ba1052b736b13edf78883b249735312c6b98486e5dd16d4f2c96858"
|
||||
},
|
||||
{
|
||||
"path": "tests/test_rendering_audit.py",
|
||||
"sha256": "5e1aa72a322409a9576962c817d8714ee5eed042bbc38f22cb656a8319f52f67"
|
||||
},
|
||||
{
|
||||
"path": "tests/test_bubble_bundle.py",
|
||||
"sha256": "2ad0453be2c1c1643d4ef6af2e40dc270f70f863522aa221d1d4bb018a4f1f59"
|
||||
},
|
||||
{
|
||||
"path": "tests/test_bubble_body_resources.py",
|
||||
"sha256": "b3c420b62bceb253cd7228f3005b235c2d3bfd170136b960968311eb8fe48077"
|
||||
}
|
||||
],
|
||||
"validation": {
|
||||
"focused_tests_passed": 24,
|
||||
"full_gate": "make check passed",
|
||||
"current_verifier_reproduces_private_report": true,
|
||||
"all_original_draft_bytes_verified": 545,
|
||||
"junit": {
|
||||
"tests": 595,
|
||||
"errors": 0,
|
||||
"failures": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"focused_result_source": "full acceptance gate JUnit"
|
||||
},
|
||||
"statehub_readback": {
|
||||
"tasks": [
|
||||
{
|
||||
"task_id": "0002882d-f156-5a5d-b524-d04793f4684d",
|
||||
"status": "progress",
|
||||
"body_resource_evidence_synced": true
|
||||
},
|
||||
{
|
||||
"task_id": "8d06cdee-e0ce-5c3e-bf98-705deed0ee62",
|
||||
"status": "progress",
|
||||
"body_resource_evidence_synced": true
|
||||
}
|
||||
],
|
||||
"fix_consistency_exit_code": 0,
|
||||
"automation_errors": 0,
|
||||
"assessment_failures": 0,
|
||||
"warnings": 7
|
||||
}
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.bubble-resource-observation-result.v1",
|
||||
"recorded_at": "2026-10-31T14:35:31.435479+00:00",
|
||||
"task": "CSOC-WP-0014-T01",
|
||||
"status": "completed_bounded_observation",
|
||||
"source_articles_sha256": "f33967c79c0f8a60a7d504f5d5e4082f8bc9e3c34f6a3160cb200fd380831d62",
|
||||
"visited_articles": 5,
|
||||
"route_matched_visits": 5,
|
||||
"fresh_unchanged_parent_records": 5,
|
||||
"typed_resources_observed": 0,
|
||||
"empty_resource_envelopes": 0,
|
||||
"response_status_counts": {
|
||||
"200": 41
|
||||
},
|
||||
"response_timeouts": 0,
|
||||
"response_read_failures": 2,
|
||||
"retained_network_documents_checked": 294,
|
||||
"retained_typed_resources_found": 0,
|
||||
"linked_descriptor_targets_found": 0,
|
||||
"settled_resource_controls_checked": 2,
|
||||
"settled_control_label": "Add attachment",
|
||||
"controls_activated": false,
|
||||
"provider_queries_fabricated": false,
|
||||
"resource_completeness_verified": false,
|
||||
"resource_absence_inferred": false,
|
||||
"operator_navigation_question_pending": true,
|
||||
"original_capture_changed": false,
|
||||
"production_imported": false,
|
||||
"validation": {
|
||||
"full_gate": "make check passed",
|
||||
"junit": {
|
||||
"tests": 596,
|
||||
"errors": 0,
|
||||
"failures": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"synthetic_resource_node_tests": 4
|
||||
},
|
||||
"private_files": [
|
||||
{
|
||||
"path": "capture.json",
|
||||
"sha256": "81a8ee56ee6885e5d54ebd184bf309effb01fade3ff5d7ff6229e9d96f973751"
|
||||
},
|
||||
{
|
||||
"path": "index.html",
|
||||
"sha256": "9218781bcf9273e2095494296d1d3f23d324e671c6d21920d69207b36181122f"
|
||||
},
|
||||
{
|
||||
"path": "ui-resource-controls-settled.json",
|
||||
"sha256": "ad0b3823db1d241ce1473df83bd2a7bba32da49e44dc48e0e1d5954bd8a6faa9"
|
||||
},
|
||||
{
|
||||
"path": "ui-resource-controls.json",
|
||||
"sha256": "4050f519bca5e4791ac0f0680a63eee2167c2b0e89c530ad045514bcb26a5da3"
|
||||
},
|
||||
{
|
||||
"path": "ui-resource-observation.json",
|
||||
"sha256": "704363f4bb6ea5dcc606da13b667b979dd419d631b14b2c8517deb90723ccd1e"
|
||||
}
|
||||
],
|
||||
"implementation_files": [
|
||||
{
|
||||
"path": "scripts/capture-bubble-resources.mjs",
|
||||
"sha256": "647691c4283ee09eb8b320bbf3ef943eb8ad6be8d365e98a6b28dfd2a43bc92a"
|
||||
},
|
||||
{
|
||||
"path": "scripts/bubble-resource-utils.mjs",
|
||||
"sha256": "e0cbd131bc28f67b3a88c45fb1e07cf12b33a71db051b5507e2e7ac14bf30170"
|
||||
},
|
||||
{
|
||||
"path": "scripts/bubble-corpus-utils.mjs",
|
||||
"sha256": "aeb867c5a4fc332e3c994a24e47c7f93cf9d1b8f95738871ef9971f81571f502"
|
||||
},
|
||||
{
|
||||
"path": "scripts/tests/bubble-resource-utils.test.mjs",
|
||||
"sha256": "d52dfc4fe8c3630ed020e9d6456e6836302c8f3e378bda424a1e3007873dee63"
|
||||
},
|
||||
{
|
||||
"path": "tests/test_bubble_capture_guards.py",
|
||||
"sha256": "384e7da7eee76ca7f55cfcb45f9e2d8722509c9d0f3668288053b56f410047e1"
|
||||
}
|
||||
],
|
||||
"statehub_readback": {
|
||||
"tasks": [
|
||||
{
|
||||
"task_id": "0002882d-f156-5a5d-b524-d04793f4684d",
|
||||
"status": "progress",
|
||||
"resource_evidence_synced": true
|
||||
},
|
||||
{
|
||||
"task_id": "8d06cdee-e0ce-5c3e-bf98-705deed0ee62",
|
||||
"status": "progress",
|
||||
"resource_evidence_synced": true
|
||||
}
|
||||
],
|
||||
"t01_intervention_note_matches_source": true,
|
||||
"fix_consistency_exit_code": 0,
|
||||
"automation_errors": 0,
|
||||
"assessment_failures": 0,
|
||||
"warnings": 7
|
||||
}
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.bubble-resource-hover-observation.v1",
|
||||
"completed_at": "2026-10-31T18:35:54.302241+00:00",
|
||||
"source_articles_sha256": "f33967c79c0f8a60a7d504f5d5e4082f8bc9e3c34f6a3160cb200fd380831d62",
|
||||
"private_observation_sha256": "79d9fcae0a894a04ffbba73d91b1080dcfa745fd0d9a9eb9c89e63908d00a412",
|
||||
"articles_visited": 5,
|
||||
"all_source_routes_matched": true,
|
||||
"visible_images_hovered": 42,
|
||||
"typed_resources_found": 0,
|
||||
"visual_overlay_download_points_to_already_retained_visual": true,
|
||||
"ui_controls_activated": false,
|
||||
"resource_completeness_verified": false,
|
||||
"production_changes": false
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.source-case-disposition.v1",
|
||||
"status": "accepted_intentional_omission",
|
||||
"source_field": "_list_custom_scrap",
|
||||
"decision_id": "6db14274-4450-4ae2-b77a-cd4c88369eaa",
|
||||
"decided_by": "Bernd",
|
||||
"recorded_at": "2026-10-31T19:56:57.605591+00:00",
|
||||
"user_instruction": "Lets ignore the scrap cases as they are legacy relicts that are no longer needed.",
|
||||
"case_manifest_sha256": "c8c8394a7b801b7cf00ae3bb3411b0f12a52fd502b3f87ed0620124167d5a758",
|
||||
"source_articles_sha256": "f33967c79c0f8a60a7d504f5d5e4082f8bc9e3c34f6a3160cb200fd380831d62",
|
||||
"original_source_evidence_retained": true,
|
||||
"page_bodies_or_dates_changed": false,
|
||||
"production_data_deleted": false,
|
||||
"other_source_exceptions_waived": false,
|
||||
"case_numbers": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4
|
||||
],
|
||||
"private_disposition_sha256": "ae9aef7b6520734a22b4c276ba161ef6206872009a41ddc3d044007fe65d045d"
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.scrap-navigation-observation.v1",
|
||||
"completed_at": "2026-10-31T19:51:07.317085+00:00",
|
||||
"source_articles_sha256": "f33967c79c0f8a60a7d504f5d5e4082f8bc9e3c34f6a3160cb200fd380831d62",
|
||||
"navigators_opened": 4,
|
||||
"typed_resource_records": 0,
|
||||
"absence_inferred": false,
|
||||
"source_mutations": false,
|
||||
"production_imported": false,
|
||||
"private_observation_sha256": "e2eaf4a94c311107c5fd1a43371ca9bfd7a2cf5f2010f40097441bf1f67712c8",
|
||||
"private_case_manifest_sha256": "c8c8394a7b801b7cf00ae3bb3411b0f12a52fd502b3f87ed0620124167d5a758",
|
||||
"private_review_path": "/home/worsch/.config/coulomb-social/auth/exports/scrap-review-20261031/index.html",
|
||||
"remaining_required_evidence": "Original scrap viewing path/content or explicit per-case disposition"
|
||||
}
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.bubble-visual-preparation.v1",
|
||||
"status": "captured_and_privately_prepared_not_imported",
|
||||
"owner_task": "CSOC-WP-0014-T08",
|
||||
"private_bundle": "~/.config/coulomb-social/auth/exports/visual-bundle-20261031",
|
||||
"source_report_sha256": "75fcd87d17ea0c5042e903efd60e65839da7716e5399ff431a345486ddd10f01",
|
||||
"capture": {
|
||||
"references": 242,
|
||||
"unique_urls": 108,
|
||||
"downloaded_bytes": 168139156,
|
||||
"materialized_pages": 236,
|
||||
"body_rewriting_performed": false,
|
||||
"grants_changed": false,
|
||||
"browser_render_verified": false,
|
||||
"production_imported": false
|
||||
},
|
||||
"browser": {
|
||||
"schema": "coulomb.private-visual-decode.v1",
|
||||
"status": "all_captured_visuals_decoded",
|
||||
"decoded_images": 90,
|
||||
"bundle_sha256": "a255df2237d95588b21a5db059487ca0178d1df28c810ebaaf744c5e6491267a",
|
||||
"browser_network_disabled": true,
|
||||
"productive_fidelity_accepted": false
|
||||
},
|
||||
"preservation": {
|
||||
"schema": "coulomb.visual-preservation-proof.v1",
|
||||
"verified_output_files": 738,
|
||||
"verified_original_files": 545,
|
||||
"frontmatter_only_changes": 303,
|
||||
"all_source_bodies_and_dates_preserved": true,
|
||||
"spaces_preserved": 71,
|
||||
"original_blockers_preserved": true,
|
||||
"unassigned_records_preserved": true,
|
||||
"private_modes_verified": true,
|
||||
"private_bundle_sha256": "a255df2237d95588b21a5db059487ca0178d1df28c810ebaaf744c5e6491267a",
|
||||
"production_imported": false
|
||||
},
|
||||
"boundaries": {
|
||||
"cdn_origins": 1,
|
||||
"https_only": true,
|
||||
"redirects_allowed": false,
|
||||
"cookies_or_authorization_sent": false,
|
||||
"live_application_or_grants_changed": false,
|
||||
"source_completeness_or_fidelity_accepted": false,
|
||||
"all_other_links_attachments_reconciled": false
|
||||
},
|
||||
"tests": {
|
||||
"focused_passed": 24,
|
||||
"full_gate_passed": 570,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"warnings": 69,
|
||||
"full_junit_sha256": "d11afa225571077d1d59c68711a5f0eb402de8ceff7f2f50c279fbba7f923349",
|
||||
"final_verification_script": "native private bundle pass; final all-repo Ruff pass"
|
||||
},
|
||||
"remaining": {
|
||||
"source_graph_exception_groups": 4,
|
||||
"unassigned_article_records": 1,
|
||||
"body_link_references": 18,
|
||||
"attachment_review_flags": 1,
|
||||
"identity_and_explicit_grants": "unresolved",
|
||||
"productive_fidelity_verdict": "pending"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"path": "scripts/capture-bubble-visuals.py",
|
||||
"sha256": "c16c8cf5013a6f02c9a9f79f444aea82ced7d8642b0fb2d2dc5315fabe92be7c"
|
||||
},
|
||||
{
|
||||
"path": "scripts/verify-bubble-visuals.mjs",
|
||||
"sha256": "2cb9625b0738028508957b8bc40a69b7ab2719046d20e0a69a0ac1a9394f56c5"
|
||||
},
|
||||
{
|
||||
"path": "scripts/verify-bubble-visual-preservation.py",
|
||||
"sha256": "9fbc212bd668126a0f6ce6a458b1ca3fba1e14d4b44438c0697f63dc34b5bc3d"
|
||||
},
|
||||
{
|
||||
"path": "tests/test_bubble_visuals.py",
|
||||
"sha256": "707fc9aa4ac0de5e40d33ee76571d74c141b361154a659f10c723a6597262006"
|
||||
}
|
||||
],
|
||||
"captured_at": "2026-10-31T13:48:44.558963+00:00",
|
||||
"goal_task_projection_readback": {
|
||||
"workplans": [
|
||||
{
|
||||
"workplan": "CSOC-WP-0012",
|
||||
"tasks": 14,
|
||||
"done": 6
|
||||
},
|
||||
{
|
||||
"workplan": "CSOC-WP-0013",
|
||||
"tasks": 5,
|
||||
"done": 2
|
||||
},
|
||||
{
|
||||
"workplan": "CSOC-WP-0014",
|
||||
"tasks": 8,
|
||||
"done": 3
|
||||
},
|
||||
{
|
||||
"workplan": "CSOC-WP-0015",
|
||||
"tasks": 6,
|
||||
"done": 3
|
||||
}
|
||||
],
|
||||
"all_task_statuses_match_source": true,
|
||||
"progress_event_id": "bb485164-d8ff-49cb-8c88-6aebe4e15cf0"
|
||||
}
|
||||
}
|
||||
|
|
@ -96,19 +96,3 @@ session revocation, process-log disposition and primary/mirror/protected-kit bac
|
|||
expiry. The existing independent-kit no-expiry protection must not be silently
|
||||
overridden. No client offboarding or productive deletion is authorized by this
|
||||
implementation or its tests.
|
||||
|
||||
## October31 deployed return and offboarding scope
|
||||
|
||||
Revision19 has since deployed the reviewed exporter. Its packaged current-point
|
||||
proof verifies85selected local files and four record sets, no selected external
|
||||
bindings and unchanged source data; the temporary ZIP was removed afterward.
|
||||
See `identity-export-release-client-export-2026-10-31.json`. The earlier source-only
|
||||
and81file statements above retain their original dated scope.
|
||||
|
||||
The subsequent native scope check finds a second space outside the accepted
|
||||
export tenant, with an external binding under the deployment default tenant.
|
||||
Zero external bindings in the selected tenant must not be promoted to complete
|
||||
instance attribution. The retained content PVC, five isolated database restores,
|
||||
sessions, root journals and protected backup holds also need explicit disposition.
|
||||
T12's concrete review is `client-offboarding-scope-review-2026-10-31.md`; it does
|
||||
not authorize teardown or deletion of this active service.
|
||||
|
|
|
|||
|
|
@ -1,157 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.client-offboarding-scope.v1",
|
||||
"recorded_at": "2026-10-31T14:55:21.318848+00:00",
|
||||
"task": "CSOC-WP-0012-T12",
|
||||
"task_status": "progress",
|
||||
"current_application_scope": {
|
||||
"observed_at": "2026-10-31T14:51:29.215499+00:00",
|
||||
"scope": "accepted tenant:platform only; canonical client binding unresolved",
|
||||
"database_name": "coulomb_social_db",
|
||||
"record_counts": {
|
||||
"members.user": 1,
|
||||
"members.member": 1,
|
||||
"spaces.space": 1,
|
||||
"spaces.spacemembership": 1
|
||||
},
|
||||
"selected_local_content_files": 85,
|
||||
"external_binding_count": 0,
|
||||
"all_spaces_count": 2,
|
||||
"selected_spaces_count": 1,
|
||||
"session_row_count": 43,
|
||||
"export_ownership_checks_passed": true,
|
||||
"read_only_repeatable_read_transaction": true,
|
||||
"external_writer_fence": false,
|
||||
"coherent_export_created": false,
|
||||
"source_changed": false
|
||||
},
|
||||
"unselected_scope": {
|
||||
"unselected_spaces": 1,
|
||||
"unselected_external_bindings": 1,
|
||||
"unselected_tenant_count": 1,
|
||||
"unselected_tenants_match_deployment_default": true,
|
||||
"unselected_spaces_with_creator": 0,
|
||||
"canonical_client_assignment_inferred": false
|
||||
},
|
||||
"native_content_storage": {
|
||||
"observed_at": "2026-10-31T14:49:42.586579+00:00",
|
||||
"deployment_uid": "2dbe661a-d232-4477-bbd1-833813077fbe",
|
||||
"persistent_claims": [
|
||||
{
|
||||
"name": "coulomb-social-content",
|
||||
"uid": "9888abeb-9d52-4c70-a23d-b5494780d9c3",
|
||||
"phase": "Bound",
|
||||
"storage_class": "local-path",
|
||||
"capacity": {
|
||||
"storage": "2Gi"
|
||||
},
|
||||
"helm_resource_policy": "keep",
|
||||
"pv_name": "pvc-9888abeb-9d52-4c70-a23d-b5494780d9c3",
|
||||
"pv_uid": "ac1aa73c-08d9-4561-995b-41060468e506",
|
||||
"pv_reclaim_policy": "Delete",
|
||||
"claim_uid_matches": true
|
||||
}
|
||||
],
|
||||
"configuration_changed": false
|
||||
},
|
||||
"retained_local_restores": {
|
||||
"containers": 5,
|
||||
"running": 5,
|
||||
"backing_database_volumes": 5,
|
||||
"all_networks_internal": true,
|
||||
"all_networks_single_container": true,
|
||||
"published_ports": 0,
|
||||
"public_receipt_linked_containers": 4,
|
||||
"additional_private_receipt_sha256": "cc1d1be94da22756b52a00cc743ecd72b5cf8e956a7fd91288174dbb4499902b",
|
||||
"additional_public_binding": "docs/release/identity-export-release-client-export-2026-10-31.json",
|
||||
"all_five_have_receipt_bindings": true,
|
||||
"stopped_or_deleted": false
|
||||
},
|
||||
"scope_limits": {
|
||||
"canonical_client_assignment_resolved": false,
|
||||
"unselected_external_content_resolved": false,
|
||||
"fresh_coherent_export_created": false,
|
||||
"client_delivery_or_acceptance": false,
|
||||
"sessions_decoded_or_revoked": false,
|
||||
"instance_or_data_deleted": false,
|
||||
"backup_hold_released": false,
|
||||
"provider_expiry_performed": false,
|
||||
"disposable_offboarding_rehearsal_performed": false,
|
||||
"offboarding_accepted": false
|
||||
},
|
||||
"private_inventory_files": [
|
||||
{
|
||||
"name": "accepted-point-link.json",
|
||||
"sha256": "eb54af2fe49bf90a02680d68c8f69335e8a591042479faa0367dc9c925f6f097"
|
||||
},
|
||||
{
|
||||
"name": "current-application-scope.json",
|
||||
"sha256": "e24c3112c52e8ffd80a146c4dec8bd00e187ca0de14661644dd58206ebc535a6"
|
||||
},
|
||||
{
|
||||
"name": "native-storage.json",
|
||||
"sha256": "e8f4c32462ffb9869ceaf8991874d14858705ebe59978eb9fc2743daa0135efc"
|
||||
},
|
||||
{
|
||||
"name": "restore-scope-linked.json",
|
||||
"sha256": "8f2af25c9c80c69319bd6b61cf96094fe4054ed27fc1c63ae586962987971111"
|
||||
},
|
||||
{
|
||||
"name": "restore-scope-summary.json",
|
||||
"sha256": "6d24beb8739c34eaa6c34b9d5829b161ba5e863eea1376103598b7a2f04822a5"
|
||||
},
|
||||
{
|
||||
"name": "retained-restores.json",
|
||||
"sha256": "5b24822d8025c83011a286f097ca7f88125e42979864660ec5613e5b83a1323d"
|
||||
},
|
||||
{
|
||||
"name": "unselected-scope.json",
|
||||
"sha256": "33df8b171bfc31713118b216f1fb3b113c716d42560a00585eaee0fa91dcd56d"
|
||||
}
|
||||
],
|
||||
"evidence_sources": [
|
||||
{
|
||||
"path": "docs/release/identity-export-release-client-export-2026-10-31.json",
|
||||
"sha256": "d1b9d88b850a5aed19159bee867c4b0723a7a1df9e13c179d57a3de9e9cb67af"
|
||||
},
|
||||
{
|
||||
"path": "docs/release/provider-kit-recovery-post-date-2026-10-31.json",
|
||||
"sha256": "b7191972f4e4f7d0b74ae7bbdeb93aabdb79e2baf27ccb49108f6f30f417182c"
|
||||
},
|
||||
{
|
||||
"path": "docs/release/generation-retention-post-date-2026-10-31.json",
|
||||
"sha256": "10c78d8a69c02f28f9ad5f126c4daac89f6988516e3234ea67eaee6c0b5be6df"
|
||||
},
|
||||
{
|
||||
"path": "coulomb_social/apps/members/client_export.py",
|
||||
"sha256": "223a9ee42af6f17829aa263abcae595626e292b887de85820f48fdfa4a6363fa"
|
||||
},
|
||||
{
|
||||
"path": "/home/worsch/railiance-apps/helm/coulomb-social-values.yaml",
|
||||
"sha256": "63a45d1cfb395eff7cfdf21ed2100fb9562b7a2ab6b896afecbebfaabacae547"
|
||||
},
|
||||
{
|
||||
"path": "/home/worsch/railiance-apps/charts/coulomb-social/templates/content-pvc.yaml",
|
||||
"sha256": "5c4ddcaee2b3dcdf17da061b1a7a2cb1e0398d2f56f4ef31790cfaaf648b0fee"
|
||||
},
|
||||
{
|
||||
"path": "/home/worsch/the-custodian/canon/standards/business-app-service-contract_v0.1.md",
|
||||
"sha256": "83d2799d39f957d88aa1d71c3f04f7c2a0e168390249dc409ce149128d44e80c"
|
||||
}
|
||||
],
|
||||
"statehub_readback": {
|
||||
"task_id": "54af74b0-3212-537e-a02c-d2d8a091caf9",
|
||||
"status": "progress",
|
||||
"scope_review_synced": true,
|
||||
"fix_consistency_exit_code": 0,
|
||||
"automation_errors": 0,
|
||||
"assessment_failures": 0,
|
||||
"warnings": 8
|
||||
},
|
||||
"validation": {
|
||||
"native_scope_assertions_passed": true,
|
||||
"private_modes_and_hashes_verified": true,
|
||||
"source_hashes_verified": true,
|
||||
"json_round_trip_checked": true,
|
||||
"application_code_changed": false
|
||||
}
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
# Client offboarding scope review — 2026-10-31
|
||||
|
||||
CSOC-WP-0012-T12 now has a concrete, non-destructive scope review. It remains
|
||||
**progress**, not accepted or executable. This review neither closes the active
|
||||
service nor authorizes deletion, session revocation, expiry or credential changes.
|
||||
|
||||
The governing [service contract §6.2](/home/worsch/the-custodian/canon/standards/business-app-service-contract_v0.1.md)
|
||||
requires support for complete client export and deletion: export, instance
|
||||
teardown and backup expiry. Demonstrating that capability does not require
|
||||
tearing down this active client now. T12 still needs its agreed scope, private
|
||||
export delivery/acceptance and independently verified teardown/expiry procedure.
|
||||
|
||||
## Verified scope and unresolved attribution
|
||||
|
||||
The packaged revision19 export proof covers the accepted `tenant:platform`:
|
||||
one User, Member, Space and SpaceMembership and85local files. Its coherent
|
||||
07:13recovery point had no external bindings in that selected tenant. The temporary
|
||||
export was removed after validation; this is not a delivered client archive.
|
||||
|
||||
A fresh read-only application transaction at14:51Z repeats the ownership checks
|
||||
and finds the same four record counts and85selected local files, with no selected
|
||||
external binding. It also finds **two spaces in the instance**, one outside the
|
||||
selected tenant. A separate bounded read confirms that unselected space has an
|
||||
external binding and belongs to the configured default tenant (`tenant:coulomb`),
|
||||
with no creator link. These facts do not establish its legal client, whether it
|
||||
is dispensable, or whether its remote content has been preserved. T11's canonical
|
||||
client/app/instance mapping and the disposition of this unselected binding must
|
||||
precede any proposal to tear down the whole database or instance.
|
||||
|
||||
The live read observed43session rows. Those rows were counted, not decoded or
|
||||
attributed to the selected client. The read used a read-only transaction; app
|
||||
writers were not fenced and no new coherent export was created. Do not combine
|
||||
its counts with the older export hash to claim a newly verified deliverable.
|
||||
|
||||
## Stores and owner returns
|
||||
|
||||
| Store or boundary | Established evidence | Required offboarding return |
|
||||
| --- | --- | --- |
|
||||
| App SQL data, local principals, grants and admin history | Database `coulomb_social_db`; schema-derived inventory and selected-tenant export guards; one unselected externally bound space | Resolve client/tenant scope, produce and privately deliver a final coherent export, obtain acceptance, then review the database/role action through the deployment/database owners. Preserve the shared apps-pg cluster and other databases. |
|
||||
| Local pages, assets, aliases and all revisions |85selected local files; deployed content PVC `coulomb-social-content`, UID9888abeb-9d52-4c70-a23d-b5494780d9c3, Bound2Gi/local-path | Export all assigned content, including deleted-page revisions. A future teardown must separately identify the claim/PV and verify its storage outcome. The PVC has `helm.sh/resource-policy: keep`; uninstalling the release alone is not content deletion. |
|
||||
| App sessions and transient OIDC state |43current session rows; intentionally excluded from the client ZIP | Establish the approved app/tenant scope and revoke its sessions through a reviewed action. A count does not attribute anonymous/transient sessions; do not infer authority to revoke shared identity-provider sessions. |
|
||||
| External content and identity links | One unselected externally bound space; OIDC/NetKingdom and user-engine are shared owners | Resolve the remote content and client assignment. Review only application-specific links/grants with their owners; do not delete shared human identities, provider clients or services based on local Member removal. |
|
||||
| Node backup and release state | Existing paired archives, release capsules and date-operation journals; date journals can retain original index bytes outside CONTENT_ROOT | Include all assigned private bytes and journal/preimage copies in the exact retained/deleted set. T04's custody repair changes ownership/modes only and is not a disposition or expiry approval. |
|
||||
| Local retained restores | Five running PostgreSQL recovery containers, five volume-backed stores; internal networks, one container each, no published ports | Preserve them pending disposition. The private inventory records container IDs, volume/mount identities, networks and links to existing restore receipts. Future cleanup must bind exact identities and verify both database volumes and corresponding plaintext content directories; stopping a container is not deletion. |
|
||||
| Private source captures, review bundles and local archives | Source inventory spans71spaces and several source principals; private review/export copies are outside the live app | Classify ownership before deleting any directory. The whole source capture is not automatically the selected tenant's dataset. Preserve originals, accepted evidence and unresolved source records until explicit disposition. |
|
||||
| Primary provider copies | Dedicated Coulomb application-archive prefix in shared `railiance-platform-pg-backup` | Provider owner must inventory exact versions, retain the final accepted export/recovery point as agreed, then execute admitted expiry. Do not delete the shared bucket or other applications' prefixes. |
|
||||
| Mirrored generations and public receipts | Existing dated generation selection and exact-version readback; expiry remains separately admitted | Recompute the current exact keep/expiry set at execution. Rolling retention is not full client offboarding; deleting one mirror does not remove primary or protected copies. |
|
||||
| Protected kits, proofs and separate recovery-key custody | Latest provider kit4166eb8b/version1793432303941465 is explicitly outside automatic expiry | Obtain explicit owner disposition for all client-bearing kit versions, proofs and associated recovery custody. Existing no-expiry protection remains in force; destroying a key alone is not a demonstrated complete offboarding procedure. |
|
||||
| Logs, telemetry and notification ledgers | App/process logs and operator state are outside the ZIP; email-connect is a shared owner | Establish attribution and the permitted retention/expiry outcome with each owner. No log, mail-ledger or telemetry payload inventory or removal is claimed here. Preserve unrelated applications and required retained records. |
|
||||
| Deployment, endpoint and credential projections | Revision19 and its declared resource/identity boundaries remain active | After accepted export and explicit teardown admission, remove only the bound instance resources/projections and verify routing, workloads, data stores and owner returns. Keep shared cluster, forge, identity, mail, telemetry and provider services. |
|
||||
|
||||
The PVC's native PV reclaim policy is `Delete`, and its claim UID matches the
|
||||
bound PVC. That policy is a configuration fact, not proof of deletion: the claim
|
||||
has not been removed, and no storage teardown has been exercised.
|
||||
|
||||
## Evidence and closure sequence
|
||||
|
||||
The public aggregate proof is `client-offboarding-scope-2026-10-31.json`. Exact
|
||||
local restore volume/path metadata stays in the private
|
||||
`~/.config/coulomb-social/auth/exports/offboarding-review-20261031/` inventory.
|
||||
Four restore containers link directly to public recovery receipts; the fifth
|
||||
links through the private receipt whose SHA matches the published revision19
|
||||
client-export proof. All five remain running and untouched.
|
||||
|
||||
1. Bind the canonical client to the actual tenant/instance scope and resolve the
|
||||
unselected external binding; do not substitute the deployment default tenant.
|
||||
2. Agree the complete store list and retention/expiry outcomes, including the
|
||||
protected-kit hold, shared-owner stores and retained private copies.
|
||||
3. Prepare the exact teardown/expiry procedure and demonstrate it on a disposable
|
||||
scoped instance and provider-owner test resources. Keep production identities,
|
||||
data and held backups out of that destructive rehearsal.
|
||||
4. Produce a fresh coherent export for private delivery and obtain the required
|
||||
client acceptance. The existing rehearsal archive no longer exists.
|
||||
5. If actual offboarding is later requested, bind the then-current identities,
|
||||
object versions, writer fence, accepted export and approvals before execution;
|
||||
retain independent completion/exception receipts for every included store.
|
||||
|
||||
This review does not choose retention durations, release holds, infer a client ID
|
||||
or claim that steps3–5 have been performed. It supplies the missing concrete
|
||||
scope for T12 while preserving T04 retention, T11 attribution, WP-0013 portability
|
||||
and WP-0014 source/grant obligations.
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.content-release-supervisor-disposition.v1",
|
||||
"proposal_digest": "sha256:e96752ecfa7adef2fd1d9da48902c8e63de124ccfd272fe20ba79b758b3ca4a3",
|
||||
"decision_id": "d9b70cc5-e035-40ae-8d0d-020190581202",
|
||||
"approved_by": "Bernd",
|
||||
"recorded_at": "2026-10-31T20:16:08.885956+00:00",
|
||||
"user_instruction": "Good, then lets do deployment the productive acceptance work now.",
|
||||
"status": "deployment_scope_approved_awaiting_founder_execution",
|
||||
"execution_performed": false,
|
||||
"human_only_execution_lane_changed": false,
|
||||
"productive_acceptance_inferred": false
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.content-acceptance-build.v1",
|
||||
"completed_at": "2026-10-31T18:38:08.525103+00:00",
|
||||
"source": "1139a6d30eee4f75317b46bd45120a15d818455f",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5",
|
||||
"build_context": "clean restricted git archive",
|
||||
"source_full_gate_tests": 568,
|
||||
"runtime_packages_and_python_unchanged": true,
|
||||
"runtime": {
|
||||
"python": "3.12.16",
|
||||
"distributions": {
|
||||
"h11": "0.16.0",
|
||||
"httpcore": "1.0.9",
|
||||
"psycopg": "3.3.4",
|
||||
"joserfc": "1.7.4",
|
||||
"anyio": "4.14.2",
|
||||
"cryptography": "50.0.0",
|
||||
"idna": "3.18",
|
||||
"certifi": "2026.7.22",
|
||||
"packaging": "26.3",
|
||||
"python-decouple": "3.8",
|
||||
"psycopg-binary": "3.3.4",
|
||||
"sqlparse": "0.5.5",
|
||||
"whitenoise": "6.12.0",
|
||||
"cffi": "2.1.1",
|
||||
"markdown": "3.10.3",
|
||||
"webencodings": "0.5.1",
|
||||
"pycparser": "3.0",
|
||||
"bleach": "6.4.0",
|
||||
"authlib": "1.7.2",
|
||||
"django": "6.1",
|
||||
"typing_extensions": "4.16.0",
|
||||
"gunicorn": "26.0.0",
|
||||
"asgiref": "3.12.1",
|
||||
"httpx": "0.28.1",
|
||||
"dj-database-url": "3.1.2"
|
||||
}
|
||||
},
|
||||
"django_checks": {
|
||||
"check": "System check identified no issues (0 silenced).",
|
||||
"makemigrations": "No changes detected"
|
||||
},
|
||||
"new_database_migrations": false,
|
||||
"production_deployed": false
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-content-acceptance-recovery.v1",
|
||||
"status": "packaged_recovered_export_and_views_verified",
|
||||
"source": "1139a6d30eee4f75317b46bd45120a15d818455f",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5",
|
||||
"restore_receipt_sha256": "9dacbd44544f93abf99354158cf610b4fb1f4e59611b22056b3086e0033231ab",
|
||||
"retained_point_captured_at": "2026-10-31T20:21:01Z",
|
||||
"candidate_application": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 40,
|
||||
"unsaved_outsider_page_denials": 40,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"previous_image_application": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 40,
|
||||
"unsaved_outsider_page_denials": 40,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"client_export": {
|
||||
"status": "recovered_client_export_verified",
|
||||
"schema": "coulomb.client-dataset-export.v1",
|
||||
"content_files": 85,
|
||||
"records": {
|
||||
"members.user": 1,
|
||||
"members.member": 1,
|
||||
"spaces.space": 1,
|
||||
"spaces.spacemembership": 1
|
||||
},
|
||||
"admin_events": 0,
|
||||
"archive_sha256": "597f5929cae723e9f5d895afac6f5c96022049cb6bd938d4908d6aa56221f4ea",
|
||||
"offboarding_complete": false,
|
||||
"all_source_tables_compared": 13,
|
||||
"all_source_files_compared": 86,
|
||||
"archive_member_hashes_verified": true,
|
||||
"selected_client_content_complete_locally": true,
|
||||
"source_sql_and_content_unchanged": true,
|
||||
"external_bindings_require_review": 0,
|
||||
"sessions_and_credentials_excluded": true
|
||||
},
|
||||
"source_content_files_unchanged": 86,
|
||||
"all_tables_unchanged": true,
|
||||
"application_source_overlay": false,
|
||||
"network_internal": true,
|
||||
"published_ports": 0,
|
||||
"production_access": false,
|
||||
"production_restore": false,
|
||||
"driver_sha256": "ce8c34a0ad00f9c4ac1ba6dd2043884aa07c90e216074cae070626aa04bf1639"
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.image-release-independent-recovery.v1",
|
||||
"status": "fresh_point_independently_retrieved_and_restored",
|
||||
"completed_at": "2026-10-31T20:27:35.058428+00:00",
|
||||
"captured_at": "2026-10-31T20:21:01Z",
|
||||
"primary_version": "1793478121590106",
|
||||
"mirror_version": "1793478426025763",
|
||||
"mirror_receipt_version": "1793478427159655",
|
||||
"ciphertext_sha256": "91b4ffe4874a53e3422d604b7c3fa85f6551a481411ef82b2209993552486bfb",
|
||||
"independent_reader_used": true,
|
||||
"unpack": {
|
||||
"status": "decrypted_pair_verified",
|
||||
"version_id": "1793478121590106",
|
||||
"encrypted_sha256": "91b4ffe4874a53e3422d604b7c3fa85f6551a481411ef82b2209993552486bfb",
|
||||
"captured_at": "2026-10-31T20:21:01Z",
|
||||
"database_sha256": "c5faa20ac0c443635393e04cf5b154710780d829d6c085edc098e2dd7525fc6a",
|
||||
"content_sha256": "1bf31bafc19d8c4847f3793463189f13ce4b470ed96ccdc614b269acca6c12c0",
|
||||
"application_restore_verified": false
|
||||
},
|
||||
"restore": {
|
||||
"status": "restored_verified",
|
||||
"database_tables": 13,
|
||||
"database_rows": 115,
|
||||
"database_rows_and_sequences_match": true,
|
||||
"content_files": 86,
|
||||
"content_hashes_match": true,
|
||||
"network_internal": true,
|
||||
"published_ports": 0,
|
||||
"postgres_image_id": "sha256:ff23cdce56cac62ada6f66013e1a50864c0abbe79d132d40b6e05bd80f378a70",
|
||||
"elapsed_seconds": 4.42,
|
||||
"content_was_empty": false
|
||||
},
|
||||
"elapsed_seconds": 5.517,
|
||||
"production_restore": false,
|
||||
"current_kit_replaced": false,
|
||||
"driver_sha256": "a88a63c0e990cc4d8d9180d1907ec367f2e7f54c81d00e79f38ded4f30384341"
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.content-acceptance-independent-postflight.v1",
|
||||
"status": "deployed_image_and_complete_native_state_verified",
|
||||
"proposal_digest": "sha256:e96752ecfa7adef2fd1d9da48902c8e63de124ccfd272fe20ba79b758b3ca4a3",
|
||||
"receipt_sha256": "074ec03d62d43f35bd6c276213a28de4a7b0161132379221bec0e402b5334233",
|
||||
"helm_revision": 20,
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5",
|
||||
"source": "1139a6d30eee4f75317b46bd45120a15d818455f",
|
||||
"packaged_source_files_verified": 79,
|
||||
"sole_ready_content_writer": true,
|
||||
"all_frozen_capsule_files_verified": 23,
|
||||
"installed_helper_hashes_verified": true,
|
||||
"snapshot_pin_refreshed": true,
|
||||
"public_health_landing_static_verified": true,
|
||||
"postflight": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 40,
|
||||
"unsaved_outsider_page_denials": 40,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"fresh_paired_point": {
|
||||
"captured_at": "2026-10-31T20:21:01Z",
|
||||
"destination": "s3://railiance-platform-pg-backup/platform-pg/application-archives/coulomb-social/2026/10/31/20261031T202101Z-2ad4faf215939d67e82f67a4.tar.age",
|
||||
"version_id": "1793478121590106",
|
||||
"encrypted_sha256": "91b4ffe4874a53e3422d604b7c3fa85f6551a481411ef82b2209993552486bfb",
|
||||
"encrypted_bytes": 2181848,
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed"
|
||||
},
|
||||
"timers_activated": false,
|
||||
"production_data_restored": false,
|
||||
"productive_acceptance_inferred": false
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.guarded-image-release.v1",
|
||||
"proposal_digest": "sha256:e96752ecfa7adef2fd1d9da48902c8e63de124ccfd272fe20ba79b758b3ca4a3",
|
||||
"started_at": "2026-10-31T18:41:21.634253+00:00",
|
||||
"status": "live_release_preflight_verified",
|
||||
"production_data_restored": false,
|
||||
"timers_activated": false,
|
||||
"node_request_percent": {
|
||||
"cpu": 68,
|
||||
"memory": 76
|
||||
},
|
||||
"preflight": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0
|
||||
},
|
||||
"live_changes": false
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.guarded-image-release.v1",
|
||||
"proposal_digest": "sha256:e96752ecfa7adef2fd1d9da48902c8e63de124ccfd272fe20ba79b758b3ca4a3",
|
||||
"started_at": "2026-10-31T20:14:42.622703+00:00",
|
||||
"status": "live_release_preflight_verified",
|
||||
"production_data_restored": false,
|
||||
"timers_activated": false,
|
||||
"node_request_percent": {
|
||||
"cpu": 68,
|
||||
"memory": 76
|
||||
},
|
||||
"preflight": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0
|
||||
},
|
||||
"live_changes": false
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-source-provenance.v1",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5",
|
||||
"source": "1139a6d30eee4f75317b46bd45120a15d818455f",
|
||||
"packaged_file_count": 79,
|
||||
"all_packaged_source_bytes_match": true,
|
||||
"source_revision_label_verified": true,
|
||||
"registry_digest_resolves": true,
|
||||
"application_source_overlay": false,
|
||||
"manifest_sha256": "2eca0618df5bdf35928869c3b848be36190065a4cca8f855bba372df6c516556"
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
{
|
||||
"completed_at": "2026-10-31T20:22:30.428195+00:00",
|
||||
"elapsed_seconds": 97.22,
|
||||
"existing_global_constraint_preserved": true,
|
||||
"fresh_paired_point": {
|
||||
"age_recipient": "age1qm30jk8q0cezey652dk2dhcr3d9vs528v6lg8mavl6d4q3e3vgnqmrmyy3",
|
||||
"application": "coulomb-social",
|
||||
"application_restore_verified": false,
|
||||
"captured_at": "2026-10-31T20:21:01Z",
|
||||
"ciphertext_bytes": 2181848,
|
||||
"ciphertext_sha256": "91b4ffe4874a53e3422d604b7c3fa85f6551a481411ef82b2209993552486bfb",
|
||||
"completed_at": "2026-10-31T20:22:02.185627+00:00",
|
||||
"content_sha256": "1bf31bafc19d8c4847f3793463189f13ce4b470ed96ccdc614b269acca6c12c0",
|
||||
"database_sha256": "c5faa20ac0c443635393e04cf5b154710780d829d6c085edc098e2dd7525fc6a",
|
||||
"destination": "s3://railiance-platform-pg-backup/platform-pg/application-archives/coulomb-social/2026/10/31/20261031T202101Z-2ad4faf215939d67e82f67a4.tar.age",
|
||||
"encrypted_bytes": 2181848,
|
||||
"encrypted_sha256": "91b4ffe4874a53e3422d604b7c3fa85f6551a481411ef82b2209993552486bfb",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed",
|
||||
"immutable_create": true,
|
||||
"local_archive": "20261031T202101Z-2ad4faf215939d67e82f67a4.tar.age",
|
||||
"object_key": "platform-pg/application-archives/coulomb-social/2026/10/31/20261031T202101Z-2ad4faf215939d67e82f67a4.tar.age",
|
||||
"pause_and_capture_seconds": 59.82,
|
||||
"remote_retrieval_verified": true,
|
||||
"schema": "platform.application-primary-archive.v1",
|
||||
"status": "offsite_fetched_verified",
|
||||
"version_id": "1793478121590106"
|
||||
},
|
||||
"helm_revision": 20,
|
||||
"node_request_percent": {
|
||||
"cpu": 68,
|
||||
"memory": 76
|
||||
},
|
||||
"pid": 1461378,
|
||||
"postflight": {
|
||||
"actual_owner_pages_rendered": 40,
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"business_tables": 12,
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"duplicate_slug_groups": 0,
|
||||
"global_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"production_identity_or_grant_created": false,
|
||||
"tenant_slug_constraint": true,
|
||||
"unsaved_outsider_page_denials": 40
|
||||
},
|
||||
"preflight": {
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"business_tables": 12,
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"duplicate_slug_groups": 0,
|
||||
"global_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"tenant_slug_constraint": true
|
||||
},
|
||||
"private_values_printed": false,
|
||||
"production_data_restored": false,
|
||||
"proposal_digest": "sha256:e96752ecfa7adef2fd1d9da48902c8e63de124ccfd272fe20ba79b758b3ca4a3",
|
||||
"public_health_landing_static_verified": true,
|
||||
"schema": "coulomb.guarded-image-release.v1",
|
||||
"snapshot_pin_refreshed": true,
|
||||
"started_at": "2026-10-31T20:20:53.065197+00:00",
|
||||
"status": "image_candidate_deployed_verified",
|
||||
"timers_activated": false
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.content-release-reconciliation.v1",
|
||||
"helm_revision": 20,
|
||||
"snapshot_server_dry_run": {
|
||||
"status": "reviewed",
|
||||
"server_dry_run": true,
|
||||
"image_pinned": true,
|
||||
"pvc_read_only": true,
|
||||
"db_scope": "coulomb_social_db",
|
||||
"replicas_restored_to": 1
|
||||
},
|
||||
"backup_timers_inactive_disabled": true,
|
||||
"snapshot_source_sha256": "23f92c96b840df61f92858004241e860e0ddb32ed6fd7448294d3c8278906e46",
|
||||
"owner_live_values_match_sealed_values": true,
|
||||
"recovery_container_stopped": true,
|
||||
"snapshot_restore_regression_tests_passed": 9
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-content-acceptance-recovery.v1",
|
||||
"status": "packaged_recovered_export_and_views_verified",
|
||||
"source": "1139a6d30eee4f75317b46bd45120a15d818455f",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5",
|
||||
"restore_receipt_sha256": "3d6fe0b5d7426c9fb39ba22f18770319e0c89ba1981c61db171199d3b4e68524",
|
||||
"retained_point_captured_at": "2026-10-31T07:13:52Z",
|
||||
"candidate_application": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 92,
|
||||
"business_rows_sha256": "6243955479f7861fcdcd79b62f7f1e9f9a27c05a17bd2c17b792ebc98b2fa7b6",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 40,
|
||||
"unsaved_outsider_page_denials": 40,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"previous_image_application": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 92,
|
||||
"business_rows_sha256": "6243955479f7861fcdcd79b62f7f1e9f9a27c05a17bd2c17b792ebc98b2fa7b6",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 40,
|
||||
"unsaved_outsider_page_denials": 40,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"client_export": {
|
||||
"status": "recovered_client_export_verified",
|
||||
"schema": "coulomb.client-dataset-export.v1",
|
||||
"content_files": 85,
|
||||
"records": {
|
||||
"members.user": 1,
|
||||
"members.member": 1,
|
||||
"spaces.space": 1,
|
||||
"spaces.spacemembership": 1
|
||||
},
|
||||
"admin_events": 0,
|
||||
"archive_sha256": "eb982edcdb94c976ab3d4e9797e4c34eb72a3ee3886a37e64508744ac172a8a8",
|
||||
"offboarding_complete": false,
|
||||
"all_source_tables_compared": 13,
|
||||
"all_source_files_compared": 86,
|
||||
"archive_member_hashes_verified": true,
|
||||
"selected_client_content_complete_locally": true,
|
||||
"source_sql_and_content_unchanged": true,
|
||||
"external_bindings_require_review": 0,
|
||||
"sessions_and_credentials_excluded": true
|
||||
},
|
||||
"source_content_files_unchanged": 86,
|
||||
"all_tables_unchanged": true,
|
||||
"application_source_overlay": false,
|
||||
"network_internal": true,
|
||||
"published_ports": 0,
|
||||
"production_access": false,
|
||||
"production_restore": false,
|
||||
"driver_sha256": "da85e5f7d5cf68f599a897a932d51399340bdd026a7cddf9603bef4aeb40909a"
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/content-point-recovery-20261031/csoc-mirror-content-point.py: bc4d04c3f8ee3ca089fa9b038e6ab617eaababcb7f0aec94339e7f4eeb70f13a
|
||||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/content-point-recovery-20261031/csoc-recover-content-point.py: a88a63c0e990cc4d8d9180d1907ec367f2e7f54c81d00e79f38ded4f30384341
|
||||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/content-point-recovery-20261031/csoc-verify-deployed-content.py: fb6079fb614a23eba0985c1d4a2e5b776e2d873f29c158cf6f38254d1415b387
|
||||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/content-point-recovery-20261031/csoc-verify-fresh-content-point.py: ce8c34a0ad00f9c4ac1ba6dd2043884aa07c90e216074cae070626aa04bf1639
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
# Editor attachment follow-up — deployed and independently verified
|
||||
|
||||
Founder execution completed at Helm revision21 on2026-10-31T23:32:38Z.
|
||||
All97business rows/98files remain unchanged;43owner/43outsider checks pass.
|
||||
The command below is historical: do not rerun it. Evidence:
|
||||
editor-attachments-{receipt,independent-postflight}-2026-11-01.json.
|
||||
|
||||
Productive review found that revision20 preserves attachments but does not show
|
||||
them in edit tabs. Source `31eaa581a65e454b6ef9979326c5bdfe10e13806` adds the
|
||||
saved-file list/downloads to the editor, retains it after stale-edit refusal,
|
||||
and opens management separately so unsaved text remains in its tab.
|
||||
Main670, isolated568 and packaged110 checks pass, including the two-editor browser
|
||||
journey. Candidate/previous images pass recovered views/export without changing
|
||||
source data. Full native preflight passes against revision20/97rows/98files.
|
||||
All prior93rows/86files are unchanged; review added2spaces/2memberships/12files.
|
||||
|
||||
Image: `sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e`.
|
||||
Proposal: `sha256:2cddcf38b7052287c10dce467a200a74cfa9699c666ae9ac538fc82917129e7a`.
|
||||
This captures a fresh paired backup, performs the atomic image-only upgrade,
|
||||
checks unchanged data and refreshes the backup image pin. Rollback preserves
|
||||
writes and restores revision20's image/pin. No schema, timer, purge or mail change.
|
||||
|
||||
Save work in open editor tabs before running; reopen the editor after verified
|
||||
success. The current source-bound launcher explicitly requires founder-terminal
|
||||
execution (tools/coulomb-image-release.py:1–5 in railiance-apps).
|
||||
|
||||
```bash
|
||||
python3 /home/worsch/railiance-apps/tools/coulomb-image-release.py \
|
||||
--plan /home/worsch/railiance-apps/release/coulomb-editor-attachments-31eaa58.json \
|
||||
--execute \
|
||||
--expect-digest sha256:2cddcf38b7052287c10dce467a200a74cfa9699c666ae9ac538fc82917129e7a
|
||||
```
|
||||
|
||||
At the prompt:
|
||||
|
||||
```text
|
||||
DEPLOY sha256:2cddcf38b7052287c10dce467a200a74cfa9699c666ae9ac538fc82917129e7a
|
||||
```
|
||||
|
||||
Return the JSON result for independent verification. The next productive review
|
||||
must check both edit tabs, downloads and stale-edit text/attachment preservation.
|
||||
Evidence: editor-attachments-{validation,provenance,tests,recovery,target,baseline-change,preflight}-2026-10-31.json.
|
||||
|
||||
---
|
||||
|
||||
# Combined content release for WP-0013
|
||||
|
||||
Deployed and independently verified at Helm revision20, completed
|
||||
2026-10-31T20:22:30Z. The command below is historical: do not rerun it.
|
||||
All93business rows/86files are unchanged;40owner views/40outsider denials pass.
|
||||
See content-acceptance-independent-postflight-2026-10-31.json.
|
||||
|
||||
The candidate adds the requested attachment action menu, including author uploads
|
||||
and removal, authenticated downloads, and independent attachments on copies and
|
||||
moves. It also restores ordered-list starting numbers and fixes interrupted
|
||||
copy/move asset recovery. Removal detaches the current association; earlier
|
||||
revisions retain the file. Existing body links and visuals remain editable in the
|
||||
page editor. The upload limit is16 MiB per file and100 associations per page.
|
||||
|
||||
Source: `1139a6d30eee4f75317b46bd45120a15d818455f` on
|
||||
`csoc-wp0013-content-release`. Immutable image:
|
||||
`sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5`.
|
||||
The working repository passes670tests; the isolated release branch passes568;
|
||||
the actual image passes110focused checks without application-source overlays.
|
||||
Every packaged source file matches that commit. Runtime dependencies/Python and
|
||||
database migrations are unchanged. Historical release packets remain unchanged.
|
||||
|
||||
Both the candidate and previous image render40owner pages and deny40outsiders on
|
||||
the retained independently restored07:13point. The packaged client export verifies
|
||||
85files while all13SQL tables/86source files remain unchanged. The temporary
|
||||
recovery database was returned to its previously stopped state. This retained
|
||||
point has92business rows; current production has93. Session/login-only drift was
|
||||
previously reviewed and its fingerprints are unchanged. Execution creates and
|
||||
reads back a fresh paired backup before Helm; independent recovery of that new
|
||||
point is now verified: all13tables/115rows and86files restore exactly; the
|
||||
deployed and previous packages pass40owner/40outsider checks, and client export
|
||||
verifies85files without altering source data. See content-acceptance-fresh-
|
||||
{recovery,client-export}-2026-10-31.json.
|
||||
|
||||
The route and inactive installation prerequisites are independently verified.
|
||||
Full recurring backup/service acceptance remains WP-0012. This proposal does not
|
||||
activate timers, purge retained data, restore production data or send email.
|
||||
|
||||
## Exact attended action
|
||||
|
||||
Plan: `/home/worsch/railiance-apps/release/coulomb-content-acceptance-1139a6d.json`.
|
||||
Proposal: `sha256:e96752ecfa7adef2fd1d9da48902c8e63de124ccfd272fe20ba79b758b3ca4a3`.
|
||||
Baseline: revision19/image522bcd7f,93business rows/86files. The controller checks
|
||||
complete data/spec fingerprints, creates the paired recovery point, performs the
|
||||
atomic image-only Helm upgrade, verifies live views/data and refreshes the
|
||||
snapshot image pin. Rollback restores the prior image/pin while preserving writes.
|
||||
An older image retains the new attachment metadata/files but lacks the new menu.
|
||||
|
||||
Full native preflight reports `live_release_preflight_verified` at this exact
|
||||
digest (receipt: content-acceptance-preflight-2026-10-31.json). Resolved approval
|
||||
decision: d9b70cc5-e035-40ae-8d0d-020190581202. Executed command:
|
||||
|
||||
```bash
|
||||
python3 /home/worsch/railiance-apps/tools/coulomb-image-release.py \
|
||||
--plan /home/worsch/railiance-apps/release/coulomb-content-acceptance-1139a6d.json \
|
||||
--execute \
|
||||
--expect-digest sha256:e96752ecfa7adef2fd1d9da48902c8e63de124ccfd272fe20ba79b758b3ca4a3
|
||||
```
|
||||
|
||||
At its prompt:
|
||||
|
||||
```text
|
||||
DEPLOY sha256:e96752ecfa7adef2fd1d9da48902c8e63de124ccfd272fe20ba79b758b3ca4a3
|
||||
```
|
||||
|
||||
Founder-terminal execution is required by the source-bound launcher and the
|
||||
standing supervised execution contract in
|
||||
`the-custodian/docs/agent-autonomy-decision.md`: “The supervisor approves that
|
||||
proposal or performs it through the privileged execution path.” Bernd separately
|
||||
approved and executed this proposal; the execution gate is satisfied.
|
||||
|
||||
The action pauses writes during backup capture and the Recreate rollout. It adds
|
||||
one encrypted primary backup object and temporary scratch within the admitted
|
||||
capacity limits; provider cost is unpriced and no autopilot budget is claimed.
|
||||
Check the durable receipt before any retry. Required final status:
|
||||
`image_candidate_deployed_verified`. Receipt path:
|
||||
`/var/lib/coulomb-social-backup/releases/e96752ecfa7adef2fd1d9da48902c8e63de124ccfd272fe20ba79b758b3ca4a3/receipt.json`.
|
||||
|
||||
## Productive review after verified deployment
|
||||
|
||||
Use the prepared UC-003–006 steps in
|
||||
[productive-content-acceptance-session.md](../usecases/productive-content-acceptance-session.md).
|
||||
On a disposable page, open Attachments, add a file, download it as an authorized
|
||||
reader, duplicate/move the page, and remove the copied association. Verify that
|
||||
the original remains independent and revoked/outsider access is denied. Record
|
||||
attachment, authoring, copy/move, sharing and portability verdicts separately.
|
||||
|
||||
The three custom-topic rendering cases are accepted for now under decision
|
||||
69ec9380. The two downloadable attachments are recovered. Bernd explicitly omitted the
|
||||
four reviewed scrap cases as obsolete legacy data under resolved decision6db14274.
|
||||
Other source-body/graph exceptions remain with source reconciliation.
|
||||
No productive acceptance or WP-0013 completion is inferred from these tests.
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"baseline_revision": 19,
|
||||
"baseline_helm_manifest_sha256": "93cb277abd1aea0657be482e458dcfb268fe0bfbd45d90aa1faedcc7f5bce499",
|
||||
"deployment_uid": "2dbe661a-d232-4477-bbd1-833813077fbe",
|
||||
"baseline_spec_sha256": "42e091e52d5dae3c1f986e4898c62057fa80846adfce049a75d8fbd4681180ea",
|
||||
"candidate_spec_sha256": "8d79c64cff4bd2c62f03494e80847dc99b965ddabf35645da67e8d1020220798",
|
||||
"old_image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed",
|
||||
"expected_data": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0
|
||||
},
|
||||
"image_only_server_preview": true
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-content-acceptance-tests.v1",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5",
|
||||
"source": "1139a6d30eee4f75317b46bd45120a15d818455f",
|
||||
"tests": 110,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"network": "none",
|
||||
"read_only_root": true,
|
||||
"application_source_overlay": false,
|
||||
"synthetic_fixtures_only": true
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-content-lifecycle-tests.v1",
|
||||
"source": "23ffe2cf4b214666754a2420558943438e54251a",
|
||||
"image_id": "sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed",
|
||||
"tests": 29,
|
||||
"failures": 4,
|
||||
"expected_baseline_regressions": true,
|
||||
"failed_nodes": [
|
||||
"test_process_death_during_copy_or_move_is_recoverable[copy_page-during_first_asset]",
|
||||
"test_process_death_during_copy_or_move_is_recoverable[copy_page-during_second_asset]",
|
||||
"test_process_death_during_copy_or_move_is_recoverable[transfer_page-during_first_asset]",
|
||||
"test_process_death_during_copy_or_move_is_recoverable[transfer_page-during_second_asset]"
|
||||
],
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"network": "none",
|
||||
"read_only_root": true,
|
||||
"application_source_overlay": false,
|
||||
"test_tooling_injected": true,
|
||||
"application_modules_from_image_verified": true,
|
||||
"production_access": false,
|
||||
"junit_sha256": "edc52bd3a321d028d255b3d478020b3383d94747957ffe2985583b1f0741cb85",
|
||||
"driver_sha256": "85b65114997c7e7c5323cb77a0043e495ec132506eef07dd394c6a6361380d36",
|
||||
"test_source_sha256": "84a25a22a3cbda397e39c0508db8ea5aa90e6c467ccfa7da2b568d174d1ec449"
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
/home/worsch/coulomb-social/coulomb_social/apps/spaces/pageops.py: 055ef25b5efc75798cf17ffa68739de4d4099d2cab4d041e7c7eacdfaf43803e
|
||||
/home/worsch/coulomb-social/tests/test_content_recovery.py: 84a25a22a3cbda397e39c0508db8ea5aa90e6c467ccfa7da2b568d174d1ec449
|
||||
/home/worsch/coulomb-social/scripts/verify-packaged-source.py: 99d734f20331e8d699081d3d77e7a0d0b3bc676be69ce101377bc69eae6c70d5
|
||||
/tmp/csoc-packaged-lifecycle-tests-20261031.py: 85b65114997c7e7c5323cb77a0043e495ec132506eef07dd394c6a6361380d36
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.content-lifecycle-candidate-build.v1",
|
||||
"completed_at": "2026-10-31T11:58:26.697591+00:00",
|
||||
"source": "f306dbfa2604e4815523667740be2925c333b84e",
|
||||
"tag": "forgejo.coulomb.social/coulomb/coulomb-social:f306dbfa2604",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:d3f2f5bb90f0ba79f4e1d8098d2eb06f8940b8789e5ecb851914bbab364597ec",
|
||||
"registry_digest_independently_verified": true,
|
||||
"source_revision_label_verified": true,
|
||||
"build_context": "Clean git archive restricted to Dockerfile, dockerignore, lock, project, manage.py, app and entrypoint.",
|
||||
"build_inputs": [
|
||||
{
|
||||
"path": "Dockerfile",
|
||||
"sha256": "d0e197a18db8980eb3e51cca842d693e10ab0b4208627bba28691d10719d4a00"
|
||||
},
|
||||
{
|
||||
"path": ".dockerignore",
|
||||
"sha256": "901c8b95d95549d0e78c1c3d6d0538bf0252c8a77e9409129e0cadfa55c7c56c"
|
||||
},
|
||||
{
|
||||
"path": "pyproject.toml",
|
||||
"sha256": "5758c56fd1be89b973861ccc5ecbadb495e742ee13ebd7e19a221a0f119c54ee"
|
||||
},
|
||||
{
|
||||
"path": "uv.lock",
|
||||
"sha256": "e8ebb6fc4b5abd1ac80f1c9012f1983642d0528a8a213cfcc394261606fad887"
|
||||
},
|
||||
{
|
||||
"path": "scripts/docker-entrypoint.sh",
|
||||
"sha256": "70100256ca41ae6afe77078c810a8b6012472f0a741919f403f32088f98ab463"
|
||||
}
|
||||
],
|
||||
"runtime": {
|
||||
"previous": {
|
||||
"python": "3.12.16",
|
||||
"distributions": {
|
||||
"h11": "0.16.0",
|
||||
"httpcore": "1.0.9",
|
||||
"psycopg": "3.3.4",
|
||||
"joserfc": "1.7.4",
|
||||
"anyio": "4.14.2",
|
||||
"cryptography": "50.0.0",
|
||||
"idna": "3.18",
|
||||
"certifi": "2026.7.22",
|
||||
"packaging": "26.3",
|
||||
"python-decouple": "3.8",
|
||||
"psycopg-binary": "3.3.4",
|
||||
"sqlparse": "0.5.5",
|
||||
"whitenoise": "6.12.0",
|
||||
"cffi": "2.1.1",
|
||||
"markdown": "3.10.3",
|
||||
"webencodings": "0.5.1",
|
||||
"pycparser": "3.0",
|
||||
"bleach": "6.4.0",
|
||||
"authlib": "1.7.2",
|
||||
"django": "6.1",
|
||||
"typing_extensions": "4.16.0",
|
||||
"gunicorn": "26.0.0",
|
||||
"asgiref": "3.12.1",
|
||||
"httpx": "0.28.1",
|
||||
"dj-database-url": "3.1.2"
|
||||
}
|
||||
},
|
||||
"candidate": {
|
||||
"python": "3.12.16",
|
||||
"distributions": {
|
||||
"h11": "0.16.0",
|
||||
"httpcore": "1.0.9",
|
||||
"psycopg": "3.3.4",
|
||||
"joserfc": "1.7.4",
|
||||
"anyio": "4.14.2",
|
||||
"cryptography": "50.0.0",
|
||||
"idna": "3.18",
|
||||
"certifi": "2026.7.22",
|
||||
"packaging": "26.3",
|
||||
"python-decouple": "3.8",
|
||||
"psycopg-binary": "3.3.4",
|
||||
"sqlparse": "0.5.5",
|
||||
"whitenoise": "6.12.0",
|
||||
"cffi": "2.1.1",
|
||||
"markdown": "3.10.3",
|
||||
"webencodings": "0.5.1",
|
||||
"pycparser": "3.0",
|
||||
"bleach": "6.4.0",
|
||||
"authlib": "1.7.2",
|
||||
"django": "6.1",
|
||||
"typing_extensions": "4.16.0",
|
||||
"gunicorn": "26.0.0",
|
||||
"asgiref": "3.12.1",
|
||||
"httpx": "0.28.1",
|
||||
"dj-database-url": "3.1.2"
|
||||
}
|
||||
},
|
||||
"runtime_packages_equal": true,
|
||||
"python_versions_equal": true,
|
||||
"django_check": {
|
||||
"returncode": 0,
|
||||
"output": "System check identified no issues (0 silenced)."
|
||||
},
|
||||
"migration_drift": {
|
||||
"returncode": 0,
|
||||
"output": "No changes detected"
|
||||
}
|
||||
},
|
||||
"source_delta_from_revision_19": [
|
||||
"coulomb_social/apps/spaces/pageops.py"
|
||||
],
|
||||
"new_database_migrations": false,
|
||||
"production_deployed": false,
|
||||
"live_release_pins_modified": false,
|
||||
"source_full_gate_tests": 546,
|
||||
"packaged_lifecycle_tests": 29,
|
||||
"previous_image_expected_lifecycle_failures": 4,
|
||||
"owner_release_task": "RAPPS-WP-0015-T07",
|
||||
"remaining": [
|
||||
"Exact current-target release packet, paired rollback evidence and candidate/previous-image restored-store checks.",
|
||||
"Attended image release and independent native postflight.",
|
||||
"Productive lifecycle verdict; retention policy already accepted under c3a191f2-ce06-483f-82d7-ef8c54ea0d5e."
|
||||
]
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-source-provenance.v1",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:d3f2f5bb90f0ba79f4e1d8098d2eb06f8940b8789e5ecb851914bbab364597ec",
|
||||
"network": "none",
|
||||
"read_only_root": true,
|
||||
"entrypoint_bypassed": true,
|
||||
"database_contact": false,
|
||||
"production_changes": false,
|
||||
"comparisons": [
|
||||
{
|
||||
"commit": "f306dbfa2604e4815523667740be2925c333b84e",
|
||||
"packaged_file_count": 80,
|
||||
"source_file_count": 80,
|
||||
"different_files": 0,
|
||||
"all_packaged_source_bytes_match": true
|
||||
}
|
||||
],
|
||||
"actual_packaged_manifest_sha256": "b5c8a16b4b3d30cc9d8a7a9f3ed61bd8cb0e182589aceb5e4127fff27a8ae482",
|
||||
"dependency_or_build_reproducibility_proved": false
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-content-lifecycle-recovery.v1",
|
||||
"status": "packaged_recovered_client_export_and_views_verified",
|
||||
"source": "f306dbfa2604e4815523667740be2925c333b84e",
|
||||
"image_id": "sha256:d3f2f5bb90f0ba79f4e1d8098d2eb06f8940b8789e5ecb851914bbab364597ec",
|
||||
"restore_receipt_sha256": "966d6640e42e2f4940c66d1cd5c8a802cd950de0305572f3c8b720ee3d81ae2b",
|
||||
"client_export": {
|
||||
"status": "recovered_client_export_verified",
|
||||
"schema": "coulomb.client-dataset-export.v1",
|
||||
"content_files": 85,
|
||||
"records": {
|
||||
"members.user": 1,
|
||||
"members.member": 1,
|
||||
"spaces.space": 1,
|
||||
"spaces.spacemembership": 1
|
||||
},
|
||||
"admin_events": 0,
|
||||
"archive_sha256": "e364a61570e0083e729a3f314eb707c57347200438bd98170c77b8f7fcc2b337",
|
||||
"offboarding_complete": false,
|
||||
"all_source_tables_compared": 13,
|
||||
"all_source_files_compared": 86,
|
||||
"archive_member_hashes_verified": true,
|
||||
"selected_client_content_complete_locally": true,
|
||||
"source_sql_and_content_unchanged": true,
|
||||
"external_bindings_require_review": 0,
|
||||
"sessions_and_credentials_excluded": true
|
||||
},
|
||||
"candidate_application": {
|
||||
"status": "isolated_application_recovery_verified",
|
||||
"recovered_spaces_with_content": 1,
|
||||
"actual_pages_rendered_through_view": 40,
|
||||
"restored_owner_access_verified": true,
|
||||
"synthetic_viewer_reads": 1,
|
||||
"synthetic_viewer_mutation_denials": 1,
|
||||
"same_tenant_ungranted_page_denials": 40,
|
||||
"fixture_transaction_rolled_back": true,
|
||||
"production_access": false,
|
||||
"external_identity_provider_used": false,
|
||||
"real_browser_journey_verified": false
|
||||
},
|
||||
"previous_image_application": {
|
||||
"status": "isolated_application_recovery_verified",
|
||||
"recovered_spaces_with_content": 1,
|
||||
"actual_pages_rendered_through_view": 40,
|
||||
"restored_owner_access_verified": true,
|
||||
"synthetic_viewer_reads": 1,
|
||||
"synthetic_viewer_mutation_denials": 1,
|
||||
"same_tenant_ungranted_page_denials": 40,
|
||||
"fixture_transaction_rolled_back": true,
|
||||
"production_access": false,
|
||||
"external_identity_provider_used": false,
|
||||
"real_browser_journey_verified": false
|
||||
},
|
||||
"source_content_files_unchanged": 86,
|
||||
"all_tables_unchanged_after_both_view_checks": true,
|
||||
"application_source_overlay": false,
|
||||
"export_archive_removed": true,
|
||||
"network_internal": true,
|
||||
"published_ports": 0,
|
||||
"production_access": false,
|
||||
"production_restore": false,
|
||||
"post_date_correction_data_claimed": true,
|
||||
"retained_point_captured_at": "2026-10-31T07:13:52Z",
|
||||
"driver_sha256": "92b66225e5f9bdf03d0a0999b613370c42341a2ceef468f1743fb4301884cb25"
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-content-lifecycle-tests.v1",
|
||||
"source": "f306dbfa2604e4815523667740be2925c333b84e",
|
||||
"image_id": "sha256:d3f2f5bb90f0ba79f4e1d8098d2eb06f8940b8789e5ecb851914bbab364597ec",
|
||||
"tests": 29,
|
||||
"failures": 0,
|
||||
"expected_baseline_regressions": false,
|
||||
"failed_nodes": [],
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"network": "none",
|
||||
"read_only_root": true,
|
||||
"application_source_overlay": false,
|
||||
"test_tooling_injected": true,
|
||||
"application_modules_from_image_verified": true,
|
||||
"production_access": false,
|
||||
"junit_sha256": "f2968ef1048ec9af68a187b967d558db0f6ee76e765a8106fb7fab284953511f",
|
||||
"driver_sha256": "85b65114997c7e7c5323cb77a0043e495ec132506eef07dd394c6a6361380d36",
|
||||
"test_source_sha256": "84a25a22a3cbda397e39c0508db8ea5aa90e6c467ccfa7da2b568d174d1ec449"
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
/tmp/csoc-content-release-observation-20261031.py: 1065625ee5b0736ae68a5230684f0effcb2c92cf0f814154ee86450b5a8fda4a
|
||||
/tmp/csoc-content-row-drift-20261031.py: 49c8f0b8a92524205e2b190bbefec76d9cc38d966c4d20ffa7391e85ff17bf0e
|
||||
/tmp/csoc-packaged-lifecycle-recovery-20261031.py: 92b66225e5f9bdf03d0a0999b613370c42341a2ceef468f1743fb4301884cb25
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
{
|
||||
"proposal_digest": "sha256:c9c3231620721ef3ea9b2bf22fc6c62fe3ed8efb91386cf7ec96acc6959dae08",
|
||||
"execution_started": false,
|
||||
"status": "release_refused_or_failed",
|
||||
"failure_type": "Refused",
|
||||
"failure_reason": "inactive_backup_installation_required_before_image_release"
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.content-release-preparation.v1",
|
||||
"prepared_at": "2026-10-31T12:16:52.085864+00:00",
|
||||
"status": "prepared_waiting_for_inactive_backup_installation",
|
||||
"proposal_digest": "sha256:c9c3231620721ef3ea9b2bf22fc6c62fe3ed8efb91386cf7ec96acc6959dae08",
|
||||
"capsule_members": 20,
|
||||
"owner_task": "RAPPS-WP-0015-T07",
|
||||
"owner_task_id": "8f448934-bdfe-539f-8cab-a739ec752491",
|
||||
"consumer_task": "CSOC-WP-0013-T05",
|
||||
"baseline_revision": 19,
|
||||
"current_business_rows": 93,
|
||||
"candidate_image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:d3f2f5bb90f0ba79f4e1d8098d2eb06f8940b8789e5ecb851914bbab364597ec",
|
||||
"prerequisite_installation_digest": "sha256:8f442bf0ebed8bbf3b7f227b52081df52613f3f5f6874c4a59511cfc2ba06d42",
|
||||
"ordering": [
|
||||
"historical custody repair",
|
||||
"recurring alert route",
|
||||
"inactive backup-source installation",
|
||||
"content image preflight and supervised release",
|
||||
"native recurring proof and schedule activation"
|
||||
],
|
||||
"controller_tests": {
|
||||
"tests": 40,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"helm_lint": "passed",
|
||||
"image_only_local_render_difference": true,
|
||||
"candidate_image_only_server_preview_verified": true,
|
||||
"native_full_preflight": "refused_expected_missing_installation",
|
||||
"full_preflight_passed": false,
|
||||
"historical_custody_packet_digest_unchanged": true,
|
||||
"inactive_installer_packet_digest_unchanged": true,
|
||||
"release_executed": false,
|
||||
"fresh_backup_created_by_preparation": false,
|
||||
"production_data_restored": false,
|
||||
"timers_activated": false,
|
||||
"new_resources_committed": 0,
|
||||
"cost_risk_review": {
|
||||
"additional_infrastructure_reservations": 0,
|
||||
"new_backup_objects": 1,
|
||||
"encrypted_file_limit_bytes": 1073741824,
|
||||
"incremental_provider_cost_eur": null,
|
||||
"autopilot_budget_claimed": false,
|
||||
"risks": [
|
||||
"Brief application pause for paired capture and Recreate image rollout.",
|
||||
"Rollback restores previous image/helper without rolling back productive data.",
|
||||
"Uncertain or changed baseline refuses; inspect durable receipt before retry."
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
{
|
||||
"repo": "railiance-apps",
|
||||
"path": "tools/coulomb-image-release.py",
|
||||
"sha256": "4cefb7b4ce7fb7eece1cd78ce3c1712a2b5cc2f9c81acfed06e3c6ac7c4abad3"
|
||||
},
|
||||
{
|
||||
"repo": "railiance-apps",
|
||||
"path": "tools/coulomb_image_release_node.py",
|
||||
"sha256": "5547b3809f34178e48404cd1590f665729b062b4333f561e2da81b56d435dece"
|
||||
},
|
||||
{
|
||||
"repo": "railiance-apps",
|
||||
"path": "tests/test_coulomb_image_release.py",
|
||||
"sha256": "dc9cd51bd0698b46c5e2a4f2f0fb8f89eceed722a92bd7b03f7278ed77a497d4"
|
||||
},
|
||||
{
|
||||
"repo": "railiance-apps",
|
||||
"path": "release/coulomb-content-lifecycle-f306dbf.json",
|
||||
"sha256": "1bcd840aee2a93130838b7430de279c56dd7aecbce4244765a85be9d0a7130e2"
|
||||
}
|
||||
],
|
||||
"native_no_attempt_readback": {
|
||||
"release_journal_exists": false,
|
||||
"release_receipt_exists": false
|
||||
},
|
||||
"sequencing_decision_id": "de5a4528-0864-4769-b9d0-2f658b0310c6",
|
||||
"owner_controller_commit": "9c748846413c6db3f13ae3e55627fe3f6ad89194"
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.reviewed-image-release.v1",
|
||||
"proposal_id": "CSOC-CONTENT-LIFECYCLE-20261031",
|
||||
"scope": "ADMINISTER @ realm:kubernetes/railiance01; supervised founder execution only",
|
||||
"operation": "image_only_existing_migration_0003",
|
||||
"cluster_uid": "a553c742-0115-43d4-99a4-a5ca56fe0786",
|
||||
"baseline_revision": 19,
|
||||
"baseline_helm_manifest_sha256": "93cb277abd1aea0657be482e458dcfb268fe0bfbd45d90aa1faedcc7f5bce499",
|
||||
"candidate_render_sha256": "1606725273089b83689850ad1c25d1834faa15e00c8cf8aa24e1053273af71bc",
|
||||
"deployment_uid": "2dbe661a-d232-4477-bbd1-833813077fbe",
|
||||
"pvc_uid": "9888abeb-9d52-4c70-a23d-b5494780d9c3",
|
||||
"baseline_spec_sha256": "42e091e52d5dae3c1f986e4898c62057fa80846adfce049a75d8fbd4681180ea",
|
||||
"candidate_spec_sha256": "c65cb691bab7054ae25de58cdb75933d383621ec4e049d2daa1b1bf52dce0bba",
|
||||
"old_image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed",
|
||||
"candidate_image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:d3f2f5bb90f0ba79f4e1d8098d2eb06f8940b8789e5ecb851914bbab364597ec",
|
||||
"product_source": "f306dbfa2604e4815523667740be2925c333b84e",
|
||||
"expected_data": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0
|
||||
},
|
||||
"public_recipient": "age1qm30jk8q0cezey652dk2dhcr3d9vs528v6lg8mavl6d4q3e3vgnqmrmyy3",
|
||||
"installed_helper_hashes": {
|
||||
"/opt/coulomb-social-backup/paired-backup.py": "d161c742d1a6a182460a57d0a1719591ab58fc94006f55169ad3d74442a93630",
|
||||
"/opt/coulomb-social-backup/snapshot-content-and-db.py": "dcc8dd2a3989f279597595f9260b31b24fcc9b6dc787f04c17ef0491c53d830d",
|
||||
"/opt/coulomb-social-backup/mirror-paired-backup.py": "9ceb26d9083af016c4b787907e4dce7bdf437c782fb2d15eb28d9e334e6e431c",
|
||||
"/opt/coulomb-social-backup/check-paired-backup-health.py": "2d40ec6e4c59ea7fe1d46065d197b9a87ca6811f023cc6f3e20e4184a3490566",
|
||||
"/opt/coulomb-social-backup/backup_capacity.py": "cb699a79e67b129239b5aa5d6f3b0d4ffaa9773a8b073227ad17fdecb5b9d893",
|
||||
"/opt/railiance-platform/scripts/application_recovery_identities.py": "20f56255ed6eeec4aafe33f142bc3ee03f623d4957a7b0cabb741d340f15f79d",
|
||||
"/opt/railiance-platform/scripts/application_recovery_mirror.py": "d48ab95e89b9eeae36269d853ebe4c44c22e1f57d4e14224f03d0b9aeeb34178",
|
||||
"/opt/railiance-platform/scripts/application_recovery_resources.py": "ab70ec341e738272730eb0daf76840d0bca807caeb3c4e4c2357f162fbed4498",
|
||||
"/opt/railiance-platform/scripts/primary_application_archive.py": "a3f0a61e869a6012edb4b5288be14e3b0c4a9a1273b090320ab146d12e5aa94d",
|
||||
"/opt/coulomb-social-backup/backup_alerts.py": "07522437d4276b92f0a44149adc6c9e81bb18dbe59ce0f1f9e58a48347700d0e",
|
||||
"/opt/coulomb-social-backup/notify-backup-alert.py": "0bd53bc5ad22d8bcb0326fb18a17737744b06416fe785dad077308e45f051d5a",
|
||||
"/opt/coulomb-social-backup/observe-backup-alerts.py": "17caf4fa65283242f618b039ff1d018801c9890ea2a9178912cbdd4b50ee2664"
|
||||
},
|
||||
"clipboard_static_sha256": "347eabe0c8d93bf439df02b5a08a7ea71004600e6ff4e8a42cecbee52a9f0413",
|
||||
"fresh_backup_before_helm": true,
|
||||
"requires_dataset_equality_before_and_after": true,
|
||||
"node_request_percent_limit": 90,
|
||||
"helm_atomic_timeout_seconds": 300,
|
||||
"rollback": "Restore Helm revision19/image522bcd7f and verified snapshot pin; preserve all post-capture data. No production data restore or schema downgrade.",
|
||||
"approval_status": "prepared_not_admitted",
|
||||
"recovery_rehearsal_scope": "Retained independently recovered 2026-10-31T07:13:52Z point; candidate and previous image preserve all 13 source tables and 86 files. Live observation now has93 business rows versus92 in that point; exact fresh paired backup/readback is required before Helm. Independent restore of the new point remains consumer follow-through. Read-only drift comparison confines differences to sessions and user/member login timestamps; all content and migration history match the retained point.",
|
||||
"rehearsal_evidence_sha256": {
|
||||
"content-lifecycle-candidate-build-2026-10-31.json": "83ad2ec41c85f8bb5087a250fdb91126ed92f12351cdc72b353c6f0e1a26452b",
|
||||
"content-lifecycle-candidate-provenance-2026-10-31.json": "35ed909e0a2fa5c57cea1fcc4fbebb877eae559ca9dc753c3da00f84806d7b73",
|
||||
"content-lifecycle-candidate-tests-2026-10-31.json": "27a75cfee6bbda41f377b73d6a6c7ecde0c54806c113f1be5223dd2f2cf39b3b",
|
||||
"content-lifecycle-baseline-tests-2026-10-31.json": "de14e4e10337990ccec1c483f7d943bdc7e11b03aa813aff47d00a9b38a07b65",
|
||||
"content-lifecycle-candidate-recovery-2026-10-31.json": "8d15172e5e330d01f153336e67f6bffb4363d571530c31ea05db872ca10807a9",
|
||||
"content-lifecycle-validation-2026-10-31.json": "cbb093af470588ca6e8eb3ec5bc1ccee0be537ab37a46625b6ac267c17343d99",
|
||||
"content-lifecycle-release-target-2026-10-31.json": "e9b50be3c8284c5a9ae96d75b800cbc4090580fa811c2ecd098d73ce8cbee74e",
|
||||
"content-lifecycle-release-row-drift-2026-10-31.json": "b10f65bf55e900199ae6037767f32e8901aaccb6f7f3a86461f13dd02ec8efce"
|
||||
},
|
||||
"new_resources_committed": 0,
|
||||
"autopilot_or_eur_budget_claimed": false,
|
||||
"values_file": "release/content-lifecycle-values.yaml",
|
||||
"snapshot_file": "release/content-lifecycle-snapshot.py",
|
||||
"evidence_directory": "release/content-lifecycle-evidence",
|
||||
"prerequisite_installation_digest": "sha256:8f442bf0ebed8bbf3b7f227b52081df52613f3f5f6874c4a59511cfc2ba06d42",
|
||||
"requires_inactive_backup_units": true,
|
||||
"files": {
|
||||
"tools/coulomb-image-release.py": "4cefb7b4ce7fb7eece1cd78ce3c1712a2b5cc2f9c81acfed06e3c6ac7c4abad3",
|
||||
"tools/coulomb_image_release_node.py": "5547b3809f34178e48404cd1590f665729b062b4333f561e2da81b56d435dece",
|
||||
"tools/coulomb_image_probe.py": "7d241b288992fbbc961b42a1311f7d0938b0c899c0675b7db92653c5ace6014f",
|
||||
"release/content-lifecycle-values.yaml": "daa302f96bddb889c7fe4aa95b740e9f5184d2ac463cd2403431b3e94db86528",
|
||||
"release/content-lifecycle-snapshot.py": "c1508043f473d2762723acda04944a36f5346e7641fbe6fdf21a91acd3921a54",
|
||||
"charts/coulomb-social/Chart.yaml": "663d6c23c57457a03bc376ebafb8107ee7f150e150f4d4fb6a3a949fb21006aa",
|
||||
"charts/coulomb-social/templates/_helpers.tpl": "65379818d484959e7221d3f538b59ffd6b8b7d3c9493250e47520576aee1fc68",
|
||||
"charts/coulomb-social/templates/content-pvc.yaml": "5c4ddcaee2b3dcdf17da061b1a7a2cb1e0398d2f56f4ef31790cfaaf648b0fee",
|
||||
"charts/coulomb-social/templates/deployment.yaml": "f90b7517959ec8785f578f917fec222287931e4f8a27f6f9e8fc0a28385f7df8",
|
||||
"charts/coulomb-social/templates/service.yaml": "78ce0ec6990c5ad57703c7a8d5d2c88c8eb9302d325cb2ba9d2df34e5f90ebdd",
|
||||
"charts/coulomb-social/values.yaml": "af48d133f7fe45f0d762b40878f306ef48262f6cbbca61808ffac5dd9fc9d241",
|
||||
"release/content-lifecycle-evidence/content-lifecycle-baseline-tests-2026-10-31.json": "de14e4e10337990ccec1c483f7d943bdc7e11b03aa813aff47d00a9b38a07b65",
|
||||
"release/content-lifecycle-evidence/content-lifecycle-candidate-build-2026-10-31.json": "83ad2ec41c85f8bb5087a250fdb91126ed92f12351cdc72b353c6f0e1a26452b",
|
||||
"release/content-lifecycle-evidence/content-lifecycle-candidate-provenance-2026-10-31.json": "35ed909e0a2fa5c57cea1fcc4fbebb877eae559ca9dc753c3da00f84806d7b73",
|
||||
"release/content-lifecycle-evidence/content-lifecycle-candidate-recovery-2026-10-31.json": "8d15172e5e330d01f153336e67f6bffb4363d571530c31ea05db872ca10807a9",
|
||||
"release/content-lifecycle-evidence/content-lifecycle-candidate-tests-2026-10-31.json": "27a75cfee6bbda41f377b73d6a6c7ecde0c54806c113f1be5223dd2f2cf39b3b",
|
||||
"release/content-lifecycle-evidence/content-lifecycle-release-row-drift-2026-10-31.json": "b10f65bf55e900199ae6037767f32e8901aaccb6f7f3a86461f13dd02ec8efce",
|
||||
"release/content-lifecycle-evidence/content-lifecycle-release-target-2026-10-31.json": "e9b50be3c8284c5a9ae96d75b800cbc4090580fa811c2ecd098d73ce8cbee74e",
|
||||
"release/content-lifecycle-evidence/content-lifecycle-validation-2026-10-31.json": "cbb093af470588ca6e8eb3ec5bc1ccee0be537ab37a46625b6ac267c17343d99"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
{
|
||||
"changed_columns": {
|
||||
"django_session": [
|
||||
"session_key",
|
||||
"session_data",
|
||||
"expire_date"
|
||||
],
|
||||
"members_member": [
|
||||
"updated_at",
|
||||
"last_login_at"
|
||||
],
|
||||
"members_user": [
|
||||
"last_login"
|
||||
]
|
||||
},
|
||||
"file_changes": [],
|
||||
"retained_fingerprint": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 92,
|
||||
"business_rows_sha256": "6243955479f7861fcdcd79b62f7f1e9f9a27c05a17bd2c17b792ebc98b2fa7b6",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0
|
||||
},
|
||||
"schema": "coulomb.content-release-row-drift.v1",
|
||||
"changed_tables": [
|
||||
{
|
||||
"table": "django_session",
|
||||
"retained_rows": 42,
|
||||
"current_rows": 43,
|
||||
"retained_sha256": "c958e33ec782f9f2fd1b3cceba4a64da0038fde51050f25905ae42de91ca6dde",
|
||||
"current_sha256": "594e246ef6297d9be9b6e8d9eda076a5b2ab36afb9263606b719f64f51293ba6"
|
||||
},
|
||||
{
|
||||
"table": "members_member",
|
||||
"retained_rows": 1,
|
||||
"current_rows": 1,
|
||||
"retained_sha256": "4d465d2b9d1e6311e505f861f2ed4b67763a545a965f9a7d0c586a3d07e3e9a3",
|
||||
"current_sha256": "ab82b3f2c5e49f8634c598c9642894747f4b6fcff0f5230ac27f41939feb8640"
|
||||
},
|
||||
{
|
||||
"table": "members_user",
|
||||
"retained_rows": 1,
|
||||
"current_rows": 1,
|
||||
"retained_sha256": "81ccb3a40191e910a68c101896df518a588c00231728934c4c900577f8ae4f12",
|
||||
"current_sha256": "0fc7a71b4b80a71fbedce527bbd2cae3858cf6a062e5714fc231be13ff987256"
|
||||
}
|
||||
],
|
||||
"all_other_business_tables_equal": true,
|
||||
"migration_history_equal": true,
|
||||
"content_equal": true,
|
||||
"retained_point": "2026-10-31T07:13:52Z",
|
||||
"current_business_rows": 93,
|
||||
"current_business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"private_row_values_printed": false,
|
||||
"production_changes": false
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.content-release-target-observation.v1",
|
||||
"observed_at": "2026-10-31T12:07:24.322343+00:00",
|
||||
"cluster_uid": "a553c742-0115-43d4-99a4-a5ca56fe0786",
|
||||
"deployment_uid": "2dbe661a-d232-4477-bbd1-833813077fbe",
|
||||
"pvc_uid": "9888abeb-9d52-4c70-a23d-b5494780d9c3",
|
||||
"baseline_revision": 19,
|
||||
"baseline_helm_manifest_sha256": "93cb277abd1aea0657be482e458dcfb268fe0bfbd45d90aa1faedcc7f5bce499",
|
||||
"baseline_spec_sha256": "42e091e52d5dae3c1f986e4898c62057fa80846adfce049a75d8fbd4681180ea",
|
||||
"candidate_spec_sha256": "c65cb691bab7054ae25de58cdb75933d383621ec4e049d2daa1b1bf52dce0bba",
|
||||
"old_image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed",
|
||||
"candidate_image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:d3f2f5bb90f0ba79f4e1d8098d2eb06f8940b8789e5ecb851914bbab364597ec",
|
||||
"sole_ready_pvc_writer": true,
|
||||
"existing_unmanaged_metadata_preserved": true,
|
||||
"candidate_image_only_server_preview_verified": true,
|
||||
"data": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 40,
|
||||
"unsaved_outsider_page_denials": 40,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"matches_verified_revision19_data": false,
|
||||
"installed_helper_sha256": {
|
||||
"/opt/coulomb-social-backup/paired-backup.py": "43e119acb6a4933b4e144c349a091e074e1a91ab61dbe15a65c8264c1d47661a",
|
||||
"/opt/coulomb-social-backup/snapshot-content-and-db.py": "dcc8dd2a3989f279597595f9260b31b24fcc9b6dc787f04c17ef0491c53d830d",
|
||||
"/opt/railiance-platform/scripts/primary_application_archive.py": "a3f0a61e869a6012edb4b5288be14e3b0c4a9a1273b090320ab146d12e5aa94d"
|
||||
},
|
||||
"timers": {
|
||||
"coulomb-social-paired-backup.timer": {
|
||||
"LoadState": "not-found",
|
||||
"ActiveState": "inactive",
|
||||
"UnitFileState": ""
|
||||
},
|
||||
"coulomb-social-backup-freshness.timer": {
|
||||
"LoadState": "not-found",
|
||||
"ActiveState": "inactive",
|
||||
"UnitFileState": ""
|
||||
}
|
||||
},
|
||||
"prerequisites": {
|
||||
"custody": {
|
||||
"exists": false
|
||||
},
|
||||
"installation": {
|
||||
"exists": false
|
||||
},
|
||||
"route": {
|
||||
"exists": false
|
||||
}
|
||||
},
|
||||
"production_data_modified": false,
|
||||
"release_executed": false
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
# Inspecting uncertain corpus imports
|
||||
|
||||
CSOC-WP-0014-T07 preparation. The receipt-backed importer now reserves the new
|
||||
Space UUID in its durable `started` checkpoint before import writes. Its SQL
|
||||
operation creates that exact UUID exclusively. A competing row at the slug or
|
||||
reserved UUID refuses instead of being updated or receiving imported grants.
|
||||
The committed return must still have the reserved identity before completion.
|
||||
Ordinary imports without receipt mode retain their existing behavior.
|
||||
|
||||
This closes an identity gap in the earlier checkpoint implementation: a started
|
||||
receipt previously named no intended SQL identity, and the underlying generic
|
||||
importer could update an existing same-tenant row when its content tree was absent.
|
||||
Legacy completed checkpoints remain usable. Legacy started checkpoints remain
|
||||
uncertain and are reported as identity-unbound; no identity is invented for them.
|
||||
|
||||
## Read-only inspection
|
||||
|
||||
The new management command is:
|
||||
|
||||
```sh
|
||||
python manage.py inspect_content_corpus /private/reviewed/manifest.json \
|
||||
--receipt-dir /private/import-attempt
|
||||
```
|
||||
|
||||
It requires the original manifest/source/mapping/destination binding and an
|
||||
existing checkpoint and lock files. It does not create missing directories or
|
||||
locks. It takes the existing importer/content locks without invoking content
|
||||
recovery, then reads SQL in one transaction. PostgreSQL uses `REPEATABLE READ,
|
||||
READ ONLY`. It compares destination and checkpoint bookends and rechecks source
|
||||
hashes before reporting. These cooperating locks are **not** proof of an external
|
||||
writer fence; the report explicitly records that limit.
|
||||
|
||||
Output contains unit indexes, classifications, counts and hashes, without source
|
||||
bodies, identity names or SQL rows. It binds the checkpoint bytes and observed SQL,
|
||||
grants and files. Classifications distinguish:
|
||||
|
||||
- A reserved identity whose current source-derived metadata, mapped grants and
|
||||
complete source file hashes match.
|
||||
- A reserved identity with differences, including later content, metadata, grant
|
||||
or original-date changes.
|
||||
- Foreign/replacement identities, files without SQL, or SQL without files.
|
||||
- No SQL row or published tree, which does not establish absence of staging.
|
||||
- Older started receipts without a reserved identity.
|
||||
- Pending destinations and the continued presence of completed identities.
|
||||
|
||||
Original space dates are compared when supplied by the source index; absence is
|
||||
reported. Insertion/update timestamps that cannot be derived from source are
|
||||
fingerprinted, not fabricated. A matching result does not prove that no intervening
|
||||
edit ever occurred. Synthesized indexes or omitted extra source files cannot be
|
||||
called byte-exact by the whole-tree comparison. Completed units may have later
|
||||
edits; their original receipt remains historical evidence, not an overwrite target.
|
||||
Unattributed `.import-*` entries are counted, never assigned to an attempt or removed.
|
||||
|
||||
Every result explicitly says that no checkpoint was completed, no retry was
|
||||
authorized and no data was restored. The inspector does not convert `started` to
|
||||
`completed` or `pending`. The deployment owner must still reconcile the specific
|
||||
uncertain state with its retained backup, writer fence and reviewed operation.
|
||||
Do not remove the checkpoint or use replacement import to bypass uncertainty.
|
||||
|
||||
The subsequent [matching-commit procedure](corpus-import-reconciliation-2026-10-31.md)
|
||||
adds a separate, explicit checkpoint operation for one exactly matching reserved
|
||||
commit. Inspection itself remains read-only. Partial, changed, unbound and
|
||||
unattributed-staging states still require owner reconciliation.
|
||||
|
||||
## Verification and release boundary
|
||||
|
||||
Fifteen new cases cover matching committed state without receipt, partial stores,
|
||||
legacy/unrelated identities, later edits/grants, original dates, active locks,
|
||||
missing paths, changing observations and occupied-slug refusal. The existing real
|
||||
process-exit tests now inspect both the pre-write and committed-without-receipt
|
||||
states while proving unchanged checkpoints. A row inserted after corpus preflight
|
||||
is retained without imported grants or destination files.
|
||||
|
||||
Full `make check`: **629 passed, 69 existing warnings, zero failures/errors/skips
|
||||
in 71.11s**, including the required browser journeys. Ruff and whitespace checks
|
||||
pass. Log: `/tmp/csoc-import-inspection-check-20261031.log`.
|
||||
|
||||
`scripts/rehearse-import-inspection.py` also runs the corpus, receipt and inspection
|
||||
tests against disposable PostgreSQL 16.14 on an internal Docker network with no
|
||||
published ports. It passed 60 checks of actual inspection transactions' read-only
|
||||
and repeatable-read modes. Current source and locked development dependencies are explicit
|
||||
read-only overlays on the cached application image; this is not packaged-candidate
|
||||
or production proof. Its containers, anonymous test volumes and network were
|
||||
removed. Source-bound receipt:
|
||||
`corpus-import-inspection-postgres-2026-10-31.json`.
|
||||
|
||||
No live cohort, grant, deployment, release pin or previously reviewed executor
|
||||
changed. T07 remains in progress: source/identity/grant reconciliation, a concrete
|
||||
owner procedure for uncertain imports, supervised executor integration, release,
|
||||
fresh backup/fencing, native postflight and productive acceptance remain required.
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.corpus-inspection-rehearsal.v1",
|
||||
"proof": {
|
||||
"status": "passed",
|
||||
"database_vendor": "postgresql",
|
||||
"server_version": 160014,
|
||||
"inspection_transaction_mode_checks": 60,
|
||||
"source_overlay": true,
|
||||
"locked_development_dependencies": true,
|
||||
"production_data_used": false
|
||||
},
|
||||
"app_dependency_image": "sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed",
|
||||
"postgres_image": "sha256:ff23cdce56cac62ada6f66013e1a50864c0abbe79d132d40b6e05bd80f378a70",
|
||||
"internal_network": true,
|
||||
"published_ports": false,
|
||||
"disposable_resources_removed": true,
|
||||
"source_sha256": {
|
||||
"scripts/rehearse-import-inspection.py": "2f560e25f00b08cdbcf1a27440c02fc74c57d255429b0496e3f4e25b7eb90468",
|
||||
"uv.lock": "e8ebb6fc4b5abd1ac80f1c9012f1983642d0528a8a213cfcc394261606fad887",
|
||||
"coulomb_social/apps/spaces/import_tree.py": "f232bde0d1741668ff28a6cb24306b7f67d8bf9fa3838507a8db4f4e80361784",
|
||||
"coulomb_social/apps/spaces/import_receipts.py": "670a5eb48613df47bf8fd0cf7d9306f7d2e992d46dff69680e6e7998f64f9cb2",
|
||||
"coulomb_social/apps/spaces/import_inspection.py": "627f7c006f6aedf337cd146b1052028afe8342ce820283cdfb7963266d9e754d",
|
||||
"coulomb_social/apps/spaces/management/commands/inspect_content_corpus.py": "b083e39aa766c8ba268788fae98507780604d40832e119db1cd9f7c10f1aa212",
|
||||
"tests/test_import_corpus.py": "5a0670c408740de86ce601cd9d2a0a12cf0aaa5afda416867605180c568a1c5f",
|
||||
"tests/test_import_receipts.py": "134e8901991dc493333b7543bbd6ff1f1e7b7ca3d5cf9d7849d7c45212e20aab",
|
||||
"tests/test_import_inspection.py": "890e783eec30dd1b9e93ad7c3ab3173b57174a096938520865eaaf420bc605fb"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
# Restartable corpus import checkpoints
|
||||
|
||||
WP-0014-T07 preparation, 2026-10-31. The existing corpus importer committed one
|
||||
space at a time, but a whole-manifest retry failed when an earlier destination
|
||||
already existed. Its ordinary-error rollback did not constitute crash recovery.
|
||||
|
||||
`import_content_corpus --receipt-dir <private-directory>` now supports durable
|
||||
boundaries between new-space imports. Existing commands without this option retain
|
||||
their behavior. Receipt mode refuses `--replace` and any unreceipted SQL row or
|
||||
content destination, even when only one of those stores exists. The entire corpus
|
||||
is preflighted before import writes. Dry-run does not create content or receipts.
|
||||
|
||||
## Receipt contract
|
||||
|
||||
- A checkpoint binds the exact manifest bytes/order, source tree hashes, resolved
|
||||
source paths, explicit mapped member IDs/roles, database configuration identity
|
||||
and content root. It neither discovers identities nor grants approval. Plan order
|
||||
is preserved; the reconciled manifest must supply the agreed LIFO order.
|
||||
- The receipt directory must be owned by the operator, private and separate from
|
||||
source and served content. Symlinks, shared permissions and hardlinked receipt
|
||||
files are refused. Directory mode is0700 and files0600. A nonblocking lock stops
|
||||
simultaneous use of one receipt directory; the existing content lock serializes
|
||||
cooperating content writers.
|
||||
- Each space moves from pending to started before import writes. On success, the
|
||||
helper verifies the mapped grants, fsyncs content files/directories, then writes
|
||||
an atomic, fsynced completed checkpoint containing the stable Space ID, content,
|
||||
metadata and grant hashes and page/asset counts. It refuses an enclosing database
|
||||
transaction, so a completed receipt cannot precede an outer rollback.
|
||||
The later inspection follow-through also reserves the new Space UUID before
|
||||
writes and uses exclusive SQL creation; see the linked review below.
|
||||
- A retry checks the binding and skips completed spaces with the same stable SQL
|
||||
identity. Later body, title and grant edits remain intact. A deleted or replaced
|
||||
identity requires reconciliation. Historical completion hashes describe the
|
||||
original return; they do not claim the current edited space is unchanged.
|
||||
- A started checkpoint always stops automatic retry, including after a lost commit
|
||||
reply or failed receipt write. A crash between the filesystem and SQL operations
|
||||
may leave partial content or staging directories. This change does not implement
|
||||
automatic repair within a space. Do not delete the checkpoint, use `--replace`,
|
||||
or label it completed merely to bypass that stop.
|
||||
|
||||
## Execution boundary
|
||||
|
||||
Only synthetic isolated fixtures were imported for this change. No deployment,
|
||||
production import, grant or release-packet change occurred. The previously approved
|
||||
single-cohort executor is unchanged and does not use this new option.
|
||||
|
||||
Before remaining-cohort execution, the deployment owner must integrate the helper
|
||||
into the existing supervised path with immutable reviewed sources, explicit mappings,
|
||||
external writer fencing, a fresh paired backup and native postflight. The cooperating
|
||||
content lock is not an external writer fence, and a database-configuration hash is
|
||||
not independent cluster identity proof. The owner must mount a durable private
|
||||
receipt directory outside served content and include it in recovery custody.
|
||||
|
||||
If an attempt leaves a started checkpoint, keep the relevant writers fenced,
|
||||
retain the checkpoint, staged trees and paired backup, and inspect the actual SQL
|
||||
and files. Any reconciliation/restore needs its concrete reviewed procedure; the
|
||||
helper supplies no generic automatic repair or permission to restore production.
|
||||
Source fidelity, original-date verification, assets/links and productive transfer
|
||||
verdicts remain the existing workplan requirements.
|
||||
|
||||
Read-only classification is now available through `inspect_content_corpus`.
|
||||
It distinguishes exact reserved identities from partial, changed, foreign and
|
||||
legacy identity-unbound outcomes without editing a checkpoint or authorizing a
|
||||
retry. See [inspection review](corpus-import-inspection-2026-10-31.md).
|
||||
|
||||
## Verification
|
||||
|
||||
The new synthetic suite exercises real process termination before import, after
|
||||
SQL commit but before a completed receipt, and after the first completed space.
|
||||
The completed-boundary retry preserves a later local edit and stable Space ID while
|
||||
importing the next space. Other checks cover changed source/manifest/destination,
|
||||
mapping refusal, existing SQL/content, private-path constraints, deleted identities,
|
||||
concurrent receipt use, enclosing SQL transactions and receipt-write failure.
|
||||
|
||||
Full `make check`: **614 passed**,69warnings,zero failures/errors/skips in71.32s,
|
||||
including the required browser journeys and all18new checkpoint cases. Log:
|
||||
`/tmp/csoc-import-receipts-check-20261031.log`. State Hub synchronization passed
|
||||
with8warnings and0errors; T07 reads back as progress. Log:
|
||||
`/tmp/csoc-import-receipts-consistency-20261031.log`.
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
# Completing a matching uncertain import checkpoint
|
||||
|
||||
CSOC-WP-0014-T07 now has an explicit checkpoint-completion operation for an
|
||||
already committed import whose reserved identity and complete source-derived
|
||||
state match. This is source preparation, not a production reconciliation or
|
||||
admission of any cohort. The existing native executor and frozen release packets
|
||||
are unchanged.
|
||||
|
||||
## Owner procedure
|
||||
|
||||
Before any native use, the deployment owner must identify the exact original
|
||||
attempt, stop and independently verify application and external writers, retain
|
||||
the original checkpoint and a coherent paired recovery point, and confirm the
|
||||
source/tenant/identity/grant mapping was admitted. Neither of the commands below
|
||||
verifies an external writer fence or provider backup. The current production
|
||||
image does not contain these new commands; owner integration and release remain
|
||||
required.
|
||||
|
||||
1. Inspect the original manifest and existing private receipt directory using
|
||||
`inspect_content_corpus`. Keep the result privately with the operation evidence.
|
||||
2. Review the selected zero-based unit index, reserved identity, source binding,
|
||||
complete file/grant/metadata comparison and the original operation's outcome.
|
||||
Only `reserved_destination_matches_source`, with no unattributed `.import-*`
|
||||
entries, is eligible for the operation below. A match describes current state;
|
||||
it is not proof that no intervening edit ever occurred.
|
||||
3. Supply the exact inspection SHA-256 and explicit completion action:
|
||||
|
||||
```sh
|
||||
python manage.py reconcile_content_import /private/reviewed/manifest.json \
|
||||
--receipt-dir /private/import-attempt \
|
||||
--unit-index 0 \
|
||||
--expect-inspection <inspection_sha256> \
|
||||
--complete-matching-commit
|
||||
```
|
||||
|
||||
The command reacquires the existing receipt/content locks and a consistent
|
||||
read-only SQL transaction, recomputes the whole inspection, and refuses a
|
||||
changed digest. It fsyncs the matching destination, rechecks the selected unit,
|
||||
source and checkpoint bytes, then atomically replaces only the checkpoint.
|
||||
The completed unit retains its original reserved identity, ordinary importer
|
||||
fingerprints/counts, prior started unit and full hash/count inspection evidence.
|
||||
SQL rows, grants and content bytes are not modified.
|
||||
4. Independently read the checkpoint and inspect again. A lost response or failure
|
||||
may occur after replacement; do not infer failure to complete from the absence
|
||||
of terminal output. The previous inspection cannot be replayed against an
|
||||
already completed checkpoint. An interrupted temporary checkpoint file is
|
||||
retained as evidence and is not automatically deleted or adopted.
|
||||
5. If continuation is separately admitted, the existing receipted importer skips
|
||||
the completed unit and preserves later edits and grants. Completion of this
|
||||
checkpoint does not authorize importing the remaining corpus.
|
||||
|
||||
## Other states remain explicit owner work
|
||||
|
||||
| Observed state | Required disposition |
|
||||
| --- | --- |
|
||||
| Reserved identity differs from source | Preserve later edits/grants; reconcile against the original operation and paired point. This command never overwrites them. |
|
||||
| SQL only, files only, or neither | Retain the uncertain checkpoint and inspect private staging, transaction outcome and the paired recovery point. No automatic reset to pending, retry, restore or deletion is implemented here. |
|
||||
| Foreign identity or legacy unbound started receipt | Resolve ownership and identity from independent evidence. Do not adopt a row because its slug matches. |
|
||||
| Unattributed staging entries | Establish their exact attempt/ownership and disposition separately. Matching published bytes do not authorize cleaning up those entries. |
|
||||
| Pending or already completed unit | No reconciliation mutation is permitted. Completed identities remain historical boundaries and may have valid later edits. |
|
||||
|
||||
The helper uses cooperating file locks and PostgreSQL repeatable-read/read-only
|
||||
transactions. These are not an external writer fence. The return explicitly
|
||||
reports that limit, no SQL/content changes, no restore, and no authorization to
|
||||
continue imports. The owner must verify native prerequisites before execution;
|
||||
passing synthetic tests does not supply them.
|
||||
|
||||
## Validation
|
||||
|
||||
The focused suite covers exact completion and evidence retention, unchanged SQL/
|
||||
content, preservation of later edits on resumed import, stale evidence, changed
|
||||
source/mapping/checkpoint, partial or foreign stores, legacy receipts, unattributed
|
||||
staging, invalid selection, sync failure and drift during fsync. Real child-process
|
||||
exits immediately before and after checkpoint replacement leave either the prior
|
||||
started checkpoint or the completed checkpoint with its reconciliation evidence.
|
||||
|
||||
Full `make check`: **648 passed, 69 existing warnings, zero failures/errors/skips
|
||||
in 150.38s**, including required browser journeys, rerun after the interrupted
|
||||
session. Nineteen new reconciliation
|
||||
cases pass; the focused corpus checkpoint/inspection/reconciliation selection
|
||||
passes all 52 cases. Log: `/tmp/csoc-import-reconciliation-check-20261031.log`.
|
||||
|
||||
The isolated PostgreSQL 16.14 rehearsal passes with 243 actual read-only and
|
||||
repeatable-read transaction checks. It uses synthetic data, explicit source and
|
||||
locked dependency overlays, an internal Docker network and no published ports.
|
||||
Its disposable containers, volumes and network were removed. Source-bound receipt:
|
||||
`corpus-import-reconciliation-postgres-2026-10-31.json`. This is not packaged
|
||||
candidate or production proof.
|
||||
|
||||
After resuming, all 12 source hashes in that PostgreSQL receipt were independently
|
||||
checked against the current files and matched. State Hub consistency passed and
|
||||
the T07 description was independently read back with the reconciliation evidence.
|
||||
|
||||
T07 remains in progress for the other reconciliation states, supervised owner
|
||||
integration, source/grant admission, native release/import/postflight and
|
||||
productive verdicts.
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.corpus-inspection-rehearsal.v1",
|
||||
"proof": {
|
||||
"status": "passed",
|
||||
"database_vendor": "postgresql",
|
||||
"server_version": 160014,
|
||||
"inspection_transaction_mode_checks": 243,
|
||||
"source_overlay": true,
|
||||
"locked_development_dependencies": true,
|
||||
"production_data_used": false
|
||||
},
|
||||
"app_dependency_image": "sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed",
|
||||
"postgres_image": "sha256:ff23cdce56cac62ada6f66013e1a50864c0abbe79d132d40b6e05bd80f378a70",
|
||||
"internal_network": true,
|
||||
"published_ports": false,
|
||||
"disposable_resources_removed": true,
|
||||
"source_sha256": {
|
||||
"scripts/rehearse-import-inspection.py": "34a95a57df6b93132a45c70f95b56b8ee9ef5be8677efa6f27f48c41bdc46f17",
|
||||
"uv.lock": "e8ebb6fc4b5abd1ac80f1c9012f1983642d0528a8a213cfcc394261606fad887",
|
||||
"coulomb_social/apps/spaces/import_tree.py": "f232bde0d1741668ff28a6cb24306b7f67d8bf9fa3838507a8db4f4e80361784",
|
||||
"coulomb_social/apps/spaces/import_receipts.py": "670a5eb48613df47bf8fd0cf7d9306f7d2e992d46dff69680e6e7998f64f9cb2",
|
||||
"coulomb_social/apps/spaces/import_inspection.py": "908a62bd31e0a6cfab3cc94f45c671ff4f1ec403035434790a29adfc5275f5ab",
|
||||
"coulomb_social/apps/spaces/import_reconciliation.py": "75abc50ec1c6e15a12534eb39edc5ad3fa4128c37a354d4cea2bf6c37f745771",
|
||||
"coulomb_social/apps/spaces/management/commands/inspect_content_corpus.py": "b083e39aa766c8ba268788fae98507780604d40832e119db1cd9f7c10f1aa212",
|
||||
"coulomb_social/apps/spaces/management/commands/reconcile_content_import.py": "2e25d94ab3a9659e38a3ea4c8b6c2e87c710216ab5834a248fccdd00da9fdbb9",
|
||||
"tests/test_import_corpus.py": "5a0670c408740de86ce601cd9d2a0a12cf0aaa5afda416867605180c568a1c5f",
|
||||
"tests/test_import_receipts.py": "134e8901991dc493333b7543bbd6ff1f1e7b7ca3d5cf9d7849d7c45212e20aab",
|
||||
"tests/test_import_inspection.py": "890e783eec30dd1b9e93ad7c3ab3173b57174a096938520865eaaf420bc605fb",
|
||||
"tests/test_import_reconciliation.py": "89d7161715a2c298c30c6ae38f8d9647688e2ea261d2913a8a9b8969202ac298"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/content-point-recovery-20261031/csoc-verify-deployed-editor.py: f5ecee55accd7653be1cdf7402dd85185d6fd6305bf676f7ce00c63ec6259bd8
|
||||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/content-point-recovery-20261031/csoc-editor-target.py: 945ae15fbc328e537ff41b778b92bfcee73754983546149cbbbd2b1503dfc6d6
|
||||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/content-point-recovery-20261031/csoc-verify-editor-package.py: 2c877018ffd329ec3f3c9a345aba4ee04608d6f21ba5eb372bebad53352bd58e
|
||||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/content-point-recovery-20261031/csoc-verify-editor-recovery.py: 29c53d551eec2b4f4d60b047f123c727eef76ee7677c054bbfb0ab008355cff9
|
||||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/content-point-recovery-20261031/csoc-editor-baseline-diff.py: 1680f58e00e78dbd50b2a45e2a0d006acc94c073fe7cfac27436647a902d34bd
|
||||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/content-point-recovery-20261031/csoc-build-editor.py: 27a07652118d5d42cc99f258f6dc2580eb84cbf8b7591b88c08f92a3c3c1dfcf
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.acceptance-baseline-change.v1",
|
||||
"retained_point": "2026-10-31T20:21:01Z",
|
||||
"old_business_rows": 93,
|
||||
"new_business_rows": 97,
|
||||
"table_changes": {
|
||||
"spaces_space": {
|
||||
"old": 2,
|
||||
"new": 4,
|
||||
"removed": 0,
|
||||
"added": 2
|
||||
},
|
||||
"spaces_spacemembership": {
|
||||
"old": 1,
|
||||
"new": 3,
|
||||
"removed": 0,
|
||||
"added": 2
|
||||
}
|
||||
},
|
||||
"old_content_files": 86,
|
||||
"new_content_files": 98,
|
||||
"old_files_missing": 0,
|
||||
"old_files_changed": 0,
|
||||
"new_files_added": 12,
|
||||
"old_rows_preserved": true,
|
||||
"current_baseline": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 97,
|
||||
"business_rows_sha256": "35b0ae7d9dd1ff21c2ceaa04649162545ec36a2c68629548238352d9cd0fb303",
|
||||
"content_files": 98,
|
||||
"content_files_sha256": "b657c0e470399b6c7500da500cbbec061bea12ab9633bd74e2f142d797b2d26a",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0
|
||||
},
|
||||
"interpretation": "Changes observed during the user-requested productive acceptance session; no user verdict inferred."
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.content-acceptance-build.v1",
|
||||
"completed_at": "2026-10-31T21:13:04.039838+00:00",
|
||||
"source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"build_context": "clean restricted git archive",
|
||||
"source_full_gate_tests": 568,
|
||||
"runtime_packages_and_python_unchanged": true,
|
||||
"runtime": {
|
||||
"python": "3.12.16",
|
||||
"distributions": {
|
||||
"h11": "0.16.0",
|
||||
"httpcore": "1.0.9",
|
||||
"psycopg": "3.3.4",
|
||||
"joserfc": "1.7.4",
|
||||
"anyio": "4.14.2",
|
||||
"cryptography": "50.0.0",
|
||||
"idna": "3.18",
|
||||
"certifi": "2026.7.22",
|
||||
"packaging": "26.3",
|
||||
"python-decouple": "3.8",
|
||||
"psycopg-binary": "3.3.4",
|
||||
"sqlparse": "0.5.5",
|
||||
"whitenoise": "6.12.0",
|
||||
"cffi": "2.1.1",
|
||||
"markdown": "3.10.3",
|
||||
"webencodings": "0.5.1",
|
||||
"pycparser": "3.0",
|
||||
"bleach": "6.4.0",
|
||||
"authlib": "1.7.2",
|
||||
"django": "6.1",
|
||||
"typing_extensions": "4.16.0",
|
||||
"gunicorn": "26.0.0",
|
||||
"asgiref": "3.12.1",
|
||||
"httpx": "0.28.1",
|
||||
"dj-database-url": "3.1.2"
|
||||
}
|
||||
},
|
||||
"django_checks": {
|
||||
"check": "System check identified no issues (0 silenced).",
|
||||
"makemigrations": "No changes detected"
|
||||
},
|
||||
"new_database_migrations": false,
|
||||
"production_deployed": false
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-content-acceptance-recovery.v1",
|
||||
"status": "packaged_recovered_export_and_views_verified",
|
||||
"source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"restore_receipt_sha256": "1a696920d4cce738553ad536b62820e2bfda01cc89a7bd3d3eb8d5ceb3e266bb",
|
||||
"retained_point_captured_at": "2026-10-31T23:29:54Z",
|
||||
"candidate_application": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 97,
|
||||
"business_rows_sha256": "35b0ae7d9dd1ff21c2ceaa04649162545ec36a2c68629548238352d9cd0fb303",
|
||||
"content_files": 98,
|
||||
"content_files_sha256": "b657c0e470399b6c7500da500cbbec061bea12ab9633bd74e2f142d797b2d26a",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 43,
|
||||
"unsaved_outsider_page_denials": 43,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"previous_image_application": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 97,
|
||||
"business_rows_sha256": "35b0ae7d9dd1ff21c2ceaa04649162545ec36a2c68629548238352d9cd0fb303",
|
||||
"content_files": 98,
|
||||
"content_files_sha256": "b657c0e470399b6c7500da500cbbec061bea12ab9633bd74e2f142d797b2d26a",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 43,
|
||||
"unsaved_outsider_page_denials": 43,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"client_exports": [
|
||||
{
|
||||
"tenant_sha256": "98dd71602ef1afc56f1dcbaa7f5517198fcdd093a57d823ba11e8a634ea58ec2",
|
||||
"status": "recovered_client_export_verified",
|
||||
"schema": "coulomb.client-dataset-export.v1",
|
||||
"content_files": 97,
|
||||
"records": {
|
||||
"members.user": 1,
|
||||
"members.member": 1,
|
||||
"spaces.space": 3,
|
||||
"spaces.spacemembership": 3
|
||||
},
|
||||
"admin_events": 0,
|
||||
"archive_sha256": "a4eb3daa1ff3427ff71eeaeb415b9ce645d84a65d81afbb0470d47478bc58b6a",
|
||||
"offboarding_complete": false,
|
||||
"all_source_tables_compared": 13,
|
||||
"all_source_files_compared": 98,
|
||||
"archive_member_hashes_verified": true,
|
||||
"selected_client_content_complete_locally": true,
|
||||
"source_sql_and_content_unchanged": true,
|
||||
"external_bindings_require_review": 0,
|
||||
"sessions_and_credentials_excluded": true
|
||||
}
|
||||
],
|
||||
"exported_tenant_count": 1,
|
||||
"source_content_files_unchanged": 98,
|
||||
"all_tables_unchanged": true,
|
||||
"application_source_overlay": false,
|
||||
"network_internal": true,
|
||||
"published_ports": 0,
|
||||
"production_access": false,
|
||||
"production_restore": false,
|
||||
"driver_sha256": "5bfac786cbbf64bdbbd5b4b19d9fddfe0f99a28499417dbbbc0c2ca74e2cc69a",
|
||||
"verification_query_note": "Deduplicate tenant IDs in memory: Space ordering by title/slug caused values_list(...).distinct() to repeat the same tenant across spaces. The corrected check exports each actual content tenant; this point has one."
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.image-release-independent-recovery.v1",
|
||||
"status": "fresh_point_independently_retrieved_and_restored",
|
||||
"completed_at": "2026-10-31T23:36:36.772911+00:00",
|
||||
"captured_at": "2026-10-31T23:29:54Z",
|
||||
"primary_version": "1793489481116168",
|
||||
"mirror_version": "1793489725683064",
|
||||
"mirror_receipt_version": "1793489727604085",
|
||||
"ciphertext_sha256": "eb495239fdf2344d6d72da9d4b02957613e7a4d67c54a2d67963ef802bc39421",
|
||||
"independent_reader_used": true,
|
||||
"unpack": {
|
||||
"status": "decrypted_pair_verified",
|
||||
"version_id": "1793489481116168",
|
||||
"encrypted_sha256": "eb495239fdf2344d6d72da9d4b02957613e7a4d67c54a2d67963ef802bc39421",
|
||||
"captured_at": "2026-10-31T23:29:54Z",
|
||||
"database_sha256": "4c49933e4fb81573257b7c64e95edd7f0395f20c9e6280348bb10383fd8eaa25",
|
||||
"content_sha256": "0768e4f61ef003cff76c31aaca687e07e1743ff15a4d2d92dc0ebf123d4ec55e",
|
||||
"application_restore_verified": false
|
||||
},
|
||||
"restore": {
|
||||
"status": "restored_verified",
|
||||
"database_tables": 13,
|
||||
"database_rows": 119,
|
||||
"database_rows_and_sequences_match": true,
|
||||
"content_files": 98,
|
||||
"content_hashes_match": true,
|
||||
"network_internal": true,
|
||||
"published_ports": 0,
|
||||
"postgres_image_id": "sha256:ff23cdce56cac62ada6f66013e1a50864c0abbe79d132d40b6e05bd80f378a70",
|
||||
"elapsed_seconds": 20.38,
|
||||
"content_was_empty": false
|
||||
},
|
||||
"elapsed_seconds": 27.87,
|
||||
"production_restore": false,
|
||||
"current_kit_replaced": false,
|
||||
"driver_sha256": "016bc4824ca885c765f8e7c267f1da8ad4b9c76ed47cc73c29c7168e6e2e1204"
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.content-acceptance-independent-postflight.v1",
|
||||
"status": "deployed_image_and_complete_native_state_verified",
|
||||
"proposal_digest": "sha256:2cddcf38b7052287c10dce467a200a74cfa9699c666ae9ac538fc82917129e7a",
|
||||
"receipt_sha256": "abf5910f3b68790356cb2b579038401ef7395e8f213fd11b0f89603fbc4ada32",
|
||||
"helm_revision": 21,
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"packaged_source_files_verified": 79,
|
||||
"sole_ready_content_writer": true,
|
||||
"all_frozen_capsule_files_verified": 21,
|
||||
"installed_helper_hashes_verified": true,
|
||||
"snapshot_pin_refreshed": true,
|
||||
"public_health_landing_static_verified": true,
|
||||
"postflight": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 97,
|
||||
"business_rows_sha256": "35b0ae7d9dd1ff21c2ceaa04649162545ec36a2c68629548238352d9cd0fb303",
|
||||
"content_files": 98,
|
||||
"content_files_sha256": "b657c0e470399b6c7500da500cbbec061bea12ab9633bd74e2f142d797b2d26a",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 43,
|
||||
"unsaved_outsider_page_denials": 43,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"fresh_paired_point": {
|
||||
"captured_at": "2026-10-31T23:29:54Z",
|
||||
"destination": "s3://railiance-platform-pg-backup/platform-pg/application-archives/coulomb-social/2026/10/31/20261031T232954Z-039d1bab2ea7ef33b7453979.tar.age",
|
||||
"version_id": "1793489481116168",
|
||||
"encrypted_sha256": "eb495239fdf2344d6d72da9d4b02957613e7a4d67c54a2d67963ef802bc39421",
|
||||
"encrypted_bytes": 2181848,
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5"
|
||||
},
|
||||
"timers_activated": false,
|
||||
"production_data_restored": false,
|
||||
"productive_acceptance_inferred": false
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.live-editor-attachment-check.v1",
|
||||
"status": "live_saved_attachments_visible_in_editors",
|
||||
"helm_revision": 21,
|
||||
"actual_user_verdict_inferred": false,
|
||||
"production_writes": false,
|
||||
"checks": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 97,
|
||||
"business_rows_sha256": "35b0ae7d9dd1ff21c2ceaa04649162545ec36a2c68629548238352d9cd0fb303",
|
||||
"content_files": 98,
|
||||
"content_files_sha256": "b657c0e470399b6c7500da500cbbec061bea12ab9633bd74e2f142d797b2d26a",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 43,
|
||||
"live_editors_rendered": 43,
|
||||
"editors_with_saved_attachments": 41,
|
||||
"editor_download_links_verified": 42,
|
||||
"unsaved_outsider_page_denials": 43,
|
||||
"production_identity_or_grant_created": false
|
||||
}
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.guarded-image-release.v1",
|
||||
"proposal_digest": "sha256:2cddcf38b7052287c10dce467a200a74cfa9699c666ae9ac538fc82917129e7a",
|
||||
"started_at": "2026-10-31T21:15:08.583669+00:00",
|
||||
"status": "live_release_preflight_verified",
|
||||
"production_data_restored": false,
|
||||
"timers_activated": false,
|
||||
"node_request_percent": {
|
||||
"cpu": 68,
|
||||
"memory": 76
|
||||
},
|
||||
"preflight": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 97,
|
||||
"business_rows_sha256": "35b0ae7d9dd1ff21c2ceaa04649162545ec36a2c68629548238352d9cd0fb303",
|
||||
"content_files": 98,
|
||||
"content_files_sha256": "b657c0e470399b6c7500da500cbbec061bea12ab9633bd74e2f142d797b2d26a",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0
|
||||
},
|
||||
"live_changes": false
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-source-provenance.v1",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"packaged_file_count": 79,
|
||||
"all_packaged_source_bytes_match": true,
|
||||
"source_revision_label_verified": true,
|
||||
"registry_digest_resolves": true,
|
||||
"application_source_overlay": false,
|
||||
"manifest_sha256": "99401a60fdd9a95aff1168858e81fd7d8802cd7603f15c0ea35eb6917981f9fe"
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
{
|
||||
"completed_at": "2026-10-31T23:32:38.446589+00:00",
|
||||
"elapsed_seconds": 173.091,
|
||||
"existing_global_constraint_preserved": true,
|
||||
"fresh_paired_point": {
|
||||
"age_recipient": "age1qm30jk8q0cezey652dk2dhcr3d9vs528v6lg8mavl6d4q3e3vgnqmrmyy3",
|
||||
"application": "coulomb-social",
|
||||
"application_restore_verified": false,
|
||||
"captured_at": "2026-10-31T23:29:54Z",
|
||||
"ciphertext_bytes": 2181848,
|
||||
"ciphertext_sha256": "eb495239fdf2344d6d72da9d4b02957613e7a4d67c54a2d67963ef802bc39421",
|
||||
"completed_at": "2026-10-31T23:31:21.582167+00:00",
|
||||
"content_sha256": "0768e4f61ef003cff76c31aaca687e07e1743ff15a4d2d92dc0ebf123d4ec55e",
|
||||
"database_sha256": "4c49933e4fb81573257b7c64e95edd7f0395f20c9e6280348bb10383fd8eaa25",
|
||||
"destination": "s3://railiance-platform-pg-backup/platform-pg/application-archives/coulomb-social/2026/10/31/20261031T232954Z-039d1bab2ea7ef33b7453979.tar.age",
|
||||
"encrypted_bytes": 2181848,
|
||||
"encrypted_sha256": "eb495239fdf2344d6d72da9d4b02957613e7a4d67c54a2d67963ef802bc39421",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5",
|
||||
"immutable_create": true,
|
||||
"local_archive": "20261031T232954Z-039d1bab2ea7ef33b7453979.tar.age",
|
||||
"object_key": "platform-pg/application-archives/coulomb-social/2026/10/31/20261031T232954Z-039d1bab2ea7ef33b7453979.tar.age",
|
||||
"pause_and_capture_seconds": 85.7,
|
||||
"remote_retrieval_verified": true,
|
||||
"schema": "platform.application-primary-archive.v1",
|
||||
"status": "offsite_fetched_verified",
|
||||
"version_id": "1793489481116168"
|
||||
},
|
||||
"helm_revision": 21,
|
||||
"node_request_percent": {
|
||||
"cpu": 68,
|
||||
"memory": 76
|
||||
},
|
||||
"pid": 2007089,
|
||||
"postflight": {
|
||||
"actual_owner_pages_rendered": 43,
|
||||
"business_rows": 97,
|
||||
"business_rows_sha256": "35b0ae7d9dd1ff21c2ceaa04649162545ec36a2c68629548238352d9cd0fb303",
|
||||
"business_tables": 12,
|
||||
"content_files": 98,
|
||||
"content_files_sha256": "b657c0e470399b6c7500da500cbbec061bea12ab9633bd74e2f142d797b2d26a",
|
||||
"duplicate_slug_groups": 0,
|
||||
"global_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"production_identity_or_grant_created": false,
|
||||
"tenant_slug_constraint": true,
|
||||
"unsaved_outsider_page_denials": 43
|
||||
},
|
||||
"preflight": {
|
||||
"business_rows": 97,
|
||||
"business_rows_sha256": "35b0ae7d9dd1ff21c2ceaa04649162545ec36a2c68629548238352d9cd0fb303",
|
||||
"business_tables": 12,
|
||||
"content_files": 98,
|
||||
"content_files_sha256": "b657c0e470399b6c7500da500cbbec061bea12ab9633bd74e2f142d797b2d26a",
|
||||
"duplicate_slug_groups": 0,
|
||||
"global_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"tenant_slug_constraint": true
|
||||
},
|
||||
"private_values_printed": false,
|
||||
"production_data_restored": false,
|
||||
"proposal_digest": "sha256:2cddcf38b7052287c10dce467a200a74cfa9699c666ae9ac538fc82917129e7a",
|
||||
"public_health_landing_static_verified": true,
|
||||
"schema": "coulomb.guarded-image-release.v1",
|
||||
"snapshot_pin_refreshed": true,
|
||||
"started_at": "2026-10-31T23:29:45.196471+00:00",
|
||||
"status": "image_candidate_deployed_verified",
|
||||
"timers_activated": false
|
||||
}
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.editor-release-reconciliation.v1",
|
||||
"helm_revision": 21,
|
||||
"snapshot_server_dry_run": {
|
||||
"status": "reviewed",
|
||||
"server_dry_run": true,
|
||||
"image_pinned": true,
|
||||
"pvc_read_only": true,
|
||||
"db_scope": "coulomb_social_db",
|
||||
"replicas_restored_to": 1
|
||||
},
|
||||
"backup_timers_inactive_disabled": true,
|
||||
"snapshot_source_sha256": "d680edba707394bc1f5857fa86676d21e6a82d1e1b3b7838dfb628938de7529a",
|
||||
"owner_live_values_match_sealed_values": true,
|
||||
"snapshot_restore_regression_tests_passed": 9,
|
||||
"recovery_container_stopped": true
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-content-acceptance-recovery.v1",
|
||||
"status": "packaged_recovered_export_and_views_verified",
|
||||
"source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"restore_receipt_sha256": "9dacbd44544f93abf99354158cf610b4fb1f4e59611b22056b3086e0033231ab",
|
||||
"retained_point_captured_at": "2026-10-31T20:21:01Z",
|
||||
"candidate_application": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 40,
|
||||
"unsaved_outsider_page_denials": 40,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"previous_image_application": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 93,
|
||||
"business_rows_sha256": "7953b37b02b80d89ca6869dab6b2b0b996541de20ca0dd1b294a5f25572fb2ca",
|
||||
"content_files": 86,
|
||||
"content_files_sha256": "ed535246f4e8f46fcd7ce01f936127996aff873c6936b297f7272194b594aeda",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0,
|
||||
"actual_owner_pages_rendered": 40,
|
||||
"unsaved_outsider_page_denials": 40,
|
||||
"production_identity_or_grant_created": false
|
||||
},
|
||||
"client_export": {
|
||||
"status": "recovered_client_export_verified",
|
||||
"schema": "coulomb.client-dataset-export.v1",
|
||||
"content_files": 85,
|
||||
"records": {
|
||||
"members.user": 1,
|
||||
"members.member": 1,
|
||||
"spaces.space": 1,
|
||||
"spaces.spacemembership": 1
|
||||
},
|
||||
"admin_events": 0,
|
||||
"archive_sha256": "ecf5dba7ce891475cd5df15eb30205606f805850af7339ecd46e1479b45d6c5f",
|
||||
"offboarding_complete": false,
|
||||
"all_source_tables_compared": 13,
|
||||
"all_source_files_compared": 86,
|
||||
"archive_member_hashes_verified": true,
|
||||
"selected_client_content_complete_locally": true,
|
||||
"source_sql_and_content_unchanged": true,
|
||||
"external_bindings_require_review": 0,
|
||||
"sessions_and_credentials_excluded": true
|
||||
},
|
||||
"source_content_files_unchanged": 86,
|
||||
"all_tables_unchanged": true,
|
||||
"application_source_overlay": false,
|
||||
"network_internal": true,
|
||||
"published_ports": 0,
|
||||
"production_access": false,
|
||||
"production_restore": false,
|
||||
"driver_sha256": "29c53d551eec2b4f4d60b047f123c727eef76ee7677c054bbfb0ab008355cff9"
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/editor-point-recovery-20261101/csoc-mirror-editor-point.py: 2cba828db15a11415136eb17586c116ba10d06b835b5f8291ae858af7ad2b448
|
||||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/editor-point-recovery-20261101/csoc-recover-editor-point.py: 016bc4824ca885c765f8e7c267f1da8ad4b9c76ed47cc73c29c7168e6e2e1204
|
||||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/editor-point-recovery-20261101/csoc-verify-editor-fresh-point.py: 5bfac786cbbf64bdbbd5b4b19d9fddfe0f99a28499417dbbbc0c2ca74e2cc69a
|
||||
/home/worsch/.config/railiance-platform/coulomb-social-recovery/editor-point-recovery-20261101/csoc-live-editor-check.py: 679336ef9d952e24f5138532cb9cdba84e5635c9a35a54ee7c80312e249d73b7
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"baseline_revision": 20,
|
||||
"baseline_helm_manifest_sha256": "e388f62c97e97d54d87671825bd0b05c854a70b0cca8a00faee452ae7841799e",
|
||||
"deployment_uid": "2dbe661a-d232-4477-bbd1-833813077fbe",
|
||||
"baseline_spec_sha256": "8d79c64cff4bd2c62f03494e80847dc99b965ddabf35645da67e8d1020220798",
|
||||
"candidate_spec_sha256": "4deab26fc15d63e09922259b3362cd4e5c6bfa10884de058f776c0de8b642b00",
|
||||
"old_image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5",
|
||||
"expected_data": {
|
||||
"business_tables": 12,
|
||||
"migration_rows_sha256": "43471516387c0e2a3d35971033ed6af330e2963efe4da93293d97633825d04af",
|
||||
"business_rows": 97,
|
||||
"business_rows_sha256": "35b0ae7d9dd1ff21c2ceaa04649162545ec36a2c68629548238352d9cd0fb303",
|
||||
"content_files": 98,
|
||||
"content_files_sha256": "b657c0e470399b6c7500da500cbbec061bea12ab9633bd74e2f142d797b2d26a",
|
||||
"global_slug_constraint": true,
|
||||
"tenant_slug_constraint": true,
|
||||
"migration_0003_applied": true,
|
||||
"duplicate_slug_groups": 0
|
||||
},
|
||||
"image_only_server_preview": true
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.packaged-content-acceptance-tests.v1",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"tests": 110,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"network": "none",
|
||||
"read_only_root": true,
|
||||
"application_source_overlay": false,
|
||||
"synthetic_fixtures_only": true
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.productive-editor-attachment-return.v1",
|
||||
"helm_revision": 21,
|
||||
"source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"user": "Bernd",
|
||||
"statement": "Both tabs now show the attachment",
|
||||
"status": "reported_editor_visibility_gap_accepted_resolved",
|
||||
"scope": "Attachment visibility in both reopened editor tabs",
|
||||
"copy_move_sharing_portability_acceptance_inferred": false,
|
||||
"complete_attachment_workflow_acceptance_inferred": false
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.editor-attachments-validation.v1",
|
||||
"reported_gap": "Attachments visible on the original page were absent from editor tabs.",
|
||||
"main_source": "8b38afddf3f3648f209c60b1bafe3dd25501d857",
|
||||
"release_source": "31eaa581a65e454b6ef9979326c5bdfe10e13806",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:b58d858abd5b4acbd6b893c3f622f7a9fdb5e606164ab9866eb3cfaa04df1a0e",
|
||||
"main_full_gate": {
|
||||
"tests": 670,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"release_full_gate": {
|
||||
"tests": 568,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0
|
||||
},
|
||||
"packaged_tests": 110,
|
||||
"browser_verifies": [
|
||||
"saved file list and exact download bytes in both editor tabs",
|
||||
"management opens separately and keeps unsaved text",
|
||||
"stale refusal keeps submitted text and attachments",
|
||||
"save keeps attachments and rejects stale overwrite",
|
||||
"existing copy/move/download/detach permissions journey"
|
||||
],
|
||||
"runtime_changes": [
|
||||
"coulomb_social/apps/spaces/views.py",
|
||||
"coulomb_social/templates/spaces/page_form.html"
|
||||
],
|
||||
"storage_schema_or_authority_changed": false,
|
||||
"productive_acceptance_inferred": false,
|
||||
"test_environment": "Main uses /var/tmp; isolated branch native observer requires /tmp. Final complete gates pass without deselection."
|
||||
}
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.service-measurement-gap.v1",
|
||||
"recorded_at": "2026-10-31T14:43:33.505165+00:00",
|
||||
"task": "CSOC-WP-0012-T11",
|
||||
"current_signals": {
|
||||
"schema": "coulomb.existing-telemetry-observation.v1",
|
||||
"observed_at": "2026-10-31T14:39:40.395913+00:00",
|
||||
"service_name": "telemetry-prometheus",
|
||||
"service_uid": "529df0e7-b8a6-4478-8f51-672f50e9eaae",
|
||||
"selected_metric_names": [],
|
||||
"queries": {
|
||||
"coulomb_ready": "kube_deployment_status_replicas_available{namespace=\"coulomb-social\"}",
|
||||
"coulomb_ingress_metadata": "kube_ingress_info{namespace=\"coulomb-social\"}",
|
||||
"coulomb_scrape_targets": "up{namespace=\"coulomb-social\"}",
|
||||
"probe_series_count": "count(probe_success)",
|
||||
"traefik_series_count": "count(traefik_service_requests_total)"
|
||||
},
|
||||
"results": {
|
||||
"coulomb_ready": {
|
||||
"resultType": "vector",
|
||||
"result": [
|
||||
{
|
||||
"metric": {
|
||||
"__name__": "kube_deployment_status_replicas_available",
|
||||
"container": "kube-state-metrics",
|
||||
"deployment": "coulomb-social",
|
||||
"endpoint": "http",
|
||||
"instance": "10.42.0.7:8080",
|
||||
"job": "kube-state-metrics",
|
||||
"namespace": "coulomb-social",
|
||||
"pod": "telemetry-kube-state-metrics-5c9cd96d7b-c7ch5",
|
||||
"service": "telemetry-kube-state-metrics"
|
||||
},
|
||||
"value": [
|
||||
1793457579.499,
|
||||
"1"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"coulomb_ingress_metadata": {
|
||||
"resultType": "vector",
|
||||
"result": [
|
||||
{
|
||||
"metric": {
|
||||
"__name__": "kube_ingress_info",
|
||||
"container": "kube-state-metrics",
|
||||
"endpoint": "http",
|
||||
"ingress": "coulomb-social",
|
||||
"ingressclass": "traefik",
|
||||
"instance": "10.42.0.7:8080",
|
||||
"job": "kube-state-metrics",
|
||||
"namespace": "coulomb-social",
|
||||
"pod": "telemetry-kube-state-metrics-5c9cd96d7b-c7ch5",
|
||||
"service": "telemetry-kube-state-metrics"
|
||||
},
|
||||
"value": [
|
||||
1793457579.742,
|
||||
"1"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"coulomb_scrape_targets": {
|
||||
"resultType": "vector",
|
||||
"result": []
|
||||
},
|
||||
"probe_series_count": {
|
||||
"resultType": "vector",
|
||||
"result": []
|
||||
},
|
||||
"traefik_series_count": {
|
||||
"resultType": "vector",
|
||||
"result": []
|
||||
}
|
||||
},
|
||||
"runtime_modified": false
|
||||
},
|
||||
"retention_and_readiness_window": {
|
||||
"observed_at": "2026-10-31T14:41:38.172491+00:00",
|
||||
"retention_flags": {
|
||||
"storage.tsdb.retention.size": "10GiB",
|
||||
"storage.tsdb.retention.time": "10d"
|
||||
},
|
||||
"queries": {
|
||||
"ready_samples_7d": "sum(count_over_time(kube_deployment_status_replicas_available{namespace=\"coulomb-social\",deployment=\"coulomb-social\"}[7d]))",
|
||||
"minimum_available_replicas_7d": "min(min_over_time(kube_deployment_status_replicas_available{namespace=\"coulomb-social\",deployment=\"coulomb-social\"}[7d]))",
|
||||
"maximum_available_replicas_7d": "max(max_over_time(kube_deployment_status_replicas_available{namespace=\"coulomb-social\",deployment=\"coulomb-social\"}[7d]))"
|
||||
},
|
||||
"results": {
|
||||
"ready_samples_7d": {
|
||||
"resultType": "vector",
|
||||
"result": [
|
||||
{
|
||||
"metric": {},
|
||||
"value": [
|
||||
1793457697.673,
|
||||
"20160"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"minimum_available_replicas_7d": {
|
||||
"resultType": "vector",
|
||||
"result": [
|
||||
{
|
||||
"metric": {},
|
||||
"value": [
|
||||
1793457697.955,
|
||||
"0"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"maximum_available_replicas_7d": {
|
||||
"resultType": "vector",
|
||||
"result": [
|
||||
{
|
||||
"metric": {},
|
||||
"value": [
|
||||
1793457698.156,
|
||||
"1"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"end_to_end_slo_proven": false,
|
||||
"runtime_modified": false
|
||||
},
|
||||
"pending_execution_receipts": {
|
||||
"observed_at": "2026-10-31T14:38:31.143707+00:00",
|
||||
"receipts": {
|
||||
"custody": {
|
||||
"exists": false
|
||||
},
|
||||
"route": {
|
||||
"exists": false
|
||||
},
|
||||
"installation": {
|
||||
"exists": false
|
||||
},
|
||||
"content_release": {
|
||||
"exists": false
|
||||
}
|
||||
},
|
||||
"mutations": false
|
||||
},
|
||||
"interpretation": {
|
||||
"application_slo_attainment_proven": false,
|
||||
"monthly_application_window_proven": false,
|
||||
"readiness_equals_http_availability": false,
|
||||
"sample_count_proves_gapless_coverage": false,
|
||||
"maintenance_or_dependency_exclusions_applied": false,
|
||||
"application_latency_percentiles_available": false,
|
||||
"configuration_changed": false,
|
||||
"requires_application_level_signals_and_window_evidence": true
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"path": "registry/release-units/coulomb-social.yaml",
|
||||
"sha256": "309102bdee9d0ec0057c5d679be729ebd7aa3477d588962c2e757a38946761f6"
|
||||
},
|
||||
{
|
||||
"path": "docs/resource-evidence/service-objectives-and-observations-2026-08.md",
|
||||
"sha256": "f989738e569022cab572b676a64bc58565b2fad9b9476ea0a0d3c799e7c8d4e4"
|
||||
},
|
||||
{
|
||||
"path": "docs/release/identity-export-release-return-2026-10-31.md",
|
||||
"sha256": "e78222c650ff3939bb8e8f550e9b75534c9f43badea612a4ea3a2792fba82d01"
|
||||
}
|
||||
],
|
||||
"current_release": {
|
||||
"observed_at": "2026-10-31T14:44:54.910350+00:00",
|
||||
"deployment_uid": "2dbe661a-d232-4477-bbd1-833813077fbe",
|
||||
"generation": 49,
|
||||
"observed_generation": 49,
|
||||
"ready_replicas": 1,
|
||||
"images": [
|
||||
"forgejo.coulomb.social/coulomb/coulomb-social@sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed"
|
||||
],
|
||||
"helm_revision": 19,
|
||||
"helm_status": "deployed"
|
||||
},
|
||||
"statehub_readback": {
|
||||
"task_id": "61f5f196-40e4-5901-a10e-318304809a00",
|
||||
"status": "progress",
|
||||
"measurement_gap_synced": true,
|
||||
"fix_consistency_exit_code": 0,
|
||||
"automation_errors": 0,
|
||||
"assessment_failures": 0,
|
||||
"warnings": 6
|
||||
},
|
||||
"validation": {
|
||||
"native_read_results_checked": true,
|
||||
"json_round_trip_checked": true,
|
||||
"application_code_changed": false,
|
||||
"new_regression_run_required": false
|
||||
}
|
||||
}
|
||||
|
|
@ -139,59 +139,3 @@ is complete and waits on T04 historical custody/capacity and T07. T04 remains in
|
|||
progress for those native returns and historical-copy disposition. The original
|
||||
roughly 40% remaining estimate is unchanged: these source fixes do not establish
|
||||
recurring operation, productive acceptance or full remaining-cohort transfer.
|
||||
|
||||
|
||||
## Service provenance checkpoint
|
||||
|
||||
WP-0012-T14 now closes the Forgejo successor and existing founder identity-choice
|
||||
bindings formerly inside T11. The records include resolved decisions, completed
|
||||
owner migration and fresh read-only native metadata. T11 advances to progress and
|
||||
retains actual ops registration, client/app/instance finance attribution/report,
|
||||
current SLO and stage-1 smoke. This makes the source checklist13of32done; it is an
|
||||
additional independently verified requirement, not a new product scope or an
|
||||
updated effort estimate. The rough remaining-work estimate is unchanged.
|
||||
|
||||
|
||||
## Visual preservation checkpoint
|
||||
|
||||
WP-0014-T08 completes the previously missing private Visual capture and draft-tree
|
||||
materialization:242references,108URLs,90distinct images,236article pages and67
|
||||
space indexes. Offline decoding and independent body/date/source preservation
|
||||
checks pass. This advances the source checklist to14of33done, not an effort
|
||||
percentage. Source exceptions, identity/grant mapping, links/attachments and
|
||||
productive transfer/verdicts remain open; the rough remaining-effort estimate
|
||||
has not been recalculated from these counts.
|
||||
|
||||
## Access reconciliation checkpoint
|
||||
|
||||
WP-0014-T01 now has a private, source-hash-bound access inventory covering the
|
||||
70 fresh spaces and 245 articles, while retaining the inventory-only 71st space.
|
||||
It identifies three distinct source principals and nine unresolved creator
|
||||
references, preserving missing access fields as unknown. Existing ReichelAG
|
||||
admission does not establish all-space identity or role mappings. The task remains
|
||||
progress: this closes an evidence gap inside the task, not productive permission
|
||||
reconciliation. The checklist stays 14 of 33 done, and the remaining-effort
|
||||
estimate is unchanged. Evidence: `bubble-access-audit-2026-10-31.json`.
|
||||
|
||||
## Offboarding scope checkpoint
|
||||
|
||||
WP-0012-T12 moves from todo to progress with a concrete non-destructive scope
|
||||
review. Fresh native evidence distinguishes the accepted85file tenant export from
|
||||
the second, externally bound space; confirms the Helm-retained content PVC; and
|
||||
accounts for five still-running isolated recovery databases and their receipts.
|
||||
The review includes sessions, root journals, private copies and protected backup
|
||||
holds. No teardown, deletion, revocation or expiry occurred. Canonical client
|
||||
scope, agreed retention, procedure proof and private delivery/acceptance remain
|
||||
open. The checklist stays14of33done; the effort estimate is unchanged. Evidence:
|
||||
`client-offboarding-scope-2026-10-31.json` and its human-readable scope review.
|
||||
|
||||
## Corpus restart checkpoint
|
||||
|
||||
WP-0014-T07 moves from todo to progress with opt-in durable per-space import
|
||||
receipts. Completed boundaries can be resumed without replaying completed spaces;
|
||||
uncertain in-space outcomes require reconciliation. Synthetic process-exit tests
|
||||
exercise both conditions. No remaining production cohort was imported. Source and
|
||||
identity/grant reconciliation, supervised executor integration and productive
|
||||
postflight/verdicts remain open. The checklist stays14of33done and the rough
|
||||
remaining-effort estimate is unchanged. Evidence:
|
||||
`corpus-import-receipts-2026-10-31.md` and `tests/test_import_receipts.py`.
|
||||
|
|
|
|||
|
|
@ -1,72 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.native-mirror-worker-proof.v1",
|
||||
"status": "native_worker_and_independent_receipt_verified",
|
||||
"completed_at": "2026-10-31T20:27:08.869833+00:00",
|
||||
"primary": {
|
||||
"application": "coulomb-social",
|
||||
"captured_at": "2026-10-31T20:21:01Z",
|
||||
"object_key": "platform-pg/application-archives/coulomb-social/2026/10/31/20261031T202101Z-2ad4faf215939d67e82f67a4.tar.age",
|
||||
"version_id": "1793478121590106",
|
||||
"ciphertext_sha256": "91b4ffe4874a53e3422d604b7c3fa85f6551a481411ef82b2209993552486bfb",
|
||||
"ciphertext_bytes": 2181848,
|
||||
"age_recipient": "age1qm30jk8q0cezey652dk2dhcr3d9vs528v6lg8mavl6d4q3e3vgnqmrmyy3",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:522bcd7fce92436765a60c1e4afa2598f3cc40913352153ff1c4319a99ca92ed",
|
||||
"database_sha256": "c5faa20ac0c443635393e04cf5b154710780d829d6c085edc098e2dd7525fc6a",
|
||||
"content_sha256": "1bf31bafc19d8c4847f3793463189f13ce4b470ed96ccdc614b269acca6c12c0"
|
||||
},
|
||||
"recovery_mirror": {
|
||||
"bucket": "railiance-coulomb-social-archives",
|
||||
"ciphertext_bytes": 2181848,
|
||||
"ciphertext_sha256": "91b4ffe4874a53e3422d604b7c3fa85f6551a481411ef82b2209993552486bfb",
|
||||
"hash_readback_verified": true,
|
||||
"object_key": "archives/platform-pg/application-archives/coulomb-social/2026/10/31/20261031T202101Z-2ad4faf215939d67e82f67a4.tar.age",
|
||||
"project_id": "06d107bc-9d84-4672-b2a0-95701cc0c07f",
|
||||
"receipt_bytes": 1664,
|
||||
"receipt_object_key": "archives/platform-pg/application-archives/coulomb-social/2026/10/31/20261031T202101Z-2ad4faf215939d67e82f67a4.tar.age.741bdf7b02b859523053f45c88c874b58d43b45a0273bb315116d2bfc34e58aa.receipt.json",
|
||||
"receipt_readback_verified": true,
|
||||
"receipt_sha256": "741bdf7b02b859523053f45c88c874b58d43b45a0273bb315116d2bfc34e58aa",
|
||||
"receipt_version_id": "1793478427159655",
|
||||
"version_id": "1793478426025763"
|
||||
},
|
||||
"worker_results": [
|
||||
{
|
||||
"status": "mirrored_with_retained_receipt",
|
||||
"primary_recaptured": false,
|
||||
"ciphertext_readback_verified": true,
|
||||
"receipt_readback_verified": true,
|
||||
"recovery_key_read": false,
|
||||
"independent_reader_used": false,
|
||||
"retained_objects_deleted": false,
|
||||
"application_restore_verified": false
|
||||
},
|
||||
{
|
||||
"status": "mirrored_with_retained_receipt",
|
||||
"primary_recaptured": false,
|
||||
"ciphertext_readback_verified": true,
|
||||
"receipt_readback_verified": true,
|
||||
"recovery_key_read": false,
|
||||
"independent_reader_used": false,
|
||||
"retained_objects_deleted": false,
|
||||
"application_restore_verified": false
|
||||
}
|
||||
],
|
||||
"native_versions_before": 0,
|
||||
"native_versions_after": 2,
|
||||
"one_ciphertext_and_one_receipt_version_after_retry": true,
|
||||
"independent_reader_ciphertext_and_receipt_verified": true,
|
||||
"retained_receipt_equals_exact_public_field_filter": true,
|
||||
"local_primary_receipt_and_ciphertext_unchanged": true,
|
||||
"retry_last_mirror_bytes_unchanged": true,
|
||||
"runtime_source_commit": "09f4fd33cbeefecb833998246cf53848bb1e5d8d",
|
||||
"private_state_copy_used": true,
|
||||
"production_application_contact": false,
|
||||
"node_helpers_or_state_modified": false,
|
||||
"node_timers_changed": false,
|
||||
"native_capture_performed": false,
|
||||
"decryption_identity_read": false,
|
||||
"retained_objects_deleted": false,
|
||||
"operating_capacity_profile_admitted": false,
|
||||
"alert_reception_verified": false,
|
||||
"scheduled_service_execution_verified": false,
|
||||
"sources_manifest_sha256": "a865efe1cbf468c34e8f06912a6d423845ce08fc8a9963936f1e8af73897cad2"
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
/home/worsch/coulomb-social/deploy/backup/mirror-platform-runtime.json: 9253c5f6e956b67f499d3e12d2851be7fabd3bc56b00496b8810bbd0be8209f1
|
||||
/home/worsch/coulomb-social/scripts/backup_capacity.py: cb699a79e67b129239b5aa5d6f3b0d4ffaa9773a8b073227ad17fdecb5b9d893
|
||||
/home/worsch/coulomb-social/scripts/check-paired-backup-health.py: 2d40ec6e4c59ea7fe1d46065d197b9a87ca6811f023cc6f3e20e4184a3490566
|
||||
/home/worsch/coulomb-social/scripts/mirror-paired-backup.py: 9ceb26d9083af016c4b787907e4dce7bdf437c782fb2d15eb28d9e334e6e431c
|
||||
/home/worsch/railiance-platform/scripts/application_recovery_identities.py: 20f56255ed6eeec4aafe33f142bc3ee03f623d4957a7b0cabb741d340f15f79d
|
||||
/home/worsch/railiance-platform/scripts/application_recovery_mirror.py: d48ab95e89b9eeae36269d853ebe4c44c22e1f57d4e14224f03d0b9aeeb34178
|
||||
/home/worsch/railiance-platform/scripts/application_recovery_resources.py: ab70ec341e738272730eb0daf76840d0bca807caeb3c4e4c2357f162fbed4498
|
||||
/home/worsch/railiance-platform/scripts/primary_application_archive.py: a3f0a61e869a6012edb4b5288be14e3b0c4a9a1273b090320ab146d12e5aa94d
|
||||
/tmp/csoc-mirror-content-point.py: bc4d04c3f8ee3ca089fa9b038e6ab617eaababcb7f0aec94339e7f4eeb70f13a
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.native-mirror-worker-proof.v1",
|
||||
"status": "native_worker_and_independent_receipt_verified",
|
||||
"completed_at": "2026-10-31T23:35:37.716717+00:00",
|
||||
"primary": {
|
||||
"application": "coulomb-social",
|
||||
"captured_at": "2026-10-31T23:29:54Z",
|
||||
"object_key": "platform-pg/application-archives/coulomb-social/2026/10/31/20261031T232954Z-039d1bab2ea7ef33b7453979.tar.age",
|
||||
"version_id": "1793489481116168",
|
||||
"ciphertext_sha256": "eb495239fdf2344d6d72da9d4b02957613e7a4d67c54a2d67963ef802bc39421",
|
||||
"ciphertext_bytes": 2181848,
|
||||
"age_recipient": "age1qm30jk8q0cezey652dk2dhcr3d9vs528v6lg8mavl6d4q3e3vgnqmrmyy3",
|
||||
"image": "forgejo.coulomb.social/coulomb/coulomb-social@sha256:7906f461bc8d2d5204fd4fde67a251850f725b914452a66172919d6853672ed5",
|
||||
"database_sha256": "4c49933e4fb81573257b7c64e95edd7f0395f20c9e6280348bb10383fd8eaa25",
|
||||
"content_sha256": "0768e4f61ef003cff76c31aaca687e07e1743ff15a4d2d92dc0ebf123d4ec55e"
|
||||
},
|
||||
"recovery_mirror": {
|
||||
"bucket": "railiance-coulomb-social-archives",
|
||||
"ciphertext_bytes": 2181848,
|
||||
"ciphertext_sha256": "eb495239fdf2344d6d72da9d4b02957613e7a4d67c54a2d67963ef802bc39421",
|
||||
"hash_readback_verified": true,
|
||||
"object_key": "archives/platform-pg/application-archives/coulomb-social/2026/10/31/20261031T232954Z-039d1bab2ea7ef33b7453979.tar.age",
|
||||
"project_id": "06d107bc-9d84-4672-b2a0-95701cc0c07f",
|
||||
"receipt_bytes": 1664,
|
||||
"receipt_object_key": "archives/platform-pg/application-archives/coulomb-social/2026/10/31/20261031T232954Z-039d1bab2ea7ef33b7453979.tar.age.1d1589e5e6dc5edc6354434bf851ffe07c65c92eb7fcf1ff296aea7bca67c91b.receipt.json",
|
||||
"receipt_readback_verified": true,
|
||||
"receipt_sha256": "1d1589e5e6dc5edc6354434bf851ffe07c65c92eb7fcf1ff296aea7bca67c91b",
|
||||
"receipt_version_id": "1793489727604085",
|
||||
"version_id": "1793489725683064"
|
||||
},
|
||||
"worker_results": [
|
||||
{
|
||||
"status": "mirrored_with_retained_receipt",
|
||||
"primary_recaptured": false,
|
||||
"ciphertext_readback_verified": true,
|
||||
"receipt_readback_verified": true,
|
||||
"recovery_key_read": false,
|
||||
"independent_reader_used": false,
|
||||
"retained_objects_deleted": false,
|
||||
"application_restore_verified": false
|
||||
},
|
||||
{
|
||||
"status": "mirrored_with_retained_receipt",
|
||||
"primary_recaptured": false,
|
||||
"ciphertext_readback_verified": true,
|
||||
"receipt_readback_verified": true,
|
||||
"recovery_key_read": false,
|
||||
"independent_reader_used": false,
|
||||
"retained_objects_deleted": false,
|
||||
"application_restore_verified": false
|
||||
}
|
||||
],
|
||||
"native_versions_before": 0,
|
||||
"native_versions_after": 2,
|
||||
"one_ciphertext_and_one_receipt_version_after_retry": true,
|
||||
"independent_reader_ciphertext_and_receipt_verified": true,
|
||||
"retained_receipt_equals_exact_public_field_filter": true,
|
||||
"local_primary_receipt_and_ciphertext_unchanged": true,
|
||||
"retry_last_mirror_bytes_unchanged": true,
|
||||
"runtime_source_commit": "09f4fd33cbeefecb833998246cf53848bb1e5d8d",
|
||||
"private_state_copy_used": true,
|
||||
"production_application_contact": false,
|
||||
"node_helpers_or_state_modified": false,
|
||||
"node_timers_changed": false,
|
||||
"native_capture_performed": false,
|
||||
"decryption_identity_read": false,
|
||||
"retained_objects_deleted": false,
|
||||
"operating_capacity_profile_admitted": false,
|
||||
"alert_reception_verified": false,
|
||||
"scheduled_service_execution_verified": false,
|
||||
"sources_manifest_sha256": "dc4648e896c65ba0efccb80ff3b545b8efd582e1c7f54b6152ee0194b5af9eda"
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
/home/worsch/coulomb-social/deploy/backup/mirror-platform-runtime.json: 9253c5f6e956b67f499d3e12d2851be7fabd3bc56b00496b8810bbd0be8209f1
|
||||
/home/worsch/coulomb-social/scripts/backup_capacity.py: cb699a79e67b129239b5aa5d6f3b0d4ffaa9773a8b073227ad17fdecb5b9d893
|
||||
/home/worsch/coulomb-social/scripts/check-paired-backup-health.py: 2d40ec6e4c59ea7fe1d46065d197b9a87ca6811f023cc6f3e20e4184a3490566
|
||||
/home/worsch/coulomb-social/scripts/mirror-paired-backup.py: 9ceb26d9083af016c4b787907e4dce7bdf437c782fb2d15eb28d9e334e6e431c
|
||||
/home/worsch/railiance-platform/scripts/application_recovery_identities.py: 20f56255ed6eeec4aafe33f142bc3ee03f623d4957a7b0cabb741d340f15f79d
|
||||
/home/worsch/railiance-platform/scripts/application_recovery_mirror.py: d48ab95e89b9eeae36269d853ebe4c44c22e1f57d4e14224f03d0b9aeeb34178
|
||||
/home/worsch/railiance-platform/scripts/application_recovery_resources.py: ab70ec341e738272730eb0daf76840d0bca807caeb3c4e4c2357f162fbed4498
|
||||
/home/worsch/railiance-platform/scripts/primary_application_archive.py: a3f0a61e869a6012edb4b5288be14e3b0c4a9a1273b090320ab146d12e5aa94d
|
||||
/tmp/csoc-mirror-editor-point.py: 2cba828db15a11415136eb17586c116ba10d06b835b5f8291ae858af7ad2b448
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# Native password-reset bind prerequisite
|
||||
|
||||
WP-0015-T06 owns the remaining native authority return. An isolated native Authelia/LLDAP test identifies a
|
||||
WP-0015-T04 remains open. An isolated native Authelia/LLDAP test identifies a
|
||||
directory permission prerequisite before the full UC-009 browser journey can be
|
||||
accepted. It does not change the existing personal reset acceptance, prove the
|
||||
currently installed bind's privileges or authorize any live permission change.
|
||||
|
|
@ -95,237 +95,3 @@ expiry/replay, KeyCape, user-engine HTTP and the actual app callback using an
|
|||
explicit synthetic password-manager bind. See native-recovery-browser-review-2026-10-31.md.
|
||||
That new proof does not grant production reset authority or rewrite this API-only
|
||||
receipt's scope.
|
||||
|
||||
|
||||
## Owner return assessed on October 31
|
||||
|
||||
The bind split and its post-split restore drill are now complete under
|
||||
NK-WP-0054-T05. Their checks cover sign-in and MFA, not password replacement.
|
||||
The founder receipt records svc-authelia as strict-readonly. Current read-only
|
||||
metadata finds that bind in the ConfigMap and both deployed images exactly match
|
||||
this isolated proof. No current directory membership or production reset was
|
||||
queried, so this is an unresolved reset-authority return rather than a live
|
||||
failure claim. See reset-owner-return-assessment-2026-10-31.json.
|
||||
|
||||
The same owner workplan now carries T09 (completed evidence assessment) and T10
|
||||
(supported reset authority, reviewed execution and native/recovery acceptance).
|
||||
CSOC-WP-0015-T06 consumes T10. T05 remains complete for its original migration
|
||||
scope. Previous personal reset acceptance does not establish behavior after the
|
||||
bind changed; no new grant is inferred from either the old approval or the
|
||||
synthetic password-manager success. Preparation may proceed independently of the
|
||||
pending application image and backup installation.
|
||||
|
||||
|
||||
## Native authority matrix — October 31
|
||||
|
||||
`scripts/rehearse-reset-authority.py` extends the synthetic investigation without
|
||||
changing the application, canonical bind helper, declaration or live directory.
|
||||
It uses the same pinned native images and network-none loopback confinement.
|
||||
Run with `--output` naming a fresh local JSON receipt; adjacent source manifest
|
||||
and receipt refuse overwrite. Disabled assertions refuse before Docker access.
|
||||
|
||||
| Synthetic target | Strict-readonly | Password-manager |
|
||||
| --- | --- | --- |
|
||||
| Two ordinary users | Reset refused | Reset succeeds |
|
||||
| Member of `lldap_admin` | Reset refused | Reset refused |
|
||||
| Application-admin group member, outside `lldap_admin` | Reset refused | Reset succeeds |
|
||||
| Other read-only service account, direct directory password API | Refused | Password changes |
|
||||
|
||||
The first four user cases are tested through actual Authelia reset/link flows
|
||||
and direct directory password changes. Old/replacement password authentication
|
||||
confirms every outcome; HTTP 200 is insufficient. Unverified requests and consumed
|
||||
link replay refuse. Service interactive login through Authelia is excluded by the
|
||||
filter in every scenario. This does not prohibit direct LLDAP web login, and that
|
||||
filter does not constrain a compromised bind credential's directory password API.
|
||||
|
||||
For each role, seven valid directory mutations refuse: create/delete user,
|
||||
edit another user's profile, create/delete group, self-promote to directory admin,
|
||||
and remove another administrator's membership. Matching admin controls succeed,
|
||||
and complete user/group metadata remains unchanged after the denied operations.
|
||||
This bounds the tested operations; it does not enumerate every API right.
|
||||
|
||||
The LLDAP-admin restriction agrees with the pinned upstream
|
||||
[LLDAP v0.6.2 integration guidance](https://github.com/lldap/lldap/blob/v0.6.2/README.md#general-configuration-guide).
|
||||
The application-admin and service results matter to admission: a password-manager
|
||||
role is not restricted to Coulomb users or to human accounts. It must not be
|
||||
presented as restoring all prior reset behavior. No actual account's current
|
||||
classification has been inferred from these fixtures.
|
||||
|
||||
Owner T11 records this completed rehearsal; T10 retains the supported runtime path.
|
||||
Before an executable proposal, obtain owner-authorized, value-free classification
|
||||
of the intended reset subjects and current bind memberships. Review a service-owned
|
||||
password-write grant against SI-3 and its complete non-LLDAP-admin reach, and, if the accepted subject is a directory administrator, a
|
||||
supported recovery route for that subject. Preserve the
|
||||
existing human-admin separation and MFA requirements. A role change alone is not
|
||||
a complete proposal, and no runtime grant or policy exception is approved here.
|
||||
|
||||
Evidence: reset-authority-matrix-2026-10-31.json and its source manifest;
|
||||
reset-authority-validation-2026-10-31.json. Ten direct password cases, eight native
|
||||
Authelia flows, fourteen unrelated-write denials and fourteen matching admin
|
||||
controls pass. All disposable containers are removed. Both original native reset
|
||||
scenarios still pass; the full `make check` gate passes 546 tests with zero
|
||||
failures/errors/skips. These checks add neither productive acceptance nor a
|
||||
current membership observation. Existing expiry/browser/app proof retains its
|
||||
separate scope; this matrix does not retest the complete issuer/MFA journey.
|
||||
|
||||
|
||||
## Current-role observation for the accepted account
|
||||
|
||||
The October6 acceptance record names **tegwick**
|
||||
(`history/20261006T185411Z-personal-workspace-acceptance.md`). Decision
|
||||
8770d4ea-8538-4f88-a9f8-8bcfb0542603 corrects the earlier inference that a new route
|
||||
for all directory administrators must precede this consumer's remedy. Check
|
||||
tegwick's current membership first. If it is an LLDAP administrator, its supported
|
||||
recovery path is required; otherwise retain the administrator exclusion under
|
||||
existing NetKingdom recovery ownership. The admitted password-write scope still
|
||||
requires explicit review. This preserves the accepted workflow and adds no grant.
|
||||
|
||||
The fixed-subject observer is prepared and tested (owner T12); actual observation
|
||||
is owner T13. Run these commands in your own workstation terminal:
|
||||
|
||||
```bash
|
||||
install -d -m 700 /home/worsch/.local/state/net-kingdom/reset-authority
|
||||
python3 /home/worsch/net-kingdom/sso-mfa/k8s/lldap/reset-authority-observe.py \
|
||||
--receipt /home/worsch/.local/state/net-kingdom/reset-authority/roles-20261031.json
|
||||
```
|
||||
|
||||
Enter the **human admin account's password** at the hidden prompt. The tool already
|
||||
selects tegwick, svc-authelia and admin; it asks for no username, token or backup
|
||||
credential. Do not paste the password into chat. Return only its JSON result.
|
||||
The existing NetKingdom bind helper uses this human-held input for authenticated
|
||||
reads; the new observer reuses its bounded transport without credential discovery.
|
||||
|
||||
Expected status is `current_reset_roles_observed`. It creates a mode0600 local
|
||||
receipt, signs in as admin and performs three read queries. It changes no group,
|
||||
password, declaration or deployment, sends no reset email, and grants nothing.
|
||||
TLS failures and unexpected/missing users refuse; do not bypass verification.
|
||||
An existing receipt refuses without overwrite. A successful result proves current
|
||||
role metadata only, not Authelia reset success, app authorization or acceptance.
|
||||
|
||||
Evidence: reset-observer-preparation-2026-10-31.json. The observer and shared
|
||||
transport pass92 checks; four native owner cases pass and the final observer node
|
||||
passes with unchanged directory metadata and verified fixture cleanup. Production
|
||||
observation has not been performed during preparation.
|
||||
|
||||
|
||||
### Attended observation received
|
||||
|
||||
The founder completed the read at12:57:44Z on October31. Independent local receipt
|
||||
verification confirms its private custody, exact subject/endpoint and all four
|
||||
prepared source hashes. svc-authelia has only strict-readonly and no additional
|
||||
groups. tegwick has no built-in directory privilege role and one other group.
|
||||
Thus the directory-admin exclusion does not block the accepted personal flow on
|
||||
this observed state. Owner T13 is complete; T10 prepares the reviewed transition,
|
||||
including the full non-admin reach established by the native matrix. No grant,
|
||||
reset, app authorization or productive acceptance is contained in this receipt.
|
||||
Do not rerun the completed observer command. Evidence: reset-role-observation-
|
||||
2026-10-31.json and reset-role-return-verification-2026-10-31.json.
|
||||
|
||||
|
||||
## Reviewed role-transition proposal — 2026-10-31
|
||||
|
||||
**Prepared, not admitted or executed.** Owner preparation is NK-WP-0054-T14;
|
||||
founder admission/execution is T15; declaration alignment and productive reset plus
|
||||
fresh identity restore acceptance are T16. T10 and CSOC-WP-0015-T06 remain open.
|
||||
|
||||
Proposal: `sha256:753f50f139a0d090a8b64ba15174f2a7e8b0e639eb0dd01d17783476b5a3759f`. Exact controller and plan are
|
||||
`/home/worsch/net-kingdom/sso-mfa/k8s/lldap/reset-role-transition.py` and
|
||||
`reset-role-plan.json`. The digest binds the controller, existing transport and
|
||||
observer sources, current role observation, native rights matrix, pinned runtime
|
||||
identities/configuration and final validation. No new resources or recurring
|
||||
capacity are requested; no credential rotation, service rename or restart is
|
||||
included. Both pinned workloads were Ready when observed.
|
||||
|
||||
### Decision and scope
|
||||
|
||||
The proposed change replaces **only svc-authelia's strict-readonly membership**
|
||||
with **lldap_password_manager**. This restores the native password-write capability
|
||||
needed by the accepted tegwick recovery flow. The role can change passwords for
|
||||
**all non-LLDAP-admin directory identities**, including other service accounts and
|
||||
application administrators outside lldap_admin. It is not limited to Coulomb or to
|
||||
human accounts. LLDAP administrators are excluded. Seven tested unrelated writes
|
||||
remain refused; this is not an exhaustive rights audit. Both roles already permit
|
||||
own-profile/password operations in the pinned [LLDAP access-control source](https://github.com/lldap/lldap/blob/v0.6.2/crates/auth/src/access_control.rs).
|
||||
|
||||
The same dedicated SERVICE account and single Authelia consumer remain. The plan
|
||||
contains the proposed declaration: directory read USE plus narrowly described
|
||||
password ADMINISTER scope, without the read-only bind convention. SI-3 permits a
|
||||
service-owned write account with its narrowest working scope. The canonical
|
||||
read-only declaration has not been changed to imply approval. Following a verified
|
||||
grant, T16 must align it and existing bind verification/repair expectations. Do
|
||||
not rerun the historical read-only bind migration as reset verification.
|
||||
|
||||
**Rollback limit:** membership rollback restores fresh Authelia reset denial, but
|
||||
it does not revoke previously issued HTTP tokens or undo changed user passwords.
|
||||
A native test proves a token obtained during the grant can still change an eligible
|
||||
password after membership rollback; a freshly issued token cannot. The pinned
|
||||
[LLDAP token implementation](https://github.com/lldap/lldap/blob/v0.6.2/server/src/auth_service.rs)
|
||||
embeds groups in a token with a one-day expiry. Treat retained token authority as
|
||||
lasting up to 24 hours unless separately revoked. This packet includes no token
|
||||
revocation or incident-containment operation. Admission includes this limitation.
|
||||
|
||||
### Execution and recovery
|
||||
|
||||
Run in the founder's workstation terminal only after accepting the scope above:
|
||||
|
||||
```bash
|
||||
python3 /home/worsch/net-kingdom/sso-mfa/k8s/lldap/reset-role-transition.py \
|
||||
--execute --expect-digest sha256:753f50f139a0d090a8b64ba15174f2a7e8b0e639eb0dd01d17783476b5a3759f
|
||||
```
|
||||
|
||||
The hidden prompt requires the human admin password. Never paste it into chat.
|
||||
After reviewing the printed scope, enter exactly:
|
||||
|
||||
```text
|
||||
GRANT sha256:753f50f139a0d090a8b64ba15174f2a7e8b0e639eb0dd01d17783476b5a3759f
|
||||
```
|
||||
|
||||
The controller checks the exact live cluster/namespace/deployment identities,
|
||||
images and Authelia configuration before private authentication and again after
|
||||
confirmation. It rechecks the human admin role, tegwick's non-admin classification
|
||||
and svc-authelia's exact baseline before writing. The old role is removed before
|
||||
the new one is added; a brief directory lookup failure is possible. Every effect
|
||||
has a durable intent record. All user IDs and group memberships are compared after
|
||||
each step; unknown concurrent changes fail verification. Profile fields/passwords
|
||||
are not copied into the receipt or claimed as independently compared.
|
||||
|
||||
Success is `password_manager_role_verified`. Paste only the returned JSON; Codex
|
||||
will verify the durable mode0600 receipt in
|
||||
`~/.local/state/net-kingdom/reset-authority/753f50f139a0d090a8b64ba15174f2a7e8b0e639eb0dd01d17783476b5a3759f/journal.json`.
|
||||
An existing attempt refuses replay. Do not delete its state or repeat the grant.
|
||||
If the operation is interrupted or reports uncertain status, restore read-only
|
||||
membership with this separate attended recovery:
|
||||
|
||||
```bash
|
||||
python3 /home/worsch/net-kingdom/sso-mfa/k8s/lldap/reset-role-transition.py \
|
||||
--recover --expect-digest sha256:753f50f139a0d090a8b64ba15174f2a7e8b0e639eb0dd01d17783476b5a3759f
|
||||
```
|
||||
|
||||
Confirm `RECOVER sha256:753f50f139a0d090a8b64ba15174f2a7e8b0e639eb0dd01d17783476b5a3759f`. For an already completed successful
|
||||
grant, use `--rollback` instead of `--recover` and confirm
|
||||
`ROLLBACK sha256:753f50f139a0d090a8b64ba15174f2a7e8b0e639eb0dd01d17783476b5a3759f`. Both restore only the role and retain
|
||||
previous journal versions. They preserve unrelated subsequent memberships and
|
||||
user password changes. Recovery tolerates workload unready status but still
|
||||
requires pinned identities, images and configuration; runtime drift requires
|
||||
review, not a bypass. If the directory itself is unreachable, recovery cannot
|
||||
claim completion until the owner restores access. These are role restoration
|
||||
commands with the token limitation above, not full credential revocation.
|
||||
|
||||
### Evidence and remaining acceptance
|
||||
|
||||
25 unit checks and four native controller checks pass with no skips/failures.
|
||||
The native checks include real process termination immediately after removal and
|
||||
addition, successful recovery without replay, and the retained-token boundary.
|
||||
A separate confined native rehearsal uses **one running Authelia process** through
|
||||
read-only → password-manager → read-only: reset refuses, succeeds, then refuses;
|
||||
old/new passwords and consumed challenge denial are checked each time. No restart
|
||||
is needed in this tested configuration. Synthetic fixtures and generated passwords
|
||||
are removed; no provider SMTP or productive password reset was used.
|
||||
|
||||
Evidence: `reset-transition-validation-2026-10-31.json`,
|
||||
`reset-role-refresh-2026-10-31.json` and its source manifest. A successful role
|
||||
receipt still leaves T16: source alignment, productive tegwick reset/app/MFA and
|
||||
fresh identity backup/restore evidence. It does not complete the four goal workplans.
|
||||
|
||||
The final consumer `make check` gate passes546 tests (zero failures/skips;69
|
||||
existing warnings). Receipt: reset-transition-consumer-gate-2026-10-31.json.
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.operator-handoff-check.v1",
|
||||
"recorded_at": "2026-10-31T16:35:39.718467+00:00",
|
||||
"custody_preflight": {
|
||||
"status": "completed_evidence_seal_preflight_verified",
|
||||
"proposal_digest": "sha256:fa2763d1dcbe92fe638a29c9a7a7d51c03d30849c4232f2d43f81ef705bae611",
|
||||
"entries": 8,
|
||||
"modified": false,
|
||||
"historical_operations_terminal": true
|
||||
},
|
||||
"route_preflight": {
|
||||
"schema": "rapp-telemetry.backup-route-execution.v1",
|
||||
"execution_digest": "sha256:4d8481061dc9ce6835169defc96887945052332a0db8d4234ae84032d63cc328",
|
||||
"proposal_digest": "sha256:4bcad54f7b8e1e77b94112e452cbb58eaf8e882dc10305129c5f9ca69f014a66",
|
||||
"status": "preflight_verified",
|
||||
"timers_activated": false,
|
||||
"notification_sent_by_helper": false,
|
||||
"production_data_restored": false
|
||||
},
|
||||
"native_receipts_present": {
|
||||
"custody": false,
|
||||
"route": false,
|
||||
"inactive_installation": false
|
||||
},
|
||||
"owner_tasks": {
|
||||
"RPF-WP-0068-T03": "wait",
|
||||
"RPF-WP-0068-T04": "todo",
|
||||
"NK-reset-role-transition": "wait",
|
||||
"CSOC-WP-0012-T07": "wait",
|
||||
"CSOC-WP-0012-T08": "wait"
|
||||
},
|
||||
"decision_queue": [
|
||||
{
|
||||
"id": "3ec2f98e-9db3-47d9-bc1a-0387f980b81c",
|
||||
"title": "Seal eight completed backup-evidence entries (fa2763d1)",
|
||||
"status": "escalated",
|
||||
"decision_type": "pending",
|
||||
"decided_by": null,
|
||||
"escalation_note": "Auto-escalated per constitution \u00a74: this pending decision touches financial or legal territory and requires explicit human approval before action."
|
||||
},
|
||||
{
|
||||
"id": "5fa7234f-2a41-4eed-b4fc-9384f493572b",
|
||||
"title": "Deploy recurring Coulomb backup alert route (4d848106)",
|
||||
"status": "escalated",
|
||||
"decision_type": "pending",
|
||||
"decided_by": null,
|
||||
"escalation_note": "Auto-escalated per constitution \u00a74: this pending decision touches financial or legal territory and requires explicit human approval before action."
|
||||
}
|
||||
],
|
||||
"new_approval_recorded": false,
|
||||
"operator_execution_performed": false,
|
||||
"message_sent": false,
|
||||
"timers_activated": false,
|
||||
"existing_destinations_and_schedule_preserved": true
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.ordered-list-fidelity.v1",
|
||||
"verified_at": "2026-10-31T17:20:32.943192+00:00",
|
||||
"source_articles_sha256": "f33967c79c0f8a60a7d504f5d5e4082f8bc9e3c34f6a3160cb200fd380831d62",
|
||||
"prior_audit_sha256": "3926e24a3b903f5e1d1c7133dc5f9df1e958183432c5131949ce838eb60acf1e",
|
||||
"current_audit_sha256": "d8f382e24d7adfe3c43dc71f32f8f6e647bf68239cbcdc6769a6c8fb85d666b9",
|
||||
"records": 245,
|
||||
"rendered_cards_verified": 242,
|
||||
"source_bodies_unchanged": true,
|
||||
"missing_bodies_retained": 3,
|
||||
"ordered_list_starts_restored": 15,
|
||||
"affected_records": 4,
|
||||
"markup_change_cases_before": 6,
|
||||
"markup_change_cases_after": 3,
|
||||
"remaining_removed_tags": {
|
||||
"topic": 3
|
||||
},
|
||||
"remaining_removed_attributes": [
|
||||
{
|
||||
"tag": "topic",
|
||||
"attribute": "name",
|
||||
"count": 2
|
||||
}
|
||||
],
|
||||
"private_review_directory": "~/.config/coulomb-social/auth/exports/rendering-review-20261031-numbering",
|
||||
"source_hashes": {
|
||||
"coulomb_social/apps/spaces/content.py": "5d6bb5c800b3e776fff385fa73284f4916403676dc2a8bc06b8fadc7d2387633",
|
||||
"tests/test_rendering_audit.py": "ae092753f4d1d006bb88f1ce11581975c105c5231819f9409ddaaf2fc83d32f5"
|
||||
},
|
||||
"validation": {
|
||||
"focused_passed": 14,
|
||||
"full_gate_passed": 650,
|
||||
"full_gate_warnings": 69,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"full_gate_seconds": 91.85
|
||||
},
|
||||
"production_deployed": false,
|
||||
"original_bubble_render_compared": false,
|
||||
"productive_fidelity_accepted": false
|
||||
}
|
||||
|
|
@ -72,9 +72,8 @@ applies to Authelia, not this additional consumer. SMTP AUTH proof must not subm
|
|||
mail. The application sender migration needs a separate supervised configuration
|
||||
executor and independent postflight after the scoped projection is Ready.
|
||||
|
||||
This candidate is **not execution-ready**: the owner admission helper is now
|
||||
prepared under RPF-WP-0068, but its native custody receipt and the separate
|
||||
supervised sender rollout packet remain absent. Resource-version and
|
||||
This candidate is **not execution-ready**: no owner admission helper/receipt or
|
||||
supervised rollout packet exists for this new consumer yet. Resource-version and
|
||||
identity tests must be refreshed and re-reviewed at execution time. Do not apply
|
||||
these individual patches by hand as a substitute for that packet.
|
||||
|
||||
|
|
@ -130,20 +129,3 @@ its global-recipient effect and release policy, and agree retention. It must ret
|
|||
proof of why suppression changed and refuse unrelated/uncertain records. Productive
|
||||
inbox access, selected-message authentication/correlation and the operator response
|
||||
remain acceptance gates alongside the sender rollout.
|
||||
|
||||
## Sender transition owner follow-through
|
||||
|
||||
EMAIL-WP-0010 makes the separate configuration executor and native return explicit
|
||||
owner tasks. Its completed T01 records a fresh six-table native ledger observation
|
||||
at15:16:41Z, with no uncertain outcomes. Successful invitations may retain an
|
||||
in_flight attempt row, so the observer follows the application rule that a delivery
|
||||
receipt takes precedence. Fingerprints and counts share one read-only transaction;
|
||||
the receiver remained live and this is not a drain or execution-time backup.
|
||||
|
||||
The source has no explicit SIGTERM drain handler. Remaining owner T02 must provide
|
||||
a concrete supervised executor, fresh recoverable point, durable phase journal,
|
||||
native postflight and recovery that preserves uncertain/accepted sends and later
|
||||
writes. Existing admission, image, source and custody packets remain unchanged.
|
||||
Evidence: `email-connect/docs/sender-transition-boundary-2026-10-31.md` and
|
||||
`sender-ledger-native-2026-10-31.json` in the owner repository. The owner tests
|
||||
report192passed/21existing optional-harness skips; all12new observer cases pass.
|
||||
|
|
|
|||
|
|
@ -1,21 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.productive-copy-move-return.v1",
|
||||
"review_date": "2026-11-01",
|
||||
"helm_revision": 21,
|
||||
"user": "Bernd",
|
||||
"statement": "The step 2 of the walkthrough seems fine.",
|
||||
"status": "owner_copy_move_workflow_accepted",
|
||||
"review_guide": "docs/usecases/productive-content-acceptance-session.md#2-independent-copy-and-move--uc-004",
|
||||
"accepted_scope": [
|
||||
"Copy a page into another space",
|
||||
"Edit the copy and detach its text attachment while the original body and downloadable file remain unchanged",
|
||||
"Move another duplicate with its content, Visual and downloads intact",
|
||||
"Previously saved address reaches the moved destination for the authorized owner"
|
||||
],
|
||||
"remaining_scope": [
|
||||
"Moved destination and old-address denial for a participant lacking destination access (step3)",
|
||||
"Sharing and revocation (step3)",
|
||||
"Account-local portability and exit/succession semantics (step4)"
|
||||
],
|
||||
"complete_uc004_permission_verdict_inferred": false
|
||||
}
|
||||
|
|
@ -1,265 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.native-reset-authority-matrix.v1",
|
||||
"observed_at": "2026-10-31T12:37:24.533367+00:00",
|
||||
"data": "synthetic",
|
||||
"status": "native_authority_matrix_verified",
|
||||
"images": {
|
||||
"lldap": "sha256:9e605a66c02514bfcffd1b67cafb1e98d50992216bb2871d7ae44622047dd09d",
|
||||
"authelia": "sha256:bd97cff4fcbf715b5ff1f9ae286afbe6033afce385302520b0368122d43a6f54",
|
||||
"client": "sha256:512819463a1902b43a615beee14be7bf97e6a05e016385082b9380692ad1a8cd"
|
||||
},
|
||||
"production_access": false,
|
||||
"provider_smtp_contacted": false,
|
||||
"owner_runtime_or_permission_change_performed": false,
|
||||
"no_ports_host_mounts_or_external_routes": true,
|
||||
"backend_container_flags_verified_before_fixture_import": true,
|
||||
"source_manifest_sha256": "c982e3a47d9e3aec5095a3c11fea7260fd4f5cb6db57b827b915988b432a18d0",
|
||||
"target_classes": {
|
||||
"alice": "ordinary user",
|
||||
"bob": "other ordinary user",
|
||||
"operator": "lldap_admin member",
|
||||
"appoperator": "application-admins member, not lldap_admin",
|
||||
"svc-other": "other service, lldap_strict_readonly"
|
||||
},
|
||||
"findings": {
|
||||
"scenarios": [
|
||||
{
|
||||
"bind_role": "lldap_strict_readonly",
|
||||
"directory_writes": {
|
||||
"positive_controls": 7,
|
||||
"refused_mutations": [
|
||||
"create_user",
|
||||
"edit_other_user",
|
||||
"delete_user",
|
||||
"create_group",
|
||||
"delete_group",
|
||||
"self_promote_admin",
|
||||
"remove_admin_membership"
|
||||
],
|
||||
"directory_metadata_unchanged": true
|
||||
},
|
||||
"direct_password_changes": [
|
||||
{
|
||||
"target": "alice",
|
||||
"password_changed": false,
|
||||
"old_password_accepted": true,
|
||||
"new_password_accepted": false
|
||||
},
|
||||
{
|
||||
"target": "bob",
|
||||
"password_changed": false,
|
||||
"old_password_accepted": true,
|
||||
"new_password_accepted": false
|
||||
},
|
||||
{
|
||||
"target": "operator",
|
||||
"password_changed": false,
|
||||
"old_password_accepted": true,
|
||||
"new_password_accepted": false
|
||||
},
|
||||
{
|
||||
"target": "appoperator",
|
||||
"password_changed": false,
|
||||
"old_password_accepted": true,
|
||||
"new_password_accepted": false
|
||||
},
|
||||
{
|
||||
"target": "svc-other",
|
||||
"password_changed": false,
|
||||
"old_password_accepted": true,
|
||||
"new_password_accepted": false
|
||||
}
|
||||
],
|
||||
"authelia_resets": [
|
||||
{
|
||||
"target": "alice",
|
||||
"status": "reset_refused",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": "KO",
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": true,
|
||||
"new_password_accepted_after": false
|
||||
},
|
||||
{
|
||||
"target": "bob",
|
||||
"status": "reset_refused",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": "KO",
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": true,
|
||||
"new_password_accepted_after": false
|
||||
},
|
||||
{
|
||||
"target": "operator",
|
||||
"status": "reset_refused",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": "KO",
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": true,
|
||||
"new_password_accepted_after": false
|
||||
},
|
||||
{
|
||||
"target": "appoperator",
|
||||
"status": "reset_refused",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": "KO",
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": true,
|
||||
"new_password_accepted_after": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"bind_role": "lldap_password_manager",
|
||||
"directory_writes": {
|
||||
"positive_controls": 7,
|
||||
"refused_mutations": [
|
||||
"create_user",
|
||||
"edit_other_user",
|
||||
"delete_user",
|
||||
"create_group",
|
||||
"delete_group",
|
||||
"self_promote_admin",
|
||||
"remove_admin_membership"
|
||||
],
|
||||
"directory_metadata_unchanged": true
|
||||
},
|
||||
"direct_password_changes": [
|
||||
{
|
||||
"target": "alice",
|
||||
"password_changed": true,
|
||||
"old_password_accepted": false,
|
||||
"new_password_accepted": true
|
||||
},
|
||||
{
|
||||
"target": "bob",
|
||||
"password_changed": true,
|
||||
"old_password_accepted": false,
|
||||
"new_password_accepted": true
|
||||
},
|
||||
{
|
||||
"target": "operator",
|
||||
"password_changed": false,
|
||||
"old_password_accepted": true,
|
||||
"new_password_accepted": false
|
||||
},
|
||||
{
|
||||
"target": "appoperator",
|
||||
"password_changed": true,
|
||||
"old_password_accepted": false,
|
||||
"new_password_accepted": true
|
||||
},
|
||||
{
|
||||
"target": "svc-other",
|
||||
"password_changed": true,
|
||||
"old_password_accepted": false,
|
||||
"new_password_accepted": true
|
||||
}
|
||||
],
|
||||
"authelia_resets": [
|
||||
{
|
||||
"target": "alice",
|
||||
"status": "reset_completed",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": null,
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": false,
|
||||
"new_password_accepted_after": true
|
||||
},
|
||||
{
|
||||
"target": "bob",
|
||||
"status": "reset_completed",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": null,
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": false,
|
||||
"new_password_accepted_after": true
|
||||
},
|
||||
{
|
||||
"target": "operator",
|
||||
"status": "reset_refused",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": "KO",
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": true,
|
||||
"new_password_accepted_after": false
|
||||
},
|
||||
{
|
||||
"target": "appoperator",
|
||||
"status": "reset_completed",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": null,
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": false,
|
||||
"new_password_accepted_after": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"cleanup_verified": true
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
scripts/rehearse-reset-authority.py: 120d3b8d4e54ec87386f9f2d53abe836feab48c7cc883a13e0d4672bcc347b0c
|
||||
scripts/rehearse-native-password-reset.py: 133c8230c524fbbaf7f66e4872e14b826ed2c5a4f4de3bc47fa86cfef7631d5d
|
||||
scripts/native_recovery/probe.py: eab3bae55626abd4920eb6aa2e329c83559007c54ac74c3aaa1cf41e84eb6556
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.reset-authority-validation.v1",
|
||||
"status": "source_and_isolated_native_verified",
|
||||
"full_gate": {
|
||||
"command": "make check",
|
||||
"tests": 546,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"junit_sha256": "ff99e36bad4e42a1983bdac2749b834a454a22c708065752ecd31f8be5ac963a"
|
||||
},
|
||||
"native_matrix": {
|
||||
"roles": 2,
|
||||
"direct_password_cases": 10,
|
||||
"authelia_reset_cases": 8,
|
||||
"unrelated_write_denials": 14,
|
||||
"valid_admin_write_controls": 14,
|
||||
"cleanup_verified": true
|
||||
},
|
||||
"legacy_native_reset_regression": "passed both original role scenarios",
|
||||
"cli_refusals": [
|
||||
"disabled assertions",
|
||||
"existing receipt",
|
||||
"existing source manifest"
|
||||
],
|
||||
"current_live_membership_verified": false,
|
||||
"production_reset_verified": false,
|
||||
"authority_grant_approved": false,
|
||||
"sources": [
|
||||
{
|
||||
"path": "scripts/rehearse-reset-authority.py",
|
||||
"sha256": "120d3b8d4e54ec87386f9f2d53abe836feab48c7cc883a13e0d4672bcc347b0c"
|
||||
},
|
||||
{
|
||||
"path": "scripts/native_recovery/probe.py",
|
||||
"sha256": "eab3bae55626abd4920eb6aa2e329c83559007c54ac74c3aaa1cf41e84eb6556"
|
||||
},
|
||||
{
|
||||
"path": "docs/release/reset-authority-matrix-2026-10-31.json",
|
||||
"sha256": "89c555ac2c580153bd81ae03c662d024a0cdbeba173f93e6ebfa041a1a0261c7"
|
||||
},
|
||||
{
|
||||
"path": "docs/release/reset-default-regression-2026-10-31.json",
|
||||
"sha256": "82efb79154b5e5003ce4b821ebeba73deb4375a13f4df93eddbd3b8908e705ea"
|
||||
}
|
||||
],
|
||||
"upstream_reference": "https://github.com/lldap/lldap/blob/v0.6.2/README.md#general-configuration-guide"
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.native-reset-prerequisite.v1",
|
||||
"data": "synthetic",
|
||||
"status": "native_bind_role_reset_boundary_verified",
|
||||
"observed_at": "2026-10-31T12:36:56.223367+00:00",
|
||||
"images": {
|
||||
"lldap": "sha256:9e605a66c02514bfcffd1b67cafb1e98d50992216bb2871d7ae44622047dd09d",
|
||||
"authelia": "sha256:bd97cff4fcbf715b5ff1f9ae286afbe6033afce385302520b0368122d43a6f54",
|
||||
"probe": "sha256:512819463a1902b43a615beee14be7bf97e6a05e016385082b9380692ad1a8cd"
|
||||
},
|
||||
"production_access": false,
|
||||
"browser_app_or_mfa_acceptance": false,
|
||||
"provider_smtp_contacted": false,
|
||||
"notifier": "private_tmpfs_file",
|
||||
"no_ports_host_mounts_or_external_routes": true,
|
||||
"backend_container_flags_verified_before_fixture_import": true,
|
||||
"owner_runtime_or_permission_change_performed": false,
|
||||
"findings": {
|
||||
"scenarios": [
|
||||
{
|
||||
"bind_role": "lldap_strict_readonly",
|
||||
"status": "reset_refused",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": "KO",
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": true,
|
||||
"new_password_accepted_after": false,
|
||||
"directory_group_creation_refused": true,
|
||||
"native_reset_notification_present": true
|
||||
},
|
||||
{
|
||||
"bind_role": "lldap_password_manager",
|
||||
"status": "reset_completed",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": null,
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": false,
|
||||
"new_password_accepted_after": true,
|
||||
"directory_group_creation_refused": true,
|
||||
"native_reset_notification_present": true
|
||||
}
|
||||
],
|
||||
"cleanup_verified": true
|
||||
},
|
||||
"source_manifest_sha256": "1f3977f01757519dd5d08007b4baffa555f2cad44d9301d5dd484ded46f274e9"
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
scripts/rehearse-native-password-reset.py: 133c8230c524fbbaf7f66e4872e14b826ed2c5a4f4de3bc47fa86cfef7631d5d
|
||||
scripts/native_recovery/probe.py: eab3bae55626abd4920eb6aa2e329c83559007c54ac74c3aaa1cf41e84eb6556
|
||||
|
|
@ -1,77 +0,0 @@
|
|||
{
|
||||
"schema": "netkingdom.reset-observer-preparation.v1",
|
||||
"status": "tested_ready_for_attended_read",
|
||||
"owner_task": "NK-WP-0054-T12",
|
||||
"operator_return_task": "NK-WP-0054-T13",
|
||||
"consumer_task": "CSOC-WP-0015-T06",
|
||||
"accepted_subject": "tegwick",
|
||||
"acceptance_source": {
|
||||
"repo": "coulomb-social",
|
||||
"path": "history/20261006T185411Z-personal-workspace-acceptance.md",
|
||||
"sha256": "15ac9e1af4d0cb16b854d1ecf5fa89b634b1479174b02143b5c341cb3b5df2c3"
|
||||
},
|
||||
"technical_binding_decision_id": "8770d4ea-8538-4f88-a9f8-8bcfb0542603",
|
||||
"queries": [
|
||||
"human admin role",
|
||||
"svc-authelia roles",
|
||||
"tegwick roles"
|
||||
],
|
||||
"private_input": "human admin password via terminal only",
|
||||
"directory_mutations_available": false,
|
||||
"production_observation_performed": false,
|
||||
"password_reset_attempted": false,
|
||||
"grant_approved": false,
|
||||
"target_url": "https://lldap.coulomb.social",
|
||||
"planned_private_receipt": "/home/worsch/.local/state/net-kingdom/reset-authority/roles-20261031.json",
|
||||
"gates": {
|
||||
"unit_and_transport": {
|
||||
"tests": 92,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"junit_sha256": "7ee639ba82c7100d7805cc01ca5c2a6c502550eac4abdb252ad3c7d8b1ac232b"
|
||||
},
|
||||
"native_split_regression": {
|
||||
"tests": 4,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"junit_sha256": "b35645a61c52f45d0e826e3986145212f45d4abc065026b42bd651f6f4b5fb41"
|
||||
},
|
||||
"final_native_observer": {
|
||||
"tests": 1,
|
||||
"failures": 0,
|
||||
"errors": 0,
|
||||
"skipped": 0,
|
||||
"junit_sha256": "251831ae820081aa6e935d08c4e7854a1ad5cf840b8a41ae8af4add5f5406f2a"
|
||||
}
|
||||
},
|
||||
"native_fixture": "pinned owner LLDAP fixture; synthetic credentials, loopback-only published ports; container and volume removal verified",
|
||||
"lint": "passed",
|
||||
"sources": [
|
||||
{
|
||||
"path": "sso-mfa/k8s/lldap/reset-authority-observe.py",
|
||||
"sha256": "9f19c5551e2a93319c04c1b2fd0ddc0f7757fdff96ad18b81d7ee7bb393b75b9"
|
||||
},
|
||||
{
|
||||
"path": "sso-mfa/k8s/lldap/lldap_admin.py",
|
||||
"sha256": "5e39e2eac53846a97cd25151c0a4af1ffc0230db881a6325efb66de6a51bfc36"
|
||||
},
|
||||
{
|
||||
"path": "identity-provisioner/provisioner.py",
|
||||
"sha256": "a303a25d3b3876485c796a9ba0836ddaf0a0bec155b609790e028882ad983138"
|
||||
},
|
||||
{
|
||||
"path": "identity-provisioner/group_provenance.py",
|
||||
"sha256": "405e08eaaab7c21d618dff4db5970607806f32ab6c461effb81c737e32182b10"
|
||||
},
|
||||
{
|
||||
"path": "tests/test_reset_authority_observer.py",
|
||||
"sha256": "348fab447a4182357bf3f7d058b05c7d6088ae084d8e433e76ce5c39c513e152"
|
||||
},
|
||||
{
|
||||
"path": "sso-mfa/k8s/lldap/test_bind_split.py",
|
||||
"sha256": "ae69051a3df4596fe220306d88a28b2c12e42fbfe3587e02135e3684eb5f354a"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.reset-owner-boundary.v1",
|
||||
"observed_at": "2026-10-31T12:27:58.389484+00:00",
|
||||
"configmap_uid": "7af1fa0d-1bd4-47e1-8873-0f620788ef3f",
|
||||
"configmap_resource_version": "82819079",
|
||||
"configuration_sha256": "0a8bca50641a4c6f27830f476c2c9f413fc3795711becccb8344ee4d6c376e80",
|
||||
"bind_is_svc_authelia": true,
|
||||
"reset_disabled_in_config": false,
|
||||
"deployments": {
|
||||
"authelia": {
|
||||
"uid": "dc40a925-2306-4a3b-89c0-e714187503c3",
|
||||
"generation": 31,
|
||||
"observed_generation": 31,
|
||||
"ready_replicas": 1,
|
||||
"images": [
|
||||
"docker.io/authelia/authelia@sha256:bd97cff4fcbf715b5ff1f9ae286afbe6033afce385302520b0368122d43a6f54"
|
||||
]
|
||||
},
|
||||
"lldap": {
|
||||
"uid": "743a86bd-5cb0-4ca0-9c56-a3438f4746a8",
|
||||
"generation": 9,
|
||||
"observed_generation": 9,
|
||||
"ready_replicas": 1,
|
||||
"images": [
|
||||
"docker.io/lldap/lldap@sha256:9e605a66c02514bfcffd1b67cafb1e98d50992216bb2871d7ae44622047dd09d"
|
||||
]
|
||||
}
|
||||
},
|
||||
"directory_memberships_read_here": false,
|
||||
"password_reset_attempted": false,
|
||||
"secret_read": false,
|
||||
"email_sent": false,
|
||||
"runtime_changed": false,
|
||||
"status": "reset_authority_return_incomplete",
|
||||
"owner_bind_split_task": "NK-WP-0054-T05",
|
||||
"owner_bind_split_status": "done",
|
||||
"owner_followthrough": "NK-WP-0054-T10",
|
||||
"consumer_task": "CSOC-WP-0015-T06",
|
||||
"owner_membership_receipt_at": "2026-10-30T18:53:16.176849+00:00",
|
||||
"owner_receipt_bind_groups": [
|
||||
"lldap_strict_readonly"
|
||||
],
|
||||
"owner_restore_drill_proves": [
|
||||
"independent retrieval",
|
||||
"directory login",
|
||||
"Authelia first factor",
|
||||
"by-user MFA",
|
||||
"cleanup"
|
||||
],
|
||||
"owner_restore_drill_proves_password_change": false,
|
||||
"deployed_images_match_isolated_reset_proof": true,
|
||||
"isolated_readonly_reset_result": "HTTP 200/KO; old password accepted; replacement refused",
|
||||
"isolated_password_manager_reset_result": "ordinary fixture user changed password; directory group creation refused",
|
||||
"production_password_reset_failure_claimed": false,
|
||||
"current_membership_unknown_since_owner_receipt": true,
|
||||
"prior_personal_reset_acceptance": "preserved as historical; does not prove post-split reset",
|
||||
"knowledge_orientation": {
|
||||
"version": "0.2.7",
|
||||
"digest": "22b7294e24137c0a350764b9cf37f3d4f2e9f35eb7c97a287d9c89477ef24d7a",
|
||||
"cards": [
|
||||
"start",
|
||||
"identity"
|
||||
],
|
||||
"source_status": "verified-files",
|
||||
"authority": "orientation only"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"repo": "net-kingdom",
|
||||
"commit": "55fe8303f31d7476de5180f35c736652f5b4c475",
|
||||
"path": "workplans/NK-WP-0054-service-identity-policy.md",
|
||||
"sha256": "1b5411a38583edede8124881825f252b2498335de22559e23d52c787d9c9581a"
|
||||
},
|
||||
{
|
||||
"repo": "net-kingdom",
|
||||
"commit": "55fe8303f31d7476de5180f35c736652f5b4c475",
|
||||
"path": "docs/evidence/2026-10-30-nk54-bind-split/10-verify.json",
|
||||
"sha256": "b6318e9239623a09d3f6eac1208b0fd7c7a3d3facf55a4c31c8f628454e42ebb"
|
||||
},
|
||||
{
|
||||
"repo": "net-kingdom",
|
||||
"commit": "55fe8303f31d7476de5180f35c736652f5b4c475",
|
||||
"path": "docs/evidence/2026-10-31-identity-restore-drill/drill.json",
|
||||
"sha256": "47a5a88bdc8a7494d9e5e6687372398367931dca84e38d7de9f6290375caffa2"
|
||||
},
|
||||
{
|
||||
"repo": "net-kingdom",
|
||||
"commit": "55fe8303f31d7476de5180f35c736652f5b4c475",
|
||||
"path": "tools/bootstrap-recovery/isolated-authelia.py",
|
||||
"sha256": "6139294f6ebdcbaad35934f04b11177d8cf89d134506a730f0c0ebbb3a4967be"
|
||||
},
|
||||
{
|
||||
"repo": "net-kingdom",
|
||||
"commit": "55fe8303f31d7476de5180f35c736652f5b4c475",
|
||||
"path": "sso-mfa/k8s/lldap/bind-split.py",
|
||||
"sha256": "4decc3bbe65120ff6c4cef5613b9a41a60168ae64ecd4c1380f61a2fcd37b6b3"
|
||||
},
|
||||
{
|
||||
"repo": "coulomb-social",
|
||||
"commit": "a786a8050db92807d0f16e637043fbd191ab9335",
|
||||
"path": "docs/release/native-password-reset-2026-10-30.json",
|
||||
"sha256": "0666b35773ee3888e12d8d8d877bd8690c9c41b6f98096bf3c5a50195be2294f"
|
||||
},
|
||||
{
|
||||
"repo": "coulomb-social",
|
||||
"commit": "a786a8050db92807d0f16e637043fbd191ab9335",
|
||||
"path": "docs/release/native-recovery-browser-2026-10-31.json",
|
||||
"sha256": "4d3b644cdf0e76e8ff775a79d8845831f7573a1e2e716e60dd53416343b6e3ba"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
{
|
||||
"schema": "netkingdom.reset-role-observation.v1",
|
||||
"status": "current_reset_roles_observed",
|
||||
"observed_at": "2026-10-31T12:57:44.913538+00:00",
|
||||
"endpoint_sha256": "21b7c63da95eb01178305e49af9b3143295607b8ad68c522d1fa9545b7ef4d9f",
|
||||
"selected_subject_sha256": "835958a092b4fcddf93eadb83dc2d21519ed1aeab570d04a3d798a4c0f24c0ba",
|
||||
"human_admin_role_verified": true,
|
||||
"bind": {
|
||||
"builtin_roles": {
|
||||
"lldap_admin": false,
|
||||
"lldap_password_manager": false,
|
||||
"lldap_strict_readonly": true
|
||||
},
|
||||
"other_group_count": 0,
|
||||
"matches_reviewed_service_name_filter": true,
|
||||
"application_authority_assessed": false
|
||||
},
|
||||
"selected_subject": {
|
||||
"builtin_roles": {
|
||||
"lldap_admin": false,
|
||||
"lldap_password_manager": false,
|
||||
"lldap_strict_readonly": false
|
||||
},
|
||||
"other_group_count": 1,
|
||||
"matches_reviewed_service_name_filter": false,
|
||||
"application_authority_assessed": false
|
||||
},
|
||||
"bind_has_multiple_builtin_roles": false,
|
||||
"membership_changed": false,
|
||||
"password_reset_attempted": false,
|
||||
"grant_approved": false,
|
||||
"application_access_verified": false,
|
||||
"credential_values_recorded": false,
|
||||
"sources": [
|
||||
{
|
||||
"path": "sso-mfa/k8s/lldap/reset-authority-observe.py",
|
||||
"sha256": "9f19c5551e2a93319c04c1b2fd0ddc0f7757fdff96ad18b81d7ee7bb393b75b9"
|
||||
},
|
||||
{
|
||||
"path": "sso-mfa/k8s/lldap/lldap_admin.py",
|
||||
"sha256": "5e39e2eac53846a97cd25151c0a4af1ffc0230db881a6325efb66de6a51bfc36"
|
||||
},
|
||||
{
|
||||
"path": "identity-provisioner/provisioner.py",
|
||||
"sha256": "a303a25d3b3876485c796a9ba0836ddaf0a0bec155b609790e028882ad983138"
|
||||
},
|
||||
{
|
||||
"path": "identity-provisioner/group_provenance.py",
|
||||
"sha256": "405e08eaaab7c21d618dff4db5970607806f32ab6c461effb81c737e32182b10"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.native-reset-role-refresh.v1",
|
||||
"observed_at": "2026-10-31T13:23:16.597535+00:00",
|
||||
"data": "synthetic",
|
||||
"status": "native_role_refresh_verified",
|
||||
"images": {
|
||||
"lldap": "sha256:9e605a66c02514bfcffd1b67cafb1e98d50992216bb2871d7ae44622047dd09d",
|
||||
"authelia": "sha256:bd97cff4fcbf715b5ff1f9ae286afbe6033afce385302520b0368122d43a6f54",
|
||||
"client": "sha256:512819463a1902b43a615beee14be7bf97e6a05e016385082b9380692ad1a8cd"
|
||||
},
|
||||
"production_access": false,
|
||||
"provider_smtp_contacted": false,
|
||||
"owner_runtime_or_permission_change_performed": false,
|
||||
"no_ports_host_mounts_or_external_routes": true,
|
||||
"backend_container_flags_verified_before_fixture_import": true,
|
||||
"source_manifest_sha256": "f3c6d7b5a286d15d3049bba7e4c543052388f6a95a5e3254414f3b51da1285d0",
|
||||
"findings": {
|
||||
"scenarios": [
|
||||
{
|
||||
"bind_role": "lldap_strict_readonly",
|
||||
"same_authelia_process": true,
|
||||
"status": "reset_refused",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": "KO",
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": true,
|
||||
"new_password_accepted_after": false
|
||||
},
|
||||
{
|
||||
"bind_role": "lldap_password_manager",
|
||||
"same_authelia_process": true,
|
||||
"status": "reset_completed",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": null,
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": false,
|
||||
"new_password_accepted_after": true
|
||||
},
|
||||
{
|
||||
"bind_role": "lldap_strict_readonly",
|
||||
"same_authelia_process": true,
|
||||
"status": "reset_refused",
|
||||
"only_loopback_interface": true,
|
||||
"external_routes_absent": true,
|
||||
"old_password_initially_accepted": true,
|
||||
"new_password_initially_refused": true,
|
||||
"native_first_factor": true,
|
||||
"interactive_service_login_refused": true,
|
||||
"reset_http_status": 200,
|
||||
"reset_response_status": "KO",
|
||||
"native_identity_finish": true,
|
||||
"reset_without_verified_challenge_refused": true,
|
||||
"consumed_identity_token_replay_refused": true,
|
||||
"old_password_accepted_after": true,
|
||||
"new_password_accepted_after": false
|
||||
}
|
||||
],
|
||||
"cleanup_verified": true
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
scripts/rehearse-reset-role-refresh.py: c84751c3ed2893ef25460401ab760f109ac8502b308aae120990d402f85ed42f
|
||||
scripts/rehearse-native-password-reset.py: 133c8230c524fbbaf7f66e4872e14b826ed2c5a4f4de3bc47fa86cfef7631d5d
|
||||
scripts/native_recovery/probe.py: eab3bae55626abd4920eb6aa2e329c83559007c54ac74c3aaa1cf41e84eb6556
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.reset-role-return-verification.v1",
|
||||
"status": "attended_role_receipt_verified",
|
||||
"observed_at": "2026-10-31T12:57:44.913538+00:00",
|
||||
"private_receipt_sha256": "bde2c45eda858ea317febfabefe1bd254b62c218c66fd4fb0cbec41db61fb788",
|
||||
"private_file_owner_mode_single_link_verified": true,
|
||||
"exact_endpoint_and_accepted_subject_verified": true,
|
||||
"all_four_prepared_source_hashes_verified": true,
|
||||
"bind_role": "lldap_strict_readonly",
|
||||
"bind_other_groups": 0,
|
||||
"accepted_subject_is_lldap_admin": false,
|
||||
"accepted_subject_has_other_groups": 1,
|
||||
"grant_approved": false,
|
||||
"password_reset_attempted": false,
|
||||
"owner_task": "NK-WP-0054-T13",
|
||||
"owner_task_id": "278d5ba8-1c2a-58d9-a24e-2233af2c1aef",
|
||||
"consumer_task": "CSOC-WP-0015-T06"
|
||||
}
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"schema": "coulomb.reset-transition-consumer-gate.v1",
|
||||
"command": "make check",
|
||||
"passed": 546,
|
||||
"failures": 0,
|
||||
"skipped": 0,
|
||||
"warnings": 69,
|
||||
"elapsed_seconds": 55.15,
|
||||
"junit_sha256": "717412e60cbe12d52c4a14f124fbe60a59789bc52467c0b938645c2b28c24232",
|
||||
"proposal_digest": "sha256:753f50f139a0d090a8b64ba15174f2a7e8b0e639eb0dd01d17783476b5a3759f",
|
||||
"production_grant_performed": false
|
||||
}
|
||||
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