Merge remote-tracking branch 'origin/main' into codex/leo-gcp-data-parity-20260715

# Conflicts:
#	.agents/skills/teleo-gcp-parity-ops/SKILL.md
This commit is contained in:
twentyOne2x 2026-07-15 10:26:26 +02:00
commit 1a3305ac5d
112 changed files with 25803 additions and 1604 deletions

View file

@ -50,7 +50,7 @@ Name the canary before sending:
## Message Discipline ## Message Discipline
Use unique markers such as `WL-LIVE-TG-CORY-YYYYMMDD-Tn`. Use unique markers such as `WL-LIVE-TG-M3TAVERSAL-YYYYMMDD-Tn`.
Ask Leo for machine-checkable reply markers like: Ask Leo for machine-checkable reply markers like:
@ -74,10 +74,14 @@ After each live Telegram canary:
## Current Known Proof ## Current Known Proof
- Live memory and KB audit passed for marker `WL-LIVE-TG-CORY-20260709`. - Live memory and KB audit are retained in
- Live staged write passed for `WL-LIVE-TG-CORY-20260709-T3`. `docs/reports/leo-working-state-20260709/telegram-live-canary-current.json`.
- Readback passed for `WL-LIVE-TG-CORY-20260709-T4`. - Live staged-write proof is retained in
- Open-ended m3taversal-style read-only triage passed for the legacy marker `docs/reports/leo-working-state-20260709/telegram-live-db-write-canary-20260709.json`.
`WL-LIVE-TG-CORY-OPEN-20260709`. - Open-ended m3taversal-standard read-only triage is retained in
`docs/reports/leo-working-state-20260709/telegram-live-open-ended-suite-current.md`.
Historical receipts contain immutable legacy marker IDs. Treat them only as
evidence identifiers; never reuse them as a participant name or future marker.
Use `docs/reports/leo-working-state-20260709/current-truth-index.md` for artifact paths. Use `docs/reports/leo-working-state-20260709/current-truth-index.md` for artifact paths.

View file

@ -25,7 +25,7 @@ Prefer deterministic local surfaces before asking an LLM:
- generated claim indexes from `lib/claim_index.py`; - generated claim indexes from `lib/claim_index.py`;
- search helpers in `lib/search.py`; - search helpers in `lib/search.py`;
- copied SQLite state through `teleo-db-operator`; - copied SQLite state through `teleo-db-operator`;
- retained proof JSON in `.crabbox-results/` or `proof/`. - retained proof JSON at a caller-specified generated-output path.
Read outputs must include file paths, source paths, claim/entity IDs when available, and the exact query used. Read outputs must include file paths, source paths, claim/entity IDs when available, and the exact query used.
@ -80,7 +80,7 @@ If a runtime cannot implement one of these, record the missing tool as a blocker
## Expected Artifact ## Expected Artifact
Write `.crabbox-results/kb-interop-proof.json` or a caller-specified proof path containing: Write `<proof-output>/kb-interop-proof.json` containing:
- runtime name; - runtime name;
- model/provider if known; - model/provider if known;

View file

@ -28,9 +28,10 @@ Create or update:
- `AGENTS.md`: scope, repo boundaries, proof requirements; - `AGENTS.md`: scope, repo boundaries, proof requirements;
- `SOUL.md`: Rio or Theseus identity; - `SOUL.md`: Rio or Theseus identity;
- `TOOLS.md`: bounded tools only; - `TOOLS.md`: bounded tools only;
- `skills/decision-engine-refinement/SKILL.md`; - `<openclaw-workspace>/skills/decision-engine-refinement/SKILL.md`;
- `skills/living-ip-kb-interop/SKILL.md`; - `<openclaw-workspace>/skills/living-ip-kb-interop/SKILL.md`;
- `skills/teleo-db-operator/SKILL.md` only for read-only local copies unless explicitly authorized. - `<openclaw-workspace>/skills/teleo-db-operator/SKILL.md` only for read-only
local copies unless explicitly authorized.
## Tool Policy ## Tool Policy

View file

@ -103,6 +103,24 @@ That historical clone predates the expanded ownership/ACL and independently
authenticated receipt contract. It remains useful historical row/schema proof, authenticated receipt contract. It remains useful historical row/schema proof,
but it is not current T3 proof under this skill. but it is not current T3 proof under this skill.
## Open Least-Privilege Candidates
PR #148, `Scope GCP Leo runtime to least-privilege Cloud SQL access`, is open as
of the 2026-07-15 skill-pack reconciliation. Draft PR #162, `Harden GCP Leo
runtime least-privilege proof`, is its current hardening successor. They propose
scoped runtime roles, secret access, fail-closed Cloud SQL behavior, deployment
rollback, and positive plus negative permission checks. Those branch files and
proposed live outcomes are candidate evidence only. Before using them, run:
```bash
gh pr view 148 --json state,mergedAt,mergeCommit,headRefName,url
gh pr view 162 --json state,mergedAt,mergeCommit,headRefName,url
```
Until a successor is merged and its runtime receipt passes, use only paths present on
canonical `main`, keep persistent GCP classified as staging, do not promote it,
and do not infer least-privilege cutover from a branch or dry run.
Primary retained proof: Primary retained proof:
- `docs/reports/leo-working-state-20260709/gcp-db-first-working-leo-20260714.md` - `docs/reports/leo-working-state-20260709/gcp-db-first-working-leo-20260714.md`

View file

@ -26,11 +26,13 @@ Prevent incorrect assumptions about where Leo/Teleo code, runtime state, DB stat
- Hermes/leoclean runtime profile. - Hermes/leoclean runtime profile.
- Postgres canonical DB. - Postgres canonical DB.
- `kb_stage` proposal ledger. - `kb_stage` proposal ledger.
- Retained proof artifacts under local `outputs/`. - Caller-specific external output directories, which are retained evidence but
are not repository routes unless copied into the repo evidence pack.
- Synced report artifacts under the VPS profile report directory. - Synced report artifacts under the VPS profile report directory.
## Current Known Path Map ## Current Known Path Map
- Canonical code/deployment repository: GitHub `living-ip/teleo-infrastructure`.
- Repo-local evidence pack: `docs/reports/leo-working-state-20260709/` - Repo-local evidence pack: `docs/reports/leo-working-state-20260709/`
- VPS deploy/source area: `/opt/teleo-eval/workspaces/deploy-infra` - VPS deploy/source area: `/opt/teleo-eval/workspaces/deploy-infra`
- VPS deploy stamp: `/opt/teleo-eval/.last-deploy-sha` - VPS deploy stamp: `/opt/teleo-eval/.last-deploy-sha`

View file

@ -44,7 +44,7 @@ Run the deterministic source-to-proposal canary:
```bash ```bash
.venv/bin/python scripts/run_leo_local_ingestion_proposal_canary.py \ .venv/bin/python scripts/run_leo_local_ingestion_proposal_canary.py \
--fixture fixtures/working-leo/document-ingestion-v1.json \ --fixture fixtures/working-leo/document-ingestion-v1.json \
--output outputs/leo-local-ingestion-proposal-canary-current.json --output /tmp/leo-local-ingestion-proposal-canary-current.json
``` ```
Require the source, claim, evidence, and proposal UUIDs to link exactly; claim Require the source, claim, evidence, and proposal UUIDs to link exactly; claim
@ -131,7 +131,8 @@ Read:
- `docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.json` - `docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.json`
- `docs/reports/leo-working-state-20260709/leo-source-composition-clone-checkpoint-current.json` - `docs/reports/leo-working-state-20260709/leo-source-composition-clone-checkpoint-current.json`
- `outputs/leo-local-ingestion-proposal-canary-current.json` - `docs/reports/leo-working-state-20260709/leo-v3-document-source-lifecycle-current.md`
- `docs/reports/leo-working-state-20260709/source-document-compiler-canary-20260713.md`
## Claim Ceiling ## Claim Ceiling

View file

@ -1,13 +1,15 @@
--- ---
name: teleo-leo-onboarding name: teleo-leo-onboarding
description: Use when a worker needs fast context on Teleo/Living IP, Leo, the product architecture, current VPS/GCP split, and the July 9 working-state evidence before doing Leo, Teleo, KB, Telegram, VPS, or GCP work. description: Use when a worker needs fast context on Teleo/Living IP, Leo architecture, VPS/GCP and Hermes runtime boundaries, database provenance, ingestion/apply/reconstruction, identity, testing, security, secrets, or incident recovery before doing Leo or Teleo work.
--- ---
# Teleo / Leo Onboarding # Teleo / Leo Onboarding
## Job ## Job
Orient the worker before action. Build a current, proof-linked understanding of the company/product, Leo's role, the infrastructure surfaces, and the exact claim ceiling. Orient the worker before action. Build a current, proof-linked understanding of
the company/product, Leo's role, the infrastructure surfaces, and the exact
claim ceiling without rediscovering the system from historical chat.
## Trigger Phrases ## Trigger Phrases
@ -17,6 +19,8 @@ Orient the worker before action. Build a current, proof-linked understanding of
- "Fable handoff for Leo" - "Fable handoff for Leo"
- "before working on Teleo infra" - "before working on Teleo infra"
- "explain the architecture" - "explain the architecture"
- "recover or reconstruct Leo"
- "which skill should I use"
## Core Model ## Core Model
@ -46,6 +50,52 @@ Orient the worker before action. Build a current, proof-linked understanding of
- `SOUL.md` is a rendered/runtime artifact. Direct file edits are not canonical - `SOUL.md` is a rendered/runtime artifact. Direct file edits are not canonical
identity changes without DB row and render/sync proof. identity changes without DB row and render/sync proof.
## Clean-Context First Commands
From the repository root, validate the pack without a virtual environment or
network access:
```bash
.agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py --root .
```
Install exactly the manifest-indexed skills into an empty temporary agent skill
root with:
```bash
.agents/skills/teleo-leo-onboarding/scripts/install_skill_pack.py \
--root . \
--target /private/tmp/teleo-clean-agent/skills
```
Installed skills still resolve repository-relative routes against the current
`teleo-infrastructure` checkout. Keep the agent working directory at the repo
root. For pytest, use `.venv/bin/python`; if `.venv` is absent, create it from
`README.md` before running tests. Do not guess a bare `python` command.
Run the deterministic isolated acceptance canary with:
```bash
.agents/skills/teleo-leo-onboarding/scripts/run_clean_context_canary.py \
--root . \
--output docs/reports/leo-working-state-20260709/skill-pack-clean-context-canary-current.json
```
## Task Router
| Area | Skill | Canonical first route |
|---|---|---|
| Company, product, architecture | `teleo-leo-onboarding` | `docs/reports/leo-working-state-20260709/current-truth-index.md` |
| VPS runtime and incidents | `teleo-vps-runtime-ops` | Fresh service, deploy, DB, and cleanup readbacks |
| GCP and Cloud SQL | `teleo-gcp-parity-ops` | Current main evidence; keep open PR #148 candidate-only |
| Hermes packaging/runtime | `nousresearch-hermes-agent` | `hermes-agent/` plus the live service-specific ops skill |
| Database provenance | `teleo-infra-provenance` and `teleo-db-operator` | Separate Git, runtime, SQLite, Postgres, and retained proof |
| Source ingestion and proposal/apply | `teleo-kb-db-change-workflow` | Hash-bound source, review, guarded apply, receipt |
| Reconstruction and recovery | `teleo-reconstruction-recovery` | `docs/kb-rebuild-and-recompile.md` |
| Identity and rendered soul | `working-leo-m3taversal-outcomes` | Canonical identity rows before `SOUL.md` |
| Testing and proof tiers | `teleo-proof-handoff` | Exact tier, command, receipt, cleanup, claim ceiling |
| Secrets | `private-password-storage` | Provider login first; never paste or retrieve a secret |
## Read First ## Read First
From the repo root, read: From the repo root, read:
@ -61,6 +111,7 @@ From the repo root, read:
9. `.agents/skills/working-leo-m3taversal-outcomes/SKILL.md` 9. `.agents/skills/working-leo-m3taversal-outcomes/SKILL.md`
10. `docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.md` 10. `docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.md`
11. `docs/reports/leo-working-state-20260709/gcp-cloud-sql-t3-live-readonly-current.md` 11. `docs/reports/leo-working-state-20260709/gcp-cloud-sql-t3-live-readonly-current.md`
12. `docs/kb-rebuild-and-recompile.md`
## Required Status Split ## Required Status Split
@ -82,6 +133,9 @@ Do not collapse GCP demo readiness into Telegram completion. Do not collapse pro
- Do not production-apply DB packets unless explicitly authorized. - Do not production-apply DB packets unless explicitly authorized.
- Do not expose secret contents. - Do not expose secret contents.
- Do not treat an old summary as current if a fresh readback is cheap. - Do not treat an old summary as current if a fresh readback is cheap.
- PRs #146 and #147 are merged repository truth. PR #148 remains an open GCP
least-privilege candidate until live `gh pr view 148` readback says otherwise;
never route a deployment from its branch as though it were `main`.
- Use `ssh -o BatchMode=yes teleo-gcp-staging true` to preflight passwordless - Use `ssh -o BatchMode=yes teleo-gcp-staging true` to preflight passwordless
GCP VM access. If the firewall route drifts, rediscover the authenticated GCP VM access. If the firewall route drifts, rediscover the authenticated
non-secret route before declaring a blocker. The OIDC/IAP workflow is still non-secret route before declaring a blocker. The OIDC/IAP workflow is still

View file

@ -0,0 +1,106 @@
#!/usr/bin/env python3
"""Install the manifest-indexed Leo/Teleo skills into an empty skill root."""
from __future__ import annotations
import argparse
import json
import re
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path
DEFAULT_MANIFEST = Path("docs/reports/leo-working-state-20260709/skill-pack-manifest.json")
SKILL_NAME = re.compile(r"[a-z0-9-]{1,64}")
def _tracked_skill_files(root: Path, skill_dir: Path) -> list[Path]:
relative_dir = skill_dir.relative_to(root)
result = subprocess.run(
["git", "-C", str(root), "ls-files", "-z", "--", str(relative_dir)],
check=False,
capture_output=True,
)
if result.returncode != 0:
raise RuntimeError(result.stderr.decode("utf-8", errors="replace"))
files = [root / Path(item.decode("utf-8")) for item in result.stdout.split(b"\0") if item]
if not files:
raise ValueError(f"skill has no tracked files: {relative_dir}")
for source in files:
if source.is_symlink():
raise ValueError(f"skill contains a symlink: {source.relative_to(root)}")
if not source.is_file():
raise ValueError(f"skill route is not a regular file: {source.relative_to(root)}")
source.resolve().relative_to(skill_dir.resolve())
return files
def install(root: Path, manifest_path: Path, target: Path) -> dict[str, object]:
manifest_file = root / manifest_path
manifest = json.loads(manifest_file.read_text(encoding="utf-8"))
skills = manifest["skills"]
if target.exists():
raise ValueError(f"target already exists: {target}")
target.parent.mkdir(parents=True, exist_ok=True)
stage = Path(tempfile.mkdtemp(prefix=".teleo-skill-pack-", dir=target.parent))
installed: list[str] = []
try:
for entry in skills:
name = entry["name"]
if not isinstance(name, str) or SKILL_NAME.fullmatch(name) is None:
raise ValueError(f"invalid skill name: {name!r}")
expected_path = Path(".agents") / "skills" / name / "SKILL.md"
if Path(entry["path"]) != expected_path:
raise ValueError(f"skill path must be {expected_path}: {entry['path']!r}")
if name in installed:
raise ValueError(f"duplicate skill name: {name}")
source = root / expected_path.parent
source.resolve().relative_to((root / ".agents" / "skills").resolve())
if not source.is_dir():
raise FileNotFoundError(source)
destination = stage / name
destination.resolve().relative_to(stage.resolve())
for tracked_source in _tracked_skill_files(root, source):
relative = tracked_source.relative_to(source)
tracked_destination = destination / relative
tracked_destination.resolve().relative_to(destination.resolve())
tracked_destination.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(tracked_source, tracked_destination)
installed.append(name)
stage.rename(target)
except Exception:
shutil.rmtree(stage, ignore_errors=True)
raise
return {
"artifact": "leo_teleo_skill_pack_install",
"status": "pass",
"installed_skill_count": len(installed),
"installed_skills": installed,
"contains_secrets": False,
"production_mutation_authorized": False,
}
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--root", type=Path, default=Path.cwd())
parser.add_argument("--manifest", type=Path, default=DEFAULT_MANIFEST)
parser.add_argument("--target", type=Path, required=True)
args = parser.parse_args()
try:
result = install(args.root.resolve(), args.manifest, args.target.resolve())
except Exception as exc:
result = {"artifact": "leo_teleo_skill_pack_install", "status": "fail", "error": str(exc)}
sys.stdout.write(json.dumps(result, indent=2, sort_keys=True) + "\n")
return 1
sys.stdout.write(json.dumps(result, indent=2, sort_keys=True) + "\n")
return 0
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,172 @@
#!/usr/bin/env python3
"""Run the deterministic T2 isolated-install acceptance canary for the skill pack."""
from __future__ import annotations
import argparse
import json
import subprocess
import sys
import tempfile
from pathlib import Path
DEFAULT_MANIFEST = Path("docs/reports/leo-working-state-20260709/skill-pack-manifest.json")
SEMANTIC_CONTRACT = {
"authority": (
"teleo-infra-provenance",
"Canonical code/deployment repository: GitHub `living-ip/teleo-infrastructure`.",
"GitHub living-ip/teleo-infrastructure",
),
"vps_database": (
"teleo-leo-onboarding",
"VPS canonical KB: Docker Postgres `teleo-pg`, database `teleo`.",
"teleo-pg / teleo",
),
"gcp_database": (
"teleo-leo-onboarding",
"GCP canonical KB: private Cloud SQL database `teleo_canonical`.",
"private Cloud SQL teleo_canonical; persistent copy remains staging",
),
"live_service": (
"teleo-infra-provenance",
"Live service: `leoclean-gateway.service`",
"leoclean-gateway.service",
),
"merged_reconstruction": (
"teleo-reconstruction-recovery",
"PR #146 is merged",
"PR #146 merged deterministic genesis-plus-ledger reconstruction",
),
"merged_reasoning_verifier": (
"teleo-reconstruction-recovery",
"PR #147 is merged",
"PR #147 merged unseen-reasoning verifier hardening",
),
"candidate_only_gcp": (
"teleo-reconstruction-recovery",
"PR #148 is a separate, open GCP least-privilege candidate",
"PR #148 open candidate only; not canonical main",
),
"next_safe_action": (
"teleo-leo-onboarding",
".agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py --root .",
"run the repo-local path validator before any operational action",
),
}
def _run(command: list[str]) -> subprocess.CompletedProcess[str]:
return subprocess.run(command, check=False, capture_output=True, text=True)
def _contains_contract(text: str, required_text: str) -> bool:
"""Compare prose semantically across ordinary Markdown line wrapping."""
return " ".join(required_text.split()) in " ".join(text.split())
def run_canary(root: Path, manifest_path: Path) -> dict[str, object]:
manifest = json.loads((root / manifest_path).read_text(encoding="utf-8"))
installer = root / manifest["installer"]
selected_skills = sorted({contract[0] for contract in SEMANTIC_CONTRACT.values()})
result: dict[str, object]
with tempfile.TemporaryDirectory(prefix="teleo-clean-context-") as temporary_text:
temporary = Path(temporary_text)
installed_root = temporary / "skills"
install_process = _run(
[str(installer), "--root", str(root), "--manifest", str(manifest_path), "--target", str(installed_root)]
)
try:
install_receipt = json.loads(install_process.stdout)
except json.JSONDecodeError:
install_receipt = {"status": "fail", "error": install_process.stdout or install_process.stderr}
semantic_checks: dict[str, bool] = {}
answers: dict[str, str] = {}
evidence_paths: dict[str, str] = {}
for key, (skill_name, required_text, answer) in SEMANTIC_CONTRACT.items():
installed_skill = installed_root / skill_name / "SKILL.md"
text = installed_skill.read_text(encoding="utf-8") if installed_skill.is_file() else ""
semantic_checks[key] = _contains_contract(text, required_text)
answers[key] = answer
evidence_paths[key] = f".agents/skills/{skill_name}/SKILL.md"
installed_validator = installed_root / "teleo-leo-onboarding" / "scripts" / "validate_skill_pack.py"
validator_process = _run([str(installed_validator), "--root", str(root), "--manifest", str(manifest_path)])
try:
validator_receipt = json.loads(validator_process.stdout)
except json.JSONDecodeError:
validator_receipt = {"status": "fail", "error": validator_process.stdout or validator_process.stderr}
problems: list[dict[str, str]] = []
if install_process.returncode != 0 or install_receipt.get("status") != "pass":
problems.append({"kind": "install_failed", "detail": str(install_receipt.get("error", "unknown"))})
if validator_process.returncode != 0 or validator_receipt.get("status") != "pass":
problems.append({"kind": "path_validation_failed", "detail": str(validator_receipt.get("problems", []))})
for key, passed in semantic_checks.items():
if not passed:
problems.append({"kind": "semantic_route_missing", "detail": key})
passed = not problems
result = {
"artifact": "leo_teleo_skill_pack_isolated_install_canary",
"status": "pass" if passed else "fail",
"required_tier": "T2_runtime",
"current_tier": "T2_runtime" if passed else "T1_model",
"proof_scope": "deterministic_isolated_install_and_route_validation",
"fresh_temporary_skill_root": True,
"ambient_skill_root_used": False,
"agent_reasoning_exercised": False,
"installed_skill_count": install_receipt.get("installed_skill_count", 0),
"selected_installed_skills": selected_skills,
"semantic_checks": semantic_checks,
"expected_answers": answers,
"evidence_paths": evidence_paths,
"canary_command": ".agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py --root .",
"canary_exit_status": validator_process.returncode,
"canary_receipt": validator_receipt,
"missing_to_reach_required_tier": [] if passed else problems,
"strongest_claim_allowed": (
"T2 deterministic isolated local skill install, route-contract, and path validation only; this artifact "
"does not claim an agent reasoning run, and retained product proofs keep their own VPS, GCP-staging, "
"isolated-clone, Telegram, and production claim ceilings"
),
"contains_secrets": False,
"production_mutation_authorized": False,
"external_runtime_contacted": False,
"problems": problems,
}
result["cleanup_readback"] = {
"temporary_skill_root_removed": not Path(temporary_text).exists(),
"orphan_processes_started": False,
}
if not result["cleanup_readback"]["temporary_skill_root_removed"]:
result["status"] = "fail"
result["current_tier"] = "T1_model"
result["problems"].append({"kind": "cleanup_failed", "detail": "temporary skill root remains"})
return result
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--root", type=Path, default=Path.cwd())
parser.add_argument("--manifest", type=Path, default=DEFAULT_MANIFEST)
parser.add_argument("--output", type=Path)
args = parser.parse_args()
root = args.root.resolve()
result = run_canary(root, args.manifest)
payload = json.dumps(result, indent=2, sort_keys=True) + "\n"
if args.output:
output = args.output if args.output.is_absolute() else root / args.output
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(payload, encoding="utf-8")
sys.stdout.write(payload)
return 0 if result["status"] == "pass" else 1
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,248 @@
#!/usr/bin/env python3
"""Validate the repo-native Leo/Teleo skill pack and its local routes."""
from __future__ import annotations
import argparse
import hashlib
import json
import os
import re
import shlex
import subprocess
import sys
from pathlib import Path
DEFAULT_MANIFEST = Path("docs/reports/leo-working-state-20260709/skill-pack-manifest.json")
REPO_PREFIXES = (
".agents/",
".github/",
"deploy/",
"docs/",
"fixtures/",
"hermes-agent/",
"lib/",
"ops/",
"outputs/",
"schemas/",
"scripts/",
"systemd/",
"tests/",
)
PATH_SUFFIXES = (".json", ".jsonl", ".md", ".py", ".sh", ".sql", ".yaml", ".yml")
CODE_SPAN = re.compile(r"`([^`\n]+)`")
MARKDOWN_LINK = re.compile(r"\[[^\]]+\]\(([^)]+)\)")
FENCED_SHELL = re.compile(r"```(?:bash|sh|shell)\n(.*?)```", re.DOTALL)
def _frontmatter(text: str) -> dict[str, str]:
if not text.startswith("---\n"):
return {}
try:
block = text.split("---\n", 2)[1]
except IndexError:
return {}
values: dict[str, str] = {}
for line in block.splitlines():
if ":" not in line:
continue
key, value = line.split(":", 1)
values[key.strip()] = value.strip().strip('"')
return values
def _tracked_paths(root: Path) -> set[Path]:
result = subprocess.run(
["git", "-C", str(root), "ls-files", "-z"],
check=False,
capture_output=True,
)
if result.returncode != 0:
raise RuntimeError(result.stderr.decode("utf-8", errors="replace"))
return {Path(item.decode("utf-8")) for item in result.stdout.split(b"\0") if item}
def _is_tracked(root: Path, path: Path, tracked: set[Path]) -> bool:
relative = path.resolve().relative_to(root.resolve())
if path.is_file():
return relative in tracked
prefix = f"{relative.as_posix().rstrip('/')}/"
return any(item.as_posix().startswith(prefix) for item in tracked)
def _clean_token(token: str) -> str:
token = token.strip().strip("'\"")
token = token.rstrip(",;.)]")
token = re.sub(r":\d+$", "", token)
return token
def _candidate_tokens(span: str) -> list[str]:
try:
tokens = shlex.split(span)
except ValueError:
tokens = span.split()
return [_clean_token(token) for token in tokens]
def _resolve_candidate(root: Path, source: Path, token: str) -> Path | None:
if not token or token in {".md", ".json", ".py", ".sh", ".sql"}:
return None
if any(marker in token for marker in ("*", "<", ">", "...", "${", "$LEDGER")):
return None
if token.startswith(("http://", "https://", "/", "~/")):
return None
if token.startswith(REPO_PREFIXES) or token in {"README.md", "CODEOWNERS"}:
candidate = root / token
elif token.endswith(PATH_SUFFIXES) and "/" in token:
candidate = source.parent / token
else:
return None
try:
candidate.resolve().relative_to(root.resolve())
except ValueError:
return None
return candidate
def _inline_paths(root: Path, source: Path) -> set[Path]:
text = source.read_text(encoding="utf-8")
candidates: set[Path] = set()
spans = CODE_SPAN.findall(text) + MARKDOWN_LINK.findall(text)
for block in FENCED_SHELL.findall(text):
spans.extend(line for line in block.splitlines() if line.strip())
for span in spans:
for token in _candidate_tokens(span):
candidate = _resolve_candidate(root, source, token)
if candidate is not None:
candidates.add(candidate)
return candidates
def validate(root: Path, manifest_path: Path) -> dict[str, object]:
problems: list[dict[str, str]] = []
checked: set[Path] = set()
manifest_file = root / manifest_path
if not manifest_file.is_file():
return {
"artifact": "leo_teleo_skill_pack_path_validation",
"status": "fail",
"problems": [{"kind": "missing_manifest", "path": str(manifest_path)}],
}
manifest = json.loads(manifest_file.read_text(encoding="utf-8"))
tracked = _tracked_paths(root)
if not _is_tracked(root, manifest_file, tracked):
problems.append({"kind": "untracked_manifest", "path": str(manifest_path)})
skills = manifest.get("skills", [])
skill_names = {entry.get("name") for entry in skills}
for entry in skills:
relative = Path(entry["path"])
path = root / relative
checked.add(path)
if not path.is_file():
problems.append({"kind": "missing_skill", "path": str(relative)})
continue
if not _is_tracked(root, path, tracked):
problems.append({"kind": "untracked_skill", "path": str(relative)})
metadata = _frontmatter(path.read_text(encoding="utf-8"))
if metadata.get("name") != entry.get("name"):
problems.append({"kind": "skill_name_mismatch", "path": str(relative)})
if not metadata.get("description"):
problems.append({"kind": "missing_skill_description", "path": str(relative)})
if set(metadata) != {"name", "description"}:
problems.append({"kind": "invalid_skill_frontmatter_keys", "path": str(relative)})
if not re.fullmatch(r"[a-z0-9-]{1,64}", metadata.get("name", "")):
problems.append({"kind": "invalid_skill_name", "path": str(relative)})
if relative.parent.name != metadata.get("name"):
problems.append({"kind": "skill_folder_name_mismatch", "path": str(relative)})
required_coverage = manifest.get("required_coverage", {})
for area, owners in required_coverage.items():
for owner in owners:
if owner not in skill_names:
problems.append({"kind": "unknown_coverage_owner", "path": f"{area}:{owner}"})
reference_paths = list(manifest.get("reference_files", []))
command_paths = list(manifest.get("command_files", []))
scan_paths = list(manifest.get("scan_files", []))
for relative_text in reference_paths + command_paths + scan_paths:
relative = Path(relative_text)
path = root / relative
checked.add(path)
if not path.is_file():
problems.append({"kind": "missing_manifest_path", "path": str(relative)})
elif not _is_tracked(root, path, tracked):
problems.append({"kind": "untracked_manifest_path", "path": str(relative)})
for relative_text in manifest.get("executable_files", []):
relative = Path(relative_text)
path = root / relative
checked.add(path)
if not path.is_file():
problems.append({"kind": "missing_executable", "path": str(relative)})
elif not os.access(path, os.X_OK):
problems.append({"kind": "not_executable", "path": str(relative)})
scan_sources = [root / entry["path"] for entry in skills]
scan_sources += [root / relative for relative in manifest.get("scan_files", [])]
for source in scan_sources:
if not source.is_file():
continue
for candidate in _inline_paths(root, source):
checked.add(candidate)
if not candidate.exists():
problems.append(
{
"kind": "missing_inline_path",
"path": str(candidate.resolve().relative_to(root.resolve())),
"source": str(source.relative_to(root)),
}
)
elif not _is_tracked(root, candidate, tracked):
problems.append(
{
"kind": "untracked_inline_path",
"path": str(candidate.resolve().relative_to(root.resolve())),
"source": str(source.relative_to(root)),
}
)
relative_paths = sorted(str(path.resolve().relative_to(root.resolve())) for path in checked)
digest = hashlib.sha256("\n".join(relative_paths).encode("utf-8")).hexdigest()
return {
"artifact": "leo_teleo_skill_pack_path_validation",
"required_tier": "T2_runtime",
"status": "pass" if not problems else "fail",
"manifest": str(manifest_path),
"skill_count": len(skills),
"coverage_area_count": len(required_coverage),
"checked_path_count": len(relative_paths),
"checked_paths_sha256": digest,
"contains_secrets": False,
"production_mutation_authorized": False,
"problems": problems,
}
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--root", type=Path, default=Path.cwd())
parser.add_argument("--manifest", type=Path, default=DEFAULT_MANIFEST)
parser.add_argument("--output", type=Path)
args = parser.parse_args()
root = args.root.resolve()
result = validate(root, args.manifest)
payload = json.dumps(result, indent=2, sort_keys=True) + "\n"
if args.output:
output = args.output if args.output.is_absolute() else root / args.output
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(payload, encoding="utf-8")
sys.stdout.write(payload)
return 0 if result["status"] == "pass" else 1
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,83 @@
---
name: teleo-reconstruction-recovery
description: Use when restoring, rebuilding, recompiling, or incident-recovering Leo's Teleo knowledge database, including snapshot recovery, genesis-plus-ledger replay, source recompilation, parity verification, and honest recovery claim ceilings.
---
# Teleo Reconstruction Recovery
## Job
Choose the smallest recovery path that restores a usable Leo knowledge system
without confusing snapshot restoration, strict ledger replay, and semantic
source recompilation.
## Authority
Read `docs/kb-rebuild-and-recompile.md` first. It is the canonical recovery
contract. Use `docs/reports/leo-working-state-20260709/current-truth-index.md`
only for the newest retained proof point, and refresh live state before making a
current VPS or GCP claim.
PR #146 is merged and owns the deterministic genesis-plus-ledger reconstruction
slice in `ops/run_local_genesis_ledger_rebuild.py`. PR #147 is merged and owns
the current unseen-reasoning verifier in
`scripts/verify_leo_unseen_reasoning_chain.py`. PR #148 is a separate, open GCP
least-privilege candidate; do not treat its branch files or proposed live state
as canonical `main` recovery instructions until it merges.
## Select The Recovery Mode
| Need | Path | Honest result |
|---|---|---|
| Restore the latest verified state quickly | `ops/run_local_canonical_postgres_rebuild.py` | Exact snapshot recovery |
| Prove strict post-genesis applies replay exactly | `ops/run_local_genesis_ledger_rebuild.py` | Isolated insert-only ledger replay |
| Turn one retained source into a reviewed packet | `scripts/compile_kb_source_packet.py` | Deterministic proposal packet, not canonical knowledge |
| Rebuild every row from original sources | Follow the semantic recompilation contract in `docs/kb-rebuild-and-recompile.md` | Partial until every row and receipt is accounted for |
| Diagnose a live incident before recovery | Use `.agents/skills/teleo-vps-runtime-ops/SKILL.md` and `.agents/skills/teleo-infra-provenance/SKILL.md` | Fresh read-only incident map |
## Safe Order
1. Identify the intended source database, snapshot, manifest, commit, and hashes.
2. Keep private dumps, row payloads, source excerpts, and replay material outside
the repository and mode `0600`.
3. Run the selected path in an isolated, network-disabled local container.
4. Verify schema, constraints, roles, counts, row hashes, key queries, and exact
cleanup.
5. Run the relevant focused tests, then the unseen-reasoning verifier when the
restored state is meant to support Leo answers.
6. Separate local reconstruction from VPS restore, GCP restore, service restart,
Telegram delivery, promotion, and production apply. Each is its own proof row.
## Commands
Use the repository virtual environment documented in `README.md`:
```bash
.venv/bin/python ops/run_local_canonical_postgres_rebuild.py --help
.venv/bin/python ops/run_local_genesis_ledger_rebuild.py --help
.venv/bin/python scripts/compile_kb_source_packet.py --help
.venv/bin/python -m pytest -q \
tests/test_run_local_canonical_postgres_rebuild.py \
tests/test_run_local_genesis_ledger_rebuild.py \
tests/test_verify_leo_unseen_reasoning_chain.py
```
The help and focused-test commands are safe local canaries. A real recovery
requires caller-supplied private material and must retain a sanitized receipt
without the material itself.
## Stop Conditions
Stop before any live restore or restart when the source snapshot is not
hash-bound, the source authority is ambiguous, parity fails, private material
would enter Git or logs, cleanup cannot be proved, or the requested operation
would promote GCP or mutate production without exact authorization.
## Claim Ceiling
- Exact snapshot recovery is working when its parity receipt passes.
- The merged genesis-plus-ledger path proves an isolated insert-only slice.
- Semantic source-to-blank-database recompilation remains incomplete until every
canonical row traces to a genesis record or reviewed replay receipt.
- No local receipt proves a live VPS/GCP restore, service restart, Telegram
delivery, production apply, or GCP promotion.

View file

@ -0,0 +1,4 @@
interface:
display_name: "Teleo Reconstruction Recovery"
short_description: "Recover and reconstruct Leo knowledge safely"
default_prompt: "Use $teleo-reconstruction-recovery to choose and verify the safest Leo database recovery path."

View file

@ -62,11 +62,16 @@ A working Leo is a Telegram-facing agent that:
## Current Benchmark Cases ## Current Benchmark Cases
- Marker memory: `WL-LIVE-TG-CORY-20260709`. - Historical marker-memory receipt:
`docs/reports/leo-working-state-20260709/telegram-live-canary-current.json`.
- Truth correction: `approved != applied`. - Truth correction: `approved != applied`.
- Applied canary: proposal `00957f6c-9883-4015-95a4-6b09367efb0e` and edge `c167933e-d513-4f43-9335-d5d8aeb259f2`. - Applied canary: proposal `00957f6c-9883-4015-95a4-6b09367efb0e` and edge `c167933e-d513-4f43-9335-d5d8aeb259f2`.
- Staged write canary: proposal `8dfedb3f-3aa4-4200-970f-4c0016f6869f`, status `pending_review`, with no new public canonical rows after the test timestamp. - Staged write canary: proposal `8dfedb3f-3aa4-4200-970f-4c0016f6869f`, status `pending_review`, with no new public canonical rows after the test timestamp.
- Open-ended triage canary: `WL-LIVE-TG-CORY-OPEN-20260709`, where Leo inferred the likely failure mode from "agents not working / same state as last night" and explained the proposed, approved, and applied split without exact IDs. - Open-ended triage receipt:
`docs/reports/leo-working-state-20260709/telegram-live-open-ended-suite-current.md`,
where Leo inferred the likely failure mode from "agents not working / same
state as last night" and explained the proposed, approved, and applied split
without exact IDs.
- Old rich proposal packets: `14fa5ecc...`, `ac036c9d...`, and `a64df080...` are not to be silently production-applied. - Old rich proposal packets: `14fa5ecc...`, `ac036c9d...`, and `a64df080...` are not to be silently production-applied.
- Guarded apply proof: both generic and real Helmer v3 receipts pass `37/37` in - Guarded apply proof: both generic and real Helmer v3 receipts pass `37/37` in
disposable PostgreSQL; production Helmer remains unapplied. disposable PostgreSQL; production Helmer remains unapplied.

View file

@ -0,0 +1,316 @@
name: gcp-observatory-read-adapter
on:
workflow_dispatch:
inputs:
action:
description: Build, preflight, or deploy the protected staging service and run live receipts
required: true
default: build_only
type: choice
options:
- build_only
- preflight_staging
- deploy_staging
permissions:
contents: read
id-token: write
concurrency:
group: gcp-observatory-read-adapter-${{ github.ref }}
cancel-in-progress: false
env:
PROJECT_ID: teleo-501523
REGION: europe-west6
ZONE: europe-west6-a
REPOSITORY: teleo
IMAGE_NAME: observatory-read-adapter
SERVICE_NAME: observatory-read-adapter-staging
RUNTIME_SERVICE_ACCOUNT: sa-observatory-read-adapter@teleo-501523.iam.gserviceaccount.com
BUILD_SERVICE_ACCOUNT: sa-artifact-builder@teleo-501523.iam.gserviceaccount.com
DEPLOY_SERVICE_ACCOUNT: sa-observatory-deployer@teleo-501523.iam.gserviceaccount.com
DB_IAM_USER: sa-observatory-read-adapter@teleo-501523.iam
API_KEY_SECRET: observatory-read-api-key-staging
BUILD_WORKLOAD_IDENTITY_PROVIDER: projects/785938879453/locations/global/workloadIdentityPools/github-actions/providers/living-ip-github
DEPLOY_WORKLOAD_IDENTITY_PROVIDER: projects/785938879453/locations/global/workloadIdentityPools/github-actions/providers/observatory-read-adapter-main
EXPECTED_WORKFLOW_REF: living-ip/teleo-infrastructure/.github/workflows/gcp-observatory-read-adapter.yml@refs/heads/main
jobs:
build:
name: Test, build, and push adapter image
runs-on: ubuntu-latest
timeout-minutes: 20
outputs:
image_ref: ${{ steps.image.outputs.image_ref }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11"
cache: pip
- name: Run focused adapter tests
run: |
python -m pip install -e '.[dev]'
python -m pytest tests/test_observatory_read_adapter.py -q
python -m ruff check observatory_read_adapter tests/test_observatory_read_adapter.py
- id: auth
uses: google-github-actions/auth@v3
with:
workload_identity_provider: ${{ env.BUILD_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ env.BUILD_SERVICE_ACCOUNT }}
- uses: google-github-actions/setup-gcloud@v3
with:
project_id: ${{ env.PROJECT_ID }}
- name: Configure Artifact Registry
run: gcloud auth configure-docker "${REGION}-docker.pkg.dev" --quiet
- id: image
name: Build, smoke, and push run-unique immutable image
shell: bash
run: |
set -euo pipefail
tag="${GITHUB_SHA}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
image="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${IMAGE_NAME}:${tag}"
docker build -f Dockerfile.observatory-read-adapter -t "${image}" .
docker run --rm --env PYTHONPYCACHEPREFIX=/tmp/pycache \
"${image}" python -m compileall -q /app/observatory_read_adapter
docker run --rm "${image}" python -c 'import observatory_read_adapter; print("adapter-import-ok")'
docker push "${image}"
digest="$(gcloud artifacts docker images describe "${image}" \
--project="${PROJECT_ID}" \
--format='value(image_summary.digest)')"
[[ "${digest}" =~ ^sha256:[0-9a-f]{64}$ ]]
image_ref="${image}@${digest}"
printf 'image_ref=%s\n' "${image_ref}" >> "${GITHUB_OUTPUT}"
printf 'revision=%s\nimage_ref=%s\n' "${GITHUB_SHA}" "${image_ref}" > observatory-adapter-image.txt
- uses: actions/upload-artifact@v4
with:
name: observatory-adapter-image
path: observatory-adapter-image.txt
if-no-files-found: error
preflight-staging:
name: Verify private staging prerequisites
if: ${{ inputs.action != 'build_only' }}
needs: build
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Enforce reviewed main-only staging path
shell: bash
run: |
set -euo pipefail
[[ "${GITHUB_REF}" == "refs/heads/main" ]]
[[ "${GITHUB_WORKFLOW_REF}" == "${EXPECTED_WORKFLOW_REF}" ]]
[[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]
- id: auth
uses: google-github-actions/auth@v3
with:
workload_identity_provider: ${{ env.DEPLOY_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ env.DEPLOY_SERVICE_ACCOUNT }}
- uses: google-github-actions/setup-gcloud@v3
with:
project_id: ${{ env.PROJECT_ID }}
- name: Run adapter-specific read-only GCP preflight
shell: bash
env:
IMAGE_REF: ${{ needs.build.outputs.image_ref }}
run: |
set -euo pipefail
python3 ops/check_observatory_read_adapter_gcp_preflight.py \
--image-ref "${IMAGE_REF}" \
--output observatory-read-adapter-preflight.json
- uses: actions/upload-artifact@v4
if: always()
with:
name: observatory-read-adapter-preflight
path: observatory-read-adapter-preflight.json
if-no-files-found: error
deploy-staging:
name: Deploy and prove staging read path
if: ${{ inputs.action == 'deploy_staging' }}
needs:
- build
- preflight-staging
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- name: Enforce reviewed main-only staging path
shell: bash
run: |
set -euo pipefail
[[ "${GITHUB_REF}" == "refs/heads/main" ]]
[[ "${GITHUB_WORKFLOW_REF}" == "${EXPECTED_WORKFLOW_REF}" ]]
[[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]
- id: auth
uses: google-github-actions/auth@v3
with:
workload_identity_provider: ${{ env.DEPLOY_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ env.DEPLOY_SERVICE_ACCOUNT }}
- uses: google-github-actions/setup-gcloud@v3
with:
project_id: ${{ env.PROJECT_ID }}
- id: deploy
name: Deploy bounded GCP staging service
shell: bash
env:
IMAGE_REF: ${{ needs.build.outputs.image_ref }}
run: |
set -euo pipefail
api_key_version="$(gcloud secrets versions list "${API_KEY_SECRET}" \
--project="${PROJECT_ID}" \
--filter='state=ENABLED' \
--sort-by='~createTime' \
--limit=1 \
--format='value(name)')"
api_key_version="${api_key_version##*/}"
[[ "${api_key_version}" =~ ^[0-9]+$ ]]
gcloud run deploy "${SERVICE_NAME}" \
--project="${PROJECT_ID}" \
--region="${REGION}" \
--image="${IMAGE_REF}" \
--execution-environment=gen2 \
--service-account="${RUNTIME_SERVICE_ACCOUNT}" \
--network=teleo-staging-net \
--subnet=teleo-staging-europe-west6 \
--vpc-egress=private-ranges-only \
--ingress=all \
--no-invoker-iam-check \
--port=8080 \
--cpu=1 \
--memory=512Mi \
--concurrency=8 \
--max-instances=2 \
--timeout=15 \
--set-secrets="OBSERVATORY_API_KEY=${API_KEY_SECRET}:${api_key_version}" \
--set-env-vars="GCP_PROJECT_ID=${PROJECT_ID},CLOUD_SQL_INSTANCE=${PROJECT_ID}:${REGION}:teleo-pgvector-standby,DB_NAME=teleo_canonical,DB_IAM_USER=${DB_IAM_USER},DB_AUTHORIZATION_ROLE=kb_observatory_read,SERVICE_REVISION=${GITHUB_SHA}" \
--labels="livingip-tier=gcp-staging,livingip-surface=observatory-read-adapter" \
--quiet
printf 'api_key_version=%s\n' "${api_key_version}" >> "${GITHUB_OUTPUT}"
- name: Capture positive and negative live receipts
shell: bash
env:
API_KEY_VERSION: ${{ steps.deploy.outputs.api_key_version }}
EXPECTED_IMAGE_REF: ${{ needs.build.outputs.image_ref }}
run: |
set -euo pipefail
service_json="$(gcloud run services describe "${SERVICE_NAME}" --project="${PROJECT_ID}" --region="${REGION}" --format=json)"
service_url="$(jq -r '.status.url // empty' <<<"${service_json}")"
revision="$(jq -r '.status.latestReadyRevisionName // empty' <<<"${service_json}")"
runtime_service_account="$(jq -r '.spec.template.spec.serviceAccountName // .template.serviceAccount // empty' <<<"${service_json}")"
deployed_image="$(jq -r '.spec.template.spec.containers[0].image // .template.containers[0].image // empty' <<<"${service_json}")"
deployed_secret_version="$(jq -r '
[
.spec.template.spec.containers[]?.env[]?
| select(.name == "OBSERVATORY_API_KEY")
| .valueFrom.secretKeyRef.key
][0] // [
.template.containers[]?.env[]?
| select(.name == "OBSERVATORY_API_KEY")
| .valueSource.secretKeyRef.version
][0] // empty
' <<<"${service_json}")"
expected_digest="${EXPECTED_IMAGE_REF##*@}"
api_key="$(gcloud secrets versions access "${API_KEY_VERSION}" --secret="${API_KEY_SECRET}" --project="${PROJECT_ID}")"
test -n "${service_url}"
test -n "${revision}"
test "${runtime_service_account}" = "${RUNTIME_SERVICE_ACCOUNT}"
test "${deployed_secret_version}" = "${API_KEY_VERSION}"
[[ "${deployed_image}" == "${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${IMAGE_NAME}@${expected_digest}" ]]
test -n "${api_key}"
curl --fail --silent --show-error \
--header "X-Api-Key: ${api_key}" \
"${service_url}/v1/claims/sample" > positive.json
jq -e \
--arg project_id "${PROJECT_ID}" \
--arg cloud_sql_instance "${PROJECT_ID}:${REGION}:teleo-pgvector-standby" \
--arg db_iam_user "${DB_IAM_USER}" \
--arg git_sha "${GITHUB_SHA}" '
.schema == "livingip.observatory-canonical-claim.v1"
and .read_only == true
and .provenance.gcp_project == $project_id
and .provenance.cloud_sql_instance == $cloud_sql_instance
and .provenance.database == "teleo_canonical"
and .provenance.database_principal == $db_iam_user
and .provenance.authorization_role == "kb_observatory_read"
and .provenance.transaction_read_only == true
and .provenance.write_privileges_denied == true
and .provenance.service_revision == $git_sha
and (.canonical.evidence | length) > 0
and .proposal_ledger.distinct_from_canonical == true
' positive.json >/dev/null
anonymous_status="$(curl --silent --output anonymous.json --write-out '%{http_code}' "${service_url}/v1/claims/sample")"
write_status="$(curl --silent --output write.json --write-out '%{http_code}' \
--request POST --header "X-Api-Key: ${api_key}" --header 'Content-Type: application/json' \
--data '{"status":"applied"}' "${service_url}/v1/claims/sample")"
test "${anonymous_status}" = 401
test "${write_status}" = 405
curl --fail --silent --show-error \
--header "X-Api-Key: ${api_key}" \
"${service_url}/v1/claims/sample" > after-write-attempt.json
cmp <(jq -S . positive.json) <(jq -S . after-write-attempt.json)
jq -f ops/redact_observatory_read_adapter_receipt.jq \
positive.json > positive-redacted.json
jq -n \
--arg service_url "${service_url}" \
--arg revision "${revision}" \
--arg git_sha "${GITHUB_SHA}" \
--arg runtime_service_account "${runtime_service_account}" \
--arg database_principal "${DB_IAM_USER}" \
--arg deployed_image "${deployed_image}" \
--arg api_key_secret_version "${API_KEY_VERSION}" \
--argjson positive "$(cat positive-redacted.json)" \
--arg anonymous_status "${anonymous_status}" \
--arg write_status "${write_status}" \
'{
schema: "livingip.observatory-read-adapter-live-receipt.v1",
required_tier: "T3_live_readonly",
service_url: $service_url,
revision: $revision,
git_sha: $git_sha,
runtime_service_account: $runtime_service_account,
database_principal: $database_principal,
deployed_image: $deployed_image,
api_key_secret_version: $api_key_secret_version,
positive: $positive,
negative: {
anonymous_http_status: ($anonymous_status | tonumber),
authenticated_post_http_status: ($write_status | tonumber),
canonical_state_unchanged_after_post: true,
database_write_privileges_denied: $positive.provenance.write_privileges_denied
},
production_repoint_executed: false
}' > observatory-read-adapter-live-receipt.json
unset api_key
rm -f positive.json positive-redacted.json after-write-attempt.json anonymous.json write.json
- uses: actions/upload-artifact@v4
with:
name: observatory-read-adapter-live-receipt
path: observatory-read-adapter-live-receipt.json
if-no-files-found: error

View file

@ -0,0 +1,20 @@
FROM python:3.11-slim
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV PORT=8080
WORKDIR /app
COPY pyproject.toml README.md /app/
COPY observatory_read_adapter /app/observatory_read_adapter
COPY lib /app/lib
RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir ".[observatory]" \
&& addgroup --system --gid 10001 adapter \
&& adduser --system --uid 10001 --ingroup adapter --no-create-home adapter
USER 10001:10001
CMD ["python", "-m", "observatory_read_adapter"]

View file

@ -84,8 +84,8 @@ A mirror sync (every 2 minutes) fast-forwards the PR onto Forgejo, where
the pipeline picks it up. From there it's the same flow as agent-authored the pipeline picks it up. From there it's the same flow as agent-authored
PRs — same tiers, same reviewers, same merge rules. PRs — same tiers, same reviewers, same merge rules.
The contributor-facing guide lives in The contributor-facing guide is the
[`teleo-codex/CONTRIBUTING.md`](https://github.com/living-ip/teleo-codex/blob/main/CONTRIBUTING.md). [Teleo Codex contributing guide](https://github.com/living-ip/teleo-codex/blob/main/CONTRIBUTING.md).
## Repository layout ## Repository layout
@ -119,10 +119,26 @@ status report in their Pentagon profile.
## Development ## Development
```bash ```bash
pip install -e ".[dev]" python3 -m venv .venv
pytest .venv/bin/pip install -e ".[dev]"
.venv/bin/python -m pytest
``` ```
## Leo / Teleo Operator Onboarding
Start with the repo-native skill router, not historical chat or a runtime mirror:
```bash
.agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py --root .
```
Then read `.agents/skills/teleo-leo-onboarding/SKILL.md` and
`docs/reports/leo-working-state-20260709/current-truth-index.md`. Recovery work
starts at `docs/kb-rebuild-and-recompile.md`. GitHub
`living-ip/teleo-infrastructure` is canonical code/deployment truth; VPS/GCP
runtime, canonical Postgres, proposal staging, Hermes memory, and retained
proofs are separate state surfaces.
## Operations ## Operations
Production deployment runs on a single VPS. Runbook, restart procedures, Production deployment runs on a single VPS. Runbook, restart procedures,

View file

@ -25,11 +25,12 @@ Run:
--output /tmp/teleo-canonical-rebuild-receipt.json --output /tmp/teleo-canonical-rebuild-receipt.json
``` ```
The newest retained 2026-07-14 post-V3 canary restored a fresh, network-isolated The retained 2026-07-14 post-V3 canary restored a fresh, network-isolated
Postgres and then removed it. The restored target matched the source across all Postgres and then removed it. The restored target matched the source across all
39 manifest tables and all 52,167 rows, with no schema, data, constraint, role, 39 manifest tables and all 52,167 rows, with no schema, data, constraint, role,
or performance mismatch. Total runtime was 10.56 seconds, including 2.71 or performance mismatch. The same source snapshot was subsequently restored to
seconds for `pg_restore`. Key rows included: a disposable private-TLS GCP Cloud SQL clone with exact parity, a bounded
no-send reasoning turn, and verified cleanup. Key rows included:
- 1,837 claims; - 1,837 claims;
- 4,145 sources; - 4,145 sources;
@ -38,9 +39,10 @@ seconds for `pg_restore`. Key rows included:
- 17 reasoning tools; - 17 reasoning tools;
- 29 proposals. - 29 proposals.
This snapshot includes the completed V3 source canary. It is ready as the This snapshot includes the completed V3 source canary. Disposable GCP restore
current restore input, but it has not yet been restored to GCP; current GCP parity is proven at that retained point. Persistent GCP `teleo_canonical`
parity therefore remains unproven. remains the older staging copy, so ongoing parity, promotion, and production
cutover remain unproven.
This is the fastest disaster-recovery path. It does not require Leo to This is the fastest disaster-recovery path. It does not require Leo to
re-extract or relearn the corpus. re-extract or relearn the corpus.
@ -134,7 +136,7 @@ kept all database counts and the proposal payload hash unchanged, left the Leo
gateway on the same PID with zero restarts, and removed the temporary private gateway on the same PID with zero restarts, and removed the temporary private
receipt. The full receipt is deliberately not committed because it can contain receipt. The full receipt is deliberately not committed because it can contain
claim bodies or source excerpts; the sanitized proof is retained as claim bodies or source excerpts; the sanitized proof is retained as
`reports/leo-working-state-20260709/kb-apply-replay-receipt-current.json`. `docs/reports/leo-working-state-20260709/kb-apply-replay-receipt-current.json`.
Normal applies mark the SQL hash as `exact_executed_sql`. A later Normal applies mark the SQL hash as `exact_executed_sql`. A later
`--receipt-only` recovery marks it as `reconstructed_current_engine`; it never `--receipt-only` recovery marks it as `reconstructed_current_engine`; it never
@ -146,7 +148,7 @@ not retain every column of the proposal ledger, so exact reconstruction also
needs the full approved proposal row, immutable approval snapshot, and final needs the full approved proposal row, immutable approval snapshot, and final
applied proposal row. applied proposal row.
## Genesis Plus Strict Ledger: Working Insert-Only Slice ## Genesis Plus Strict Ledger: Working Deterministic Slice
`ops/run_local_genesis_ledger_rebuild.py` now executes the first exact `ops/run_local_genesis_ledger_rebuild.py` now executes the first exact
genesis-plus-ledger slice in one command: genesis-plus-ledger slice in one command:
@ -204,27 +206,67 @@ Each referenced material object has exact top-level keys
must contain every current `kb_stage.kb_proposals` column; partial envelopes must contain every current `kb_stage.kb_proposals` column; partial envelopes
are rejected. are rejected.
The command verifies every hash before starting Docker, restores a tmpfs-backed The command verifies every hash before starting Docker, requires a
Postgres with `--network none`, reapplies the current guarded prerequisites, SHA-256-pinned Postgres image (and defaults to a pinned PostgreSQL 16 Alpine
and proves genesis parity. For each entry it seeds the receipt's exact row IDs multi-platform digest), restores it on tmpfs with `--network none`, reapplies
and timestamps in the disposable clone, executes the existing `kb_apply` the current guarded prerequisites, and proves genesis parity. Insert-only
payload-bound guard and ledger transition, checks exact proposal and canonical entries seed the receipt's exact canonical row IDs and timestamps before the
row readbacks, then verifies the complete final parity manifest. Its public existing `kb_apply` payload-bound guard executes. For `revise_strategy`, the
runner seeds only the proposal and approval, captures the target agent's
prestate, executes the real guarded transition, validates the generated delta,
and then replaces only those generated rows with the receipt-pinned IDs and
timestamps. Every path checks exact proposal and canonical row readbacks before
verifying the complete final parity manifest. Its public
mode-`0600` receipt contains hashes, IDs, types, counts, parity summaries, and mode-`0600` receipt contains hashes, IDs, types, counts, parity summaries, and
cleanup proof, but no payloads, rows, SQL, source paths, or command errors. cleanup proof, but no payloads, rows, SQL, source paths, or command errors.
The legacy `seed_exact` summary is the insert-only aggregate of
`proposal_seed_exact` and `canonical_seed_exact`; it is intentionally false for
successful mutating entries, which instead report
`mutating_delta_validated` and `mutating_poststate_normalized`.
Fresh guard bootstrap rows use a fixed baseline timestamp rather than wall
clock time, so repeated clean restores have identical row hashes.
The exact v1 claim ceiling is intentionally narrow: The exact v1 claim ceiling is intentionally bounded:
- `add_edge`, `attach_evidence`, and `approve_claim` strict receipts execute; - `add_edge`, `attach_evidence`, `approve_claim`, and `revise_strategy` strict
receipts execute;
- sequence gaps, hash drift, engine drift, duplicate proposals, and legacy or - sequence gaps, hash drift, engine drift, duplicate proposals, and legacy or
freeform payloads fail before container start; freeform payloads fail before container start;
- `revise_strategy` fails closed because its current receipt omits the prior - `revise_strategy` is accepted only when the receipt pins the exact SQL that
strategies and nodes that the apply engine deactivates or retires; matches the current guarded apply engine. Immediately before each entry, the
runner captures the target agent's strategy/node IDs, active strategy,
non-retired nodes, and maximum version. It then validates the generated
post-minus-pre delta, requires `version = previous maximum + 1`, and replaces
only the generated strategy/node rows with the exact receipt rows;
- the original transaction timestamp is derived from the fresh strategy
`created_at` and must equal every fresh node's `created_at` and `updated_at`.
It must also fall within the immutable, timezone-aware interval
`reviewed_at <= transaction timestamp <= applied_at`.
Only node IDs observed as non-retired before apply receive that timestamp;
already-retired, unrelated-agent, and shared NULL-agent rows stay untouched;
- generated nodes must have no anchors before normalization, preventing a
delete-and-reinsert step from silently cascading future trigger-created rows;
- full proposal before/after rows are mandatory because the current receipt - full proposal before/after rows are mandatory because the current receipt
envelope does not retain proposal origin fields or exact `updated_at`; envelope does not retain proposal origin fields or exact `updated_at`;
- this proves only an isolated local reconstruction. It does not touch or prove - this proves only an isolated local reconstruction. It does not touch or prove
VPS, GCP, Telegram, a live database, or blank-schema source recompilation. VPS, GCP, Telegram, a live database, or blank-schema source recompilation.
The transition contract for `revise_strategy` is final-state deterministic, not
a claim that the v1 receipt independently contains a historical before-image:
```text
exact genesis/pre-entry state
+ exact current/original guarded SQL
+ receipt-pinned fresh strategy and nodes
-> prior active strategy inactive
-> exactly the prior non-retired nodes retired at the original transaction time
-> one receipt-exact active strategy and receipt-exact node set
```
The genesis and final manifests remain mandatory oracles. Any incorrect
prestate, unrelated-row mutation, missing/extra generated row, semantic drift,
version drift, hash drift, or final rowset difference fails the reconstruction.
The source compiler now turns one raw artifact, its strict UTF-8 extraction, The source compiler now turns one raw artifact, its strict UTF-8 extraction,
and a reviewed extraction manifest into a deterministic, hash-bound and a reviewed extraction manifest into a deterministic, hash-bound
`pending_review` proposal bundle: `pending_review` proposal bundle:
@ -270,10 +312,9 @@ neither command applies canonical rows.
The existing full-data clone canary separately proves that a reviewed packet The existing full-data clone canary separately proves that a reviewed packet
can create source, claim, evidence, and edge rows and affect later reasoning. can create source, claim, evidence, and edge rows and affect later reasoning.
The remaining reconstruction work is to retain complete deltas for mutating The remaining reconstruction work is to backfill or explicitly reject legacy
contracts such as `revise_strategy`, backfill or explicitly reject legacy freeform applies and extend beyond genesis recovery to a blank-schema source
freeform applies, and extend beyond genesis recovery to a blank-schema source compiler. The strict ledger runner does not prove that every historical
compiler. The insert-only ledger runner does not prove that every historical
canonical row can be rebuilt semantically from retained sources. canonical row can be rebuilt semantically from retained sources.
## Definition Of Working ## Definition Of Working

View file

@ -0,0 +1,212 @@
# Reproducible Leo identity
## Definition of Working
- **Working target:** generate one pinned Leo identity manifest, compile a
disposable profile, answer the fixed identity query in a fresh process,
restart in a second process, and reject any drift before an answer.
- **Operator path:** run
`python -m scripts.run_leo_identity_reconstruction_canary` with the committed
identity fixtures from a clean checkout.
- **Done means:** the T2 receipt reports two distinct stopped processes with the
same manifest, identity inputs, query, answer hash, and output provenance;
the second process starts from a newly compiled empty profile; the drift
attempt exits before answering; every process group and temporary profile is
removed.
- **Not done:** a hand-edited `SOUL.md`, a manifest self-hash, unit tests without
process restart, or prior VPS restart evidence that did not reconstruct from
this manifest.
- **Required tier:** `T2_runtime`. T3 VPS restart/readback is a post-merge
graduation target.
## Identity input inventory
`GatewayRunner` and the surrounding Hermes profile can change an answer through
the following surfaces. The manifest either pins each surface or explicitly
keeps it outside identity authority.
| Surface | Binding | Authority |
| --- | --- | --- |
| Model provider, route, limits, and reasoning settings | secret-free semantic config hash | runtime input; the actual model remains a per-turn receipt |
| Hosted model weights | provider-managed, explicitly not locally hashable | never claimed as a local hash |
| Hermes and Teleo code | clean Git commits plus executable source-tree hashes | runtime input |
| Python ABI and imported runtime packages | exact implementation/version and curated package versions | runtime input |
| Skills, plugins, and database tools | content hashes | runtime input |
| Gateway/tool permissions | strict allowlisted config hash plus exact no-send/read-only policy | runtime input; this local compiler does not claim an authorizer readback |
| Static constitutional rules | committed source path, byte hash, and semantic hash | static authority |
| Database snapshot version | database/user/system identity plus content, row, structure, and capture-provenance hashes; only WAL position is excluded | T2 pins a noncanonical fixture; it cannot grant canonical authority |
| Database-derived identity rows | typed table/row/kind/rank/evidence bindings plus source mode | synthetic fixtures are explicitly noncanonical; T3 requires independently verified database-exporter output |
| `SOUL.md` and `identity.json` | deterministic compiled-view hashes | generated views, never authorities |
| Sessions, state, and memory | excluded from the identity input hash and labeled temporary | continuity only; never evidence |
The disposable profile is compiled from a strict non-secret configuration
allowlist; unrecognized transport/credential fields are not copied. Credential
values are omitted rather than hashed. Rotating a bot token changes the broad
operational behavior observation but does not change Leo's identity.
Changing a non-secret permission, model setting, skill, code file, database
fingerprint, constitutional rule, database identity row, or compiled view does
change a pinned input and fails closed.
### Current `GatewayRunner` consumption map
The T2 compiler contract was checked against the current live runtime source.
This inventory defines what the post-merge T3 receipt must observe rather than
silently assuming that a profile file is the whole prompt:
- Startup resolves `-p leoclean` to `HERMES_HOME`, then loads profile and project
environment files before `config.yaml`; environment expansion, legacy
`gateway.json`, and defaults can change the effective configuration. The T2
compiler therefore enforces an exact top-level profile allowlist (including
rejection of dangling symlinks) rather than relying on a filename denylist.
- Routing consumes the requested default model, the top-level
`smart_model_routing` switch, provider endpoints/defaults, auth pool choice,
reasoning settings, token/turn limits, and fallbacks. The pinned top-level
routing switch must be a boolean; arbitrary nested routing data is rejected.
Credentials are runtime capability, not identity, and their values are never
retained.
- Prompt construction consumes generated `SOUL.md`, the gateway/agent system
message, persistent `MEMORY.md`/`USER.md`, compiled skills, project-context
files, current time/timezone, and the effective model/provider. T2 requires
memory and project context absent; T3 records the effective system-prompt and
compiled-skills-prompt hashes.
- Plugin discovery can include profile plugins, optional project plugins, and
installed entry points. The live database-context hook can inject a
query-bound contract before the model and can reject or replace the reply
afterward, so T3 retains plugin registry, contract, retrieval, and delivered
response hashes.
- Effective tools come from platform toolsets and the runtime registry, not a
descriptive fixture field. T3 must read back exact tool schemas, prove the
send tool absent, and keep terminal restricted to the clone-bound read-only
wrapper.
- Authorization consumes chat/user allowlists and pairing-store state. T2 starts
with pairing absent; T3 records the fixed synthetic source and the actual
authorization decision without exposing IDs or tokens.
- Session keys consume platform/chat/user/thread/topic fields. Auto-skill,
reply/media/file context, persisted transcripts, and a reused system prompt
can all change a turn. Verification therefore happens before every child
starts, and T3 binds session key, persisted session ID, message-context
absence, and prompt hashes.
The committed T2 database/identity inputs are synthetic fixtures and the
compiled view labels them `synthetic_noncanonical_fixture`; they do not stand
in for approved production rows. This T2 schema never grants canonical
authority from caller-supplied or merely self-hashed JSON. T3 must use output
that is independently verified by the database-owning same-transaction exporter
and bound to the database fingerprint, database user, system identifier, and
row digest.
Every pinned source tree and profile component is structurally revalidated:
the verifier recomputes its file count, total bytes, sorted unique paths, and
canonical content hash, and rejects missing files, unreadable entries, or
symlinks. Rehashing forged structural metadata cannot make it authoritative.
The current live Hermes checkout is not clean, so its Git SHA alone is not a
reproducible source bundle. This T2 receipt intentionally uses the committed
clean local runtime and the committed database/identity snapshot fixture. It
does not claim to reconstruct the current dirty VPS runtime. T3 must run only
after the merged identity code is deployed and must bind the deployed clean
content (or a content-addressed dirty-source bundle if the live checkout has not
yet been repaired).
## Commands
The complete canary is the preferred operator command:
```bash
python -m scripts.run_leo_identity_reconstruction_canary \
--profile-template fixtures/working-leo/leo-identity-v1/profile-template \
--hermes-root fixtures/working-leo/leo-identity-v1/hermes-runtime \
--deployment-root . \
--source-root . \
--database-fingerprint fixtures/working-leo/leo-identity-v1/leo-database-fingerprint-v1.json \
--constitution fixtures/working-leo/leo-identity-v1/leo-constitution-v1.json \
--database-identity fixtures/working-leo/leo-identity-v1/leo-database-identity-v1.json \
--output docs/reports/leo-working-state-20260709/leo-reproducible-identity-t2-current.json
```
The negative lifecycle is separately runnable. It proves drift is caught before
the second process starts:
```bash
python -m scripts.run_leo_identity_reconstruction_canary \
--profile-template fixtures/working-leo/leo-identity-v1/profile-template \
--hermes-root fixtures/working-leo/leo-identity-v1/hermes-runtime \
--deployment-root . \
--source-root . \
--database-fingerprint fixtures/working-leo/leo-identity-v1/leo-database-fingerprint-v1.json \
--constitution fixtures/working-leo/leo-identity-v1/leo-constitution-v1.json \
--database-identity fixtures/working-leo/leo-identity-v1/leo-database-identity-v1.json \
--inject-drift-before-restart \
--output /tmp/leo-identity-drift-rejection.json
```
For inspection, the lifecycle can be decomposed into explicit manifest and
compile commands:
```bash
python -m scripts.leo_behavior_manifest \
--profile fixtures/working-leo/leo-identity-v1/profile-template \
--hermes-root fixtures/working-leo/leo-identity-v1/hermes-runtime \
--deployment-root . \
--output /tmp/leo-behavior.json
python -m scripts.leo_identity_manifest generate \
--behavior-manifest /tmp/leo-behavior.json \
--database-fingerprint fixtures/working-leo/leo-identity-v1/leo-database-fingerprint-v1.json \
--constitution fixtures/working-leo/leo-identity-v1/leo-constitution-v1.json \
--database-identity fixtures/working-leo/leo-identity-v1/leo-database-identity-v1.json \
--source-root . \
--output /tmp/leo-identity-manifest.json
python -m scripts.leo_identity_profile compile \
--manifest /tmp/leo-identity-manifest.json \
--source-root . \
--profile-template fixtures/working-leo/leo-identity-v1/profile-template \
--profile /tmp/leo-disposable-profile \
--hermes-root fixtures/working-leo/leo-identity-v1/hermes-runtime \
--deployment-root .
```
All commands require a clean Git worktree because a commit plus an unretained
dirty source tree is not reproducible.
Child processes execute the real interpreter and temporary-profile paths only
in process-local memory. Retained receipts persist a repo-relative
`logical_command`, the stable `<python>` and `<temporary-profile>` placeholders,
and an explicit `profile_role`; they never serialize the checkout, interpreter,
or temporary directory path.
## State inventory and transitions
| State | Meaning | Next valid transition |
| --- | --- | --- |
| `inputs_unverified` | source paths exist but are not yet bound | validate clean Git, runtime, DB, rules, rows, and permissions |
| `manifest_pinned` | every material identity input has a stable hash | compile deterministic views |
| `profile_compiled` | static profile copied and generated views match the manifest | verify immediately before start |
| `runtime_verified` | runtime/code/view hashes match and session state is non-authoritative | answer fixed query |
| `stopped_cleanly` | child and process group are absent | compile a new empty profile from the manifest |
| `restart_reproduced` | child from the newly compiled profile has the same identity/query/provenance inputs | retain receipt and clean every profile |
| `drift_detected` | any input or generated view differs | fail closed; no answer and no next start |
The irreversible boundary is not a database or production mutation: this T2
canary is a local compiler/process runtime, no-send, database-read-only, and
disposable. The successful-restart receipt reaches `T2_runtime`; the standalone
pre-restart drift receipt is a passing negative component but reports
`T1_model` and `goal_tier_satisfied=false`. Neither proves the live VPS
`GatewayRunner`, Telegram delivery, hosted-model behavior, production database
state, or T3 restart recovery.
Here `T2_runtime` uses the required Capability Tier Proof vocabulary: local
runtime behavior with restart. It does not imply Hermes/GatewayRunner or a
hosted model; those exclusions are explicit in the receipt's `runtime_variant`,
`tier_basis`, and `claim_ceiling`.
## T3 graduation
After merge and rollback proof, extend the schema with independent verification
of the database-owning same-transaction exporter, generate the manifest from
that live read-only canonical capture and deployed clean commits, compile a
disposable VPS profile, invoke the real no-send `GatewayRunner`, terminate that
child, open a new child from the same manifest, and retain model-call, DB-read,
service, cleanup, and drift-negative readbacks. Do not replace the production
profile during that graduation.

View file

@ -0,0 +1,188 @@
# GCP Observatory Read Adapter
## Definition of Working
- Working target: an authenticated GCP staging API returns one canonical claim
with source/evidence provenance and a separately labeled proposal ledger.
- Operator path: `GET /v1/claims/sample` or `GET /v1/claims/{uuid}` with the
server-only `X-Api-Key` value.
- Done means: the response names `teleo_canonical`, the dedicated IAM database
principal and `kb_observatory_read`, reports a read-only transaction and
denied write privileges, and live anonymous/write HTTP attempts return
`401`/`405`.
- Not done: the VPS `teleo-pg`, a public Cloud SQL address, a browser-visible
key, a mock-only receipt, or a production Vercel repoint.
- Required tier: `T3_live_readonly`.
## Existing Connector Boundary
The current `living-ip/livingip-web` main branch reads claims through
`src/lib/api.ts`. It selects `NEXT_PUBLIC_API_URL` and otherwise falls back to
`http://77.42.65.182:8081`, then calls the legacy `/api/claims` routes. That is
the VPS-local/public Observatory path. It is not safe to replace that public
environment variable with this protected API: the response shape differs and
the adapter key must never enter a `NEXT_PUBLIC_` variable or browser bundle.
The existing Teleo route `GET /api/kb/claims` is the compatibility reference
for route-scoped authentication, but its default database/container settings
still describe the VPS-local process. This service is a separate GCP runtime;
it does not change Argus or PR #148's Leo runtime files.
## Runtime Contract
- Cloud Run service: `observatory-read-adapter-staging` in `europe-west6`.
- Direct VPC egress: `teleo-staging-net` / `teleo-staging-europe-west6`.
- Cloud SQL: `teleo-501523:europe-west6:teleo-pgvector-standby`, private IP.
- Database: `teleo_canonical` only.
- Build identity: `sa-artifact-builder@teleo-501523.iam.gserviceaccount.com`;
image build/push only.
- Staging deploy/canary identity:
`sa-observatory-deployer@teleo-501523.iam.gserviceaccount.com`; an exact
workflow/main-only WIF provider, a five-permission Cloud Run custom role,
repository read, exact runtime `actAs`, and exact secret access. Never grant
deploy permissions to the artifact builder.
- Runtime identity: `sa-observatory-read-adapter@teleo-501523.iam.gserviceaccount.com`.
- IAM database user: `sa-observatory-read-adapter@teleo-501523.iam`.
- Database authorization role: `kb_observatory_read` (`NOLOGIN`).
- API authentication: route-scoped key from Secret Manager secret
`observatory-read-api-key-staging`; the value is not in Git or deploy logs.
- No mutation routes exist. Authenticated unsupported methods return `405`.
The Cloud SQL Python Connector uses Application Default Credentials from the
Cloud Run service identity, automatic IAM database authentication, and private
IP. Every request starts a read-only transaction and refuses the response if
the database, IAM principal, authorization membership, required reads, or
effective write-denial checks drift.
## One-Time Staging Bootstrap
These are staging mutations. Run them only with an authenticated GCP operator;
they do not route production traffic.
1. Reauthenticate the project operator, then run the first full direct check:
```bash
gcloud projects describe teleo-501523 --format=value(projectId)
python3 ops/check_gcp_infra_readiness.py
```
2. Review the exact dry-run packet. It enables only required APIs, creates
separate staging deploy/runtime identities, creates the dedicated
`observatory-read-adapter-main` WIF provider, keeps the artifact builder
narrow, scopes Cloud SQL connect/login to `teleo-pgvector-standby`, and
scopes secret access to `observatory-read-api-key-staging`:
```bash
python3 ops/plan_observatory_read_adapter_gcp.py
python3 ops/plan_observatory_read_adapter_gcp.py --format shell
```
The shell output is unexecuted and uses `set -euo pipefail`. Apply it only
after review with an authenticated `teleo-501523` administrator. The
deployer custom role contains only `run.services.create`,
`run.services.update`, `run.services.get`, `run.services.setIamPolicy`, and
`run.operations.get`; it contains no delete permission. Do not add
`run.admin`, `run.developer`, `cloudsql.admin`, `secretmanager.admin`,
`compute.admin`, Editor, or Owner to either lane identity.
3. Add the dedicated runtime service account as a Cloud SQL IAM
service-account user on `teleo-pgvector-standby`.
4. From the existing private GCP VM database-admin path, run
`ops/observatory_read_role.sql` against `teleo_canonical` with
`OBSERVATORY_DB_IAM_USER=sa-observatory-read-adapter@teleo-501523.iam`.
Do not read, copy, or retain the administrator password.
5. Create `observatory-read-api-key-staging`, add a generated whitespace-free
32-byte-or-longer value through stdin only when no enabled version exists,
and grant that secret's accessor role only to the runtime service account
and the dedicated staging deploy/canary identity. Deployment pins the exact
enabled version; it does not inject `latest` into Cloud Run.
6. Dispatch the read-only preflight from merged `main`:
```bash
gh workflow run gcp-observatory-read-adapter.yml \
--repo living-ip/teleo-infrastructure \
--ref main \
-f action=preflight_staging
```
Require a passing `observatory-read-adapter-preflight` artifact before a
bounded `action=deploy_staging` dispatch. The preflight verifies the exact
WIF condition, custom-role permission sets, project/resource IAM bindings,
Cloud Run service agent, private VPC/subnet relationship, private-only Cloud
SQL network and IAM authentication, trimmed IAM database user, exact secret
policy/value shape, and the run-unique immutable image. It also rejects any
artifact-builder deploy, runtime `actAs`, secret, or service binding.
The workflow always builds a run-unique immutable image, deploys at most two Cloud Run
instances, and retains the positive response plus anonymous `401` and
authenticated POST `405` receipts. The retained positive receipt contains
identity/provenance, counts, and proposal/live state only; claim text, source
URLs, excerpts, unknown future provenance fields, and secret values are
removed by an explicit tested allowlist. The live gate binds the response to
the exact project, private instance, database principal, Git revision, Cloud
Run image digest, runtime identity, and pinned secret version. It does not
modify Vercel. The app-level `X-Api-Key` remains the staging authentication
boundary, so anonymous Cloud Run invocation reaches the adapter and returns
the required `401` instead of a platform-generated status.
## Current T2 Receipt And Exact T3 Gate
GitHub Actions run `29389090997` proves the existing `living-ip-github` WIF
provider can federate as the artifact builder, run the checker, upload its
artifact, and clean up credentials. The checker reported `8` pass, `10`
blocked, `0` fail. Eight blocks are missing inventory permissions on the
artifact-builder identity; two are missing restore/replication proof. This is
partial OIDC/T2 evidence, not T3 and not authorization to deploy with that
identity.
The exact external action is for `billy@livingip.xyz` to reauthenticate gcloud
and ADC, prove `gcloud projects describe teleo-501523`, run
`python3 ops/check_gcp_infra_readiness.py`, review and execute the planner's
shell output as a project IAM/API administrator, then apply
`ops/observatory_read_role.sql` from the existing private database-admin path.
The general readiness identity and artifact-builder identity are not deployer
substitutes. After those actions, dispatch `preflight_staging`; only a passing
artifact permits `deploy_staging`. A passing preflight remains T2 setup proof:
the fail-closed live claim and negative receipts are what establish T3.
The IAM basis is the Google Cloud deployment contract for Cloud Run (Cloud Run
access, Artifact Registry repository read, and exact runtime `actAs`), Secret
Manager resource-level accessor grants, Direct VPC access through the default
Cloud Run service agent, and conditional Cloud SQL client access to one named
instance:
- https://docs.cloud.google.com/run/docs/deploying
- https://docs.cloud.google.com/run/docs/authenticating/public
- https://docs.cloud.google.com/run/docs/configuring/vpc-direct-vpc
- https://docs.cloud.google.com/iam/docs/workload-identity-federation-with-deployment-pipelines
- https://docs.cloud.google.com/secret-manager/docs/manage-access-to-secrets
- https://docs.cloud.google.com/sql/docs/postgres/iam-conditions
## Unexecuted Cutover Packet
Production cutover requires a separate exact authorization and a
`living-ip/livingip-web` change. Do not execute these steps from this lane.
1. Add server-only Vercel secrets `OBSERVATORY_CANONICAL_API_URL` and
`OBSERVATORY_CANONICAL_API_KEY` to a protected preview environment. The URL
targets the GCP service; neither setting may use `NEXT_PUBLIC_`.
2. Add a Next.js server route or server action that calls the GCP API, validates
`livingip.observatory-canonical-claim.v1`, and maps it to the Observatory UI.
The browser calls only the same-origin Next.js route.
3. Prove preview Deployment Protection, anonymous denial, source/evidence
rendering, proposal/live labels, and no browser key exposure.
4. Obtain exact production-repoint authorization naming the reviewed
`livingip-web` commit and Vercel project before changing production values.
## Unexecuted Rollback Packet
1. Revert the authorized `livingip-web` connector commit or disable its
server-side feature flag.
2. Restore the prior production Vercel values and redeploy the last accepted
production revision.
3. Verify `/claims` again uses the prior `/api/claims` contract.
4. Leave the private Cloud SQL instance and adapter role intact while receipts
are reviewed; scale the staging Cloud Run service to zero if isolation is
required.
5. Delete the staging service/role/secret only under a separate cleanup
decision. Rollback never adds a Cloud SQL public IP and never redirects the
adapter to VPS `teleo-pg`.

View file

@ -2,6 +2,30 @@
Use this file before making status claims. Prefer fresh VPS/GCP readbacks when cheap; this directory is the retained July 9 evidence snapshot committed to the Teleo infrastructure repo. Use this file before making status claims. Prefer fresh VPS/GCP readbacks when cheap; this directory is the retained July 9 evidence snapshot committed to the Teleo infrastructure repo.
## Repository And Skill Routing Addendum - 2026-07-15
- PRs #146 and #147 are merged into canonical `main`. The reconstruction source
of truth is `docs/kb-rebuild-and-recompile.md`; the merged deterministic paths
are `ops/run_local_genesis_ledger_rebuild.py`,
`scripts/leo_turn_execution_manifest.py`, and
`scripts/verify_leo_unseen_reasoning_chain.py`.
- PR #148 remains open candidate evidence for least-privilege GCP Cloud SQL
runtime access. Do not use its branch-only runbook, deployment script, role
migration, or proposed live outcome as canonical `main` until the PR is merged
and its retained runtime receipt passes.
- The repo-native onboarding entry point is
`.agents/skills/teleo-leo-onboarding/SKILL.md`. Its standard-library validator
is `.agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py`; run it
before relying on any skill route from a clean context.
- The deterministic isolated install/routing/cleanup receipt is
`docs/reports/leo-working-state-20260709/skill-pack-clean-context-canary-current.json`.
- The separate no-history agent onboarding receipt is
`docs/reports/leo-working-state-20260709/skill-pack-clean-context-agent-review-current.json`.
- Exact snapshot restoration is working. The merged genesis-plus-ledger path is
an isolated insert-only recovery slice. Full semantic recompilation from every
original source remains incomplete. None of these local tiers proves a live
VPS/GCP restore, Telegram delivery, production apply, or GCP promotion.
## GCP Database-First Addendum - 2026-07-14 10:07 UTC ## GCP Database-First Addendum - 2026-07-14 10:07 UTC
This addendum supersedes the GCP-pending statements in the earlier July 14 This addendum supersedes the GCP-pending statements in the earlier July 14
@ -135,8 +159,8 @@ sections below override this newer status.
- VPS canonical KB: claims `1837`, sources `4145`, evidence `4670`, edges - VPS canonical KB: claims `1837`, sources `4145`, evidence `4670`, edges
`4916`, proposals `26`; proposal states are applied `2`, approved `3`, `4916`, proposals `26`; proposal states are applied `2`, approved `3`,
pending review `14`, canceled `7`. pending review `14`, canceled `7`.
- VPS direct Cory answers: no-send `DC-01` through `DC-06` strict-score `6/6`. - VPS direct m3taversal-standard answers: no-send `DC-01` through `DC-06` strict-score `6/6`.
- Telegram direct Cory answers: partial. `DC-01` was visibly sent and its live - Telegram direct m3taversal-standard answers: partial. `DC-01` was visibly sent and its live
gateway reply strict-passed server-side, but the reply itself is not yet gateway reply strict-passed server-side, but the reply itself is not yet
captured in Telegram. `DC-02` through `DC-06` are not yet sent. captured in Telegram. `DC-02` through `DC-06` are not yet sent.
- DB composition/application: deterministic source-to-proposal, full-data clone - DB composition/application: deterministic source-to-proposal, full-data clone
@ -146,7 +170,7 @@ sections below override this newer status.
- GCP canonical DB: exact VPS parity is proven across `39` tables and `52,164` - GCP canonical DB: exact VPS parity is proven across `39` tables and `52,164`
rows over private TLS, with zero row/catalog/role/extension/performance rows over private TLS, with zero row/catalog/role/extension/performance
mismatches. Gateway PID `148735`, `NRestarts=0` stayed unchanged. mismatches. Gateway PID `148735`, `NRestarts=0` stayed unchanged.
- GCP Cory replay: six DB-read routes pass. One real no-send model replay - GCP m3taversal-standard replay: six DB-read routes pass. One real no-send model replay
nominally scored `6/6`, but it was rejected because two replies printed false nominally scored `6/6`, but it was rejected because two replies printed false
zero canonical counts. The harness now enables the required `status` read and zero canonical counts. The harness now enables the required `status` read and
rejects any printed count that differs from the canonical status receipt. A rejects any printed count that differs from the canonical status receipt. A
@ -170,16 +194,16 @@ Newest artifacts:
- `docs/reports/leo-working-state-20260709/gcp-canonical-parity-live-20260712.json` - `docs/reports/leo-working-state-20260709/gcp-canonical-parity-live-20260712.json`
- `docs/reports/leo-working-state-20260709/teleo_clone_cory_20260712t1940z-canonical-parity-receipt.json` - `docs/reports/leo-working-state-20260709/teleo_clone_cory_20260712t1940z-canonical-parity-receipt.json`
- `docs/reports/leo-working-state-20260709/telegram-visible-direct-claim-dc01-partial-current.json` - `docs/reports/leo-working-state-20260709/telegram-visible-direct-claim-dc01-partial-current.json`
- `docs/reports/leo-working-state-20260709/gcp-cory-model-replay-current.json` (created only after the hardened rerun) - `docs/reports/leo-working-state-20260709/gcp-db-first-blind-claim-current.json`
- `docs/reports/leo-working-state-20260709/gcp-operator-access-blocker-current.json` - `docs/reports/leo-working-state-20260709/gcp-operator-access-blocker-current.json`
## Definition And Outcomes ## Definition And Outcomes
- Working Leo definition: `docs/reports/leo-working-state-20260709/working-leo-definition-20260709.md` - Working Leo definition: `docs/reports/leo-working-state-20260709/working-leo-definition-20260709.md`
- Cory expected outcomes: `docs/reports/leo-working-state-20260709/cory-expected-working-leo-outcomes-20260709.md` - Legacy-named expected-outcomes evidence: `docs/reports/leo-working-state-20260709/cory-expected-working-leo-outcomes-20260709.md`
- Current state: `docs/reports/leo-working-state-20260709/working-leo-current-state-20260709.md` - Current state: `docs/reports/leo-working-state-20260709/working-leo-current-state-20260709.md`
- Execution plan: `docs/reports/leo-working-state-20260709/working-leo-execution-plan-current.md` - Execution plan: `docs/reports/leo-working-state-20260709/working-leo-execution-plan-current.md`
- Open-ended benchmark spec: `docs/reports/leo-working-state-20260709/working-leo-open-ended-benchmark-spec.json` (5 live-safe open prompts, 9 broader Cory-style outcome scenarios, and 6 no-context direct-claim follow-up prompts for disposable clone/sandbox first) - Open-ended benchmark spec: `docs/reports/leo-working-state-20260709/working-leo-open-ended-benchmark-spec.json` (5 live-safe open prompts, 9 broader m3taversal-standard outcome scenarios, and 6 no-context direct-claim follow-up prompts for disposable clone/sandbox first)
- Open-ended live Telegram canary: `docs/reports/leo-working-state-20260709/telegram-live-open-ended-cory-style-20260709.md` - Open-ended live Telegram canary: `docs/reports/leo-working-state-20260709/telegram-live-open-ended-cory-style-20260709.md`
- Open-ended live Telegram canary JSON: `docs/reports/leo-working-state-20260709/telegram-live-open-ended-cory-style-20260709.json` - Open-ended live Telegram canary JSON: `docs/reports/leo-working-state-20260709/telegram-live-open-ended-cory-style-20260709.json`
- Retained Telegram benchmark score for the open-ended canary: `docs/reports/leo-working-state-20260709/telegram-live-open-ended-benchmark-score-current.md` - Retained Telegram benchmark score for the open-ended canary: `docs/reports/leo-working-state-20260709/telegram-live-open-ended-benchmark-score-current.md`
@ -187,9 +211,9 @@ Newest artifacts:
- Full live-safe open-ended Telegram suite report: `docs/reports/leo-working-state-20260709/telegram-live-open-ended-suite-current.md` - Full live-safe open-ended Telegram suite report: `docs/reports/leo-working-state-20260709/telegram-live-open-ended-suite-current.md`
- Full live-safe open-ended Telegram suite score: `docs/reports/leo-working-state-20260709/telegram-live-open-ended-suite-score-current.md` - Full live-safe open-ended Telegram suite score: `docs/reports/leo-working-state-20260709/telegram-live-open-ended-suite-score-current.md`
- Full live-safe open-ended Telegram suite score JSON: `docs/reports/leo-working-state-20260709/telegram-live-open-ended-suite-score-current.json` - Full live-safe open-ended Telegram suite score JSON: `docs/reports/leo-working-state-20260709/telegram-live-open-ended-suite-score-current.json`
- Full Cory-style outcome/direct-claim sandbox results: `docs/reports/leo-working-state-20260709/working-leo-cory-outcome-sandbox-results-current.md` - Full m3taversal-standard outcome/direct-claim sandbox results: `docs/reports/leo-working-state-20260709/working-leo-cory-outcome-sandbox-results-current.md`
- Full Cory-style outcome/direct-claim sandbox score: `docs/reports/leo-working-state-20260709/working-leo-cory-outcome-sandbox-score-current.md` - Full m3taversal-standard outcome/direct-claim sandbox score: `docs/reports/leo-working-state-20260709/working-leo-cory-outcome-sandbox-score-current.md`
- Full Cory-style outcome sandbox score JSON: `docs/reports/leo-working-state-20260709/working-leo-cory-outcome-sandbox-score-current.json` - Full m3taversal-standard outcome sandbox score JSON: `docs/reports/leo-working-state-20260709/working-leo-cory-outcome-sandbox-score-current.json`
- Live VPS handler direct-claim suite report: `docs/reports/leo-working-state-20260709/telegram-handler-direct-claim-suite-current.json` - Live VPS handler direct-claim suite report: `docs/reports/leo-working-state-20260709/telegram-handler-direct-claim-suite-current.json`
- Live VPS handler direct-claim suite score: `docs/reports/leo-working-state-20260709/telegram-handler-direct-claim-suite-score-current.md` - Live VPS handler direct-claim suite score: `docs/reports/leo-working-state-20260709/telegram-handler-direct-claim-suite-score-current.md`
- Live VPS handler direct-claim suite review: `docs/reports/leo-working-state-20260709/telegram-handler-direct-claim-suite-review-current.md` - Live VPS handler direct-claim suite review: `docs/reports/leo-working-state-20260709/telegram-handler-direct-claim-suite-review-current.md`
@ -311,9 +335,9 @@ Newest artifacts:
- Skill-pack map: `docs/reports/leo-working-state-20260709/leo-db-state-13-skill-pack.svg` - Skill-pack map: `docs/reports/leo-working-state-20260709/leo-db-state-13-skill-pack.svg`
- Helmer packet proof: `docs/reports/leo-working-state-20260709/leo-db-state-14-helmer-packet.svg` - Helmer packet proof: `docs/reports/leo-working-state-20260709/leo-db-state-14-helmer-packet.svg`
- Open-ended Cory-style canary map: `docs/reports/leo-working-state-20260709/leo-db-state-15-open-ended-canary.svg` - Open-ended m3taversal-standard canary map: `docs/reports/leo-working-state-20260709/leo-db-state-15-open-ended-canary.svg`
- Helmer ledger packet proof: `docs/reports/leo-working-state-20260709/leo-db-state-16-helmer-ledger.svg` - Helmer ledger packet proof: `docs/reports/leo-working-state-20260709/leo-db-state-16-helmer-ledger.svg`
- Cory-style outcome benchmark map: `docs/reports/leo-working-state-20260709/leo-db-state-17-cory-outcome-benchmark.svg` - m3taversal-standard outcome benchmark map: `docs/reports/leo-working-state-20260709/leo-db-state-17-cory-outcome-benchmark.svg`
- Leoclean DB versus workspace map: `docs/reports/leo-working-state-20260709/leo-db-state-18-db-vs-workspace.svg` - Leoclean DB versus workspace map: `docs/reports/leo-working-state-20260709/leo-db-state-18-db-vs-workspace.svg`
- Claim/body/metadata schema map: `docs/reports/leo-working-state-20260709/leo-db-state-19-claims-body-metadata.svg` - Claim/body/metadata schema map: `docs/reports/leo-working-state-20260709/leo-db-state-19-claims-body-metadata.svg`
- Cross-surface strategy anchor proof: `docs/reports/leo-working-state-20260709/leo-db-state-20-cross-surface-anchor.svg` - Cross-surface strategy anchor proof: `docs/reports/leo-working-state-20260709/leo-db-state-20-cross-surface-anchor.svg`
@ -331,7 +355,7 @@ Newest artifacts:
- VPS Leo Telegram memory, KB audit, and staged-write canaries are live-proven. - VPS Leo Telegram memory, KB audit, and staged-write canaries are live-proven.
- VPS Leo live-safe open-ended Telegram suite is live-proven and retained-benchmark-scored for `OE-01` through `OE-05`: full selected coverage, `5/5` scored prompts passing, no overclaim, and no marker/staging/canonical KB rows created by the suite. - VPS Leo live-safe open-ended Telegram suite is live-proven and retained-benchmark-scored for `OE-01` through `OE-05`: full selected coverage, `5/5` scored prompts passing, no overclaim, and no marker/staging/canonical KB rows created by the suite.
- The broader sandbox-first Cory-style benchmark has a full-catalog mixed-evidence score: real retained live Telegram evidence for `OE-01` through `OE-05`, sandbox fixture replies for `CS-01` through `CS-09`, and no-context direct-claim expected-answer/follow-up fixtures for `DC-01` through `DC-06`, `20/20` passing. This is not a live Telegram run for the CS/DC prompts. - The broader sandbox-first m3taversal-standard benchmark has a full-catalog mixed-evidence score: real retained live Telegram evidence for `OE-01` through `OE-05`, sandbox fixture replies for `CS-01` through `CS-09`, and no-context direct-claim expected-answer/follow-up fixtures for `DC-01` through `DC-06`, `20/20` passing. This is not a live Telegram run for the CS/DC prompts.
- After deploy commit `0183a5c805fa3b51d638267afd20f67a1bc3777f`, three fresh VPS GatewayRunner clean-session trials strict-scored `6/6` (`18/18` replies). Every trial posted nothing, made no live profile or production DB change, preserved counts (`1837/4145/4916/4670/26`), removed its temp profile, and left `leoclean-gateway.service` active/running with PID `2403328`, zero restarts, and the same start timestamp. Final cleanup found no matching temp directories. - After deploy commit `0183a5c805fa3b51d638267afd20f67a1bc3777f`, three fresh VPS GatewayRunner clean-session trials strict-scored `6/6` (`18/18` replies). Every trial posted nothing, made no live profile or production DB change, preserved counts (`1837/4145/4916/4670/26`), removed its temp profile, and left `leoclean-gateway.service` active/running with PID `2403328`, zero restarts, and the same start timestamp. Final cleanup found no matching temp directories.
- Intentional restart survival is now live-proven as a separate required proof row, not implied by `NRestarts=0`: `systemctl restart leoclean-gateway.service` returned `0`, service moved from `MainPID=1908033` to `MainPID=2845730`, stayed active/running after restart and after the no-post handler smoke, canonical DB counts stayed unchanged (`1837/4145/4670/4916/26`), no Telegram post or production DB apply ran, no live profile change was recorded, temp profile cleanup succeeded, and the post-restart no-post `DC-01` through `DC-06` handler smoke returned six runtime replies. The retained pre-repair post-restart strict score was `5/6`; after deploying repair SHA `090becae1621436467610e529d6328d70964d11f`, the same no-post direct-claim suite strict-scored `6/6` with `DC-01` through `DC-06` all passing, DB counts unchanged, no Telegram post, no production DB apply, no live profile change, and cleanup confirmed. The raw handler JSON is retained on the VPS at `/tmp/leo-post-skill-repair-direct-claim-current.json` with SHA256 `6fffdbafc18913c4fc62feb00906988dee2e696d279f22dd284951a79451f39c`. - Intentional restart survival is now live-proven as a separate required proof row, not implied by `NRestarts=0`: `systemctl restart leoclean-gateway.service` returned `0`, service moved from `MainPID=1908033` to `MainPID=2845730`, stayed active/running after restart and after the no-post handler smoke, canonical DB counts stayed unchanged (`1837/4145/4670/4916/26`), no Telegram post or production DB apply ran, no live profile change was recorded, temp profile cleanup succeeded, and the post-restart no-post `DC-01` through `DC-06` handler smoke returned six runtime replies. The retained pre-repair post-restart strict score was `5/6`; after deploying repair SHA `090becae1621436467610e529d6328d70964d11f`, the same no-post direct-claim suite strict-scored `6/6` with `DC-01` through `DC-06` all passing, DB counts unchanged, no Telegram post, no production DB apply, no live profile change, and cleanup confirmed. The raw handler JSON is retained on the VPS at `/tmp/leo-post-skill-repair-direct-claim-current.json` with SHA256 `6fffdbafc18913c4fc62feb00906988dee2e696d279f22dd284951a79451f39c`.
- The Telegram-visible direct-claim benchmark was run in group `Leo` (`-5146042086`): all six prompts and replies are visible, and DB/service state is unchanged. The hardened semantic scorer gives `5/6`; `DC-05` incorrectly suggests applying the strict canary `add_edge` path to one of three legacy approved proposals whose payload types do not all match. - The Telegram-visible direct-claim benchmark was run in group `Leo` (`-5146042086`): all six prompts and replies are visible, and DB/service state is unchanged. The hardened semantic scorer gives `5/6`; `DC-05` incorrectly suggests applying the strict canary `add_edge` path to one of three legacy approved proposals whose payload types do not all match.
@ -364,7 +388,7 @@ Newest artifacts:
- Latest cleanup readback found no leftover rehearsal/clone/staging database names on the VPS Postgres container and did not mutate production DB or post to Telegram. - Latest cleanup readback found no leftover rehearsal/clone/staging database names on the VPS Postgres container and did not mutate production DB or post to Telegram.
- A live Telegram regression canary should be rerun after any production apply; no production apply has been authorized or executed. - A live Telegram regression canary should be rerun after any production apply; no production apply has been authorized or executed.
- GCP control-plane Chrome readback now proves project `teleo-501523`, running VM `teleo-prod-1` in `europe-west6-a`, and one available private-only PostgreSQL `16.14` Cloud SQL instance, `teleo-pgvector-standby`, in `europe-west6-c`. Cloud SQL Studio is reachable but exposes no enabled existing IAM database principal and requires built-in password authentication; no credential was submitted and no SQL ran. Database-row/runtime/DC-01-through-DC-06 parity therefore remains unproven. The exact next gate is an already-existing authenticated Studio principal or a separately authorized IAM/database-user enablement window. - GCP control-plane Chrome readback now proves project `teleo-501523`, running VM `teleo-prod-1` in `europe-west6-a`, and one available private-only PostgreSQL `16.14` Cloud SQL instance, `teleo-pgvector-standby`, in `europe-west6-c`. Cloud SQL Studio is reachable but exposes no enabled existing IAM database principal and requires built-in password authentication; no credential was submitted and no SQL ran. Database-row/runtime/DC-01-through-DC-06 parity therefore remains unproven. The exact next gate is an already-existing authenticated Studio principal or a separately authorized IAM/database-user enablement window.
- GCP Console observability now separately proves `teleo-prod-1` is running and that serial output through `2026-07-10T15:57:54Z` contains recurring successful `leoclean-cloudsql-memory-sync.service` cycles. The latest exact `leoclean-gcp-prod-parallel.service` lifecycle event in the retained serial buffer is a Hermes start on July 9 with no later exact stop/failure. Cloud Logging has `92` guest/platform records over seven days but zero matches for `leoclean`, `hermes`, `gateway`, `postgres`, or `teleo-kb`, and Ops Agent is absent. This is bounded unit-activity evidence, not current PID/restart/SHA/profile/model/auth/Telegram/DB-row parity; no-post Cory execution remains unsafe and was not attempted. The agent-created Console tab was closed and no GCP/DB/service/IAM/deploy/credential/Telegram mutation occurred. - GCP Console observability now separately proves `teleo-prod-1` is running and that serial output through `2026-07-10T15:57:54Z` contains recurring successful `leoclean-cloudsql-memory-sync.service` cycles. The latest exact `leoclean-gcp-prod-parallel.service` lifecycle event in the retained serial buffer is a Hermes start on July 9 with no later exact stop/failure. Cloud Logging has `92` guest/platform records over seven days but zero matches for `leoclean`, `hermes`, `gateway`, `postgres`, or `teleo-kb`, and Ops Agent is absent. This is bounded unit-activity evidence, not current PID/restart/SHA/profile/model/auth/Telegram/DB-row parity; no-post m3taversal-standard execution remains unsafe and was not attempted. The agent-created Console tab was closed and no GCP/DB/service/IAM/deploy/credential/Telegram mutation occurred.
- PR #77 auto-deployed to the VPS checkout at merge `1a0abd882d00c1b58fe203f42de42d4eeea61cbf` without restarting Leo: the deploy journal says `No Python changes - services not restarted`, the gateway remained PID `2999690` with `NRestarts=0`, and the apply worker/timer remained disabled and inactive. This proves source synchronization and runtime non-change, not a GCP replay. - PR #77 auto-deployed to the VPS checkout at merge `1a0abd882d00c1b58fe203f42de42d4eeea61cbf` without restarting Leo: the deploy journal says `No Python changes - services not restarted`, the gateway remained PID `2999690` with `NRestarts=0`, and the apply worker/timer remained disabled and inactive. This proves source synchronization and runtime non-change, not a GCP replay.
- A passwordless GCP operator is implemented and locally validated but is not yet bootstrapped in project `teleo-501523`. It uses GitHub OIDC/Workload Identity Federation, separate status and clone-operation service accounts, IAP TCP forwarding, OS Login, five-minute SSH keys, and a root-owned dispatcher limited to `status`, `direct-claim-replay`, and `cleanup-clone`. It stores no Google password, local refresh token, service-account JSON key, or API key. One final authenticated GCP admin session is still required to install and verify the IAM/IAP/OS Login/dispatcher path; the old public `/32` rule must remain enabled until the workflow status artifact passes. - A passwordless GCP operator is implemented and locally validated but is not yet bootstrapped in project `teleo-501523`. It uses GitHub OIDC/Workload Identity Federation, separate status and clone-operation service accounts, IAP TCP forwarding, OS Login, five-minute SSH keys, and a root-owned dispatcher limited to `status`, `direct-claim-replay`, and `cleanup-clone`. It stores no Google password, local refresh token, service-account JSON key, or API key. One final authenticated GCP admin session is still required to install and verify the IAM/IAP/OS Login/dispatcher path; the old public `/32` rule must remain enabled until the workflow status artifact passes.
- The broader GCP working-Leo runner now has a complete `20`-prompt catalog and requires `32` GCP-executable non-tautological composition checks plus lifecycle, role-separation, immutable-source, and secret-redaction gates. Local tests and validation-only execution pass, and an independent VPS source baseline is retained with counts `1837/4145/4670/4916/17/26`; live GCP execution remains unproven because the SHA-bound target-identity receipt, four separated database roles/credentials, and passwordless operator bootstrap are not yet present. This does not inherit or claim the VPS-only `34/34` result. - The broader GCP working-Leo runner now has a complete `20`-prompt catalog and requires `32` GCP-executable non-tautological composition checks plus lifecycle, role-separation, immutable-source, and secret-redaction gates. Local tests and validation-only execution pass, and an independent VPS source baseline is retained with counts `1837/4145/4670/4916/17/26`; live GCP execution remains unproven because the SHA-bound target-identity receipt, four separated database roles/credentials, and passwordless operator bootstrap are not yet present. This does not inherit or claim the VPS-only `34/34` result.

View file

@ -1,18 +1,20 @@
# Fable / Worker Onboarding Prompt - Leo / Teleo # Fable / Worker Onboarding Prompt - Leo / Teleo
current_canary: read the retained evidence index, then produce a repo/VPS/GCP/Telegram working-state map with exact claim ceilings and next executable action. current_canary: validate the repo-native skill routes, then produce a repo/VPS/GCP/Telegram working-state map with exact claim ceilings and next executable action.
Use the Teleo repo skill pack at: Use the Teleo repo skill pack at:
`.agents/skills/` `.agents/skills/`
Load these draft skills first: Run `.agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py --root .`,
then load these manifest-indexed skills first:
1. `skills/teleo-leo-onboarding/SKILL.md` 1. `.agents/skills/teleo-leo-onboarding/SKILL.md`
2. `skills/working-leo-m3taversal-outcomes/SKILL.md` 2. `.agents/skills/working-leo-m3taversal-outcomes/SKILL.md`
3. `skills/teleo-kb-db-change-workflow/SKILL.md` 3. `.agents/skills/teleo-kb-db-change-workflow/SKILL.md`
4. `skills/teleo-vps-runtime-ops/SKILL.md` 4. `.agents/skills/teleo-reconstruction-recovery/SKILL.md`
5. `skills/teleo-proof-handoff/SKILL.md` 5. `.agents/skills/teleo-vps-runtime-ops/SKILL.md`
6. `.agents/skills/teleo-proof-handoff/SKILL.md`
Hard constraints: Hard constraints:

View file

@ -1,6 +1,7 @@
# Leo Architecture, Work, And Outcomes # Leo Architecture, Work, And Outcomes
Current as of `2026-07-14 01:40 UTC`. Original delivery summary from `2026-07-14 01:40 UTC`, reconciled with merged
repository truth on 2026-07-15.
This is the executive summary of what Leo is, how its knowledge system works, This is the executive summary of what Leo is, how its knowledge system works,
what changed during the July 10-14 delivery wave, what is genuinely working, what changed during the July 10-14 delivery wave, what is genuinely working,
@ -17,10 +18,16 @@ managed gateway restart. The current broad no-post suite passes `15/15`.
**The whole system is not complete.** The current broad suite has not yet been **The whole system is not complete.** The current broad suite has not yet been
repeated visibly in the real Telegram group through authenticated Google Chrome. repeated visibly in the real Telegram group through authenticated Google Chrome.
The newest post-V3 database copy has not yet been restored and replayed on GCP. The newest post-V3 database copy has since been restored to a disposable private
No V3 production proposal has been canonically applied. A snapshot can rebuild GCP Cloud SQL clone with exact parity and a bounded no-send reasoning replay,
the current database exactly, but the entire historical database cannot yet be then cleaned up. Persistent GCP remains staging and older than that disposable
recompiled from raw documents and review history alone. proof point. No V3 production proposal has been canonically applied. A snapshot
can rebuild the current database exactly, and merged PR #146 adds an exact
insert-only genesis-plus-ledger slice; the entire historical database still
cannot be recompiled from raw documents and review history alone.
Repository reconciliation: PRs #146 and #147 are merged `main` truth. PR #148
remains an open least-privilege GCP candidate and is not canonical runtime proof.
## The Architecture ## The Architecture
@ -255,7 +262,8 @@ left the gateway unchanged, and removed the private receipt afterward.
| Grounded proposal staging | live VPS `pending_review` row | Achieved | | Grounded proposal staging | live VPS `pending_review` row | Achieved |
| Exact snapshot rebuild | isolated local Postgres, `52,167` rows | Achieved | | Exact snapshot rebuild | isolated local Postgres, `52,167` rows | Achieved |
| New strict-apply row receipt | deployed VPS read-only recovery | Achieved | | New strict-apply row receipt | deployed VPS read-only recovery | Achieved |
| Prior GCP database copy and six-question replay | private Cloud SQL and GCP compute | Achieved at the earlier `52,164`-row proof point | | Current disposable GCP copy and ID-free replay | private Cloud SQL and GCP compute, `52,167/52,167` rows | Achieved and cleaned up |
| Genesis plus strict insert-only replay | isolated local Postgres through merged PR #146 | Achieved for supported strict contracts |
## What Is Not Achieved ## What Is Not Achieved
@ -263,9 +271,9 @@ left the gateway unchanged, and removed the private receipt afterward.
| --- | --- | | --- | --- |
| Current broad Telegram-visible proof | Telegram Web in the connected Google Chrome is not authenticated; handler proof is not visible-chat proof | | Current broad Telegram-visible proof | Telegram Web in the connected Google Chrome is not authenticated; handler proof is not visible-chat proof |
| V3 production canonical apply | proposal remains `pending_review`; no review or apply was authorized | | V3 production canonical apply | proposal remains `pending_review`; no review or apply was authorized |
| Current GCP parity | the `52,167`-row post-V3 snapshot has not yet been restored and replayed on GCP |
| Arbitrary automatic document/post/tweet intake | the current source command handles one bounded text-like artifact; general fetch/extract/stage automation is not complete | | Arbitrary automatic document/post/tweet intake | the current source command handles one bounded text-like artifact; general fetch/extract/stage automation is not complete |
| Full source-to-blank-DB recompilation | historical provenance gaps remain and the genesis-plus-ledger replay runner is not finished | | Persistent GCP parity and promotion | the disposable `52,167`-row proof passed, but persistent `teleo_canonical` remains the older staging copy and is not cut over |
| Full source-to-blank-DB recompilation | historical provenance gaps and unsupported mutating contracts remain beyond the merged insert-only genesis-plus-ledger slice |
| General DB-to-identity rendering | no complete scheduled DB-to-`SOUL.md` renderer is proven | | General DB-to-identity rendering | no complete scheduled DB-to-`SOUL.md` renderer is proven |
| Deployed decision matrix | matrix tables and voting flow are absent from the current live schema | | Deployed decision matrix | matrix tables and voting flow are absent from the current live schema |
@ -282,13 +290,13 @@ left the gateway unchanged, and removed the private receipt afterward.
## How This Moves GCP Forward ## How This Moves GCP Forward
- The prior GCP vertical slice proved the architecture can run against private - The current post-V3 snapshot has been restored to a disposable private Cloud
Cloud SQL and real GCP compute. SQL clone with exact parity, bounded no-send replay, and cleanup.
- The current post-V3 dump and manifest are already captured and locally - Persistent `teleo_canonical` remains the older staging copy; promotion,
verified, so GCP work starts from a known input rather than rebuilding one. continuous replication, Telegram delivery, and production cutover are
- The same `15/15` suite and exact V3 question are ready for replay. separate decisions and proof rows.
- The remaining GCP work is operational: authenticate, restore the current copy, - Open PR #148 proposes least-privilege runtime access. Its branch and proposed
verify parity/private connectivity/performance, replay, and clean up. live end state remain candidate evidence until merge and receipt verification.
## How This Moves On-Demand Rebuild Forward ## How This Moves On-Demand Rebuild Forward
@ -311,10 +319,11 @@ verified post-V3 snapshot = genesis epoch
-> broad answer benchmark -> broad answer benchmark
``` ```
The new receipt path closes the future side of this model. The next repo-owned The new receipt path closes the future side of this model. Merged PR #146 now
step is to replay one reviewed `approve_claim` receipt onto a clean genesis clone replays supported strict insert-only receipts on a clean genesis clone and proves
and prove exact post-apply parity. Historical import gaps can then be repaired exact post-apply parity. The next reconstruction work is to retain complete
without allowing new gaps to accumulate. deltas for mutating contracts, handle or reject legacy freeform applies, and
repair historical import gaps without allowing new gaps to accumulate.
## Delivery Chain ## Delivery Chain
@ -333,16 +342,21 @@ The latest coherent delivery sequence is merged:
| `#135` | current post-V3 snapshot and exact rebuild proof | | `#135` | current post-V3 snapshot and exact rebuild proof |
| `#136` | private replay receipts for guarded applies | | `#136` | private replay receipts for guarded applies |
| `#137` | deployed receipt runtime proof | | `#137` | deployed receipt runtime proof |
| `#144` | GCP database-first restore, fail-closed helper, and live restart proof |
| `#146` | unified turn manifest and deterministic genesis-plus-ledger replay |
| `#147` | unseen-reasoning verifier hardened for valid reasoning variance |
PR #148 is open candidate work and is intentionally excluded from the merged
delivery chain above.
## Immediate Next Outcomes ## Immediate Next Outcomes
1. Authenticate Telegram Web in the connected Google Chrome and run visible, 1. Authenticate Telegram Web in the connected Google Chrome and run visible,
out-of-sample m3taversal-style questions. out-of-sample m3taversal-style questions.
2. Authenticate Google Cloud CLI through the connected Chrome flow, restore the 2. Review and merge or reject PR #148, then verify the least-privilege runtime
current post-V3 snapshot to disposable GCP staging, verify parity, replay the receipt before considering any persistent GCP promotion.
broad suite, and remove temporary resources. 3. Extend genesis-plus-receipt reconstruction beyond supported insert-only
3. Complete the genesis-plus-receipt replayer for `approve_claim` bundles and contracts while retaining exact before/after deltas.
prove exact clone-to-replay parity.
4. Run one explicitly reviewed source packet through guarded apply in a 4. Run one explicitly reviewed source packet through guarded apply in a
disposable clone before seeking any production apply authorization. disposable clone before seeking any production apply authorization.
5. Reconstruct the remaining historical source, evidence, and edge provenance. 5. Reconstruct the remaining historical source, evidence, and edge provenance.
@ -363,7 +377,8 @@ The latest coherent delivery sequence is merged:
The last three days produced a stable, testable, database-grounded Leo on the The last three days produced a stable, testable, database-grounded Leo on the
VPS at the handler tier, a real source-to-review path, exact snapshot recovery, VPS at the handler tier, a real source-to-review path, exact snapshot recovery,
and durable replay evidence for future strict applies. They did not complete and durable replay evidence for future strict applies. Subsequent work added
current Telegram-visible broad proof, current GCP parity, a V3 production apply, disposable current GCP parity plus no-send replay and an exact insert-only
general automatic source ingestion, or full historical source-derived database genesis-plus-ledger slice. The system still lacks current Telegram-visible broad
recompilation. proof, persistent GCP parity/promotion, a V3 production apply, general automatic
source ingestion, and full historical source-derived database recompilation.

View file

@ -0,0 +1,332 @@
{
"actual_hosted_model_call_performed": false,
"behavior_observation_before_compile": {
"behavior_sha256": "693a5d542e3d817c1c77c8aa3180f14d5f98ec1e71f5e4313685b4da70b489aa",
"identity_runtime_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159",
"source_commit": "b238fd6fc2636ed3582e14900774014c52732698"
},
"claim_ceiling": "Local first-process and pre-restart drift-refusal component only; no successful restart proof, GatewayRunner, hosted model, production database, VPS, or T3 claim.",
"cleanup": {
"no_profile_retained": true,
"temporary_root_removed": true
},
"compile": {
"compiled_view_sha256": {
"SOUL.md": "83d27dba6e1b160085388a5dc84da565abf5736351b1af3f220d13b35aac244a",
"identity.json": "40419152862e7d9bca631c53eaa2201052cf61eafe6d304c8a302f8ea97d6fb6"
},
"generated_views_are_authority": false,
"identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"manifest_sha256": "22e66cf39b2c5aac3b4043f37aa0773b4861fec616a435e8b5e0ff8c86586bef",
"nonauthoritative_inputs_omitted": {
".cursorrules": true,
".hermes.md": true,
".skills_prompt_snapshot.json": true,
"AGENTS.md": true,
"CLAUDE.md": true,
"HERMES.md": true,
"MEMORY.md": true,
"USER.md": true,
"memories": true,
"platforms/pairing": true
},
"profile_static_entries": [
"config.yaml",
"skills",
"plugins",
"bin"
],
"runtime_identity_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159",
"schema": "livingip.leoIdentityCompileReceipt.v1",
"session_directories_started_empty": true,
"status": "pass"
},
"compiled_profile_before_query": {
"behavior_sha256": "a62b26015a7c9506f0296404be150608a816a2d545f471f7960bd27324d6849c",
"identity_runtime_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159"
},
"current_tier": "T1_model",
"drift_target": "compiled SOUL.md generated view",
"errors": [],
"first_start": {
"actual_argv_persisted": false,
"command_serialization": "logical_redacted_v1",
"launcher_pid": 80040,
"logical_command": [
"<python>",
"-m",
"scripts.leo_identity_profile",
"query",
"--profile",
"<temporary-profile>",
"--source-root",
".",
"--hermes-root",
"fixtures/working-leo/leo-identity-v1/hermes-runtime",
"--deployment-root",
".",
"--query",
"What defines Leo's identity, and what is temporary?"
],
"orphan_cleanup_required": false,
"process_group_absent_after_wait": true,
"profile_role": "first_start",
"returncode": 0,
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"stdout": {
"answer": "Leo is defined by 3 pinned static constitutional rules and 5 active database-derived identity rows from a synthetic noncanonical fixture at fingerprint 1111111111111111111111111111111111111111111111111111111111111111. SOUL.md is a generated view; runtime/session memory is temporary, noncanonical, and cannot be evidence.",
"answer_sha256": "e0a21e1fc5357a2f358b4e96c52e971f3addee2468e44748d898adfd62dafa25",
"authorization": {
"authorization_decision_observed": false,
"claim": "local_policy_binding_not_an_authorizer_readback",
"declared_runtime_policy": {
"allowed_tools": [
"identity_readback"
],
"database_write_enabled": false,
"network_send_enabled": false
}
},
"identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"manifest_sha256": "22e66cf39b2c5aac3b4043f37aa0773b4861fec616a435e8b5e0ff8c86586bef",
"output_provenance": {
"actual_model_call_performed": false,
"compiled_identity_sha256": "40419152862e7d9bca631c53eaa2201052cf61eafe6d304c8a302f8ea97d6fb6",
"compiled_soul_sha256": "83d27dba6e1b160085388a5dc84da565abf5736351b1af3f220d13b35aac244a",
"database_authority": "synthetic_noncanonical_fixture",
"database_canonical_authority_granted": false,
"database_fingerprint_sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"database_identity_sha256": "70aaa7287cc41b52a3c902cf2e1b90fa4d84a5ee0a61e10c642f556fcc9304c3",
"runtime_identity_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159",
"static_constitution_sha256": "b576d5cee08530a95e0b196a3296f4743b70d94bcadffaa36544dd6bf1387f8a"
},
"process_id": 80040,
"query": "What defines Leo's identity, and what is temporary?",
"query_sha256": "13704c2c9ae999e3f9b3f1c9c5572d062cd7fe49903c2317fa85aaa39490af66",
"runtime_instance_id": "493f274a5f0340a2aa675f13b8e5b4af",
"schema": "livingip.leoIdentityQueryReceipt.v1",
"session": {
"classification": "temporary_noncanonical",
"included_in_output_provenance": false,
"may_be_used_as_evidence": false,
"record_sha256": "56b6a2ea25657a87dc90dc19f49bece0ac62241f5814732ed80ef4f34d426d84"
},
"started_at_utc": "2026-07-15T02:46:34.316819+00:00",
"status": "pass"
},
"terminated_with": null,
"timed_out": false
},
"fixed_query": "What defines Leo's identity, and what is temporary?",
"fixed_query_sha256": "13704c2c9ae999e3f9b3f1c9c5572d062cd7fe49903c2317fa85aaa39490af66",
"gates": {
"drift_detected_before_restart": true,
"drift_process_had_no_orphan_cleanup": true,
"drift_process_stopped": true,
"drift_returned_no_answer": true,
"first_process_stopped": true,
"first_start_passed": true,
"second_start_not_attempted": true
},
"generated_at_utc": "2026-07-15T02:46:31.831631+00:00",
"goal_tier_satisfied": false,
"manifest": {
"compiled_views": {
"SOUL.md": {
"generated_from_identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"role": "generated_view_not_authority",
"sha256": "83d27dba6e1b160085388a5dc84da565abf5736351b1af3f220d13b35aac244a"
},
"identity.json": {
"generated_from_identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"role": "generated_view_not_authority",
"sha256": "40419152862e7d9bca631c53eaa2201052cf61eafe6d304c8a302f8ea97d6fb6"
}
},
"identity_inputs": {
"canonical_database": {
"authority": "synthetic_noncanonical_fixture",
"canonical_authority_granted": false,
"database": "leo_identity_fixture",
"database_user": "leo_identity_reader",
"fingerprint_sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"source": {
"record_count": 7,
"repo_path": "fixtures/working-leo/leo-identity-v1/leo-database-fingerprint-v1.json",
"semantic_sha256": "c5bbf346613270a5e3b17f604f69306ed42f545d4f227d784ec0dcb3d675dcb2"
},
"structure_sha256": "3333333333333333333333333333333333333333333333333333333333333333",
"system_identifier": "7649789040005668902",
"table_count": 7,
"table_rows_sha256": "2222222222222222222222222222222222222222222222222222222222222222",
"total_rows": 7
},
"gatewayrunner_execution_contract": {
"fixed_message_context": {
"auto_skill": null,
"media_or_file_context": null,
"reply_context": null
},
"profile_surfaces": [
"config.yaml",
"generated SOUL.md",
"skills",
"plugins",
"bin tools"
],
"required_absent_or_empty": {
"generated_skill_prompt_cache": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
"pairing_store": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
"persistent_memory": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
"prior_sessions_at_first_start": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
"project_context": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945"
},
"required_t3_turn_receipt_fields": [
"runner_class",
"authorization_decision",
"effective_system_prompt_sha256",
"compiled_skills_prompt_sha256",
"tool_registry_schema_sha256",
"plugin_registry_sha256",
"selected_model",
"selected_provider",
"api_mode",
"base_url_host",
"database_retrieval_receipt",
"session_key_sha256",
"persisted_session_id_sha256"
]
},
"identity_name": "Leo",
"identity_sources": {
"database_derived_identity": {
"authority": "synthetic_noncanonical_fixture",
"content_sha256": "9de2dfa37529b23ba277348f3d910e967551e490a9b4d2be637bf45bb2aa7dde",
"database_fingerprint_sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"provenance": {
"authority": "synthetic_noncanonical_fixture",
"canonical_authority_granted": false,
"export_receipt_sha256": null,
"mode": "synthetic_noncanonical_fixture",
"same_transaction_as_fingerprint": false
},
"record_count": 5,
"repo_path": "fixtures/working-leo/leo-identity-v1/leo-database-identity-v1.json",
"semantic_sha256": "70aaa7287cc41b52a3c902cf2e1b90fa4d84a5ee0a61e10c642f556fcc9304c3"
},
"static_constitution": {
"authority": "pinned_static_source",
"content_sha256": "b5477e778a2be0abba783390dac2e04ed199b8ce5679fc324270f808d46543f1",
"record_count": 3,
"repo_path": "fixtures/working-leo/leo-identity-v1/leo-constitution-v1.json",
"semantic_sha256": "b576d5cee08530a95e0b196a3296f4743b70d94bcadffaa36544dd6bf1387f8a"
}
},
"model": {
"actual_model_required_in_turn_receipt": true,
"default_model": "leo-identity-readback-v1",
"gateway_smart_model_routing": null,
"hosted_weights": "external_provider_managed_not_locally_hashable",
"model_section_sha256": "90b3943ace9ff83b1711002fda8dc9736448e8d3c1c58a17ac90608f4ce58756",
"provider": "fixture-local",
"smart_routing": false,
"smart_routing_model": null
},
"permissions": {
"authorization_decision_required_in_runtime_receipt": true,
"gateway_permissions_sha256": "eac17ada1d02b5413183587d12fc265538479de00709ed8c275e9045cd720290",
"identity_config_sha256": "e6df9b65bab148ea8502555bbc260df66b4785e7dd527cfd15d2f0a48c2e8b3e",
"runtime_policy": {
"allowed_tools": [
"identity_readback"
],
"database_write_enabled": false,
"network_send_enabled": false
},
"tool_permissions_sha256": "9bb2cec2f65d43efb597a72bdced44076c25aac292f2fccbc4c448b6e7fd3e16"
},
"runtime": {
"hermes_git_head": "b238fd6fc2636ed3582e14900774014c52732698",
"hermes_source_sha256": "dcf8109051e0b69cafe2e8dd328ff501211b62ea19725416c3781bbdd594d028",
"identity_runtime_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159",
"python": {
"abi_tag": "cpython-311",
"implementation": "CPython",
"python_version": "3.11.15",
"runtime_distributions": {
"PyYAML": "6.0.3"
},
"runtime_distributions_sha256": "57a91bb880a01800903c1604b6eec1419514864ebd6a0644121920da15a8f165"
},
"teleo_git_head": "b238fd6fc2636ed3582e14900774014c52732698",
"teleo_source_sha256": "2bd2e659eafb0ac0823f7f51c4296b2eb500b6f74469b3ac5f5287a5d4810aea"
},
"session_boundary": {
"classification": "temporary_noncanonical",
"included_in_identity_inputs": false,
"may_be_used_as_evidence": false,
"restart_policy": "fresh_process_with_session_state_outside_identity_authority"
},
"skills": {
"content_sha256": "d3f449ddcd7c88238dc88c6233cf2130875f51bd2e0911b2ce477b7c602ae90f",
"file_count": 1
},
"source_commit": "b238fd6fc2636ed3582e14900774014c52732698"
},
"identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"manifest_sha256": "22e66cf39b2c5aac3b4043f37aa0773b4861fec616a435e8b5e0ff8c86586bef",
"schema": "livingip.leoIdentityManifest.v1"
},
"mode": "drift_before_restart",
"pre_restart_drift": {
"actual_argv_persisted": false,
"command_serialization": "logical_redacted_v1",
"launcher_pid": 80246,
"logical_command": [
"<python>",
"-m",
"scripts.leo_identity_profile",
"query",
"--profile",
"<temporary-profile>",
"--source-root",
".",
"--hermes-root",
"fixtures/working-leo/leo-identity-v1/hermes-runtime",
"--deployment-root",
".",
"--query",
"What defines Leo's identity, and what is temporary?"
],
"orphan_cleanup_required": false,
"process_group_absent_after_wait": true,
"profile_role": "pre_restart_drift",
"returncode": 3,
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"stdout": {
"error": "identity_drift",
"message": "compiled view drift detected: SOUL.md",
"status": "error"
},
"terminated_with": null,
"timed_out": false
},
"production_database_contacted": false,
"production_profile_replaced": false,
"receipt_sha256": "50278cc740d0427316f73a78abad840b3e3b128a516f464001d42e632e19c2a8",
"required_tier": "T2_runtime",
"runtime_component_proven": "first_local_process_plus_pre_restart_drift_refusal",
"runtime_variant": "local_deterministic_identity_compiler_readback",
"schema": "livingip.leoIdentityReconstructionReceipt.v1",
"second_start_attempted": false,
"session_boundary_readback": {
"full_behavior_changed_after_session": true,
"identity_runtime_unchanged_after_session": true,
"session_classification": "temporary_noncanonical",
"session_file_count": 1,
"session_used_as_output_provenance": false
},
"status": "pass",
"telegram_message_sent": false,
"tier_basis": "This negative component does not complete the required restart path, so it remains below T2_runtime."
}

View file

@ -0,0 +1,478 @@
{
"actual_hosted_model_call_performed": false,
"behavior_observation_before_compile": {
"behavior_sha256": "693a5d542e3d817c1c77c8aa3180f14d5f98ec1e71f5e4313685b4da70b489aa",
"identity_runtime_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159",
"source_commit": "b238fd6fc2636ed3582e14900774014c52732698"
},
"claim_ceiling": "Local disposable identity compilation, fresh-profile reconstruction, and cold-process restart only; not a live GatewayRunner, hosted-model, Telegram, production database, VPS restart, or T3 proof.",
"cleanup": {
"no_profile_retained": true,
"temporary_root_removed": true
},
"compile": {
"compiled_view_sha256": {
"SOUL.md": "83d27dba6e1b160085388a5dc84da565abf5736351b1af3f220d13b35aac244a",
"identity.json": "40419152862e7d9bca631c53eaa2201052cf61eafe6d304c8a302f8ea97d6fb6"
},
"generated_views_are_authority": false,
"identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"manifest_sha256": "22e66cf39b2c5aac3b4043f37aa0773b4861fec616a435e8b5e0ff8c86586bef",
"nonauthoritative_inputs_omitted": {
".cursorrules": true,
".hermes.md": true,
".skills_prompt_snapshot.json": true,
"AGENTS.md": true,
"CLAUDE.md": true,
"HERMES.md": true,
"MEMORY.md": true,
"USER.md": true,
"memories": true,
"platforms/pairing": true
},
"profile_static_entries": [
"config.yaml",
"skills",
"plugins",
"bin"
],
"runtime_identity_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159",
"schema": "livingip.leoIdentityCompileReceipt.v1",
"session_directories_started_empty": true,
"status": "pass"
},
"compiled_profile_before_query": {
"behavior_sha256": "a62b26015a7c9506f0296404be150608a816a2d545f471f7960bd27324d6849c",
"identity_runtime_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159"
},
"current_tier": "T2_runtime",
"drift_compile": {
"compiled_view_sha256": {
"SOUL.md": "83d27dba6e1b160085388a5dc84da565abf5736351b1af3f220d13b35aac244a",
"identity.json": "40419152862e7d9bca631c53eaa2201052cf61eafe6d304c8a302f8ea97d6fb6"
},
"generated_views_are_authority": false,
"identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"manifest_sha256": "22e66cf39b2c5aac3b4043f37aa0773b4861fec616a435e8b5e0ff8c86586bef",
"nonauthoritative_inputs_omitted": {
".cursorrules": true,
".hermes.md": true,
".skills_prompt_snapshot.json": true,
"AGENTS.md": true,
"CLAUDE.md": true,
"HERMES.md": true,
"MEMORY.md": true,
"USER.md": true,
"memories": true,
"platforms/pairing": true
},
"profile_static_entries": [
"config.yaml",
"skills",
"plugins",
"bin"
],
"runtime_identity_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159",
"schema": "livingip.leoIdentityCompileReceipt.v1",
"session_directories_started_empty": true,
"status": "pass"
},
"drift_negative": {
"actual_argv_persisted": false,
"answer_returned": false,
"command_serialization": "logical_redacted_v1",
"fail_closed": true,
"launcher_pid": 80851,
"logical_command": [
"<python>",
"-m",
"scripts.leo_identity_profile",
"query",
"--profile",
"<temporary-profile>",
"--source-root",
".",
"--hermes-root",
"fixtures/working-leo/leo-identity-v1/hermes-runtime",
"--deployment-root",
".",
"--query",
"What defines Leo's identity, and what is temporary?"
],
"orphan_cleanup_required": false,
"process_group_absent_after_wait": true,
"profile_role": "drift_negative",
"returncode": 3,
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"stdout": {
"error": "identity_drift",
"message": "compiled view drift detected: SOUL.md",
"status": "error"
},
"terminated_with": null,
"timed_out": false
},
"drift_target": "compiled SOUL.md generated view",
"errors": [],
"first_start": {
"actual_argv_persisted": false,
"command_serialization": "logical_redacted_v1",
"launcher_pid": 80054,
"logical_command": [
"<python>",
"-m",
"scripts.leo_identity_profile",
"query",
"--profile",
"<temporary-profile>",
"--source-root",
".",
"--hermes-root",
"fixtures/working-leo/leo-identity-v1/hermes-runtime",
"--deployment-root",
".",
"--query",
"What defines Leo's identity, and what is temporary?"
],
"orphan_cleanup_required": false,
"process_group_absent_after_wait": true,
"profile_role": "first_start",
"returncode": 0,
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"stdout": {
"answer": "Leo is defined by 3 pinned static constitutional rules and 5 active database-derived identity rows from a synthetic noncanonical fixture at fingerprint 1111111111111111111111111111111111111111111111111111111111111111. SOUL.md is a generated view; runtime/session memory is temporary, noncanonical, and cannot be evidence.",
"answer_sha256": "e0a21e1fc5357a2f358b4e96c52e971f3addee2468e44748d898adfd62dafa25",
"authorization": {
"authorization_decision_observed": false,
"claim": "local_policy_binding_not_an_authorizer_readback",
"declared_runtime_policy": {
"allowed_tools": [
"identity_readback"
],
"database_write_enabled": false,
"network_send_enabled": false
}
},
"identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"manifest_sha256": "22e66cf39b2c5aac3b4043f37aa0773b4861fec616a435e8b5e0ff8c86586bef",
"output_provenance": {
"actual_model_call_performed": false,
"compiled_identity_sha256": "40419152862e7d9bca631c53eaa2201052cf61eafe6d304c8a302f8ea97d6fb6",
"compiled_soul_sha256": "83d27dba6e1b160085388a5dc84da565abf5736351b1af3f220d13b35aac244a",
"database_authority": "synthetic_noncanonical_fixture",
"database_canonical_authority_granted": false,
"database_fingerprint_sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"database_identity_sha256": "70aaa7287cc41b52a3c902cf2e1b90fa4d84a5ee0a61e10c642f556fcc9304c3",
"runtime_identity_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159",
"static_constitution_sha256": "b576d5cee08530a95e0b196a3296f4743b70d94bcadffaa36544dd6bf1387f8a"
},
"process_id": 80054,
"query": "What defines Leo's identity, and what is temporary?",
"query_sha256": "13704c2c9ae999e3f9b3f1c9c5572d062cd7fe49903c2317fa85aaa39490af66",
"runtime_instance_id": "4bbcaeeeb5654b69adabed33b91cf3e4",
"schema": "livingip.leoIdentityQueryReceipt.v1",
"session": {
"classification": "temporary_noncanonical",
"included_in_output_provenance": false,
"may_be_used_as_evidence": false,
"record_sha256": "56b6a2ea25657a87dc90dc19f49bece0ac62241f5814732ed80ef4f34d426d84"
},
"started_at_utc": "2026-07-15T02:46:34.391880+00:00",
"status": "pass"
},
"terminated_with": null,
"timed_out": false
},
"fixed_query": "What defines Leo's identity, and what is temporary?",
"fixed_query_sha256": "13704c2c9ae999e3f9b3f1c9c5572d062cd7fe49903c2317fa85aaa39490af66",
"gates": {
"answer_and_provenance_explainable": true,
"drift_failed_closed": true,
"drift_process_had_no_orphan_cleanup": true,
"drift_process_stopped": true,
"drift_profile_started_without_sessions": true,
"first_process_stopped": true,
"first_start_passed": true,
"identity_inputs_reproduced": true,
"manifest_generated": true,
"manifest_reproduced": true,
"pre_restart_verification_passed": true,
"query_reproduced": true,
"restart_passed": true,
"restart_process_is_distinct": true,
"restart_process_stopped": true,
"restart_profile_recompiled_from_manifest": true,
"restart_profile_started_without_sessions": true,
"session_excluded_from_identity": true,
"views_compiled_and_bound": true
},
"generated_at_utc": "2026-07-15T02:46:31.346851+00:00",
"goal_tier_satisfied": true,
"manifest": {
"compiled_views": {
"SOUL.md": {
"generated_from_identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"role": "generated_view_not_authority",
"sha256": "83d27dba6e1b160085388a5dc84da565abf5736351b1af3f220d13b35aac244a"
},
"identity.json": {
"generated_from_identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"role": "generated_view_not_authority",
"sha256": "40419152862e7d9bca631c53eaa2201052cf61eafe6d304c8a302f8ea97d6fb6"
}
},
"identity_inputs": {
"canonical_database": {
"authority": "synthetic_noncanonical_fixture",
"canonical_authority_granted": false,
"database": "leo_identity_fixture",
"database_user": "leo_identity_reader",
"fingerprint_sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"source": {
"record_count": 7,
"repo_path": "fixtures/working-leo/leo-identity-v1/leo-database-fingerprint-v1.json",
"semantic_sha256": "c5bbf346613270a5e3b17f604f69306ed42f545d4f227d784ec0dcb3d675dcb2"
},
"structure_sha256": "3333333333333333333333333333333333333333333333333333333333333333",
"system_identifier": "7649789040005668902",
"table_count": 7,
"table_rows_sha256": "2222222222222222222222222222222222222222222222222222222222222222",
"total_rows": 7
},
"gatewayrunner_execution_contract": {
"fixed_message_context": {
"auto_skill": null,
"media_or_file_context": null,
"reply_context": null
},
"profile_surfaces": [
"config.yaml",
"generated SOUL.md",
"skills",
"plugins",
"bin tools"
],
"required_absent_or_empty": {
"generated_skill_prompt_cache": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
"pairing_store": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
"persistent_memory": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
"prior_sessions_at_first_start": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945",
"project_context": "4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945"
},
"required_t3_turn_receipt_fields": [
"runner_class",
"authorization_decision",
"effective_system_prompt_sha256",
"compiled_skills_prompt_sha256",
"tool_registry_schema_sha256",
"plugin_registry_sha256",
"selected_model",
"selected_provider",
"api_mode",
"base_url_host",
"database_retrieval_receipt",
"session_key_sha256",
"persisted_session_id_sha256"
]
},
"identity_name": "Leo",
"identity_sources": {
"database_derived_identity": {
"authority": "synthetic_noncanonical_fixture",
"content_sha256": "9de2dfa37529b23ba277348f3d910e967551e490a9b4d2be637bf45bb2aa7dde",
"database_fingerprint_sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"provenance": {
"authority": "synthetic_noncanonical_fixture",
"canonical_authority_granted": false,
"export_receipt_sha256": null,
"mode": "synthetic_noncanonical_fixture",
"same_transaction_as_fingerprint": false
},
"record_count": 5,
"repo_path": "fixtures/working-leo/leo-identity-v1/leo-database-identity-v1.json",
"semantic_sha256": "70aaa7287cc41b52a3c902cf2e1b90fa4d84a5ee0a61e10c642f556fcc9304c3"
},
"static_constitution": {
"authority": "pinned_static_source",
"content_sha256": "b5477e778a2be0abba783390dac2e04ed199b8ce5679fc324270f808d46543f1",
"record_count": 3,
"repo_path": "fixtures/working-leo/leo-identity-v1/leo-constitution-v1.json",
"semantic_sha256": "b576d5cee08530a95e0b196a3296f4743b70d94bcadffaa36544dd6bf1387f8a"
}
},
"model": {
"actual_model_required_in_turn_receipt": true,
"default_model": "leo-identity-readback-v1",
"gateway_smart_model_routing": null,
"hosted_weights": "external_provider_managed_not_locally_hashable",
"model_section_sha256": "90b3943ace9ff83b1711002fda8dc9736448e8d3c1c58a17ac90608f4ce58756",
"provider": "fixture-local",
"smart_routing": false,
"smart_routing_model": null
},
"permissions": {
"authorization_decision_required_in_runtime_receipt": true,
"gateway_permissions_sha256": "eac17ada1d02b5413183587d12fc265538479de00709ed8c275e9045cd720290",
"identity_config_sha256": "e6df9b65bab148ea8502555bbc260df66b4785e7dd527cfd15d2f0a48c2e8b3e",
"runtime_policy": {
"allowed_tools": [
"identity_readback"
],
"database_write_enabled": false,
"network_send_enabled": false
},
"tool_permissions_sha256": "9bb2cec2f65d43efb597a72bdced44076c25aac292f2fccbc4c448b6e7fd3e16"
},
"runtime": {
"hermes_git_head": "b238fd6fc2636ed3582e14900774014c52732698",
"hermes_source_sha256": "dcf8109051e0b69cafe2e8dd328ff501211b62ea19725416c3781bbdd594d028",
"identity_runtime_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159",
"python": {
"abi_tag": "cpython-311",
"implementation": "CPython",
"python_version": "3.11.15",
"runtime_distributions": {
"PyYAML": "6.0.3"
},
"runtime_distributions_sha256": "57a91bb880a01800903c1604b6eec1419514864ebd6a0644121920da15a8f165"
},
"teleo_git_head": "b238fd6fc2636ed3582e14900774014c52732698",
"teleo_source_sha256": "2bd2e659eafb0ac0823f7f51c4296b2eb500b6f74469b3ac5f5287a5d4810aea"
},
"session_boundary": {
"classification": "temporary_noncanonical",
"included_in_identity_inputs": false,
"may_be_used_as_evidence": false,
"restart_policy": "fresh_process_with_session_state_outside_identity_authority"
},
"skills": {
"content_sha256": "d3f449ddcd7c88238dc88c6233cf2130875f51bd2e0911b2ce477b7c602ae90f",
"file_count": 1
},
"source_commit": "b238fd6fc2636ed3582e14900774014c52732698"
},
"identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"manifest_sha256": "22e66cf39b2c5aac3b4043f37aa0773b4861fec616a435e8b5e0ff8c86586bef",
"schema": "livingip.leoIdentityManifest.v1"
},
"mode": "successful_restart_plus_drift_negative",
"pre_restart_verification": "pass",
"production_database_contacted": false,
"production_profile_replaced": false,
"receipt_sha256": "685641533be36b78e382dfd690bdc588bc95045379b44dd885d1d1d0ee57b507",
"required_tier": "T2_runtime",
"restart": {
"actual_argv_persisted": false,
"command_serialization": "logical_redacted_v1",
"launcher_pid": 80642,
"logical_command": [
"<python>",
"-m",
"scripts.leo_identity_profile",
"query",
"--profile",
"<temporary-profile>",
"--source-root",
".",
"--hermes-root",
"fixtures/working-leo/leo-identity-v1/hermes-runtime",
"--deployment-root",
".",
"--query",
"What defines Leo's identity, and what is temporary?"
],
"orphan_cleanup_required": false,
"process_group_absent_after_wait": true,
"profile_role": "restart",
"returncode": 0,
"stderr_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"stdout": {
"answer": "Leo is defined by 3 pinned static constitutional rules and 5 active database-derived identity rows from a synthetic noncanonical fixture at fingerprint 1111111111111111111111111111111111111111111111111111111111111111. SOUL.md is a generated view; runtime/session memory is temporary, noncanonical, and cannot be evidence.",
"answer_sha256": "e0a21e1fc5357a2f358b4e96c52e971f3addee2468e44748d898adfd62dafa25",
"authorization": {
"authorization_decision_observed": false,
"claim": "local_policy_binding_not_an_authorizer_readback",
"declared_runtime_policy": {
"allowed_tools": [
"identity_readback"
],
"database_write_enabled": false,
"network_send_enabled": false
}
},
"identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"manifest_sha256": "22e66cf39b2c5aac3b4043f37aa0773b4861fec616a435e8b5e0ff8c86586bef",
"output_provenance": {
"actual_model_call_performed": false,
"compiled_identity_sha256": "40419152862e7d9bca631c53eaa2201052cf61eafe6d304c8a302f8ea97d6fb6",
"compiled_soul_sha256": "83d27dba6e1b160085388a5dc84da565abf5736351b1af3f220d13b35aac244a",
"database_authority": "synthetic_noncanonical_fixture",
"database_canonical_authority_granted": false,
"database_fingerprint_sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"database_identity_sha256": "70aaa7287cc41b52a3c902cf2e1b90fa4d84a5ee0a61e10c642f556fcc9304c3",
"runtime_identity_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159",
"static_constitution_sha256": "b576d5cee08530a95e0b196a3296f4743b70d94bcadffaa36544dd6bf1387f8a"
},
"process_id": 80642,
"query": "What defines Leo's identity, and what is temporary?",
"query_sha256": "13704c2c9ae999e3f9b3f1c9c5572d062cd7fe49903c2317fa85aaa39490af66",
"runtime_instance_id": "109445cde86f4ac3b266930462fb62c3",
"schema": "livingip.leoIdentityQueryReceipt.v1",
"session": {
"classification": "temporary_noncanonical",
"included_in_output_provenance": false,
"may_be_used_as_evidence": false,
"record_sha256": "56b6a2ea25657a87dc90dc19f49bece0ac62241f5814732ed80ef4f34d426d84"
},
"started_at_utc": "2026-07-15T02:46:37.036778+00:00",
"status": "pass"
},
"terminated_with": null,
"timed_out": false
},
"restart_compile": {
"compiled_view_sha256": {
"SOUL.md": "83d27dba6e1b160085388a5dc84da565abf5736351b1af3f220d13b35aac244a",
"identity.json": "40419152862e7d9bca631c53eaa2201052cf61eafe6d304c8a302f8ea97d6fb6"
},
"generated_views_are_authority": false,
"identity_inputs_sha256": "c101c488a9f623b4cef841ddb561c0f289a74df54aadfdfe9b28c4b7643fec2e",
"manifest_sha256": "22e66cf39b2c5aac3b4043f37aa0773b4861fec616a435e8b5e0ff8c86586bef",
"nonauthoritative_inputs_omitted": {
".cursorrules": true,
".hermes.md": true,
".skills_prompt_snapshot.json": true,
"AGENTS.md": true,
"CLAUDE.md": true,
"HERMES.md": true,
"MEMORY.md": true,
"USER.md": true,
"memories": true,
"platforms/pairing": true
},
"profile_static_entries": [
"config.yaml",
"skills",
"plugins",
"bin"
],
"runtime_identity_sha256": "5c54248a5d1f00b35912d47d8b3045b8cfbed16ae9b86409b549ab7042f51159",
"schema": "livingip.leoIdentityCompileReceipt.v1",
"session_directories_started_empty": true,
"status": "pass"
},
"runtime_component_proven": "fresh_profile_recompile_plus_distinct_process_restart",
"runtime_variant": "local_deterministic_identity_compiler_readback",
"schema": "livingip.leoIdentityReconstructionReceipt.v1",
"second_start_attempted": true,
"session_boundary_readback": {
"full_behavior_changed_after_session": true,
"identity_runtime_unchanged_after_session": true,
"session_classification": "temporary_noncanonical",
"session_file_count": 1,
"session_used_as_output_provenance": false
},
"status": "pass",
"telegram_message_sent": false,
"tier_basis": "Capability Tier Proof defines T2_runtime as local API/runtime behavior with restart where relevant; this is compiler-process runtime proof and explicitly excludes GatewayRunner and hosted-model proof."
}

View file

@ -32,10 +32,19 @@ Always refresh before claiming current state.
## GCP ## GCP
- Project: `teleo-501523` - Project: `teleo-501523`
- Expected active account for project access: `billy@livingip.xyz` - Compute: `teleo-prod-1` in `europe-west6-a`.
- Current retained probe: local gcloud config still selects `billy@livingip.xyz` and `teleo-501523`, but this runner cannot resolve `oauth2.googleapis.com`, so parity is blocked before token refresh/project access can be rechecked. - Private Cloud SQL: `teleo-pgvector-standby`, database `teleo_canonical`.
- Current artifact: `docs/reports/leo-working-state-20260709/gcp-db-parity-current-probe-current.json` - Direct passwordless alias `ssh teleo-gcp-staging` and `sudo -n` were retained as
- Prior auth-capable artifact: `outputs/gcp-db-parity-current-blocker-20260709.json` working on 2026-07-14; always re-run the batch-mode preflight before relying on
them.
- A disposable private-TLS clone matched the current VPS snapshot at `39` tables
and `52,167` rows, then was deleted. Persistent `teleo_canonical` remains the
older staging copy and is not promoted or cut over.
- Current artifacts:
`docs/reports/leo-working-state-20260709/gcp-db-first-working-leo-20260714.md`
and `docs/reports/leo-working-state-20260709/gcp-db-first-parity-current.json`.
- PR #148 is open candidate evidence for scoped runtime access; its branch and
proposed live outcome are not canonical `main`.
## Telegram ## Telegram

View file

@ -0,0 +1,141 @@
begin;
set local standard_conforming_strings = on;
set local lock_timeout = '5s';
select pg_advisory_xact_lock(hashtextextended('proposal-rollback:' || E'edaf2c90-af15-5a2f-b6b9-fe08ab9ae81b', 0));
do $rollback$
declare
affected integer;
approval_now jsonb;
downstream_dependency_count integer;
begin
perform 1 from kb_stage.kb_proposals
where id = E'edaf2c90-af15-5a2f-b6b9-fe08ab9ae81b'::uuid
for update;
if not found then
raise exception 'proposal rollback: proposal row missing';
end if;
if not exists (
select 1 from kb_stage.kb_proposals
where id = E'edaf2c90-af15-5a2f-b6b9-fe08ab9ae81b'::uuid
and proposal_type = 'approve_claim'
and status = 'applied'
and payload = E'{"apply_payload":{"agent_id":null,"claims":[{"confidence":0.9,"created_by":null,"id":"b4d0a944-8f11-5516-80ca-bc680f0059ad","status":"open","superseded_by":null,"tags":["working-leo","clone-canary"],"text":"An approved strict proposal can create exact canonical rows atomically.","type":"structural"},{"confidence":0.85,"created_by":null,"id":"a9dd972a-b867-56f7-b3c9-3913dd9a0abe","status":"open","superseded_by":null,"tags":["working-leo","row-proof"],"text":"Row-level proof is the authority for canonical KB state.","type":"concept"}],"contract_version":2,"edges":[{"created_by":null,"edge_type":"supports","from_claim":"b4d0a944-8f11-5516-80ca-bc680f0059ad","to_claim":"a9dd972a-b867-56f7-b3c9-3913dd9a0abe","weight":0.75}],"evidence":[{"claim_id":"b4d0a944-8f11-5516-80ca-bc680f0059ad","created_by":null,"role":"grounds","source_id":"3953271f-7df5-5674-99b0-980b1b3534e6","weight":0.9},{"claim_id":"a9dd972a-b867-56f7-b3c9-3913dd9a0abe","created_by":null,"role":"illustrates","source_id":"3d31345d-a4f7-52a7-af4a-0034f99a8123","weight":0.8}],"reasoning_tools":[{"agent_id":null,"category":"verification","description":"Verify approved proposal to canonical graph lifecycle in a disposable clone.","id":"a32a7252-d39f-5ee9-873a-a82b56a6bb08","name":"Canonical row proof canary"}],"sources":[{"created_by":null,"excerpt":"Disposable clone lifecycle canary source A.","hash":"approve-claim-canary-e315c2518c-a","id":"3953271f-7df5-5674-99b0-980b1b3534e6","source_type":"observation","storage_path":null,"url":null},{"created_by":null,"excerpt":"Disposable clone lifecycle canary source B.","hash":"approve-claim-canary-e315c2518c-b","id":"3d31345d-a4f7-52a7-af4a-0034f99a8123","source_type":"observation","storage_path":null,"url":null}]}}'::jsonb
and reviewed_by_handle is not distinct from E'm3ta'
and reviewed_by_agent_id is not distinct from E'99999999-9999-9999-9999-999999999999'::uuid
and reviewed_at is not distinct from E'2026-07-15 03:59:09.091704+00'::timestamptz
and review_note is not distinct from E'Reviewed exact strict payload inside the disposable clone.'
and applied_by_handle is not distinct from E'kb-apply'
and applied_by_agent_id is not distinct from E'44444444-4444-4444-4444-444444444444'::uuid
and applied_at is not distinct from E'2026-07-15 03:59:12.452878+00'::timestamptz
) then
raise exception 'proposal rollback: applied ledger does not match apply receipt';
end if;
select jsonb_build_object(
'proposal_id', proposal_id::text,
'proposal_type', proposal_type,
'payload', payload,
'reviewed_by_handle', reviewed_by_handle,
'reviewed_by_agent_id', reviewed_by_agent_id::text,
'reviewed_by_db_role', reviewed_by_db_role::text,
'reviewed_at', reviewed_at::text,
'review_note', review_note
) into approval_now
from kb_stage.kb_proposal_approvals
where proposal_id = E'edaf2c90-af15-5a2f-b6b9-fe08ab9ae81b'::uuid;
if approval_now is distinct from E'{"payload":{"apply_payload":{"agent_id":null,"claims":[{"confidence":0.9,"created_by":null,"id":"b4d0a944-8f11-5516-80ca-bc680f0059ad","status":"open","superseded_by":null,"tags":["working-leo","clone-canary"],"text":"An approved strict proposal can create exact canonical rows atomically.","type":"structural"},{"confidence":0.85,"created_by":null,"id":"a9dd972a-b867-56f7-b3c9-3913dd9a0abe","status":"open","superseded_by":null,"tags":["working-leo","row-proof"],"text":"Row-level proof is the authority for canonical KB state.","type":"concept"}],"contract_version":2,"edges":[{"created_by":null,"edge_type":"supports","from_claim":"b4d0a944-8f11-5516-80ca-bc680f0059ad","to_claim":"a9dd972a-b867-56f7-b3c9-3913dd9a0abe","weight":0.75}],"evidence":[{"claim_id":"b4d0a944-8f11-5516-80ca-bc680f0059ad","created_by":null,"role":"grounds","source_id":"3953271f-7df5-5674-99b0-980b1b3534e6","weight":0.9},{"claim_id":"a9dd972a-b867-56f7-b3c9-3913dd9a0abe","created_by":null,"role":"illustrates","source_id":"3d31345d-a4f7-52a7-af4a-0034f99a8123","weight":0.8}],"reasoning_tools":[{"agent_id":null,"category":"verification","description":"Verify approved proposal to canonical graph lifecycle in a disposable clone.","id":"a32a7252-d39f-5ee9-873a-a82b56a6bb08","name":"Canonical row proof canary"}],"sources":[{"created_by":null,"excerpt":"Disposable clone lifecycle canary source A.","hash":"approve-claim-canary-e315c2518c-a","id":"3953271f-7df5-5674-99b0-980b1b3534e6","source_type":"observation","storage_path":null,"url":null},{"created_by":null,"excerpt":"Disposable clone lifecycle canary source B.","hash":"approve-claim-canary-e315c2518c-b","id":"3d31345d-a4f7-52a7-af4a-0034f99a8123","source_type":"observation","storage_path":null,"url":null}]}},"proposal_id":"edaf2c90-af15-5a2f-b6b9-fe08ab9ae81b","proposal_type":"approve_claim","review_note":"Reviewed exact strict payload inside the disposable clone.","reviewed_at":"2026-07-15 03:59:09.091704+00","reviewed_by_agent_id":"99999999-9999-9999-9999-999999999999","reviewed_by_db_role":"kb_review","reviewed_by_handle":"m3ta"}'::jsonb then
raise exception 'proposal rollback: immutable approval snapshot drifted';
end if;
select count(*) into downstream_dependency_count
from (
select ce.claim_id
from public.claim_evidence ce
where (ce.claim_id = any(array[E'a9dd972a-b867-56f7-b3c9-3913dd9a0abe'::uuid, E'b4d0a944-8f11-5516-80ca-bc680f0059ad'::uuid]::uuid[]) or ce.source_id = any(array[E'3953271f-7df5-5674-99b0-980b1b3534e6'::uuid, E'3d31345d-a4f7-52a7-af4a-0034f99a8123'::uuid]::uuid[]))
and not (((ce.claim_id = E'a9dd972a-b867-56f7-b3c9-3913dd9a0abe'::uuid and ce.source_id = E'3d31345d-a4f7-52a7-af4a-0034f99a8123'::uuid and ce.role = E'illustrates'::evidence_role) or (ce.claim_id = E'b4d0a944-8f11-5516-80ca-bc680f0059ad'::uuid and ce.source_id = E'3953271f-7df5-5674-99b0-980b1b3534e6'::uuid and ce.role = E'grounds'::evidence_role)))
union all
select edge.id
from public.claim_edges edge
where (edge.from_claim = any(array[E'a9dd972a-b867-56f7-b3c9-3913dd9a0abe'::uuid, E'b4d0a944-8f11-5516-80ca-bc680f0059ad'::uuid]::uuid[]) or edge.to_claim = any(array[E'a9dd972a-b867-56f7-b3c9-3913dd9a0abe'::uuid, E'b4d0a944-8f11-5516-80ca-bc680f0059ad'::uuid]::uuid[]))
and edge.id <> all(array[E'cd799806-18e8-5e8c-959c-5f9c267654a7'::uuid]::uuid[])
union all
select claim.id
from public.claims claim
where claim.superseded_by = any(array[E'a9dd972a-b867-56f7-b3c9-3913dd9a0abe'::uuid, E'b4d0a944-8f11-5516-80ca-bc680f0059ad'::uuid]::uuid[])
and claim.id <> all(array[E'a9dd972a-b867-56f7-b3c9-3913dd9a0abe'::uuid, E'b4d0a944-8f11-5516-80ca-bc680f0059ad'::uuid]::uuid[])
) external_dependencies;
if downstream_dependency_count <> 0 then
raise exception 'proposal rollback: % downstream dependenc(ies) exist; rollback quarantined', downstream_dependency_count;
end if;
if (select count(*) from public.claim_evidence t
where ((t.claim_id = E'a9dd972a-b867-56f7-b3c9-3913dd9a0abe'::uuid and t.source_id = E'3d31345d-a4f7-52a7-af4a-0034f99a8123'::uuid and t.role = E'illustrates'::evidence_role)) and to_jsonb(t) = E'{"claim_id":"a9dd972a-b867-56f7-b3c9-3913dd9a0abe","created_at":"2026-07-15T03:59:12.43629+00:00","created_by":null,"role":"illustrates","source_id":"3d31345d-a4f7-52a7-af4a-0034f99a8123","weight":0.8}'::jsonb) <> 1 then
raise exception 'proposal rollback drift: claim_evidence[0] row does not match apply receipt';
end if;
if (select count(*) from public.claim_evidence t
where ((t.claim_id = E'b4d0a944-8f11-5516-80ca-bc680f0059ad'::uuid and t.source_id = E'3953271f-7df5-5674-99b0-980b1b3534e6'::uuid and t.role = E'grounds'::evidence_role)) and to_jsonb(t) = E'{"claim_id":"b4d0a944-8f11-5516-80ca-bc680f0059ad","created_at":"2026-07-15T03:59:12.43629+00:00","created_by":null,"role":"grounds","source_id":"3953271f-7df5-5674-99b0-980b1b3534e6","weight":0.9}'::jsonb) <> 1 then
raise exception 'proposal rollback drift: claim_evidence[1] row does not match apply receipt';
end if;
if (select count(*) from public.claim_edges t
where t.id = E'cd799806-18e8-5e8c-959c-5f9c267654a7'::uuid and to_jsonb(t) = E'{"created_at":"2026-07-15T03:59:12.43629+00:00","created_by":null,"edge_type":"supports","from_claim":"b4d0a944-8f11-5516-80ca-bc680f0059ad","id":"cd799806-18e8-5e8c-959c-5f9c267654a7","to_claim":"a9dd972a-b867-56f7-b3c9-3913dd9a0abe","weight":0.75}'::jsonb) <> 1 then
raise exception 'proposal rollback drift: claim_edges[0] row does not match apply receipt';
end if;
if (select count(*) from public.reasoning_tools t
where t.id = E'a32a7252-d39f-5ee9-873a-a82b56a6bb08'::uuid and to_jsonb(t) = E'{"agent_id":null,"category":"verification","created_at":"2026-07-15T03:59:12.43629+00:00","description":"Verify approved proposal to canonical graph lifecycle in a disposable clone.","id":"a32a7252-d39f-5ee9-873a-a82b56a6bb08","name":"Canonical row proof canary"}'::jsonb) <> 1 then
raise exception 'proposal rollback drift: reasoning_tools[0] row does not match apply receipt';
end if;
if (select count(*) from public.sources t
where t.id = E'3953271f-7df5-5674-99b0-980b1b3534e6'::uuid and to_jsonb(t) = E'{"captured_at":null,"created_at":"2026-07-15T03:59:12.43629+00:00","created_by":null,"excerpt":"Disposable clone lifecycle canary source A.","hash":"approve-claim-canary-e315c2518c-a","id":"3953271f-7df5-5674-99b0-980b1b3534e6","source_type":"observation","storage_path":null,"url":null}'::jsonb) <> 1 then
raise exception 'proposal rollback drift: sources[0] row does not match apply receipt';
end if;
if (select count(*) from public.sources t
where t.id = E'3d31345d-a4f7-52a7-af4a-0034f99a8123'::uuid and to_jsonb(t) = E'{"captured_at":null,"created_at":"2026-07-15T03:59:12.43629+00:00","created_by":null,"excerpt":"Disposable clone lifecycle canary source B.","hash":"approve-claim-canary-e315c2518c-b","id":"3d31345d-a4f7-52a7-af4a-0034f99a8123","source_type":"observation","storage_path":null,"url":null}'::jsonb) <> 1 then
raise exception 'proposal rollback drift: sources[1] row does not match apply receipt';
end if;
if (select count(*) from public.claims t
where t.id = E'a9dd972a-b867-56f7-b3c9-3913dd9a0abe'::uuid and to_jsonb(t) = E'{"confidence":0.85,"created_at":"2026-07-15T03:59:12.43629+00:00","created_by":null,"id":"a9dd972a-b867-56f7-b3c9-3913dd9a0abe","status":"open","superseded_by":null,"tags":["working-leo","row-proof"],"text":"Row-level proof is the authority for canonical KB state.","type":"concept","updated_at":"2026-07-15T03:59:12.43629+00:00"}'::jsonb) <> 1 then
raise exception 'proposal rollback drift: claims[0] row does not match apply receipt';
end if;
if (select count(*) from public.claims t
where t.id = E'b4d0a944-8f11-5516-80ca-bc680f0059ad'::uuid and to_jsonb(t) = E'{"confidence":0.9,"created_at":"2026-07-15T03:59:12.43629+00:00","created_by":null,"id":"b4d0a944-8f11-5516-80ca-bc680f0059ad","status":"open","superseded_by":null,"tags":["working-leo","clone-canary"],"text":"An approved strict proposal can create exact canonical rows atomically.","type":"structural","updated_at":"2026-07-15T03:59:12.43629+00:00"}'::jsonb) <> 1 then
raise exception 'proposal rollback drift: claims[1] row does not match apply receipt';
end if;
delete from public.claim_evidence target where ((target.claim_id = E'a9dd972a-b867-56f7-b3c9-3913dd9a0abe'::uuid and target.source_id = E'3d31345d-a4f7-52a7-af4a-0034f99a8123'::uuid and target.role = E'illustrates'::evidence_role) or (target.claim_id = E'b4d0a944-8f11-5516-80ca-bc680f0059ad'::uuid and target.source_id = E'3953271f-7df5-5674-99b0-980b1b3534e6'::uuid and target.role = E'grounds'::evidence_role));
get diagnostics affected = row_count;
if affected <> 2 then
raise exception 'proposal rollback count mismatch for claim_evidence: expected 2, got %', affected;
end if;
delete from public.claim_edges where id in (E'cd799806-18e8-5e8c-959c-5f9c267654a7'::uuid);
get diagnostics affected = row_count;
if affected <> 1 then
raise exception 'proposal rollback count mismatch for claim_edges: expected 1, got %', affected;
end if;
delete from public.reasoning_tools where id in (E'a32a7252-d39f-5ee9-873a-a82b56a6bb08'::uuid);
get diagnostics affected = row_count;
if affected <> 1 then
raise exception 'proposal rollback count mismatch for reasoning_tools: expected 1, got %', affected;
end if;
delete from public.sources where id in (E'3953271f-7df5-5674-99b0-980b1b3534e6'::uuid, E'3d31345d-a4f7-52a7-af4a-0034f99a8123'::uuid);
get diagnostics affected = row_count;
if affected <> 2 then
raise exception 'proposal rollback count mismatch for sources: expected 2, got %', affected;
end if;
delete from public.claims where id in (E'a9dd972a-b867-56f7-b3c9-3913dd9a0abe'::uuid, E'b4d0a944-8f11-5516-80ca-bc680f0059ad'::uuid);
get diagnostics affected = row_count;
if affected <> 2 then
raise exception 'proposal rollback count mismatch for claims: expected 2, got %', affected;
end if;
update kb_stage.kb_proposals
set status = 'canceled',
applied_by_handle = null,
applied_by_agent_id = null,
applied_at = null,
updated_at = now()
where id = E'edaf2c90-af15-5a2f-b6b9-fe08ab9ae81b'::uuid
and status = 'applied'
and payload = E'{"apply_payload":{"agent_id":null,"claims":[{"confidence":0.9,"created_by":null,"id":"b4d0a944-8f11-5516-80ca-bc680f0059ad","status":"open","superseded_by":null,"tags":["working-leo","clone-canary"],"text":"An approved strict proposal can create exact canonical rows atomically.","type":"structural"},{"confidence":0.85,"created_by":null,"id":"a9dd972a-b867-56f7-b3c9-3913dd9a0abe","status":"open","superseded_by":null,"tags":["working-leo","row-proof"],"text":"Row-level proof is the authority for canonical KB state.","type":"concept"}],"contract_version":2,"edges":[{"created_by":null,"edge_type":"supports","from_claim":"b4d0a944-8f11-5516-80ca-bc680f0059ad","to_claim":"a9dd972a-b867-56f7-b3c9-3913dd9a0abe","weight":0.75}],"evidence":[{"claim_id":"b4d0a944-8f11-5516-80ca-bc680f0059ad","created_by":null,"role":"grounds","source_id":"3953271f-7df5-5674-99b0-980b1b3534e6","weight":0.9},{"claim_id":"a9dd972a-b867-56f7-b3c9-3913dd9a0abe","created_by":null,"role":"illustrates","source_id":"3d31345d-a4f7-52a7-af4a-0034f99a8123","weight":0.8}],"reasoning_tools":[{"agent_id":null,"category":"verification","description":"Verify approved proposal to canonical graph lifecycle in a disposable clone.","id":"a32a7252-d39f-5ee9-873a-a82b56a6bb08","name":"Canonical row proof canary"}],"sources":[{"created_by":null,"excerpt":"Disposable clone lifecycle canary source A.","hash":"approve-claim-canary-e315c2518c-a","id":"3953271f-7df5-5674-99b0-980b1b3534e6","source_type":"observation","storage_path":null,"url":null},{"created_by":null,"excerpt":"Disposable clone lifecycle canary source B.","hash":"approve-claim-canary-e315c2518c-b","id":"3d31345d-a4f7-52a7-af4a-0034f99a8123","source_type":"observation","storage_path":null,"url":null}]}}'::jsonb
and applied_at is not distinct from E'2026-07-15 03:59:12.452878+00'::timestamptz;
get diagnostics affected = row_count;
if affected <> 1 then
raise exception 'proposal rollback: expected one applied ledger row, got %', affected;
end if;
end
$rollback$;
commit;

View file

@ -0,0 +1,219 @@
{
"applied_row_keys": {
"claim_edges": [
"cd799806-18e8-5e8c-959c-5f9c267654a7"
],
"claim_evidence": [
"a9dd972a-b867-56f7-b3c9-3913dd9a0abe|3d31345d-a4f7-52a7-af4a-0034f99a8123|illustrates",
"b4d0a944-8f11-5516-80ca-bc680f0059ad|3953271f-7df5-5674-99b0-980b1b3534e6|grounds"
],
"claims": [
"a9dd972a-b867-56f7-b3c9-3913dd9a0abe",
"b4d0a944-8f11-5516-80ca-bc680f0059ad"
],
"reasoning_tools": [
"a32a7252-d39f-5ee9-873a-a82b56a6bb08"
],
"sources": [
"3953271f-7df5-5674-99b0-980b1b3534e6",
"3d31345d-a4f7-52a7-af4a-0034f99a8123"
]
},
"applied_row_sha256": {
"claim_edges": [
"aae7ed87c66cf58136f2b0027ae1cddc9092cd64bfc8e617cd7746b2306274c5"
],
"claim_evidence": [
"388f3363173efda00f0688fab77fe0ce2baf62035220b843be1adea1f1c70f7f",
"55838cb722f7158cbdbdc3b79212e764f9fa6014771985aec3c1c7856967db07"
],
"claims": [
"75fe4543c9c3194612b1cf98b074ff7e361da17c9bcd59f9b6f085c2c0861277",
"5914923936817eff6d7e5c824c94c18ae6392b7a6e80c87ace2e547865b173eb"
],
"reasoning_tools": [
"990dacb7b77cec117d9ee4a7630625a8782d06dfd549340b3269b8332c170576"
],
"sources": [
"585edbec2f98ec127041cdd662506a1494ea402f7e25ac0082dbda98197bf130",
"a8d2eead7cb3e563869978570173e2af753dfe131d4b7cfcf6dd419ffbb427e5"
]
},
"apply_payload_sha256": "e033bd4e742dfa0dad7d26e2f2b1f18eb71996541cdbc575bb2d4504c045e36f",
"apply_receipt_sha256": "ac99a2a315cc8e6e214e0f2f69d1a23413da9cfd8629c202b61a678ffda6d7ca",
"apply_sql_sha256": "b52cd47182dc0f542a394147201bb3a125518f8a4bc1a7fc44f2b0caa39c4a1b",
"approval_snapshot_sha256": "1f9d0a58ad236908da931c7489fe14ee855d0f13c4d72eb5b218370e116e2096",
"artifact": "proposal_apply_lifecycle_receipt",
"checks": {
"apply_receipt_replay_ready": true,
"apply_rows_have_exact_ids": true,
"fresh_owned_preflight_consumed_by_apply": true,
"fresh_owned_targets": true,
"immutable_approval_unchanged": true,
"rollback_counts_restored": true,
"rollback_ledger_quarantined_from_worker": true,
"rollback_replay_refused_without_mutation": true,
"rollback_sql_exact_for_bound_rows": true,
"rollback_target_rows_absent": true,
"unrelated_rows_unchanged": true
},
"current_tier": "T2_runtime",
"fresh_owned_apply_sql_sha256": "b52cd47182dc0f542a394147201bb3a125518f8a4bc1a7fc44f2b0caa39c4a1b",
"fresh_preflight_artifact_sha256": "2312c91d82ee378d4a53136b8e307900c97d0611d9f12098e799cb6de5d30077",
"fresh_preflight_sha256": "90facb2ca62feb1d3c7a242e84427ab402cf57148eaba40ec700f3cc4896d20f",
"generated_at_utc": "2026-07-15T03:59:15.412413+00:00",
"lifecycle_receipt_sha256": "4254f363b0c6115ecf07856c6e6a9879b43840e688aa73211cb9eff893b36c06",
"pass": true,
"production_apply_authorization_present": false,
"production_apply_executed": false,
"proposal_before_apply": {
"applied_at": null,
"applied_by_agent_id": null,
"applied_by_handle": null,
"id": "edaf2c90-af15-5a2f-b6b9-fe08ab9ae81b",
"payload": {
"apply_payload": {
"agent_id": null,
"claims": [
{
"confidence": 0.9,
"created_by": null,
"id": "b4d0a944-8f11-5516-80ca-bc680f0059ad",
"status": "open",
"superseded_by": null,
"tags": [
"working-leo",
"clone-canary"
],
"text": "An approved strict proposal can create exact canonical rows atomically.",
"type": "structural"
},
{
"confidence": 0.85,
"created_by": null,
"id": "a9dd972a-b867-56f7-b3c9-3913dd9a0abe",
"status": "open",
"superseded_by": null,
"tags": [
"working-leo",
"row-proof"
],
"text": "Row-level proof is the authority for canonical KB state.",
"type": "concept"
}
],
"contract_version": 2,
"edges": [
{
"created_by": null,
"edge_type": "supports",
"from_claim": "b4d0a944-8f11-5516-80ca-bc680f0059ad",
"to_claim": "a9dd972a-b867-56f7-b3c9-3913dd9a0abe",
"weight": 0.75
}
],
"evidence": [
{
"claim_id": "b4d0a944-8f11-5516-80ca-bc680f0059ad",
"created_by": null,
"role": "grounds",
"source_id": "3953271f-7df5-5674-99b0-980b1b3534e6",
"weight": 0.9
},
{
"claim_id": "a9dd972a-b867-56f7-b3c9-3913dd9a0abe",
"created_by": null,
"role": "illustrates",
"source_id": "3d31345d-a4f7-52a7-af4a-0034f99a8123",
"weight": 0.8
}
],
"reasoning_tools": [
{
"agent_id": null,
"category": "verification",
"description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.",
"id": "a32a7252-d39f-5ee9-873a-a82b56a6bb08",
"name": "Canonical row proof canary"
}
],
"sources": [
{
"created_by": null,
"excerpt": "Disposable clone lifecycle canary source A.",
"hash": "approve-claim-canary-e315c2518c-a",
"id": "3953271f-7df5-5674-99b0-980b1b3534e6",
"source_type": "observation",
"storage_path": null,
"url": null
},
{
"created_by": null,
"excerpt": "Disposable clone lifecycle canary source B.",
"hash": "approve-claim-canary-e315c2518c-b",
"id": "3d31345d-a4f7-52a7-af4a-0034f99a8123",
"source_type": "observation",
"storage_path": null,
"url": null
}
]
}
},
"proposal_type": "approve_claim",
"review_note": "Reviewed exact strict payload inside the disposable clone.",
"reviewed_at": "2026-07-15 03:59:09.091704+00",
"reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999",
"reviewed_by_handle": "m3ta",
"status": "approved"
},
"proposal_payload_sha256": "cf2676db5a64142d07a7b46f02f1ba38bfa8cca69d03484bbcaa5eeb7002af71",
"required_tier": "T2_runtime",
"rollback": {
"counts_after_rollback": {
"kb_stage.kb_proposals": 1,
"public.claim_edges": 0,
"public.claim_evidence": 1,
"public.claims": 1,
"public.reasoning_tools": 0,
"public.sources": 1
},
"counts_before_apply": {
"kb_stage.kb_proposals": 1,
"public.claim_edges": 0,
"public.claim_evidence": 1,
"public.claims": 1,
"public.reasoning_tools": 0,
"public.sources": 1
},
"delete_order": [
"claim_evidence",
"claim_edges",
"reasoning_tools",
"sources",
"claims"
],
"proposal_after": {
"applied_at": null,
"applied_by_agent_id": null,
"applied_by_handle": null,
"id": "edaf2c90-af15-5a2f-b6b9-fe08ab9ae81b",
"proposal_type": "approve_claim",
"review_note": "Reviewed exact strict payload inside the disposable clone.",
"reviewed_at": "2026-07-15 03:59:09.091704+00",
"reviewed_by_agent_id": "99999999-9999-9999-9999-999999999999",
"reviewed_by_handle": "m3ta",
"status": "canceled"
},
"rollback_sql_sha256": "50758dab3f998289a879cedb4a3f4535814e70c7f4dde417812092b9fe194901",
"schema": "livingip.proposalApplyRollback.v2",
"target_rows_after": {
"claim_edges": [],
"claim_evidence": [],
"claims": [],
"reasoning_tools": [],
"sources": []
}
},
"schema": "livingip.proposalApplyLifecycleReceipt.v2",
"strongest_claim_allowed": "deterministic disposable-clone apply and compensating rollback"
}

View file

@ -0,0 +1,260 @@
{
"artifact": "proposal_apply_production_authorization_packet",
"authorization_record_required": {
"authorization_text": "<EXACT_TEXT_FROM_VERIFIER>",
"authorized": true,
"binding_sha256": "6f1984f3a69ad049d4bbcc408ed2542dc5f081806ec9baa9a35c8959e5dab62a",
"expires_at_utc": "<UTC>",
"operator_identity": "<OPERATOR_IDENTITY>",
"production_rollback_sql_sha256": "<EXACT_PRODUCTION_ROLLBACK_SHA256>",
"received_at_utc": "<UTC>",
"rollback_authorized": true
},
"authorization_text_template": "I authorize one production DB apply for proposal 9b2b5fa4-0e0d-5db0-aa4d-6fd102889946 with payload SHA-256 6fba5e8e105a28dfaf5733ff7c9f85a20d31d653add0bc4a0f81e4b08de803af to Docker container teleo-pg, database teleo, system identifier 7649789040005668902, binding SHA-256 6f1984f3a69ad049d4bbcc408ed2542dc5f081806ec9baa9a35c8959e5dab62a. I also authorize conditional production rollback SHA-256 <PRODUCTION_ROLLBACK_SQL_SHA256> only if the bound postflight fails and no downstream dependency exists. Do not send Telegram, mutate another proposal, expose Cloud SQL, or promote GCP. Operator <OPERATOR_IDENTITY>; received <UTC>; expires <UTC>.",
"binding": {
"approval_gate": {
"apply_role_present": true,
"approve_function_present": false,
"assert_function_present": false,
"finish_function_present": false,
"immutable_approval_table_present": false,
"review_role_present": false
},
"approval_gate_dependency": {
"path": "scripts/kb_apply_prereqs.sql",
"requires_separate_production_authorization": true,
"sha256": "bdf8c5da05eed10665b05ad1e331e3c9c8d72464c59889a3cf8f34ab23822faa"
},
"candidate_readback": {
"matching_candidate": null,
"matching_candidate_count": 0
},
"destination": {
"container": "teleo-pg",
"database": "teleo",
"server_version_num": "160014",
"system_identifier": "7649789040005668902"
},
"destination_readback": {
"observed_at_utc": "2026-07-15T02:07:27.133665+00:00",
"read_only_transaction": true
},
"engine": {
"apply_engine_path": "scripts/apply_proposal.py",
"apply_engine_sha256": "ca2c0a0c1031393c95a26102d57339654d2363f4c51cdf39aabb9071d0ca6c26",
"apply_sql_sha256": "1a7d65870e415ee8891b6dd84732a29bcee00412c10862d3d1db4b191a8ade38",
"repo_git_sha": "bd3c17628c6cf7da734be01149bbf1cc77a6d71b",
"runtime_manifest": {
"scripts/apply_proposal.py": "ca2c0a0c1031393c95a26102d57339654d2363f4c51cdf39aabb9071d0ca6c26",
"scripts/kb_apply_prereqs.sql": "bdf8c5da05eed10665b05ad1e331e3c9c8d72464c59889a3cf8f34ab23822faa",
"scripts/kb_apply_replay_receipt.py": "4ead132fc32a69baaecfe7b638cba8ba6d54d8508d0b7e6a922dc8065805c97f",
"scripts/proposal_apply_lifecycle.py": "a643b83b55c9e76f545ebafb9582d6d07ff432600c1b66004cc7440d7ac1963b"
}
},
"expected_rows": {
"row_ids": {
"claim_edges": [
"b28d8770-9ac9-5b5f-bfe2-7280d7422a21"
],
"claim_evidence": [
"13e580c5-458d-5146-aef3-8c74ffc43b7c",
"dac3934f-b7ad-5205-8efe-a00163370a54"
],
"claims": [
"38dead14-6b1d-5909-99c4-3c45ad2dd21f",
"71a3331b-fb75-5e18-aa61-b256bc38af36"
],
"reasoning_tools": [
"2b8a01ea-125c-5d90-a9b9-39ccb0a1c9e0"
],
"sources": [
"a86f55dc-5058-585d-b492-a4f1d932670f",
"ed9da5f1-846e-5298-8689-15027a7ce56d"
]
},
"row_sha256": {
"claim_edges": [
"60d14cbc45d424fa1eb62db6478f185bf2c2d86559e57ffa77474e8d0b3c527c"
],
"claim_evidence": [
"e97de162c0730da69b357e1350f0da7e5843c4e67d498c12d731a0f04a8868d7",
"3054718195abe3f78e08cfcacd59902d41eb91c7153c6c63f9bcb3bc7c6902ac"
],
"claims": [
"e593b9cf7b0bc9267f3e48d8173129b84b09c028f290f1abc97ccb73940b31dc",
"24280b5159cbbf75e00eb24ae50ab69994397a583f347a241a5e262cf0c03179"
],
"reasoning_tools": [
"257924b236c3c27289b9ae2314687be0e96779415fc6ff87faada22893b757ba"
],
"sources": [
"d7a690c2b18701db5b48e8189b1621c8025c1ed75889a4d0a3a4c9761c03dc3b",
"bee048794799006bd00bf4bb02ae57998e670f5bcdfb140dff871dcb042d0198"
]
}
},
"production_preconditions": {
"approval_gate_ready": false,
"destination_readback_observed_at_utc": "2026-07-15T02:07:27.133665+00:00",
"destination_readback_was_read_only": true,
"exact_production_rollback_packet_ready": false,
"matching_candidate_count": 0,
"production_apply_authorization_present": false,
"production_apply_executed": false,
"strict_proposal_present_and_approved": false
},
"production_rollback": {
"artifact_schema": null,
"artifact_sha256": null,
"bound_for_action_time_authorization": false,
"conditional_rollback_requires_explicit_authorization": true,
"rollback_sql_sha256": null,
"scope": "exact_production_destination_postapply_receipt",
"status": "not_generated"
},
"proposal": {
"apply_payload_sha256": "c89bc03ce7714f325293329a0bf95eaba0a56c596ef021d731b48dab0447c684",
"approval_snapshot_sha256": "310b54030e26ed43d7226f2e803610586e80d21ff064c67e11ea21e93ef40bd9",
"id": "9b2b5fa4-0e0d-5db0-aa4d-6fd102889946",
"payload": {
"apply_payload": {
"agent_id": null,
"claims": [
{
"confidence": 0.9,
"created_by": null,
"id": "38dead14-6b1d-5909-99c4-3c45ad2dd21f",
"status": "open",
"superseded_by": null,
"tags": [
"working-leo",
"clone-canary"
],
"text": "An approved strict proposal can create exact canonical rows atomically.",
"type": "structural"
},
{
"confidence": 0.85,
"created_by": null,
"id": "71a3331b-fb75-5e18-aa61-b256bc38af36",
"status": "open",
"superseded_by": null,
"tags": [
"working-leo",
"row-proof"
],
"text": "Row-level proof is the authority for canonical KB state.",
"type": "concept"
}
],
"contract_version": 2,
"edges": [
{
"created_by": null,
"edge_type": "supports",
"from_claim": "38dead14-6b1d-5909-99c4-3c45ad2dd21f",
"to_claim": "71a3331b-fb75-5e18-aa61-b256bc38af36",
"weight": 0.75
}
],
"evidence": [
{
"claim_id": "38dead14-6b1d-5909-99c4-3c45ad2dd21f",
"created_by": null,
"role": "grounds",
"source_id": "ed9da5f1-846e-5298-8689-15027a7ce56d",
"weight": 0.9
},
{
"claim_id": "71a3331b-fb75-5e18-aa61-b256bc38af36",
"created_by": null,
"role": "illustrates",
"source_id": "a86f55dc-5058-585d-b492-a4f1d932670f",
"weight": 0.8
}
],
"reasoning_tools": [
{
"agent_id": null,
"category": "verification",
"description": "Verify approved proposal to canonical graph lifecycle in a disposable clone.",
"id": "2b8a01ea-125c-5d90-a9b9-39ccb0a1c9e0",
"name": "Canonical row proof canary"
}
],
"sources": [
{
"created_by": null,
"excerpt": "Disposable clone lifecycle canary source A.",
"hash": "approve-claim-canary-08c2358330-a",
"id": "ed9da5f1-846e-5298-8689-15027a7ce56d",
"source_type": "observation",
"storage_path": null,
"url": null
},
{
"created_by": null,
"excerpt": "Disposable clone lifecycle canary source B.",
"hash": "approve-claim-canary-08c2358330-b",
"id": "a86f55dc-5058-585d-b492-a4f1d932670f",
"source_type": "observation",
"storage_path": null,
"url": null
}
]
}
},
"proposal_payload_sha256": "6fba5e8e105a28dfaf5733ff7c9f85a20d31d653add0bc4a0f81e4b08de803af",
"proposal_type": "approve_claim",
"required_applied_at": null,
"required_status": "approved",
"review_note": "Reviewed exact strict payload inside the disposable clone.",
"reviewed_at": "2026-07-15 01:59:03.105846+00",
"reviewed_by_agent_id": "11111111-1111-4111-8111-111111111111",
"reviewed_by_handle": "m3ta"
},
"rollback": {
"conditional_rollback_requires_explicit_authorization": true,
"lifecycle_receipt_sha256": "8e74cf1f5c372633f9b6f15363ff759ba6ce9bf42df51288bb9be70ddabe49b3",
"production_executable": false,
"rollback_sql_sha256": "ef2464a6802426509333861cf0768ca64184901ab7bd2030529e7356a35d9cb3",
"scope": "disposable_clone_rehearsal"
}
},
"binding_sha256": "6f1984f3a69ad049d4bbcc408ed2542dc5f081806ec9baa9a35c8959e5dab62a",
"claim_ceiling": "T2 clone lifecycle plus T3 destination readback; no production apply authorization or execution",
"current_tier": "T3_live_readonly",
"generated_at_utc": "2026-07-15T02:08:10.775963+00:00",
"next_exact_action": "deploy and independently verify the immutable approval gate before selecting a production proposal",
"production_apply_authorization_present": false,
"production_apply_executed": false,
"production_preconditions": {
"approval_gate_ready": false,
"destination_readback_observed_at_utc": "2026-07-15T02:07:27.133665+00:00",
"destination_readback_was_read_only": true,
"exact_production_rollback_packet_ready": false,
"matching_candidate_count": 0,
"production_apply_authorization_present": false,
"production_apply_executed": false,
"strict_proposal_present_and_approved": false
},
"production_rollback_requirement": {
"clone_rehearsal_is_not_production_rollback": true,
"clone_rehearsal_rollback_sql_sha256": "ef2464a6802426509333861cf0768ca64184901ab7bd2030529e7356a35d9cb3",
"production_rollback_artifact_schema": null,
"production_rollback_artifact_sha256": null,
"production_rollback_sql_sha256": null,
"required_before_apply_window": true,
"required_binding": "an exact production rollback SQL SHA-256 in both the action-time record and authorization text",
"status": "not_generated"
},
"required_tier": "T6_authorized_production",
"safe_to_enter_apply_window": false,
"schema": "livingip.proposalApplyAuthorizationPacket.v1",
"scope_exclusions": {
"approval_gate_deployment_authorized": false,
"cloud_sql_exposure_authorized": false,
"gcp_promotion_authorized": false,
"telegram_send_authorized": false
}
}

View file

@ -0,0 +1,62 @@
# Proposal Apply Production Authorization Packet
Generated UTC: `2026-07-15T02:08:10.775963+00:00`
Required tier: `T6_authorized_production`
Current tier: `T3_live_readonly`
Safe to enter apply window: `False`
Production apply authorized: `False`
Production apply executed: `False`
## Exact Binding
- Proposal: `9b2b5fa4-0e0d-5db0-aa4d-6fd102889946` (`approve_claim`)
- Proposal payload SHA-256: `6fba5e8e105a28dfaf5733ff7c9f85a20d31d653add0bc4a0f81e4b08de803af`
- Apply payload SHA-256: `c89bc03ce7714f325293329a0bf95eaba0a56c596ef021d731b48dab0447c684`
- Immutable approval SHA-256: `310b54030e26ed43d7226f2e803610586e80d21ff064c67e11ea21e93ef40bd9`
- Destination: `teleo-pg/teleo`
- Destination system identifier: `7649789040005668902`
- Apply engine SHA-256: `ca2c0a0c1031393c95a26102d57339654d2363f4c51cdf39aabb9071d0ca6c26`
- Apply engine path: `scripts/apply_proposal.py`
- Apply SQL SHA-256: `1a7d65870e415ee8891b6dd84732a29bcee00412c10862d3d1db4b191a8ade38`
- Clone rehearsal rollback SQL SHA-256: `ef2464a6802426509333861cf0768ca64184901ab7bd2030529e7356a35d9cb3`
- Production rollback status: `not_generated`
- Production rollback SQL SHA-256: `None`
- Approval gate prerequisite SHA-256: `bdf8c5da05eed10665b05ad1e331e3c9c8d72464c59889a3cf8f34ab23822faa`
- Approval gate prerequisite path: `scripts/kb_apply_prereqs.sql`
- Binding SHA-256: `6f1984f3a69ad049d4bbcc408ed2542dc5f081806ec9baa9a35c8959e5dab62a`
## Production Preconditions
- `approval_gate_ready`: `False`
- `destination_readback_observed_at_utc`: `2026-07-15T02:07:27.133665+00:00`
- `destination_readback_was_read_only`: `True`
- `exact_production_rollback_packet_ready`: `False`
- `matching_candidate_count`: `0`
- `production_apply_authorization_present`: `False`
- `production_apply_executed`: `False`
- `strict_proposal_present_and_approved`: `False`
## Approval Gate Readback
- `apply_role_present`: `True`
- `approve_function_present`: `False`
- `assert_function_present`: `False`
- `finish_function_present`: `False`
- `immutable_approval_table_present`: `False`
- `review_role_present`: `False`
## Exact Action-Time Authorization Text
This text is not actionable until every production precondition above is true.
I authorize one production DB apply for proposal 9b2b5fa4-0e0d-5db0-aa4d-6fd102889946 with payload SHA-256 6fba5e8e105a28dfaf5733ff7c9f85a20d31d653add0bc4a0f81e4b08de803af to Docker container teleo-pg, database teleo, system identifier 7649789040005668902, binding SHA-256 6f1984f3a69ad049d4bbcc408ed2542dc5f081806ec9baa9a35c8959e5dab62a. I also authorize conditional production rollback SHA-256 <PRODUCTION_ROLLBACK_SQL_SHA256> only if the bound postflight fails and no downstream dependency exists. Do not send Telegram, mutate another proposal, expose Cloud SQL, or promote GCP. Operator <OPERATOR_IDENTITY>; received <UTC>; expires <UTC>.
## Current Gate
deploy and independently verify the immutable approval gate before selecting a production proposal
The production approval-gate deployment is explicitly outside this apply packet and requires separate authorization.
## Claim Ceiling
T2 clone lifecycle plus T3 destination readback; no production apply authorization or execution

View file

@ -0,0 +1,32 @@
{
"artifact": "proposal_apply_production_target_readback",
"schema": "livingip.proposalApplyProductionTargetReadback.v1",
"observed_at_utc": "2026-07-15T02:07:27.133665+00:00",
"transport": "ssh_readonly_transaction",
"read_only_transaction": true,
"read_only_setting": "on",
"container": "teleo-pg",
"database": "teleo",
"system_identifier": "7649789040005668902",
"server_version_num": "160014",
"approval_gate": {
"immutable_approval_table_present": false,
"approve_function_present": false,
"assert_function_present": false,
"finish_function_present": false,
"review_role_present": false,
"apply_role_present": true
},
"approved_strict_candidate_count": 0,
"approved_strict_candidates": [],
"attempted_recovery": {
"strict_immutable_approval_join_attempted": true,
"strict_join_failed": true,
"strict_join_exact_gate": "relation kb_stage.kb_proposal_approvals does not exist",
"fallback_read_only_gate_and_candidate_count_succeeded": true
},
"production_mutated": false,
"production_apply_authorization_present": false,
"production_apply_executed": false,
"claim_ceiling": "Fresh T3 live read-only identity and gate readback only. The immutable approval gate is absent and there are zero approved strict approve_claim candidates; production apply is neither authorized nor executed."
}

View file

@ -0,0 +1,106 @@
{
"artifact": "leo_teleo_skill_pack_fresh_agent_review",
"status": "pass",
"required_tier": "T2_runtime",
"current_tier": "T2_runtime",
"proof_scope": "fresh_context_agent_onboarding_and_stale_claim_rejection",
"evidence_origin": {
"agent": "/root/fresh_skill_canary",
"fork_turns": "none",
"onboarding_authority": "isolated installed skill pack only",
"memory_used": false
},
"answers": {
"canonical_code_deployment_repository_authority": {
"repository": "GitHub living-ip/teleo-infrastructure",
"canonical_branch": "main",
"vps_deploy_source_mirror": "/opt/teleo-eval/workspaces/deploy-infra",
"mirror_is_canonical_authority": false
},
"vps_canonical_database": {
"container": "teleo-pg",
"database": "teleo"
},
"live_vps_gateway_service": "leoclean-gateway.service",
"persistent_gcp_database": {
"instance": "teleo-pgvector-standby",
"database": "teleo_canonical",
"status": "older staging copy",
"retained_measurement": {
"tables": 39,
"rows": 52164,
"proposals": 26
},
"promoted": false,
"cut_over": false
},
"pull_requests": {
"146": "merged into canonical main",
"147": "merged into canonical main",
"148": "open least-privilege GCP candidate; not canonical main"
},
"approved_proposals_equal_applied_proposals": {
"equal": false,
"retained_vps_proposal_counts": {
"total": 29,
"applied": 2,
"approved": 3,
"pending_review": 16,
"canceled": 8
},
"meaning": "Approved proposals remain staged until canonical application and row-level proof."
},
"first_safe_local_validation_command": ".agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py --root ."
},
"stale_claims_rejected": {
"pr_148_is_merged": true,
"persistent_gcp_is_promoted": true,
"all_approved_proposals_are_applied": true
},
"validator": {
"command": "/private/tmp/teleo-clean-agent-final-20260715/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py --root /private/tmp/teleo-fleet-20260715/skills-docs-onboarding",
"exit_code": 0,
"status": "pass",
"checked_path_count": 233,
"checked_paths_sha256": "ae919c3e7d8cef19a1782a00c640eeeb66c49dfbce3ad9ceaf30eb96e77bda16",
"coverage_area_count": 13,
"skill_count": 16,
"production_mutation_authorized": false,
"contains_secrets": false,
"problems": []
},
"repository_readback": {
"status_before": [
" M .agents/skills/teleo-leo-onboarding/scripts/install_skill_pack.py",
" M .agents/skills/teleo-leo-onboarding/scripts/run_clean_context_canary.py",
" M tests/test_repo_skill_pack.py",
"?? goal.md"
],
"status_after": [
" M .agents/skills/teleo-leo-onboarding/scripts/install_skill_pack.py",
" M .agents/skills/teleo-leo-onboarding/scripts/run_clean_context_canary.py",
" M tests/test_repo_skill_pack.py",
"?? goal.md"
],
"unchanged": true
},
"files_read": [
".agents/skills/teleo-leo-onboarding/SKILL.md",
".agents/skills/teleo-infra-provenance/SKILL.md",
"docs/reports/leo-working-state-20260709/current-truth-index.md",
"docs/reports/leo-working-state-20260709/operator-surface-map.md",
"docs/reports/leo-working-state-20260709/gcp-db-first-working-leo-20260714.md",
"docs/reports/leo-working-state-20260709/working-leo-definition-20260709.md",
"docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.md"
],
"cleanup_readback": {
"temporary_skill_root_removed": true,
"matching_temporary_roots_remaining": 0,
"orphan_processes_started": false
},
"external_runtime_contacted": false,
"production_mutation": false,
"contains_secrets": false,
"problems": [],
"strongest_claim_allowed": "T2 fresh-context local onboarding and route validation only; this does not prove live VPS, GCP promotion, Telegram delivery, or production proposal application"
}

View file

@ -0,0 +1,71 @@
{
"agent_reasoning_exercised": false,
"ambient_skill_root_used": false,
"artifact": "leo_teleo_skill_pack_isolated_install_canary",
"canary_command": ".agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py --root .",
"canary_exit_status": 0,
"canary_receipt": {
"artifact": "leo_teleo_skill_pack_path_validation",
"checked_path_count": 234,
"checked_paths_sha256": "19ed1813f9cb4c19489a180081007842e241a2dcae659a5d873582fbbd50cff6",
"contains_secrets": false,
"coverage_area_count": 13,
"manifest": "docs/reports/leo-working-state-20260709/skill-pack-manifest.json",
"problems": [],
"production_mutation_authorized": false,
"required_tier": "T2_runtime",
"skill_count": 16,
"status": "pass"
},
"cleanup_readback": {
"orphan_processes_started": false,
"temporary_skill_root_removed": true
},
"contains_secrets": false,
"current_tier": "T2_runtime",
"evidence_paths": {
"authority": ".agents/skills/teleo-infra-provenance/SKILL.md",
"candidate_only_gcp": ".agents/skills/teleo-reconstruction-recovery/SKILL.md",
"gcp_database": ".agents/skills/teleo-leo-onboarding/SKILL.md",
"live_service": ".agents/skills/teleo-infra-provenance/SKILL.md",
"merged_reasoning_verifier": ".agents/skills/teleo-reconstruction-recovery/SKILL.md",
"merged_reconstruction": ".agents/skills/teleo-reconstruction-recovery/SKILL.md",
"next_safe_action": ".agents/skills/teleo-leo-onboarding/SKILL.md",
"vps_database": ".agents/skills/teleo-leo-onboarding/SKILL.md"
},
"expected_answers": {
"authority": "GitHub living-ip/teleo-infrastructure",
"candidate_only_gcp": "PR #148 open candidate only; not canonical main",
"gcp_database": "private Cloud SQL teleo_canonical; persistent copy remains staging",
"live_service": "leoclean-gateway.service",
"merged_reasoning_verifier": "PR #147 merged unseen-reasoning verifier hardening",
"merged_reconstruction": "PR #146 merged deterministic genesis-plus-ledger reconstruction",
"next_safe_action": "run the repo-local path validator before any operational action",
"vps_database": "teleo-pg / teleo"
},
"external_runtime_contacted": false,
"fresh_temporary_skill_root": true,
"installed_skill_count": 16,
"missing_to_reach_required_tier": [],
"problems": [],
"production_mutation_authorized": false,
"proof_scope": "deterministic_isolated_install_and_route_validation",
"required_tier": "T2_runtime",
"selected_installed_skills": [
"teleo-infra-provenance",
"teleo-leo-onboarding",
"teleo-reconstruction-recovery"
],
"semantic_checks": {
"authority": true,
"candidate_only_gcp": true,
"gcp_database": true,
"live_service": true,
"merged_reasoning_verifier": true,
"merged_reconstruction": true,
"next_safe_action": true,
"vps_database": true
},
"status": "pass",
"strongest_claim_allowed": "T2 deterministic isolated local skill install, route-contract, and path validation only; this artifact does not claim an agent reasoning run, and retained product proofs keep their own VPS, GCP-staging, isolated-clone, Telegram, and production claim ceilings"
}

View file

@ -1,39 +1,51 @@
{ {
"pack": "leo-teleo-skill-pack", "pack": "leo-teleo-skill-pack",
"created_date": "2026-07-09", "created_date": "2026-07-09",
"last_updated_utc": "2026-07-13T06:45:00Z", "last_updated_utc": "2026-07-15T00:16:53Z",
"status": "repo_native_validated", "status": "repo_native_path_validated",
"contains_secrets": false, "contains_secrets": false,
"production_mutation_authorized": false, "production_mutation_authorized": false,
"repo_skill_root": ".agents/skills", "repo_skill_root": ".agents/skills",
"optional_local_install_target": "/Users/user/.codex/skills", "optional_local_install_target": "/Users/user/.codex/skills",
"claim_ceiling": "Repo-native onboarding and operations skills. Generic and Helmer guarded-apply canaries pass 37/37 in disposable PostgreSQL. PR #72 source auto-synchronized to the VPS checkout without a gateway restart or profile-source delta; the permission migration was not applied, the apply worker remained disabled/inactive, and Helmer remained unapplied. Current source-composition/apply lifecycle proof is stronger and remains isolated. GCP gateway and exact canonical DB parity are proven across 39 tables and 52,164 rows, and the hardened adapter-free model replay passes 6/6 with exact count consistency. Durable GCP operator identity and retained clone cleanup remain open. Broad blind VPS reasoning is not reliable yet: independent strict judges accepted only 1/12 and 2/12 outright. Current skills require exact m3taversal naming, neutral follow-up labels, and current-v1 schema truth.", "claim_ceiling": "Repo-native onboarding and operations skills at T2 clean-context local runtime. PRs #146 and #147 are merged and own deterministic reconstruction plus unseen-reasoning verification. PR #148 is open candidate evidence only. Generic and Helmer guarded-apply canaries pass 37/37 in disposable PostgreSQL, while production rich packets remain unapplied. The latest disposable GCP clone matched 39 tables and 52,167 rows and a no-send model turn passed 18/18 runtime checks plus 6/6 reasoning outcomes; persistent GCP teleo_canonical remains staging and no promotion, production apply, or current Telegram-visible end-to-end proof is claimed.",
"repository_reconciliation": {
"merged_pull_requests": [146, 147],
"candidate_only_pull_requests": [148],
"canonical_reconstruction_contract": "docs/kb-rebuild-and-recompile.md",
"canonical_turn_manifest": "scripts/leo_turn_execution_manifest.py",
"canonical_unseen_reasoning_verifier": "scripts/verify_leo_unseen_reasoning_chain.py"
},
"skills": [ "skills": [
{ {
"name": "teleo-leo-onboarding", "name": "teleo-leo-onboarding",
"role": "Company/product/architecture orientation for Leo and Teleo work", "role": "Company, product, architecture, task routing, and clean-context entry point",
"path": ".agents/skills/teleo-leo-onboarding/SKILL.md" "path": ".agents/skills/teleo-leo-onboarding/SKILL.md"
}, },
{ {
"name": "working-leo-m3taversal-outcomes", "name": "working-leo-m3taversal-outcomes",
"role": "Definition of working Leo from m3taversal outcomes and tests", "role": "Definition of working Leo, identity discipline, behavior, and proof ceiling",
"path": ".agents/skills/working-leo-m3taversal-outcomes/SKILL.md" "path": ".agents/skills/working-leo-m3taversal-outcomes/SKILL.md"
}, },
{ {
"name": "teleo-vps-runtime-ops", "name": "teleo-vps-runtime-ops",
"role": "VPS runtime navigation, service health, Docker/Postgres checks, report sync", "role": "VPS runtime navigation, incidents, service health, Postgres, and cleanup",
"path": ".agents/skills/teleo-vps-runtime-ops/SKILL.md" "path": ".agents/skills/teleo-vps-runtime-ops/SKILL.md"
}, },
{ {
"name": "teleo-gcp-parity-ops", "name": "teleo-gcp-parity-ops",
"role": "GCP operator access, private Cloud SQL parity, m3taversal replay, rollback, and cleanup", "role": "GCP access, private Cloud SQL parity, no-send replay, rollback, and cleanup",
"path": ".agents/skills/teleo-gcp-parity-ops/SKILL.md" "path": ".agents/skills/teleo-gcp-parity-ops/SKILL.md"
}, },
{ {
"name": "teleo-kb-db-change-workflow", "name": "teleo-kb-db-change-workflow",
"role": "Strict proposal normalization, separated review/apply authority, isolated canary, and row-level proof", "role": "Source ingestion, proposal normalization, review, guarded apply, and receipts",
"path": ".agents/skills/teleo-kb-db-change-workflow/SKILL.md" "path": ".agents/skills/teleo-kb-db-change-workflow/SKILL.md"
}, },
{
"name": "teleo-reconstruction-recovery",
"role": "Snapshot recovery, genesis-ledger replay, source recompilation, and incident recovery",
"path": ".agents/skills/teleo-reconstruction-recovery/SKILL.md"
},
{ {
"name": "leo-telegram-canary-ops", "name": "leo-telegram-canary-ops",
"role": "Live Telegram bot testing through authenticated Chrome and Computer Use", "role": "Live Telegram bot testing through authenticated Chrome and Computer Use",
@ -41,29 +53,121 @@
}, },
{ {
"name": "teleo-infra-provenance", "name": "teleo-infra-provenance",
"role": "Repo/deploy/runtime provenance and path confusion prevention", "role": "Repository, deploy, runtime, database, and retained-proof provenance",
"path": ".agents/skills/teleo-infra-provenance/SKILL.md" "path": ".agents/skills/teleo-infra-provenance/SKILL.md"
}, },
{ {
"name": "teleo-proof-handoff", "name": "teleo-proof-handoff",
"role": "Evidence-indexed handoff format for Fable/Codex/Opus workers", "role": "Capability tiers, retained evidence, cleanup, and worker handoff",
"path": ".agents/skills/teleo-proof-handoff/SKILL.md" "path": ".agents/skills/teleo-proof-handoff/SKILL.md"
},
{
"name": "nousresearch-hermes-agent",
"role": "Hermes agent packaging, skills, prompts, memory, model routing, and no-secret policy",
"path": ".agents/skills/nousresearch-hermes-agent/SKILL.md"
},
{
"name": "teleo-db-operator",
"role": "Read-first Teleo pipeline SQLite discovery, audit, backup, and guarded writes",
"path": ".agents/skills/teleo-db-operator/SKILL.md"
},
{
"name": "private-password-storage",
"role": "Device-local credential presence and secure-input handling without chat disclosure",
"path": ".agents/skills/private-password-storage/SKILL.md"
},
{
"name": "crabbox",
"role": "Isolated remote Linux and CI proof without production deployment",
"path": ".agents/skills/crabbox/SKILL.md"
},
{
"name": "decision-engine-refinement",
"role": "Replayable model, evaluator, rubric, and decision-engine quality work",
"path": ".agents/skills/decision-engine-refinement/SKILL.md"
},
{
"name": "living-ip-kb-interop",
"role": "Safe external-agent knowledge read and propose-first writeback contracts",
"path": ".agents/skills/living-ip-kb-interop/SKILL.md"
},
{
"name": "openclaw-agent",
"role": "No-secret Living IP agent packaging for OpenClaw workspaces",
"path": ".agents/skills/openclaw-agent/SKILL.md"
} }
], ],
"required_coverage": {
"company_product_context": ["teleo-leo-onboarding"],
"vps": ["teleo-vps-runtime-ops"],
"gcp": ["teleo-gcp-parity-ops"],
"hermes_runtime": ["nousresearch-hermes-agent", "teleo-vps-runtime-ops"],
"database_provenance": ["teleo-infra-provenance", "teleo-db-operator"],
"ingestion": ["teleo-kb-db-change-workflow", "living-ip-kb-interop"],
"proposal_apply": ["teleo-kb-db-change-workflow"],
"reconstruction": ["teleo-reconstruction-recovery"],
"identity": ["teleo-leo-onboarding", "working-leo-m3taversal-outcomes"],
"testing": ["teleo-leo-onboarding", "teleo-proof-handoff", "crabbox", "decision-engine-refinement"],
"security": ["teleo-vps-runtime-ops", "teleo-gcp-parity-ops", "private-password-storage"],
"secrets": ["private-password-storage"],
"incident_recovery": ["teleo-reconstruction-recovery", "teleo-vps-runtime-ops"]
},
"reference_files": [ "reference_files": [
"docs/reports/leo-working-state-20260709/skill-pack-clean-context-agent-review-current.json",
"docs/reports/leo-working-state-20260709/skill-pack-clean-context-canary-current.json",
"docs/reports/leo-working-state-20260709/current-truth-index.md", "docs/reports/leo-working-state-20260709/current-truth-index.md",
"docs/reports/leo-working-state-20260709/operator-surface-map.md", "docs/reports/leo-working-state-20260709/operator-surface-map.md",
"docs/reports/leo-working-state-20260709/fable-leo-teleo-onboarding.md", "docs/reports/leo-working-state-20260709/fable-leo-teleo-onboarding.md",
"docs/reports/leo-working-state-20260709/gcp-db-first-working-leo-20260714.md",
"docs/reports/leo-working-state-20260709/gcp-db-first-parity-current.json",
"docs/reports/leo-working-state-20260709/gcp-db-first-blind-claim-current.json",
"docs/reports/leo-working-state-20260709/gcp-db-first-cleanup-current.json",
"docs/reports/leo-working-state-20260709/gcp-db-first-live-deploy-restart-current.json",
"docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.md", "docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.md",
"docs/reports/leo-working-state-20260709/gcp-cloud-sql-t3-live-readonly-current.md",
"docs/reports/leo-working-state-20260709/gcp-cloudsql-studio-parity-gate-current.md",
"docs/reports/leo-working-state-20260709/pr72-vps-auto-deploy-runtime-nonchange-current.md",
"docs/reports/leo-working-state-20260709/gcp-leo-runtime-observability-current.md",
"docs/reports/leo-working-state-20260709/gcp-canonical-parity-live-20260712.json",
"docs/reports/leo-working-state-20260709/gcp-operator-access-blocker-current.json",
"docs/reports/leo-working-state-20260709/telegram-visible-direct-claim-dc01-partial-current.json",
"docs/reports/leo-working-state-20260709/working-leo-current-proof-20260712.md", "docs/reports/leo-working-state-20260709/working-leo-current-proof-20260712.md",
"docs/reports/leo-working-state-20260709/working-leo-current-proof-20260712.json" "docs/reports/leo-working-state-20260709/leo-unified-turn-manifest-canary-current.json",
"docs/reports/leo-working-state-20260709/leo-architecture-work-and-outcomes-20260714.md",
"docs/kb-rebuild-and-recompile.md"
], ],
"validation": "tests/test_repo_skill_pack.py" "command_files": [
".agents/skills/teleo-leo-onboarding/scripts/install_skill_pack.py",
".agents/skills/teleo-leo-onboarding/scripts/run_clean_context_canary.py",
".agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py",
"ops/run_local_canonical_postgres_rebuild.py",
"ops/run_local_genesis_ledger_rebuild.py",
"ops/capture_vps_canonical_postgres_snapshot.py",
"ops/restore_gcp_generated_postgres_snapshot.py",
"ops/verify_postgres_parity_manifest.py",
"scripts/compile_kb_source_packet.py",
"scripts/approve_proposal.py",
"scripts/apply_proposal.py",
"scripts/leo_turn_execution_manifest.py",
"scripts/verify_leo_unseen_reasoning_chain.py",
"tests/test_repo_skill_pack.py"
],
"scan_files": [
"docs/reports/leo-working-state-20260709/skill-pack-readme.md",
"docs/reports/leo-working-state-20260709/current-truth-index.md",
"docs/reports/leo-working-state-20260709/operator-surface-map.md",
"docs/reports/leo-working-state-20260709/fable-leo-teleo-onboarding.md",
"docs/reports/leo-working-state-20260709/leo-architecture-work-and-outcomes-20260714.md",
"README.md",
"docs/kb-rebuild-and-recompile.md"
],
"executable_files": [
".agents/skills/teleo-leo-onboarding/scripts/install_skill_pack.py",
".agents/skills/teleo-leo-onboarding/scripts/run_clean_context_canary.py",
".agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py",
".agents/skills/private-password-storage/scripts/private-password-storage"
],
"validator": ".agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py",
"installer": ".agents/skills/teleo-leo-onboarding/scripts/install_skill_pack.py",
"isolated_install_canary": ".agents/skills/teleo-leo-onboarding/scripts/run_clean_context_canary.py",
"fresh_agent_receipt": "docs/reports/leo-working-state-20260709/skill-pack-clean-context-agent-review-current.json",
"validation": "tests/test_repo_skill_pack.py",
"validation_commands": [
".agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py --root .",
".agents/skills/teleo-leo-onboarding/scripts/run_clean_context_canary.py --root .",
".venv/bin/python -m pytest -q tests/test_repo_skill_pack.py"
]
} }

View file

@ -1,42 +1,91 @@
# Leo / Teleo Skill Pack - 2026-07-09 # Leo / Teleo Skill Pack - 2026-07-15
Purpose: reusable onboarding and operating knowledge for future Codex/Fable workers working on Leo, Teleo, the VPS, GCP parity, Telegram canaries, and KB database changes. Purpose: give a new engineer or agent one repo-native route into Leo/Teleo
architecture, operations, database lifecycle, proof tiers, secrets, and recovery
without relying on historical chat or unmerged branch prose.
This is the repo-native skill set under `.agents/skills/`. It is evidence-linked and validated by `tests/test_repo_skill_pack.py`. It does not contain secrets, private key contents, bot tokens, or production mutation authorization. The pack lives under `.agents/skills/`, contains no credentials, and grants no
production database mutation or GCP promotion authority.
## Clean-Context Entry Point
From the repository root:
```bash
.agents/skills/teleo-leo-onboarding/scripts/validate_skill_pack.py --root .
.agents/skills/teleo-leo-onboarding/scripts/install_skill_pack.py \
--root . \
--target /private/tmp/teleo-clean-agent/skills
.agents/skills/teleo-leo-onboarding/scripts/run_clean_context_canary.py --root .
```
The validator uses standard-library Python through its executable shebang. For
pytest, create the repository virtual environment from `README.md` and use
`.venv/bin/python`; do not assume a bare `python` executable exists.
## Skills In This Pack ## Skills In This Pack
1. `teleo-leo-onboarding`: company/product/architecture orientation before touching Leo or Teleo. 1. `teleo-leo-onboarding`: product, architecture, task router, and first canary.
2. `working-leo-m3taversal-outcomes`: m3taversal's expected Leo behavior and the current benchmark. 2. `working-leo-m3taversal-outcomes`: exact identity discipline and working-Leo proof ceiling.
3. `teleo-vps-runtime-ops`: VPS service, paths, Postgres, Docker, report sync, and stability checks. 3. `teleo-vps-runtime-ops`: VPS services, Postgres, incidents, and cleanup.
4. `teleo-gcp-parity-ops`: passwordless GCP access, Cloud SQL parity, no-send replay, rollback, and cleanup. 4. `teleo-gcp-parity-ops`: GCP/Cloud SQL parity, no-send replay, and rollback.
5. `teleo-kb-db-change-workflow`: source composition plus approved proposal to canonical-row workflow with clone rehearsal and rollback. 5. `teleo-kb-db-change-workflow`: source ingestion through guarded proposal/apply.
6. `leo-telegram-canary-ops`: live Telegram/Chrome/Computer Use canaries for Leo bot behavior. 6. `teleo-reconstruction-recovery`: snapshot, ledger, and semantic recovery modes.
7. `teleo-infra-provenance`: repo, deploy, mirror, and runtime provenance map. 7. `leo-telegram-canary-ops`: authorized Leo-specific Telegram canaries.
8. `teleo-proof-handoff`: evidence bundle and Fable/Codex worker handoff protocol. 8. `teleo-infra-provenance`: repository, deploy, runtime, DB, and proof provenance.
9. `teleo-proof-handoff`: tiered evidence and continuation handoffs.
10. `nousresearch-hermes-agent`: Hermes packaging and runtime boundaries.
11. `teleo-db-operator`: read-first pipeline SQLite operation.
12. `private-password-storage`: device-local secure input and presence checks.
13. `crabbox`: isolated remote Linux and CI proof.
14. `decision-engine-refinement`: replayable evaluator and model-quality work.
15. `living-ip-kb-interop`: propose-first external-agent KB access.
16. `openclaw-agent`: no-secret OpenClaw workspace packaging.
The machine-readable topic coverage and exact paths are in
`docs/reports/leo-working-state-20260709/skill-pack-manifest.json`.
## Repository Reconciliation
- PR #146 is merged: deterministic turn manifests and the first exact
genesis-plus-ledger reconstruction slice are canonical `main` behavior.
- PR #147 is merged: the unseen-reasoning verifier accepts valid reasoning
variance while keeping evidence and receipt gates.
- PR #148 is open candidate evidence only. Its proposed least-privilege GCP
files and live end state are not canonical until merged and receipt-verified.
## Current Claim Ceiling ## Current Claim Ceiling
- VPS Leo Telegram memory, KB audit, and staged write canaries are live-proven. - T2 clean-context local skill install, route validation, and focused tests are
- A strict canonical `add_edge` apply canary is live-proven. the onboarding target for this pack.
- Deterministic source composition, full-data clone composition/reasoning, and guarded approved-bundle application are isolated-proven with exact source/evidence/claim links, row deltas, rollback, and cleanup. Production rich packets remain unapplied. - VPS no-send behavior, isolated proposal/apply, snapshot recovery, disposable
- Narrow VPS DB truth and restart behavior are proven. Broad blind reasoning is not yet reliable; exact participant naming, neutral labels, and current-v1 schema guards are now required. GCP parity, and bounded no-send GCP reasoning have retained evidence.
- GCP gateway liveness, private Cloud SQL identity, exact VPS-to-GCP canonical parity, and hardened adapter-free model replay are live-proven. The database matches across `39` tables and `52,164` rows. Durable operator identity and retained replay-clone cleanup remain open because the intended target service accounts are absent. - Persistent GCP `teleo_canonical` remains staging. No GCP promotion or cutover
is authorized or claimed.
- Production rich packets remain unapplied. A current Telegram-visible complete
flow is not proven by this pack.
## Key References ## Key References
- Current whole-system proof: `docs/reports/leo-working-state-20260709/working-leo-current-proof-20260712.md` and `.json` - Fresh-agent onboarding receipt: `docs/reports/leo-working-state-20260709/skill-pack-clean-context-agent-review-current.json`
- Current truth index: `docs/reports/leo-working-state-20260709/current-truth-index.md` - Isolated-install acceptance receipt: `docs/reports/leo-working-state-20260709/skill-pack-clean-context-canary-current.json`
- Operator surface map: `docs/reports/leo-working-state-20260709/operator-surface-map.md` - Current truth: `docs/reports/leo-working-state-20260709/current-truth-index.md`
- Fable onboarding prompt: `docs/reports/leo-working-state-20260709/fable-leo-teleo-onboarding.md` - Architecture/outcomes: `docs/reports/leo-working-state-20260709/leo-architecture-work-and-outcomes-20260714.md`
- PR #72 VPS auto-deploy/runtime readback: `docs/reports/leo-working-state-20260709/pr72-vps-auto-deploy-runtime-nonchange-current.md` - Recovery contract: `docs/kb-rebuild-and-recompile.md`
- GCP canonical parity: `docs/reports/leo-working-state-20260709/gcp-canonical-parity-live-20260712.json` - GCP database-first proof: `docs/reports/leo-working-state-20260709/gcp-db-first-working-leo-20260714.md`
- GCP model replay (legacy artifact filename): `docs/reports/leo-working-state-20260709/gcp-cory-model-replay-current.json` - GCP no-send reasoning receipt: `docs/reports/leo-working-state-20260709/gcp-db-first-blind-claim-current.json`
- Three-day delivery delta: `docs/reports/leo-working-state-20260709/working-leo-three-day-delivery-summary-20260713.md` - Unified turn receipt: `docs/reports/leo-working-state-20260709/leo-unified-turn-manifest-canary-current.json`
- Blind out-of-sample audit: `docs/reports/leo-working-state-20260709/telegram-handler-blind-oos-audit-current.json` - Operator map: `docs/reports/leo-working-state-20260709/operator-surface-map.md`
- GCP operator access gate: `docs/reports/leo-working-state-20260709/gcp-operator-access-blocker-current.json`
- Skill manifest: `skill-pack-manifest.json`
## Discovery ## Team Change Notes
Codex-compatible workers should discover the committed `.agents/skills/` tree from this repository. The manifest is the index; each skill points to current retained evidence rather than embedding secrets or pretending a stale snapshot is live truth. - Replaced the missing legacy GCP replay route with the current database-first
no-send receipt.
- Added deterministic install and path-validation commands.
- Added separate T2 receipts for deterministic isolated install/path validation
and fresh-context agent reasoning, stale-claim rejection, and cleanup.
- Added an explicit topic router and recovery skill.
- Added merged-vs-open PR boundaries so branch candidates cannot silently become
source-of-truth instructions.
- Added tests for coverage, route existence, installer behavior, and exact
m3taversal identity prose.

View file

@ -0,0 +1,272 @@
{
"authorization_gate_status": "ready_to_request_exact_authorization",
"browser_provenance_contract": {
"capture_channel": "codex_chrome_extension",
"requires_browser_session_tab_and_capture_identifiers": true,
"requires_chrome_backend_tool_receipts": true,
"requires_codex_rollout_log_outside_evidence_root": true,
"requires_codex_user_message_authorization_receipt": true,
"requires_hashes_for_every_screenshot_and_accessibility_artifact": true,
"requires_preflight_challenge_nonce": true,
"requires_provenance_sha256_in_final_chrome_tool_receipt": true,
"requires_telegram_web_origin_and_chat_identity": true,
"schema": "livingip.authenticatedChromeTelegramCaptureProvenance.v1"
},
"checks": {
"authenticated_chrome_is_only_send_transport": true,
"canonical_manifest_path_and_sha_bound": true,
"database_session_and_role_fail_closed_read_only": true,
"exact_prompts_imported_from_handler_verifier": true,
"exact_three_turn_sequence": true,
"first_prompt_supplies_no_row_id": true,
"handler_checks_all_pass": true,
"handler_outcomes_all_pass": true,
"handler_prompt_ids_exact": true,
"handler_proved_no_telegram_post": true,
"handler_proved_read_only_tool_traces": true,
"handler_proved_unchanged_fingerprint": true,
"handler_receipt_passed": true,
"handler_receipt_schema_supported": true,
"handler_safety_gate_passed": true,
"handler_tier_remains_below_telegram_visible": true,
"independent_browser_provenance_required": true,
"packet_does_not_mutate_database": true,
"packet_does_not_send": true
},
"claim_ceiling": {
"current_tier": "T0_spec_plus_prior_T2_handler_evidence",
"not_proven": [
"Telegram-visible delivery of these three messages",
"Telegram-visible replies from Leo",
"post-send canonical fingerprint equality"
],
"proven": "The exact three-turn Chrome send packet is bound to a passing no-send handler receipt.",
"required_tier": "T3_live_readonly"
},
"clear_CTA": "Reply with the exact authorization sentence in this packet. That sentence names the destination, transport, complete message bodies, ordering, evidence, and no-mutation boundary.",
"exact_messages": [
{
"dimension": "independent_weak_claim_selection",
"message": "Looking at what Leo currently believes about collective intelligence or coordination, pick one claim that would matter to a founder making a product decision but seems more confident than its support. Do not ask me for an ID. Show what the database actually says and what supports it, then tell me the first narrower claim you would test. Do not change anything yet.",
"message_sha256": "c63838b98448f4f4599e4cf2b004c6b36f602ad0d25c92e442a6f866cd2740fc",
"prompt_id": "OOS-CHAIN-01",
"sequence": 1,
"wait_for_visible_reply_before_next": true
},
{
"dimension": "challenge_body_evidence_and_candidates",
"message": "That still feels like you are polishing the same idea. Inspect the exact body and evidence you just chose: what is assumption versus observed support, what would falsify it, and which replacement claim or claims would you put into review? Keep them as proposals, not live knowledge.",
"message_sha256": "73346a98db4d7f74b49e1a5741b323d4216fd21f8346f6c4a4a69b1a6dd07946",
"prompt_id": "OOS-CHAIN-02",
"sequence": 2,
"wait_for_visible_reply_before_next": true
},
{
"dimension": "user_objection_revision_and_apply_boundary",
"message": "I disagree with your first replacement because it jumps from a mechanism to a business outcome. Revise it with that objection, tell me what source would resolve the disagreement, and show the approval and apply boundary before it could become part of Leo.",
"message_sha256": "5f6b32b2c8c51cc594242ed9bdac849c744156ca2395efb7e8593c83c86286d4",
"prompt_id": "OOS-CHAIN-03",
"sequence": 3,
"wait_for_visible_reply_before_next": true
}
],
"expected_proof_paths_after_authorized_run": {
"browser_provenance": "outputs/telegram-visible-unseen-chain-20260715/browser-provenance.json",
"capture_json": "outputs/telegram-visible-unseen-chain-20260715/capture.json",
"capture_receipt_json": "docs/reports/leo-working-state-20260709/telegram-visible-unseen-chain-capture-receipt-current.json",
"final_accessibility": "outputs/telegram-visible-unseen-chain-20260715/final-accessibility.txt",
"final_screenshot": "outputs/telegram-visible-unseen-chain-20260715/final.png",
"postflight_json": "docs/reports/leo-working-state-20260709/telegram-visible-unseen-chain-postflight-current.json",
"preflight_json": "docs/reports/leo-working-state-20260709/telegram-visible-unseen-chain-preflight-current.json",
"turn_accessibility": [
"outputs/telegram-visible-unseen-chain-20260715/turn-1-accessibility.txt",
"outputs/telegram-visible-unseen-chain-20260715/turn-2-accessibility.txt",
"outputs/telegram-visible-unseen-chain-20260715/turn-3-accessibility.txt"
],
"turn_screenshots": [
"outputs/telegram-visible-unseen-chain-20260715/turn-1.png",
"outputs/telegram-visible-unseen-chain-20260715/turn-2.png",
"outputs/telegram-visible-unseen-chain-20260715/turn-3.png"
]
},
"explicit_operator_authorization_text": "I authorize Codex to use the already-authenticated Chrome Telegram UI to send exactly these three messages, in order and with no additional messages, to the Telegram group Leo (chat ID -5146042086), waiting for Leo's visible reply after each turn: [OOS-CHAIN-01] \"Looking at what Leo currently believes about collective intelligence or coordination, pick one claim that would matter to a founder making a product decision but seems more confident than its support. Do not ask me for an ID. Show what the database actually says and what supports it, then tell me the first narrower claim you would test. Do not change anything yet.\" [OOS-CHAIN-02] \"That still feels like you are polishing the same idea. Inspect the exact body and evidence you just chose: what is assumption versus observed support, what would falsify it, and which replacement claim or claims would you put into review? Keep them as proposals, not live knowledge.\" [OOS-CHAIN-03] \"I disagree with your first replacement because it jumps from a mechanism to a business outcome. Revise it with that objection, tell me what source would resolve the disagreement, and show the approval and apply boundary before it could become part of Leo.\" Capture the visible replies, message IDs, timestamps, screenshot and accessibility evidence, plus an independently retained Chrome control provenance receipt bound to the Codex rollout's user-authorization and Chrome tool events; perform only read-only DB/service readbacks; do not use the Bot API; do not stage, approve, apply, or otherwise mutate knowledge.",
"generated_at_utc": "2026-07-15T02:33:20.290077+00:00",
"handler_receipt_binding": {
"deployed_git_head": "b3aa184dd4c721f6c40dc813dcefd5930f8ed417",
"fingerprint_sha256": "32a1f2c18f4b4c623443cbd4d9520982e9f291ec74ca63855cef51c88ac56f24",
"path": "docs/reports/leo-working-state-20260709/leo-unseen-reasoning-chain-canary-current.json",
"proof_tier": "live_vps_gatewayrunner_temp_profile_no_telegram_post_no_apply",
"remote_run_id": "d5702cafbb0b",
"schema": "livingip.leoUnseenReasoningChainReceipt.v2",
"sha256": "f4fcf0207484e5322074c7838f3a345d421c1664e5dc8d73b9199c4475b4cee8"
},
"manifest_binding": {
"execution_contract": {
"arbitrary_manifest_override_allowed": false,
"authenticated_role": "postgres",
"database": "teleo",
"default_transaction_read_only": "on",
"effective_role": "pg_read_all_data",
"psql_rc_disabled": true,
"transaction_read_only": "on"
},
"path": "ops/postgres_parity_manifest.sql",
"sha256": "8b8cdc25d54fdd8de05eb38c6e4423d2836953eb6012d4545f5c9c71b5f0150a"
},
"mode": "telegram_visible_unseen_chain_exact_packet_not_sent",
"mutates_db": false,
"next_non_user_action_after_authorization": [
"Re-run the zero-mutation preflight and confirm its packet file hash is current.",
"Use authenticated Chrome only and verify the Leo chat ID before typing anything.",
"Send one exact message, wait for Leo's visible reply, then continue to the next exact message.",
"Capture message IDs, timestamps, screenshot, accessibility text, and the Chrome-control provenance receipt without copying handler output.",
"Retain the Codex rollout path whose Chrome tool receipt contains the provenance SHA256.",
"Extract the selected DB object reference and run the read-only postflight with that reference.",
"Run the Telegram-visible verifier and accept T3 only if every visible and state check passes."
],
"operator_context": {
"authorization_source": "codex_platform_user_message",
"codex_thread_id": "019f6350-3350-7040-b223-c5c22673fece"
},
"packet_generation_git_sha": "dfa6be6ba098b63b5856d03f499a44883b193e4f",
"production_apply_executed": false,
"protocol": {
"browser_provenance_contract": {
"capture_channel": "codex_chrome_extension",
"requires_browser_session_tab_and_capture_identifiers": true,
"requires_chrome_backend_tool_receipts": true,
"requires_codex_rollout_log_outside_evidence_root": true,
"requires_codex_user_message_authorization_receipt": true,
"requires_hashes_for_every_screenshot_and_accessibility_artifact": true,
"requires_preflight_challenge_nonce": true,
"requires_provenance_sha256_in_final_chrome_tool_receipt": true,
"requires_telegram_web_origin_and_chat_identity": true,
"schema": "livingip.authenticatedChromeTelegramCaptureProvenance.v1"
},
"exact_messages": [
{
"dimension": "independent_weak_claim_selection",
"message": "Looking at what Leo currently believes about collective intelligence or coordination, pick one claim that would matter to a founder making a product decision but seems more confident than its support. Do not ask me for an ID. Show what the database actually says and what supports it, then tell me the first narrower claim you would test. Do not change anything yet.",
"message_sha256": "c63838b98448f4f4599e4cf2b004c6b36f602ad0d25c92e442a6f866cd2740fc",
"prompt_id": "OOS-CHAIN-01",
"sequence": 1,
"wait_for_visible_reply_before_next": true
},
{
"dimension": "challenge_body_evidence_and_candidates",
"message": "That still feels like you are polishing the same idea. Inspect the exact body and evidence you just chose: what is assumption versus observed support, what would falsify it, and which replacement claim or claims would you put into review? Keep them as proposals, not live knowledge.",
"message_sha256": "73346a98db4d7f74b49e1a5741b323d4216fd21f8346f6c4a4a69b1a6dd07946",
"prompt_id": "OOS-CHAIN-02",
"sequence": 2,
"wait_for_visible_reply_before_next": true
},
{
"dimension": "user_objection_revision_and_apply_boundary",
"message": "I disagree with your first replacement because it jumps from a mechanism to a business outcome. Revise it with that objection, tell me what source would resolve the disagreement, and show the approval and apply boundary before it could become part of Leo.",
"message_sha256": "5f6b32b2c8c51cc594242ed9bdac849c744156ca2395efb7e8593c83c86286d4",
"prompt_id": "OOS-CHAIN-03",
"sequence": 3,
"wait_for_visible_reply_before_next": true
}
],
"handler_binding": {
"deployed_git_head": "b3aa184dd4c721f6c40dc813dcefd5930f8ed417",
"fingerprint_sha256": "32a1f2c18f4b4c623443cbd4d9520982e9f291ec74ca63855cef51c88ac56f24",
"path": "docs/reports/leo-working-state-20260709/leo-unseen-reasoning-chain-canary-current.json",
"proof_tier": "live_vps_gatewayrunner_temp_profile_no_telegram_post_no_apply",
"remote_run_id": "d5702cafbb0b",
"schema": "livingip.leoUnseenReasoningChainReceipt.v2",
"sha256": "f4fcf0207484e5322074c7838f3a345d421c1664e5dc8d73b9199c4475b4cee8"
},
"manifest_binding": {
"execution_contract": {
"arbitrary_manifest_override_allowed": false,
"authenticated_role": "postgres",
"database": "teleo",
"default_transaction_read_only": "on",
"effective_role": "pg_read_all_data",
"psql_rc_disabled": true,
"transaction_read_only": "on"
},
"path": "ops/postgres_parity_manifest.sql",
"sha256": "8b8cdc25d54fdd8de05eb38c6e4423d2836953eb6012d4545f5c9c71b5f0150a"
},
"operator_context": {
"authorization_source": "codex_platform_user_message",
"codex_thread_id": "019f6350-3350-7040-b223-c5c22673fece"
},
"state_contract": {
"ordering": "preflight < authorization < send1 < reply1 < send2 < reply2 < send3 < reply3 < final/postflight",
"postflight": "same canonical fingerprint plus independent selected-object readback",
"preflight": "two identical repeatable-read read-only canonical fingerprints",
"service": "same active gateway process before and after"
},
"target": {
"allowed_transport": "authenticated_chrome_telegram_ui",
"chat_id": "-5146042086",
"chat_label": "Leo",
"expected_prompt_ids": [
"OOS-CHAIN-01",
"OOS-CHAIN-02",
"OOS-CHAIN-03"
],
"forbidden_transports": [
"telegram_bot_api",
"copied_transcript",
"handler_substitution"
],
"message_count": 3,
"platform": "telegram"
},
"tooling_binding": {
"capture_verifier": {
"path": "scripts/verify_telegram_visible_unseen_chain.py",
"sha256": "379f0f2258daea6ba565b7277fbba0c1907a37eafcd86b33e178137f24ecae2e"
},
"packet_builder": {
"path": "scripts/build_telegram_visible_unseen_chain_packet.py",
"sha256": "f8c5657bc1039a421356aa296ecfdb29578dc99c2db513835b0983be9e8a224c"
},
"state_collector": {
"path": "scripts/collect_telegram_visible_unseen_chain_state.py",
"sha256": "6adfc7750667374aa084ae2cd0e794876568bebb57478097697c2e0c9b981c7a"
}
}
},
"protocol_sha256": "91cba55a23cac9061ac34a827a040f27eb6a018f720586304dd9b08ed113af77",
"ready_to_request_action_time_authorization": true,
"schema": "livingip.telegramVisibleUnseenChainPacket.v2",
"target": {
"allowed_transport": "authenticated_chrome_telegram_ui",
"chat_id": "-5146042086",
"chat_label": "Leo",
"expected_prompt_ids": [
"OOS-CHAIN-01",
"OOS-CHAIN-02",
"OOS-CHAIN-03"
],
"forbidden_transports": [
"telegram_bot_api",
"copied_transcript",
"handler_substitution"
],
"message_count": 3,
"platform": "telegram"
},
"telegram_visible_message_authorization_present": false,
"telegram_visible_messages_sent": false,
"tooling_binding": {
"capture_verifier": {
"path": "scripts/verify_telegram_visible_unseen_chain.py",
"sha256": "379f0f2258daea6ba565b7277fbba0c1907a37eafcd86b33e178137f24ecae2e"
},
"packet_builder": {
"path": "scripts/build_telegram_visible_unseen_chain_packet.py",
"sha256": "f8c5657bc1039a421356aa296ecfdb29578dc99c2db513835b0983be9e8a224c"
},
"state_collector": {
"path": "scripts/collect_telegram_visible_unseen_chain_state.py",
"sha256": "6adfc7750667374aa084ae2cd0e794876568bebb57478097697c2e0c9b981c7a"
}
}
}

View file

@ -0,0 +1,81 @@
# Telegram-Visible Unseen Chain Authorization Packet
Generated UTC: `2026-07-15T02:33:20.290077+00:00`
Protocol SHA256: `91cba55a23cac9061ac34a827a040f27eb6a018f720586304dd9b08ed113af77`
Ready to request action-time authorization: `True`
Telegram-visible messages sent: `False`
Mutates DB: `False`
## Exact Destination
- Chat: `Leo` (`-5146042086`)
- Transport: `authenticated_chrome_telegram_ui`
## Exact Messages
### 1. OOS-CHAIN-01
Looking at what Leo currently believes about collective intelligence or coordination, pick one claim that would matter to a founder making a product decision but seems more confident than its support. Do not ask me for an ID. Show what the database actually says and what supports it, then tell me the first narrower claim you would test. Do not change anything yet.
SHA256: `c63838b98448f4f4599e4cf2b004c6b36f602ad0d25c92e442a6f866cd2740fc`
### 2. OOS-CHAIN-02
That still feels like you are polishing the same idea. Inspect the exact body and evidence you just chose: what is assumption versus observed support, what would falsify it, and which replacement claim or claims would you put into review? Keep them as proposals, not live knowledge.
SHA256: `73346a98db4d7f74b49e1a5741b323d4216fd21f8346f6c4a4a69b1a6dd07946`
### 3. OOS-CHAIN-03
I disagree with your first replacement because it jumps from a mechanism to a business outcome. Revise it with that objection, tell me what source would resolve the disagreement, and show the approval and apply boundary before it could become part of Leo.
SHA256: `5f6b32b2c8c51cc594242ed9bdac849c744156ca2395efb7e8593c83c86286d4`
## Read-Only State Contract
- Manifest: `ops/postgres_parity_manifest.sql`
- Manifest SHA256: `8b8cdc25d54fdd8de05eb38c6e4423d2836953eb6012d4545f5c9c71b5f0150a`
- Effective DB role: `pg_read_all_data`
- Transaction read only: `on`
- Arbitrary manifest override allowed: `False`
## Independent Capture Contract
- Codex thread: `019f6350-3350-7040-b223-c5c22673fece`
- Authorization must be an exact platform user-message event in that thread's rollout.
- Each turn and final artifact must be bound by Chrome-backend tool receipts in that rollout.
## Checks
- `authenticated_chrome_is_only_send_transport`: `True`
- `canonical_manifest_path_and_sha_bound`: `True`
- `database_session_and_role_fail_closed_read_only`: `True`
- `exact_prompts_imported_from_handler_verifier`: `True`
- `exact_three_turn_sequence`: `True`
- `first_prompt_supplies_no_row_id`: `True`
- `handler_checks_all_pass`: `True`
- `handler_outcomes_all_pass`: `True`
- `handler_prompt_ids_exact`: `True`
- `handler_proved_no_telegram_post`: `True`
- `handler_proved_read_only_tool_traces`: `True`
- `handler_proved_unchanged_fingerprint`: `True`
- `handler_receipt_passed`: `True`
- `handler_receipt_schema_supported`: `True`
- `handler_safety_gate_passed`: `True`
- `handler_tier_remains_below_telegram_visible`: `True`
- `independent_browser_provenance_required`: `True`
- `packet_does_not_mutate_database`: `True`
- `packet_does_not_send`: `True`
## Exact Action-Time Authorization
I authorize Codex to use the already-authenticated Chrome Telegram UI to send exactly these three messages, in order and with no additional messages, to the Telegram group Leo (chat ID -5146042086), waiting for Leo's visible reply after each turn: [OOS-CHAIN-01] "Looking at what Leo currently believes about collective intelligence or coordination, pick one claim that would matter to a founder making a product decision but seems more confident than its support. Do not ask me for an ID. Show what the database actually says and what supports it, then tell me the first narrower claim you would test. Do not change anything yet." [OOS-CHAIN-02] "That still feels like you are polishing the same idea. Inspect the exact body and evidence you just chose: what is assumption versus observed support, what would falsify it, and which replacement claim or claims would you put into review? Keep them as proposals, not live knowledge." [OOS-CHAIN-03] "I disagree with your first replacement because it jumps from a mechanism to a business outcome. Revise it with that objection, tell me what source would resolve the disagreement, and show the approval and apply boundary before it could become part of Leo." Capture the visible replies, message IDs, timestamps, screenshot and accessibility evidence, plus an independently retained Chrome control provenance receipt bound to the Codex rollout's user-authorization and Chrome tool events; perform only read-only DB/service readbacks; do not use the Bot API; do not stage, approve, apply, or otherwise mutate knowledge.
## Clear CTA
Reply with the exact authorization sentence in this packet. That sentence names the destination, transport, complete message bodies, ordering, evidence, and no-mutation boundary.
## Claim Ceiling
Current tier: `T0_spec_plus_prior_T2_handler_evidence`
Required tier: `T3_live_readonly`

View file

@ -0,0 +1,120 @@
{
"capture_template": {
"capture_source": {
"browser_provenance": "",
"captured_at_utc": "",
"captured_by": "",
"chat_id": "-5146042086",
"chat_label": "Leo",
"final_accessibility": "",
"final_capture_reuse_reason": "",
"final_capture_reuses_turn_3": false,
"final_screenshot": "",
"platform": "telegram",
"transport": "authenticated_chrome_telegram_ui"
},
"extra_messages_sent": 0,
"messages": [
{
"prompt_id": "OOS-CHAIN-01",
"reply": "",
"reply_at_utc": "",
"reply_message_id": "",
"sent_at_utc": "",
"sent_text": "Looking at what Leo currently believes about collective intelligence or coordination, pick one claim that would matter to a founder making a product decision but seems more confident than its support. Do not ask me for an ID. Show what the database actually says and what supports it, then tell me the first narrower claim you would test. Do not change anything yet.",
"sequence": 1,
"telegram_message_id": "",
"turn_accessibility": "",
"turn_screenshot": ""
},
{
"prompt_id": "OOS-CHAIN-02",
"reply": "",
"reply_at_utc": "",
"reply_message_id": "",
"sent_at_utc": "",
"sent_text": "That still feels like you are polishing the same idea. Inspect the exact body and evidence you just chose: what is assumption versus observed support, what would falsify it, and which replacement claim or claims would you put into review? Keep them as proposals, not live knowledge.",
"sequence": 2,
"telegram_message_id": "",
"turn_accessibility": "",
"turn_screenshot": ""
},
{
"prompt_id": "OOS-CHAIN-03",
"reply": "",
"reply_at_utc": "",
"reply_message_id": "",
"sent_at_utc": "",
"sent_text": "I disagree with your first replacement because it jumps from a mechanism to a business outcome. Revise it with that objection, tell me what source would resolve the disagreement, and show the approval and apply boundary before it could become part of Leo.",
"sequence": 3,
"telegram_message_id": "",
"turn_accessibility": "",
"turn_screenshot": ""
}
],
"operator_authorization_captured_at_utc": "",
"operator_authorization_text": "I authorize Codex to use the already-authenticated Chrome Telegram UI to send exactly these three messages, in order and with no additional messages, to the Telegram group Leo (chat ID -5146042086), waiting for Leo's visible reply after each turn: [OOS-CHAIN-01] \"Looking at what Leo currently believes about collective intelligence or coordination, pick one claim that would matter to a founder making a product decision but seems more confident than its support. Do not ask me for an ID. Show what the database actually says and what supports it, then tell me the first narrower claim you would test. Do not change anything yet.\" [OOS-CHAIN-02] \"That still feels like you are polishing the same idea. Inspect the exact body and evidence you just chose: what is assumption versus observed support, what would falsify it, and which replacement claim or claims would you put into review? Keep them as proposals, not live knowledge.\" [OOS-CHAIN-03] \"I disagree with your first replacement because it jumps from a mechanism to a business outcome. Revise it with that objection, tell me what source would resolve the disagreement, and show the approval and apply boundary before it could become part of Leo.\" Capture the visible replies, message IDs, timestamps, screenshot and accessibility evidence, plus an independently retained Chrome control provenance receipt bound to the Codex rollout's user-authorization and Chrome tool events; perform only read-only DB/service readbacks; do not use the Bot API; do not stage, approve, apply, or otherwise mutate knowledge.",
"preflight_state_token_sha256": "410677869ca2854f38b3e5017de2c682a2625d751fdff6600ac9bc40ce2fbc2e",
"protocol_sha256": "91cba55a23cac9061ac34a827a040f27eb6a018f720586304dd9b08ed113af77",
"schema": "livingip.telegramVisibleUnseenChainCapture.v1"
},
"checks": {
"action_time_authorization_present": false,
"capture_present": false,
"manifest_arbitrary_override_forbidden": true,
"manifest_canonical_path_exists": true,
"manifest_default_transaction_read_only_enforced": true,
"manifest_effective_role_is_read_only": true,
"manifest_override_absent_or_exact_canonical_path": true,
"manifest_packet_path_is_exact_canonical_relative_path": true,
"manifest_packet_sha256_matches_canonical_file": true,
"manifest_protocol_binding_matches_packet": true,
"manifest_psql_rc_disabled": true,
"manifest_sql_statically_read_only": true,
"manifest_transaction_read_only_enforced": true,
"packet_check_section_present_and_passing": true,
"packet_does_not_mutate_db": true,
"packet_has_no_authorization_recorded": true,
"packet_messages_exact": true,
"packet_not_sent": true,
"packet_prompt_ids_exact": true,
"packet_protocol_sha256_derivation_valid": true,
"packet_protocol_sha256_present": true,
"packet_protocol_top_level_bindings_match": true,
"packet_ready_for_authorization_request": true,
"packet_requires_authenticated_chrome": true,
"packet_schema_supported": true,
"packet_targets_exact_leo_chat": true,
"packet_tooling_hashes_match_current_sources": true,
"postflight_present": false,
"preflight_baseline_checks_all_pass": true,
"preflight_manifest_bound": true,
"preflight_packet_checks_all_pass": true,
"preflight_packet_file_hash_bound": true,
"preflight_protocol_bound": true,
"preflight_remote_checks_all_pass": true,
"preflight_schema_supported": true,
"preflight_state_token_derivation_valid": true,
"preflight_status_and_phase_pass": true
},
"claim_ceiling": {
"not_proven": [
"Telegram-visible message delivery",
"Telegram-visible Leo replies",
"post-send fingerprint equality"
],
"proven": "The exact packet and live zero-mutation preflight are ready."
},
"current_tier": "T0_packet_plus_T3_preflight",
"generated_at_utc": "2026-07-15T02:34:03.994153+00:00",
"mode": "telegram_visible_unseen_chain_capture_verifier",
"mutates_db": false,
"packet_path": "docs/reports/leo-working-state-20260709/telegram-visible-unseen-chain-authorization-packet-current.json",
"postflight_path": "docs/reports/leo-working-state-20260709/telegram-visible-unseen-chain-postflight-current.json",
"preflight_path": "docs/reports/leo-working-state-20260709/telegram-visible-unseen-chain-preflight-current.json",
"receipt_ready": false,
"required_tier": "T3_live_readonly",
"schema": "livingip.telegramVisibleUnseenChainReceipt.v2",
"status": "awaiting_action_time_authorization",
"telegram_visible_messages_sent": false
}

View file

@ -0,0 +1,58 @@
# Telegram-Visible Unseen Chain Capture Receipt
Generated UTC: `2026-07-15T02:34:03.994153+00:00`
Status: `awaiting_action_time_authorization`
Receipt ready: `False`
Current tier: `T0_packet_plus_T3_preflight`
Required tier: `T3_live_readonly`
Telegram-visible messages sent: `False`
Mutates DB: `False`
## Checks
- `action_time_authorization_present`: `False`
- `capture_present`: `False`
- `manifest_arbitrary_override_forbidden`: `True`
- `manifest_canonical_path_exists`: `True`
- `manifest_default_transaction_read_only_enforced`: `True`
- `manifest_effective_role_is_read_only`: `True`
- `manifest_override_absent_or_exact_canonical_path`: `True`
- `manifest_packet_path_is_exact_canonical_relative_path`: `True`
- `manifest_packet_sha256_matches_canonical_file`: `True`
- `manifest_protocol_binding_matches_packet`: `True`
- `manifest_psql_rc_disabled`: `True`
- `manifest_sql_statically_read_only`: `True`
- `manifest_transaction_read_only_enforced`: `True`
- `packet_check_section_present_and_passing`: `True`
- `packet_does_not_mutate_db`: `True`
- `packet_has_no_authorization_recorded`: `True`
- `packet_messages_exact`: `True`
- `packet_not_sent`: `True`
- `packet_prompt_ids_exact`: `True`
- `packet_protocol_sha256_derivation_valid`: `True`
- `packet_protocol_sha256_present`: `True`
- `packet_protocol_top_level_bindings_match`: `True`
- `packet_ready_for_authorization_request`: `True`
- `packet_requires_authenticated_chrome`: `True`
- `packet_schema_supported`: `True`
- `packet_targets_exact_leo_chat`: `True`
- `packet_tooling_hashes_match_current_sources`: `True`
- `postflight_present`: `False`
- `preflight_baseline_checks_all_pass`: `True`
- `preflight_manifest_bound`: `True`
- `preflight_packet_checks_all_pass`: `True`
- `preflight_packet_file_hash_bound`: `True`
- `preflight_protocol_bound`: `True`
- `preflight_remote_checks_all_pass`: `True`
- `preflight_schema_supported`: `True`
- `preflight_state_token_derivation_valid`: `True`
- `preflight_status_and_phase_pass`: `True`
## Awaiting Authorized Capture
The packet and preflight are ready. No Telegram message has been sent by this verifier.
A future T3 receipt also requires the exact platform authorization event and Chrome-backend capture receipts from the bound Codex rollout log.
## Claim Ceiling
The exact packet and live zero-mutation preflight are ready.

View file

@ -0,0 +1,41 @@
{
"fallback_goal_path": "goal.md",
"expanded_active_scope": [
"canonical manifest path and SHA binding with pre-SSH write rejection",
"independent read-only Postgres session and pg_read_all_data effective role",
"supported artifact schemas, passing check sections, and derived state tokens",
"strict timezone-aware authorization/send/reply/capture/postflight chronology",
"evidence-root containment, valid PNG metadata, and distinct per-turn hashes",
"Codex rollout-backed user authorization and Chrome capture provenance",
"full local-forgery regression"
],
"generated_at_utc": "2026-07-15T02:30:26Z",
"platform_goal_after": {
"objective": "Complete and verify the Telegram-visible unseen challenge-to-revision canary defined in this goal file while proving zero database mutation.",
"status": "active",
"thread_id": "019f6350-3350-7040-b223-c5c22673fece"
},
"platform_goal_before": null,
"platform_goal_current": {
"objective": "Complete and verify the Telegram-visible unseen challenge-to-revision canary defined in this goal file while proving zero database mutation.",
"status": "active",
"thread_id": "019f6350-3350-7040-b223-c5c22673fece",
"time_used_seconds_at_readback": 4474,
"tokens_used_at_readback": 886585
},
"platform_goal_repair_action": "create_goal",
"platform_goal_replaced": false,
"platform_goal_scope_update_action": "continued_existing_active_goal_and_expanded_fallback_acceptance_scope",
"platform_goal_scope_update_after": {
"objective": "Complete and verify the Telegram-visible unseen challenge-to-revision canary defined in this goal file while proving zero database mutation.",
"status": "active",
"thread_id": "019f6350-3350-7040-b223-c5c22673fece"
},
"platform_goal_scope_update_before": {
"objective": "Complete and verify the Telegram-visible unseen challenge-to-revision canary defined in this goal file while proving zero database mutation.",
"status": "active",
"thread_id": "019f6350-3350-7040-b223-c5c22673fece"
},
"schema": "livingip.telegramVisibleUnseenChainGoalReadback.v1",
"why_not_replaced": "The active objective already covers T3 Telegram-visible and zero-mutation acceptance. The platform Goal API exposes only complete/blocked status updates while active, so replacing or falsely completing it would be incorrect; expanded integrity acceptance is retained in goal.md and this readback."
}

View file

@ -0,0 +1,83 @@
{
"cleanup_readback": {
"collector_or_verifier_processes_remaining": [],
"status": "clean"
},
"generated_at_utc": "2026-07-15T02:39:17Z",
"live_preflight": {
"canonical_fingerprint_sha256": "32a1f2c18f4b4c623443cbd4d9520982e9f291ec74ca63855cef51c88ac56f24",
"canonical_fingerprint_unchanged_across_two_snapshots": true,
"capture_challenge_nonce": "0a03b4e74a4533d3bb657d7b07fb48888293d7ba217e776f3c2c120764afe086",
"deployed_git_stamp": "626bac493e2b772db984be7a4a68e9da656f6b02",
"effective_database_role": "pg_read_all_data",
"gateway_main_pid": "347406",
"gateway_restarts": "0",
"manifest_path": "ops/postgres_parity_manifest.sql",
"manifest_sha256": "8b8cdc25d54fdd8de05eb38c6e4423d2836953eb6012d4545f5c9c71b5f0150a",
"mutates_db": false,
"packet_file_sha256": "76fb81d055a726de580d1c0ed75784b4576729e8e67badb6a4574677b2447ed0",
"path": "docs/reports/leo-working-state-20260709/telegram-visible-unseen-chain-preflight-current.json",
"preflight_file_sha256": "7705534b35921c7c27fb40acd1277c6ed07ceae114014d074737160f65d4cc6f",
"protocol_sha256": "91cba55a23cac9061ac34a827a040f27eb6a018f720586304dd9b08ed113af77",
"readback_attempts": {
"deploy": 1,
"fingerprint_after": 1,
"fingerprint_before": 1,
"service_after": 1,
"service_before": 1
},
"state_token_sha256": "410677869ca2854f38b3e5017de2c682a2625d751fdff6600ac9bc40ce2fbc2e",
"status": "pass",
"table_count": 39,
"tooling_hashes_match_current_sources": true,
"total_rows": 52167,
"transaction_read_only": "on",
"workspace_head_matches_deployed_stamp": true
},
"not_tested": [
"Telegram message delivery",
"Telegram-visible Leo replies",
"action-time authorization and authenticated-Chrome capture backed by the bound Codex rollout",
"post-send selected-object readback",
"post-send canonical fingerprint equality"
],
"proof_paths": [
"docs/reports/leo-working-state-20260709/telegram-visible-unseen-chain-authorization-packet-current.json",
"docs/reports/leo-working-state-20260709/telegram-visible-unseen-chain-preflight-current.json",
"docs/reports/leo-working-state-20260709/telegram-visible-unseen-chain-capture-receipt-current.json",
"docs/reports/leo-working-state-20260709/telegram-visible-unseen-chain-goal-readback-current.json"
],
"receipt_hashes": {
"authorization_packet_sha256": "76fb81d055a726de580d1c0ed75784b4576729e8e67badb6a4574677b2447ed0",
"capture_receipt_sha256": "0573aed8ceaf04c186afa68b5bf1c6687b76059b00725d33f87939f84b2e5401",
"preflight_sha256": "7705534b35921c7c27fb40acd1277c6ed07ceae114014d074737160f65d4cc6f"
},
"schema": "livingip.telegramVisibleUnseenChainNonsendProof.v1",
"send_boundary": {
"action_time_authorization_present": false,
"authenticated_chrome_used": false,
"telegram_visible_messages_sent": false
},
"tests": [
{
"command": "/Users/user/Documents/Codex/2026-07-09/019f34eb-d297-72d0-b7e2-b222d5515ab9-load/work/teleo-infra-main/.venv/bin/pytest -q tests/test_verify_leo_unseen_reasoning_chain.py tests/test_build_telegram_visible_unseen_chain_packet.py tests/test_collect_telegram_visible_unseen_chain_state.py tests/test_verify_telegram_visible_unseen_chain.py",
"result": "42 passed in 4.19s"
},
{
"command": "/Users/user/Documents/Codex/2026-07-09/019f34eb-d297-72d0-b7e2-b222d5515ab9-load/work/teleo-infra-main/.venv/bin/pytest -q",
"result": "1319 passed in 81.44s"
},
{
"command": "/Users/user/Documents/Codex/2026-07-09/019f34eb-d297-72d0-b7e2-b222d5515ab9-load/work/teleo-infra-main/.venv/bin/ruff check scripts/build_telegram_visible_unseen_chain_packet.py scripts/collect_telegram_visible_unseen_chain_state.py scripts/verify_telegram_visible_unseen_chain.py tests/test_build_telegram_visible_unseen_chain_packet.py tests/test_collect_telegram_visible_unseen_chain_state.py tests/test_verify_telegram_visible_unseen_chain.py",
"result": "All checks passed"
},
{
"command": "/Users/user/Documents/Codex/2026-07-09/019f34eb-d297-72d0-b7e2-b222d5515ab9-load/work/teleo-infra-main/.venv/bin/ruff format --check scripts/build_telegram_visible_unseen_chain_packet.py scripts/collect_telegram_visible_unseen_chain_state.py scripts/verify_telegram_visible_unseen_chain.py tests/test_build_telegram_visible_unseen_chain_packet.py tests/test_collect_telegram_visible_unseen_chain_state.py tests/test_verify_telegram_visible_unseen_chain.py",
"result": "6 files already formatted"
},
{
"command": "git diff --check",
"result": "pass"
}
]
}

View file

@ -0,0 +1,149 @@
{
"baseline_checks": {},
"baseline_path": "",
"baseline_state_token_sha256": "",
"blocker_readback": {
"attempted_routes": [
"local exact packet validation",
"SSH deploy stamp and gateway service readback",
"two canonical repeatable-read read-only Postgres parity manifests"
],
"clear_CTA": "Use the packet's exact authorization sentence only when ready to cross the send boundary.",
"current_canary": "Read-only pre-send readiness for the exact three-turn unseen Leo chain in Telegram",
"exact_gate": "",
"next_non_user_action": "Run the authenticated-Chrome three-turn flow only after exact authorization, then collect postflight."
},
"capture_challenge_nonce": "0a03b4e74a4533d3bb657d7b07fb48888293d7ba217e776f3c2c120764afe086",
"claim_ceiling": {
"current_tier": "T3_live_readonly",
"not_proven": [
"Telegram-visible delivery or reply behavior",
"authorization to send Telegram messages",
"canonical mutation"
],
"proven": "Two canonical read-only snapshots and the gateway process were unchanged during this probe."
},
"generated_at_utc": "2026-07-15T02:33:56.887524+00:00",
"manifest_binding": {
"execution_contract": {
"arbitrary_manifest_override_allowed": false,
"authenticated_role": "postgres",
"database": "teleo",
"default_transaction_read_only": "on",
"effective_role": "pg_read_all_data",
"psql_rc_disabled": true,
"transaction_read_only": "on"
},
"path": "ops/postgres_parity_manifest.sql",
"sha256": "8b8cdc25d54fdd8de05eb38c6e4423d2836953eb6012d4545f5c9c71b5f0150a"
},
"mode": "telegram_visible_unseen_chain_zero_mutation_state_readback",
"mutates_db": false,
"packet_checks": {
"manifest_arbitrary_override_forbidden": true,
"manifest_canonical_path_exists": true,
"manifest_default_transaction_read_only_enforced": true,
"manifest_effective_role_is_read_only": true,
"manifest_loaded_bytes_match_bound_sha256": true,
"manifest_loaded_bytes_revalidated_read_only": true,
"manifest_override_absent_or_exact_canonical_path": true,
"manifest_packet_path_is_exact_canonical_relative_path": true,
"manifest_packet_sha256_matches_canonical_file": true,
"manifest_protocol_binding_matches_packet": true,
"manifest_psql_rc_disabled": true,
"manifest_sql_statically_read_only": true,
"manifest_transaction_read_only_enforced": true,
"packet_check_section_present_and_passing": true,
"packet_does_not_mutate_db": true,
"packet_has_no_authorization_recorded": true,
"packet_messages_exact": true,
"packet_not_sent": true,
"packet_prompt_ids_exact": true,
"packet_protocol_sha256_derivation_valid": true,
"packet_protocol_sha256_present": true,
"packet_protocol_top_level_bindings_match": true,
"packet_ready_for_authorization_request": true,
"packet_requires_authenticated_chrome": true,
"packet_schema_supported": true,
"packet_targets_exact_leo_chat": true,
"packet_tooling_hashes_match_current_sources": true
},
"packet_file_sha256": "76fb81d055a726de580d1c0ed75784b4576729e8e67badb6a4574677b2447ed0",
"packet_path": "docs/reports/leo-working-state-20260709/telegram-visible-unseen-chain-authorization-packet-current.json",
"phase": "preflight",
"production_apply_executed": false,
"protocol_sha256": "91cba55a23cac9061ac34a827a040f27eb6a018f720586304dd9b08ed113af77",
"ready_for_action_time_authorization": true,
"ready_for_visible_capture_verification": false,
"remote": {
"deploy_head": "626bac493e2b772db984be7a4a68e9da656f6b02",
"deploy_stamp_ancestor": true,
"fingerprint_after": {
"current_user": "pg_read_all_data",
"fingerprint_sha256": "32a1f2c18f4b4c623443cbd4d9520982e9f291ec74ca63855cef51c88ac56f24",
"schema": "livingip.teleoCanonicalDatabaseFingerprint.v1",
"status": "ok",
"structure_sha256": "61bf482330a652ebdb419de3fb78196f2c7d25d1a482b100f385e8102c8e8d52",
"table_count": 39,
"table_rows_sha256": "f50d86fc3ce699f602bdc0029485bd901fd98bd8114eecd5dcc4346a0f52112a",
"total_rows": 52167,
"transaction_read_only": "on"
},
"fingerprint_before": {
"current_user": "pg_read_all_data",
"fingerprint_sha256": "32a1f2c18f4b4c623443cbd4d9520982e9f291ec74ca63855cef51c88ac56f24",
"schema": "livingip.teleoCanonicalDatabaseFingerprint.v1",
"status": "ok",
"structure_sha256": "61bf482330a652ebdb419de3fb78196f2c7d25d1a482b100f385e8102c8e8d52",
"table_count": 39,
"table_rows_sha256": "f50d86fc3ce699f602bdc0029485bd901fd98bd8114eecd5dcc4346a0f52112a",
"total_rows": 52167,
"transaction_read_only": "on"
},
"last_deploy_sha": "626bac493e2b772db984be7a4a68e9da656f6b02",
"readback_attempts": {
"deploy": 1,
"fingerprint_after": 1,
"fingerprint_before": 1,
"service_after": 1,
"service_before": 1
},
"service_after": {
"ActiveState": "active",
"ExecMainStartTimestamp": "Tue 2026-07-14 22:59:43 UTC",
"MainPID": "347406",
"NRestarts": "0",
"SubState": "running"
},
"service_before": {
"ActiveState": "active",
"ExecMainStartTimestamp": "Tue 2026-07-14 22:59:43 UTC",
"MainPID": "347406",
"NRestarts": "0",
"SubState": "running"
},
"subject_readback": null,
"workspace_head_matches_deployed_stamp": true
},
"remote_checks": {
"canonical_fingerprint_unchanged_during_probe": true,
"deployed_stamp_is_ancestor_of_workspace_head": true,
"deployed_stamp_is_sha": true,
"fingerprints_are_read_only": true,
"fingerprints_use_independent_read_only_role": true,
"first_fingerprint_complete": true,
"second_fingerprint_complete": true,
"service_active_before_and_after": true,
"service_identity_complete": true,
"service_process_unchanged_during_probe": true,
"ssh_readbacks_succeeded": true,
"workspace_head_is_sha": true
},
"remote_returncode": 0,
"remote_stderr": "",
"schema": "livingip.telegramVisibleUnseenChainState.v2",
"state_token_sha256": "410677869ca2854f38b3e5017de2c682a2625d751fdff6600ac9bc40ce2fbc2e",
"status": "pass",
"subject_ref": "",
"telegram_visible_messages_sent_by_collector": false
}

View file

@ -0,0 +1,70 @@
# Telegram-Visible Unseen Chain Preflight
Generated UTC: `2026-07-15T02:33:56.887524+00:00`
Status: `pass`
Protocol SHA256: `91cba55a23cac9061ac34a827a040f27eb6a018f720586304dd9b08ed113af77`
Packet file SHA256: `76fb81d055a726de580d1c0ed75784b4576729e8e67badb6a4574677b2447ed0`
State token SHA256: `410677869ca2854f38b3e5017de2c682a2625d751fdff6600ac9bc40ce2fbc2e`
Messages sent by collector: `False`
Mutates DB: `False`
## Checks
- `manifest_arbitrary_override_forbidden`: `True`
- `manifest_canonical_path_exists`: `True`
- `manifest_default_transaction_read_only_enforced`: `True`
- `manifest_effective_role_is_read_only`: `True`
- `manifest_loaded_bytes_match_bound_sha256`: `True`
- `manifest_loaded_bytes_revalidated_read_only`: `True`
- `manifest_override_absent_or_exact_canonical_path`: `True`
- `manifest_packet_path_is_exact_canonical_relative_path`: `True`
- `manifest_packet_sha256_matches_canonical_file`: `True`
- `manifest_protocol_binding_matches_packet`: `True`
- `manifest_psql_rc_disabled`: `True`
- `manifest_sql_statically_read_only`: `True`
- `manifest_transaction_read_only_enforced`: `True`
- `packet_check_section_present_and_passing`: `True`
- `packet_does_not_mutate_db`: `True`
- `packet_has_no_authorization_recorded`: `True`
- `packet_messages_exact`: `True`
- `packet_not_sent`: `True`
- `packet_prompt_ids_exact`: `True`
- `packet_protocol_sha256_derivation_valid`: `True`
- `packet_protocol_sha256_present`: `True`
- `packet_protocol_top_level_bindings_match`: `True`
- `packet_ready_for_authorization_request`: `True`
- `packet_requires_authenticated_chrome`: `True`
- `packet_schema_supported`: `True`
- `packet_targets_exact_leo_chat`: `True`
- `packet_tooling_hashes_match_current_sources`: `True`
- `canonical_fingerprint_unchanged_during_probe`: `True`
- `deployed_stamp_is_ancestor_of_workspace_head`: `True`
- `deployed_stamp_is_sha`: `True`
- `fingerprints_are_read_only`: `True`
- `fingerprints_use_independent_read_only_role`: `True`
- `first_fingerprint_complete`: `True`
- `second_fingerprint_complete`: `True`
- `service_active_before_and_after`: `True`
- `service_identity_complete`: `True`
- `service_process_unchanged_during_probe`: `True`
- `ssh_readbacks_succeeded`: `True`
- `workspace_head_is_sha`: `True`
## Live Readback
- Deploy head: `626bac493e2b772db984be7a4a68e9da656f6b02`
- Deploy stamp: `626bac493e2b772db984be7a4a68e9da656f6b02`
- Gateway MainPID: `347406`
- Gateway NRestarts: `0`
- Manifest: `ops/postgres_parity_manifest.sql`
- Manifest SHA256: `8b8cdc25d54fdd8de05eb38c6e4423d2836953eb6012d4545f5c9c71b5f0150a`
- Effective DB role: `pg_read_all_data`
- Transaction read only: `on`
- Canonical fingerprint: `32a1f2c18f4b4c623443cbd4d9520982e9f291ec74ca63855cef51c88ac56f24`
- Canonical tables: `39`
- Canonical rows: `52167`
- Selected object ref: ``
## Claim Ceiling
Two canonical read-only snapshots and the gateway process were unchanged during this probe.

View file

@ -0,0 +1,91 @@
{
"schema": "livingip.observatoryReadAdapterOidcReadinessReceipt.v1",
"status": "partial_oidc_t2",
"required_runtime_tier": "T3_live_gcp_staging_api",
"current_runtime_tier": "T2_authenticated_github_oidc_partial_inventory",
"workflow": {
"run_id": 29389090997,
"url": "https://github.com/living-ip/teleo-infrastructure/actions/runs/29389090997",
"revision": "33399bd9acfa09e4e5409873e86c8c46ac694a8d",
"ref": "refs/heads/main",
"identity": "sa-artifact-builder@teleo-501523.iam.gserviceaccount.com",
"wif_authentication": "pass",
"gcloud_setup": "pass",
"checker_execution": "pass",
"artifact_upload": "pass",
"credential_cleanup": "pass",
"job_conclusion": "failure_due_to_blocked_readiness_enforcement"
},
"summary": {
"pass_count": 8,
"blocked_count": 10,
"fail_count": 0,
"passed_checks": [
"artifact_repositories",
"cloud_build_contract",
"github_actions_readiness_ci",
"gcp_cloudsql_restore_drill_contract",
"canonical_postgres_restore_contract",
"local_canonical_postgres_restore_preflight",
"gcp_runtime_baseline_contract",
"gcp_service_communications_contract"
],
"permission_or_resource_read_blocks": [
{
"check": "cloud_build_service_account",
"missing_permission": "iam.serviceAccounts.get"
},
{
"check": "github_actions_artifact_ci",
"missing_permission": "iam.workloadIdentityPoolProviders.get"
},
{
"check": "network_ingress",
"missing_permission": "compute.firewalls.list"
},
{
"check": "compute_runtime_service_accounts",
"missing_permission": "compute.instances.list"
},
{
"check": "compute_disk_snapshots",
"missing_permission": "compute.resourcePolicies.get"
},
{
"check": "backup_buckets",
"missing_permission": "bucket metadata read denied; exact permission was not retained by the checker"
},
{
"check": "cloud_sql_standby_target",
"missing_permission": "Cloud SQL instance read denied or target invisible to this identity"
},
{
"check": "kb_source_restore_access",
"missing_permission": "secretmanager.secrets.list"
}
],
"evidence_blocks": [
"local_sqlite_postgres_restore_canary",
"kb_restore_or_replication"
]
},
"security_readback": {
"artifact_builder_deploy_authorized": false,
"cloud_run_service_created": false,
"cloud_sql_queried": false,
"secret_values_logged": false,
"production_or_vercel_routing_changed": false
},
"source_artifact": {
"github_run_url": "https://github.com/living-ip/teleo-infrastructure/actions/runs/29389090997",
"artifact_name": "gcp-readiness",
"summary_sha256": "6a1be356c069b8affacc492ac3b1e1ca63b917f92a32d7d886511a226c52925b",
"checker_sha256": "56ce4e8ba655a47e6e620a2c7039ee54fa10b1c53431d1dc6ec4db5189bb17f5",
"local_download_path": "/private/tmp/observatory-read-adapter-oidc-29389090997/gcp-readiness"
},
"proof_paths": [
"docs/reports/observatory-read-adapter/gcp-oidc-readiness-29389090997-redacted.json",
"https://github.com/living-ip/teleo-infrastructure/actions/runs/29389090997"
],
"claim_ceiling": "GitHub OIDC and the artifact-only identity work. The receipt does not prove broad GCP inventory, adapter prerequisites, a live Cloud Run service, or a teleo_canonical query."
}

View file

@ -0,0 +1,52 @@
{
"schema": "livingip.observatoryReadAdapterCurrentGate.v1",
"current_canary": "Authenticated GET /v1/claims/sample in GCP staging returns a provenance-bearing teleo_canonical claim, anonymous GET returns 401, and authenticated POST returns 405.",
"required_runtime_tier": "T3_live_gcp_staging_api",
"current_runtime_tier": "T2_authenticated_github_oidc_partial_inventory",
"attempted_routes": [
{
"route": "merged GitHub Actions deployment with artifact-builder WIF",
"result": "OIDC, image build, smoke, and push passed; the 29382683335 deploy stopped before resource creation because run.googleapis.com was disabled"
},
{
"route": "GitHub Actions GCP readiness with artifact-builder WIF, run 29389090997",
"result": "federation, gcloud setup, checker, artifact upload, and credential cleanup passed; checker result was 8 pass, 10 blocked, 0 fail"
},
{
"route": "local billy@livingip.xyz gcloud user and application-default credentials",
"result": "both require interactive Google reauthentication before project-admin API or IAM changes"
},
{
"route": "other locally authenticated Google accounts",
"result": "valid tokens but no access to project teleo-501523"
},
{
"route": "fixed read-only GCP IAP status workflow",
"result": "WIF token exchange failed because the teleo-iap-operator provider target is missing or disabled"
}
],
"exact_gate": {
"non_gui_federation": "Working. sa-artifact-builder can federate through living-ip-github and read/push Artifact Registry resources.",
"artifact_builder_scope": "Intentionally insufficient for deployment or full inventory. Do not grant it Cloud Run, Cloud SQL, Compute, IAM, or Secret Manager deployment roles.",
"last_api_readback": "The last direct deployment reported run.googleapis.com disabled. The current artifact-builder identity cannot verify or enable the required project APIs.",
"t3_bootstrap": "An authenticated teleo-501523 administrator must review and apply ops/plan_observatory_read_adapter_gcp.py, including required APIs, dedicated deploy/runtime identities, the exact workflow/main-only observatory-read-adapter-main WIF provider, five-permission Cloud Run custom role, exact Cloud SQL instance grants, exact secret grants, trimmed IAM database user, and private database role SQL.",
"local_operator": "billy@livingip.xyz requires Google password or MFA reauthentication before that administrator action can run.",
"alternate_private_operator": "The fixed teleo-iap-operator provider is absent or disabled and is not an available substitute."
},
"latest_direct_non_gui_check": {
"active_account": "billy@livingip.xyz",
"gcloud_projects_describe": "blocked: reauthentication failed and non-interactive execution cannot prompt",
"application_default_credentials": "blocked: reauthentication failed and non-interactive execution cannot prompt",
"full_readiness_checker_executed": false,
"why_not": "The required first command, gcloud projects describe teleo-501523, did not pass."
},
"why_t3_stops": "A live staging service requires authorized API, IAM, Secret Manager, Cloud SQL IAM-user, and private database-role mutations. Working artifact-builder federation does not authorize those actions.",
"clear_CTA": "Run `gcloud auth login billy@livingip.xyz --update-adc`, then `gcloud projects describe teleo-501523 --format=value(projectId)` and `python3 ops/check_gcp_infra_readiness.py`; review and apply the exact adapter packet emitted by `python3 ops/plan_observatory_read_adapter_gcp.py --format shell`.",
"next_non_user_action": "Dispatch action=preflight_staging from merged main using sa-observatory-deployer. Only after its redacted preflight artifact passes, dispatch the bounded staging deploy and capture authenticated GET, anonymous 401, authenticated POST 405, database write-denial, exact service/database identity, and cleanup receipts.",
"production_boundary": "Do not change Vercel, production routing, Cloud SQL network exposure, Telegram, x402, or any write endpoint.",
"proof_paths": [
"docs/reports/observatory-read-adapter/gcp-oidc-readiness-29389090997-redacted.json",
"docs/reports/observatory-read-adapter/gcp-staging-live-attempt-redacted.json",
"https://github.com/living-ip/teleo-infrastructure/actions/runs/29389090997"
]
}

View file

@ -0,0 +1,84 @@
{
"schema": "livingip.observatoryReadAdapterStagingReceipt.v1",
"status": "blocked_before_runtime_creation",
"required_runtime_tier": "T3_live_gcp_staging_api",
"current_runtime_tier": "T2_authenticated_github_oidc_partial_inventory",
"project_id": "teleo-501523",
"region": "europe-west6",
"service_name": "observatory-read-adapter-staging",
"database_name": "teleo_canonical",
"cloud_sql_instance": "teleo-501523:europe-west6:teleo-pgvector-standby",
"authorization_role": "kb_observatory_read",
"runtime_service_account": "sa-observatory-read-adapter@teleo-501523.iam.gserviceaccount.com",
"image": {
"revision": "53c8de0a1959a744e17888df1a70e935dfef0143",
"digest": "sha256:b5c9b2051559730cbb9003d74e5d8e577fa2f43f49b72577f251f2843a0650c5",
"artifact_registry_push": "pass",
"container_smoke": "pass",
"intentional_retained_resource": true
},
"workflow": {
"run_id": 29382683335,
"url": "https://github.com/living-ip/teleo-infrastructure/actions/runs/29382683335",
"build_job": "success",
"deploy_job": "failure",
"failure_class": "SERVICE_DISABLED",
"failure_detail": "run.googleapis.com is disabled in teleo-501523",
"authenticated_as": "sa-artifact-builder@teleo-501523.iam.gserviceaccount.com"
},
"readiness_reconciliation": {
"run_id": 29389090997,
"url": "https://github.com/living-ip/teleo-infrastructure/actions/runs/29389090997",
"identity": "sa-artifact-builder@teleo-501523.iam.gserviceaccount.com",
"wif_authentication": "pass",
"checker_result": {
"pass_count": 8,
"blocked_count": 10,
"fail_count": 0
},
"claim": "working federation with an intentionally narrow artifact identity; not a staging deploy or full inventory"
},
"live_receipts": {
"service_url": null,
"authenticated_get_sample": null,
"anonymous_get_401": null,
"authenticated_post_405": null,
"database_write_denial": null,
"database_identity": null
},
"negative_claims": {
"cloud_run_service_created": false,
"cloud_sql_public_exposure_changed": false,
"production_or_vercel_routing_changed": false,
"credentials_logged": false
},
"cleanup": {
"github_jobs_completed": true,
"local_observatory_test_containers": 0,
"local_observatory_test_images": 0,
"orphan_local_build_processes": 0,
"artifact_registry_image_retained_for_next_deploy": true
},
"source_artifacts": [
{
"run_url": "https://github.com/living-ip/teleo-infrastructure/actions/runs/29382683335",
"artifact_name": "observatory-adapter-image",
"sha256": "6d958b8d345ec878db2f70aaab5fad4318b106441983bd7f8e9170a429f4e852"
},
{
"run_url": "https://github.com/living-ip/teleo-infrastructure/actions/runs/29382844567",
"artifact_name": "gcp-iap-operator-29382844567",
"sha256": "988f77123f7624469c15e3c38bc1e8864a1e9f61e571feb5f6c838e67fe039e9"
},
{
"run_url": "https://github.com/living-ip/teleo-infrastructure/actions/runs/29389090997",
"artifact_name": "gcp-readiness",
"sha256": "6a1be356c069b8affacc492ac3b1e1ca63b917f92a32d7d886511a226c52925b"
}
],
"proof_paths": [
"docs/reports/observatory-read-adapter/gcp-staging-live-attempt-redacted.json",
"docs/reports/observatory-read-adapter/gcp-oidc-readiness-29389090997-redacted.json"
],
"claim_ceiling": "The immutable staging image and working artifact-only OIDC path exist, but no live API or database query receipt exists. T3 is not complete."
}

View file

@ -0,0 +1,12 @@
{
"fallback_goal_path": "goal.md",
"platform_goal_after": {
"objective": "Complete and verify the private GCP Observatory read adapter defined in this goal file, stopping before production repoint without exact authorization.",
"status": "active",
"thread_id": "019f6350-69fa-71f3-944b-3fc0065f4fec"
},
"platform_goal_before": null,
"platform_goal_repair_action": "create_goal",
"platform_goal_replaced": false,
"why_not_replaced": "No prior platform Goal existed; a new active Goal was created from goal.md."
}

View file

@ -0,0 +1,52 @@
{
"schema": "livingip.workingLeoSourceIngestionScenario.v2",
"artifact": {
"path": "document-ingestion-v2.txt",
"format": "plain_text"
},
"source": {
"identity": "document:working-leo-review-gated-composition-v2",
"source_key": "working_leo_document_ingestion_v2",
"source_type": "article",
"title": "Working Leo review-gated composition note",
"locator": "fixture://working-leo/document-ingestion-v2",
"metadata": {
"author": "Working Leo synthetic canary fixture",
"captured_at": "2026-07-15T00:00:00Z",
"document_kind": "operating_note",
"language": "en",
"synthetic": true
}
},
"extractor": {
"name": "deterministic_fixture_replay",
"version": "2"
},
"extraction": {
"claims": [
{
"claim_key": "staged_proposal_remains_noncanonical",
"type": "structural",
"confidence": 0.75,
"text": "A staged knowledge proposal remains non-canonical until review and guarded apply succeed.",
"body": "A staged proposal remains non-canonical until an operator reviews it and a separate guarded apply succeeds.",
"metadata": {
"needs_research": false
},
"evidence": [
{
"segment_id": "paragraph-2",
"role": "grounds",
"excerpt": "A staged proposal remains non-canonical until an operator reviews it and a separate guarded apply succeeds.",
"metadata": {
"evidence_kind": "exact_quote"
}
}
],
"edges": []
}
],
"duplicates": [],
"conflicts": []
}
}

View file

@ -0,0 +1,5 @@
Working Leo composition note. A newly captured document may produce claim and evidence candidates, but those candidates are not canonical knowledge.
A staged proposal remains non-canonical until an operator reviews it and a separate guarded apply succeeds. The proposal must retain the source content hash, exact evidence excerpt, and source identity so reviewers can trace every planned row back to the captured artifact.
For a staging-only rehearsal, pending_review is the terminal state. No public knowledge-base row should be written.

View file

@ -0,0 +1,3 @@
"""Pinned fixture prompt boundary."""
GENERATED_SOUL_IS_AUTHORITY = False

View file

@ -0,0 +1,3 @@
"""Pinned fixture process boundary; the canary uses the real profile verifier."""
SESSION_STATE_IS_IDENTITY = False

View file

@ -0,0 +1,3 @@
"""Pinned fixture tool configuration."""
ALLOWED_TOOLS = ("identity_readback",)

View file

@ -0,0 +1,3 @@
"""Pinned fixture entrypoint for the disposable identity runtime."""
RUNTIME_NAME = "leo-identity-readback-v1"

View file

@ -0,0 +1,3 @@
"""Pinned fixture registry for the no-send identity readback tool."""
REGISTERED_TOOLS = ("identity_readback",)

View file

@ -0,0 +1,18 @@
{
"identity_name": "Leo",
"rules": [
{
"id": "canonical-evidence",
"text": "Treat canonical database rows and their bound evidence as durable knowledge; never promote session memory to evidence."
},
{
"id": "review-before-apply",
"text": "Proposals may be prepared, but review and guarded apply remain separate authorized actions."
},
{
"id": "truthful-proof-tier",
"text": "State exactly what was observed, separate inference from proof, and fail closed when required provenance drifts."
}
],
"schema": "livingip.leoConstitutionSource.v1"
}

View file

@ -0,0 +1,25 @@
{
"environment": "disposable_fixture",
"fingerprint_sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"read_consistency": {
"after": {
"database": "leo_identity_fixture",
"database_user": "leo_identity_reader",
"system_identifier": "7649789040005668902",
"wal_lsn": "0/16B6C50"
},
"before": {
"database": "leo_identity_fixture",
"database_user": "leo_identity_reader",
"system_identifier": "7649789040005668902",
"wal_lsn": "0/16B6C50"
},
"status": "stable_wal_marker"
},
"schema": "livingip.teleoCanonicalDatabaseFingerprint.v1",
"status": "ok",
"structure_sha256": "3333333333333333333333333333333333333333333333333333333333333333",
"table_count": 7,
"table_rows_sha256": "2222222222222222222222222222222222222222222222222222222222222222",
"total_rows": 7
}

View file

@ -0,0 +1,58 @@
{
"database_fingerprint_sha256": "1111111111111111111111111111111111111111111111111111111111111111",
"identity_name": "Leo",
"source_provenance": {
"canonical_authority_granted": false,
"export_receipt_sha256": null,
"mode": "synthetic_noncanonical_fixture",
"same_transaction_as_fingerprint": false
},
"records": [
{
"evidence_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"kind": "persona",
"rank": 0,
"row_id": "11111111-1111-4111-8111-111111111111",
"status": "active",
"table": "public.personas",
"text": "Leo is the evidence-bound reasoning interface for the Teleo collective."
},
{
"evidence_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"kind": "strategy",
"rank": 0,
"row_id": "22222222-2222-4222-8222-222222222222",
"status": "active",
"table": "public.strategies",
"text": "Prefer source-grounded synthesis that exposes uncertainty and review boundaries."
},
{
"evidence_sha256": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
"kind": "belief",
"rank": 0,
"row_id": "33333333-3333-4333-8333-333333333333",
"status": "active",
"table": "public.beliefs",
"text": "A plausible answer without provenance is weaker than a bounded answer with an exact receipt."
},
{
"evidence_sha256": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
"kind": "shared_root",
"rank": 0,
"row_id": "44444444-4444-4444-8444-444444444444",
"status": "active",
"table": "public.shared_root",
"text": "Collective intelligence must remain inspectable, reversible, and accountable to evidence."
},
{
"evidence_sha256": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"kind": "strategy_node",
"rank": 1,
"row_id": "55555555-5555-4555-8555-555555555555",
"status": "active",
"table": "public.strategy_nodes",
"text": "Compile identity from exact canonical inputs and reject drift before runtime startup."
}
],
"schema": "livingip.leoDatabaseIdentitySource.v1"
}

View file

@ -0,0 +1,5 @@
#!/usr/bin/env python3
"""Fixture marker for the no-send identity readback tool."""
ACCESS_MODE = "read_only"
NETWORK_SEND_ENABLED = False

View file

@ -0,0 +1,24 @@
model:
provider: fixture-local
default: leo-identity-readback-v1
smart_routing: false
max_tokens: 512
agent:
reasoning_effort: deterministic
memory:
enabled: false
search: disabled
gateway:
execution_mode: local_no_send
telegram:
posting_enabled: false
bot_token: fixture-value-is-never-emitted-or-identity-hashed
tools:
allowed:
- identity_readback
write_enabled: false
identity_runtime:
network_send_enabled: false
database_write_enabled: false
allowed_tools:
- identity_readback

View file

@ -0,0 +1,4 @@
"""Fixture marker for the pinned identity-boundary middleware."""
IDENTITY_VIEW_IS_AUTHORITY = False
SESSION_MEMORY_IS_EVIDENCE = False

View file

@ -0,0 +1,3 @@
name: identity-boundary
version: 1
description: Reject startup when a compiled identity view drifts.

View file

@ -0,0 +1,8 @@
---
name: identity-readback
description: Explain the pinned Leo identity and its noncanonical session boundary.
---
Read only the compiled identity view and its manifest receipt. Never treat a
session transcript, generated SOUL file, or unverified runtime memory as a
canonical source.

View file

@ -0,0 +1,3 @@
{"ts":"2026-07-15T09:00:01Z","chat_id":900001,"chat_title":"Synthetic review gate thread","message_id":7301,"type":"message","username":"fixture_analyst","display_name":"Fixture Analyst","user_id":910001,"message":"A pending review does not change canonical knowledge; only a separate guarded apply can do that.","reply_to":null,"synthetic":true}
{"ts":"2026-07-15T09:00:12Z","chat_id":900001,"chat_title":"Synthetic review gate thread","message_id":7302,"type":"message","username":"fixture_operator","display_name":"Fixture Operator","user_id":910002,"message":"Reviewer approval alone makes the proposal canonical immediately; no apply step is needed.","reply_to":7301,"synthetic":true}
{"ts":"2026-07-15T09:00:24Z","chat_id":900001,"chat_title":"Synthetic review gate thread","message_id":7303,"type":"message","username":"fixture_reviewer","display_name":"Fixture Reviewer","user_id":910003,"message":"A pending review does not change canonical knowledge; only a separate guarded apply can do that.","reply_to":7302,"synthetic":true}

View file

@ -0,0 +1,99 @@
{
"schema": "livingip.workingLeoSourceIngestionScenario.v2",
"artifact": {
"path": "telegram-transcript-ingestion-v1.jsonl",
"format": "telegram_jsonl"
},
"source": {
"identity": "fixture:telegram-chat-900001-export-20260715",
"source_key": "telegram_review_gate_exchange_20260715",
"source_type": "transcript",
"title": "Synthetic Telegram review-gate exchange",
"locator": "fixture://working-leo/telegram-transcript-ingestion-v1",
"metadata": {
"captured_at": "2026-07-15T09:01:00Z",
"export_format": "teleo_append_only_telegram_jsonl",
"language": "en",
"synthetic": true
}
},
"extractor": {
"name": "deterministic_telegram_jsonl_replay",
"version": "1"
},
"extraction": {
"claims": [
{
"claim_key": "pending_review_does_not_change_canonical",
"type": "structural",
"confidence": 0.7,
"text": "Pending review alone does not change canonical knowledge.",
"body": "A pending review does not change canonical knowledge; only a separate guarded apply can do that.",
"metadata": {
"needs_research": false
},
"evidence": [
{
"segment_id": "message-900001-7301",
"role": "grounds",
"excerpt": "A pending review does not change canonical knowledge; only a separate guarded apply can do that.",
"metadata": {
"evidence_kind": "exact_message"
}
},
{
"segment_id": "message-900001-7303",
"role": "illustrates",
"excerpt": "A pending review does not change canonical knowledge; only a separate guarded apply can do that.",
"metadata": {
"evidence_kind": "duplicate_exact_message"
}
}
],
"edges": [
{
"edge_type": "contradicts",
"target": "approval_alone_makes_canonical"
}
]
},
{
"claim_key": "approval_alone_makes_canonical",
"type": "empirical",
"confidence": 0.4,
"text": "Reviewer approval alone makes a proposal canonical without apply.",
"body": "Reviewer approval alone makes the proposal canonical immediately; no apply step is needed.",
"metadata": {
"needs_research": true
},
"evidence": [
{
"segment_id": "message-900001-7302",
"role": "grounds",
"excerpt": "Reviewer approval alone makes the proposal canonical immediately; no apply step is needed.",
"metadata": {
"evidence_kind": "exact_message"
}
}
],
"edges": []
}
],
"duplicates": [
{
"segment_id": "message-900001-7303",
"duplicate_of_claim_key": "pending_review_does_not_change_canonical",
"excerpt": "A pending review does not change canonical knowledge; only a separate guarded apply can do that.",
"reason": "Message 7303 repeats message 7301 exactly and is retained as explicit duplicate evidence."
}
],
"conflicts": [
{
"from_claim_key": "pending_review_does_not_change_canonical",
"to_claim_key": "approval_alone_makes_canonical",
"relationship": "contradicts",
"reason": "The two candidate propositions assert incompatible canonical-state transitions."
}
]
}
}

View file

@ -0,0 +1,6 @@
"""Authenticated, read-only Observatory adapter for canonical Teleo claims."""
from .app import create_app
from .config import Settings
__all__ = ["Settings", "create_app"]

View file

@ -0,0 +1,18 @@
from __future__ import annotations
import logging
from aiohttp import web
from .app import create_app
from .config import Settings
def main() -> None:
logging.basicConfig(level=logging.INFO)
settings = Settings.from_env()
web.run_app(create_app(settings), host="0.0.0.0", port=settings.port)
if __name__ == "__main__":
main()

View file

@ -0,0 +1,111 @@
from __future__ import annotations
import asyncio
import hmac
import logging
import uuid
from typing import Any
from aiohttp import web
from .config import Settings
from .db import CloudSqlClaimReader
logger = logging.getLogger("teleo.observatory_read_adapter")
SETTINGS_KEY = web.AppKey("observatory_settings", Settings)
READER_KEY = web.AppKey("observatory_reader", object)
PUBLIC_PATHS = frozenset({"/healthz", "/readyz"})
def _private_json(payload: dict[str, Any], *, status: int = 200) -> web.Response:
response = web.json_response(payload, status=status)
response.headers["Cache-Control"] = "private, no-store, max-age=0"
response.headers["Pragma"] = "no-cache"
response.headers["Vary"] = "X-Api-Key"
response.headers["X-Content-Type-Options"] = "nosniff"
return response
@web.middleware
async def api_key_auth(request: web.Request, handler: Any) -> web.StreamResponse:
if request.path in PUBLIC_PATHS:
return await handler(request)
settings = request.app[SETTINGS_KEY]
provided = request.headers.get("X-Api-Key", "")
try:
authenticated = hmac.compare_digest(
provided.encode("ascii"),
settings.api_key.encode("ascii"),
)
except UnicodeEncodeError:
authenticated = False
if not authenticated:
return _private_json({"error": "unauthorized"}, status=401)
return await handler(request)
async def healthz(_request: web.Request) -> web.Response:
return web.json_response({"status": "ok"})
async def readyz(request: web.Request) -> web.Response:
reader = request.app[READER_KEY]
try:
await asyncio.wait_for(asyncio.to_thread(reader.check_ready), timeout=12.0)
except Exception as exc:
logger.warning("readiness check failed (%s)", type(exc).__name__)
return web.json_response({"status": "unavailable"}, status=503)
return web.json_response({"status": "ready"})
async def get_sample_claim(request: web.Request) -> web.Response:
return await _claim_response(request, None)
async def get_claim(request: web.Request) -> web.Response:
raw_claim_id = request.match_info["claim_id"]
try:
claim_id = str(uuid.UUID(raw_claim_id))
except ValueError:
return _private_json({"error": "invalid_claim_id"}, status=400)
return await _claim_response(request, claim_id)
async def _claim_response(request: web.Request, claim_id: str | None) -> web.Response:
reader = request.app[READER_KEY]
try:
payload = await asyncio.wait_for(
asyncio.to_thread(reader.read_claim, claim_id),
timeout=12.0,
)
except Exception as exc:
logger.error("canonical claim read failed (%s)", type(exc).__name__)
return _private_json({"error": "canonical_claim_unavailable"}, status=503)
if payload is None:
return _private_json({"error": "claim_not_found"}, status=404)
return _private_json(payload)
async def _cleanup(app: web.Application) -> None:
reader = app[READER_KEY]
await asyncio.to_thread(reader.close)
def create_app(
settings: Settings | None = None,
*,
reader: Any | None = None,
) -> web.Application:
settings = settings or Settings.from_env()
settings.validate()
reader = reader or CloudSqlClaimReader(settings)
app = web.Application(middlewares=[api_key_auth], client_max_size=16 * 1024)
app[SETTINGS_KEY] = settings
app[READER_KEY] = reader
app.router.add_get("/healthz", healthz)
app.router.add_get("/readyz", readyz)
app.router.add_get("/v1/claims/sample", get_sample_claim)
app.router.add_get("/v1/claims/{claim_id}", get_claim)
app.on_cleanup.append(_cleanup)
return app

View file

@ -0,0 +1,61 @@
from __future__ import annotations
import os
from dataclasses import dataclass, field
EXPECTED_PROJECT = "teleo-501523"
EXPECTED_REGION = "europe-west6"
EXPECTED_INSTANCE = "teleo-pgvector-standby"
EXPECTED_CONNECTION_NAME = f"{EXPECTED_PROJECT}:{EXPECTED_REGION}:{EXPECTED_INSTANCE}"
EXPECTED_DATABASE = "teleo_canonical"
EXPECTED_AUTHORIZATION_ROLE = "kb_observatory_read"
@dataclass(frozen=True)
class Settings:
project_id: str
instance_connection_name: str
database: str
iam_database_user: str
authorization_role: str
api_key: str = field(repr=False)
service_revision: str = "unknown"
port: int = 8080
@classmethod
def from_env(cls) -> Settings:
settings = cls(
project_id=os.environ.get("GCP_PROJECT_ID", ""),
instance_connection_name=os.environ.get("CLOUD_SQL_INSTANCE", ""),
database=os.environ.get("DB_NAME", ""),
iam_database_user=os.environ.get("DB_IAM_USER", ""),
authorization_role=os.environ.get("DB_AUTHORIZATION_ROLE", ""),
api_key=os.environ.get("OBSERVATORY_API_KEY", ""),
service_revision=os.environ.get("SERVICE_REVISION", "unknown"),
port=int(os.environ.get("PORT", "8080")),
)
settings.validate()
return settings
def validate(self) -> None:
if self.project_id != EXPECTED_PROJECT:
raise ValueError(f"GCP_PROJECT_ID must be {EXPECTED_PROJECT}")
if self.instance_connection_name != EXPECTED_CONNECTION_NAME:
raise ValueError(f"CLOUD_SQL_INSTANCE must be {EXPECTED_CONNECTION_NAME}")
if self.database != EXPECTED_DATABASE:
raise ValueError(f"DB_NAME must be {EXPECTED_DATABASE}")
if self.authorization_role != EXPECTED_AUTHORIZATION_ROLE:
raise ValueError(f"DB_AUTHORIZATION_ROLE must be {EXPECTED_AUTHORIZATION_ROLE}")
if not self.iam_database_user.endswith(f"@{EXPECTED_PROJECT}.iam"):
raise ValueError("DB_IAM_USER must be the scoped Cloud SQL service-account user")
if any(character.isspace() for character in self.iam_database_user):
raise ValueError("DB_IAM_USER must not contain whitespace")
if (
len(self.api_key) < 32
or len(self.api_key) > 512
or not self.api_key.isascii()
or any(character.isspace() for character in self.api_key)
):
raise ValueError("OBSERVATORY_API_KEY must be 32-512 non-whitespace ASCII characters")
if not 1 <= self.port <= 65535:
raise ValueError("PORT is outside the valid TCP port range")

View file

@ -0,0 +1,315 @@
from __future__ import annotations
from collections.abc import Callable
from datetime import date, datetime, timezone
from decimal import Decimal
from typing import Any
from .config import Settings
ConnectionFactory = Callable[[], Any]
class ReaderContractError(RuntimeError):
"""The live database session does not match the adapter's read-only contract."""
def _json_value(value: Any) -> Any:
if isinstance(value, Decimal):
return float(value)
if isinstance(value, (date, datetime)):
return value.isoformat()
if isinstance(value, tuple):
return list(value)
return value
def _column_name(column: Any) -> str:
return str(column.name) if hasattr(column, "name") else str(column[0])
def _row_dict(cursor: Any, row: Any) -> dict[str, Any] | None:
if row is None:
return None
names = [_column_name(column) for column in cursor.description]
return {name: _json_value(value) for name, value in zip(names, row, strict=True)}
def _rows(cursor: Any) -> list[dict[str, Any]]:
names = [_column_name(column) for column in cursor.description]
return [
{name: _json_value(value) for name, value in zip(names, row, strict=True)}
for row in cursor.fetchall()
]
class CloudSqlClaimReader:
def __init__(self, settings: Settings, *, connection_factory: ConnectionFactory | None = None):
self.settings = settings
self._connector: Any | None = None
if connection_factory is not None:
self._connection_factory = connection_factory
return
from google.cloud.sql.connector import Connector, IPTypes
self._connector = Connector(refresh_strategy="LAZY")
def connect() -> Any:
return self._connector.connect(
settings.instance_connection_name,
"pg8000",
user=settings.iam_database_user,
db=settings.database,
enable_iam_auth=True,
ip_type=IPTypes.PRIVATE,
)
self._connection_factory = connect
def close(self) -> None:
if self._connector is not None:
self._connector.close()
def check_ready(self) -> dict[str, Any]:
connection = self._connection_factory()
try:
cursor = connection.cursor()
self._begin_read_only(cursor)
session = self._load_session_contract(cursor)
connection.rollback()
return {
"ready": True,
"database": session["database"],
"authorization_role": self.settings.authorization_role,
"transaction_read_only": True,
}
finally:
connection.close()
def read_claim(self, claim_id: str | None = None) -> dict[str, Any] | None:
connection = self._connection_factory()
try:
cursor = connection.cursor()
self._begin_read_only(cursor)
session = self._load_session_contract(cursor)
claim = self._load_claim(cursor, claim_id)
if claim is None:
connection.rollback()
return None
evidence = self._load_evidence(cursor, claim["id"])
edges = self._load_edges(cursor, claim["id"])
proposal_counts = self._load_proposal_counts(cursor)
related_proposals = self._load_related_proposals(cursor, claim["id"])
recent_proposals = self._load_recent_proposals(cursor)
connection.rollback()
finally:
connection.close()
generated_at = datetime.now(timezone.utc).isoformat()
return {
"schema": "livingip.observatory-canonical-claim.v1",
"generated_at": generated_at,
"read_only": True,
"provenance": {
"gcp_project": self.settings.project_id,
"cloud_sql_instance": self.settings.instance_connection_name,
"database": session["database"],
"database_principal": session["database_principal"],
"authorization_role": self.settings.authorization_role,
"transaction_read_only": True,
"write_privileges_denied": bool(session["required_writes_denied"]),
"service_revision": self.settings.service_revision,
},
"canonical": {
"relation": "public.claims",
"claim": claim,
"evidence_relation": "public.claim_evidence -> public.sources",
"evidence": evidence,
"edge_relation": "public.claim_edges",
"edges": edges,
},
"proposal_ledger": {
"relation": "kb_stage.kb_proposals",
"distinct_from_canonical": True,
"status_counts": proposal_counts,
"related": related_proposals,
"recent": recent_proposals,
"semantics": {
"pending_review": "staged only; not canonical",
"approved": "reviewed intent; not canonical until applied_at is set",
"applied": "proposal receipt only; canonical rows remain authoritative",
},
},
}
@staticmethod
def _begin_read_only(cursor: Any) -> None:
cursor.execute("set transaction read only")
cursor.execute("set local statement_timeout = '5000ms'")
cursor.execute("set local lock_timeout = '1000ms'")
def _load_session_contract(self, cursor: Any) -> dict[str, Any]:
cursor.execute(
"""
select current_database() as database,
current_user as database_principal,
current_setting('transaction_read_only') as transaction_read_only,
pg_has_role(current_user, %s, 'member') as has_authorization_role,
has_table_privilege(current_user, 'public.claims', 'select')
and has_table_privilege(current_user, 'public.sources', 'select')
and has_table_privilege(current_user, 'public.claim_evidence', 'select')
and has_table_privilege(current_user, 'public.claim_edges', 'select')
and has_table_privilege(current_user, 'kb_stage.kb_proposals', 'select')
as has_required_reads,
not (
has_table_privilege(current_user, 'public.claims', 'insert,update,delete,truncate')
or has_table_privilege(current_user, 'public.sources', 'insert,update,delete,truncate')
or has_table_privilege(current_user, 'public.claim_evidence', 'insert,update,delete,truncate')
or has_table_privilege(current_user, 'public.claim_edges', 'insert,update,delete,truncate')
or has_table_privilege(current_user, 'kb_stage.kb_proposals', 'insert,update,delete,truncate')
) as required_writes_denied
""",
(self.settings.authorization_role,),
)
session = _row_dict(cursor, cursor.fetchone())
if session is None:
raise ReaderContractError("database session contract returned no row")
if session["database"] != self.settings.database:
raise ReaderContractError("database session selected an unexpected database")
if session["database_principal"] != self.settings.iam_database_user:
raise ReaderContractError("database session selected an unexpected principal")
if session["transaction_read_only"] != "on":
raise ReaderContractError("database session is not read-only")
if not session["has_authorization_role"] or not session["has_required_reads"]:
raise ReaderContractError("database principal lacks the exact read authorization")
if not session["required_writes_denied"]:
raise ReaderContractError("database principal has an unexpected write privilege")
return session
@staticmethod
def _load_claim(cursor: Any, claim_id: str | None) -> dict[str, Any] | None:
columns = """
select c.id::text as id,
c.type::text as type,
left(c.text, 12000) as text,
c.status::text as status,
c.confidence,
coalesce(c.tags, '{}'::text[]) as tags,
c.superseded_by::text as superseded_by,
c.created_at,
c.updated_at
from public.claims c
"""
if claim_id is not None:
cursor.execute(columns + " where c.id = %s::uuid", (claim_id,))
return _row_dict(cursor, cursor.fetchone())
cursor.execute(
columns
+ """
where exists (
select 1 from public.claim_evidence ce where ce.claim_id = c.id
)
order by coalesce(c.updated_at, c.created_at) desc, c.id desc
limit 1
"""
)
claim = _row_dict(cursor, cursor.fetchone())
if claim is not None:
return claim
cursor.execute(columns + " order by coalesce(c.updated_at, c.created_at) desc, c.id desc limit 1")
return _row_dict(cursor, cursor.fetchone())
@staticmethod
def _load_evidence(cursor: Any, claim_id: str) -> list[dict[str, Any]]:
cursor.execute(
"""
select ce.id::text as evidence_id,
ce.role::text as role,
ce.weight,
ce.created_at as linked_at,
s.id::text as source_id,
s.source_type::text as source_type,
s.url,
s.storage_path,
left(coalesce(s.excerpt, ''), 2400) as excerpt,
s.hash as content_hash,
s.captured_at,
s.created_at as source_created_at
from public.claim_evidence ce
join public.sources s on s.id = ce.source_id
where ce.claim_id = %s::uuid
order by ce.weight desc nulls last, ce.created_at, ce.id
limit 30
""",
(claim_id,),
)
return _rows(cursor)
@staticmethod
def _load_edges(cursor: Any, claim_id: str) -> list[dict[str, Any]]:
cursor.execute(
"""
select e.id::text as edge_id,
case when e.from_claim = %s::uuid then 'outgoing' else 'incoming' end as direction,
e.edge_type::text as edge_type,
e.weight,
case when e.from_claim = %s::uuid then e.to_claim::text else e.from_claim::text end
as connected_claim_id,
e.created_at
from public.claim_edges e
where e.from_claim = %s::uuid or e.to_claim = %s::uuid
order by e.created_at, e.id
limit 40
""",
(claim_id, claim_id, claim_id, claim_id),
)
return _rows(cursor)
@staticmethod
def _load_proposal_counts(cursor: Any) -> dict[str, int]:
cursor.execute(
"select status::text as status, count(*)::int as count "
"from kb_stage.kb_proposals group by status order by status"
)
return {str(status): int(count) for status, count in cursor.fetchall()}
@staticmethod
def _load_related_proposals(cursor: Any, claim_id: str) -> list[dict[str, Any]]:
cursor.execute(
"""
select p.id::text as id,
p.proposal_type::text as proposal_type,
p.status::text as status,
to_jsonb(p)->>'source_ref' as source_ref,
p.reviewed_at,
p.applied_at,
p.updated_at
from kb_stage.kb_proposals p
where p.payload::text like %s
order by p.updated_at desc, p.id desc
limit 20
""",
(f"%{claim_id}%",),
)
return _rows(cursor)
@staticmethod
def _load_recent_proposals(cursor: Any) -> list[dict[str, Any]]:
cursor.execute(
"""
select p.id::text as id,
p.proposal_type::text as proposal_type,
p.status::text as status,
to_jsonb(p)->>'source_ref' as source_ref,
p.reviewed_at,
p.applied_at,
p.updated_at
from kb_stage.kb_proposals p
order by p.updated_at desc, p.id desc
limit 10
"""
)
return _rows(cursor)

View file

@ -0,0 +1,669 @@
#!/usr/bin/env python3
"""Run the adapter-specific, non-mutating GCP staging preflight."""
from __future__ import annotations
import argparse
import json
import re
import subprocess
from collections.abc import Callable
from dataclasses import asdict, dataclass
from pathlib import Path
PROJECT = "teleo-501523"
PROJECT_NUMBER = "785938879453"
REGION = "europe-west6"
NETWORK = "teleo-staging-net"
SUBNET = "teleo-staging-europe-west6"
INSTANCE = "teleo-pgvector-standby"
SERVICE = "observatory-read-adapter-staging"
DEPLOY_SERVICE_ACCOUNT = f"sa-observatory-deployer@{PROJECT}.iam.gserviceaccount.com"
RUNTIME_SERVICE_ACCOUNT = f"sa-observatory-read-adapter@{PROJECT}.iam.gserviceaccount.com"
BUILD_SERVICE_ACCOUNT = f"sa-artifact-builder@{PROJECT}.iam.gserviceaccount.com"
DB_IAM_USER = f"sa-observatory-read-adapter@{PROJECT}.iam"
SECRET = "observatory-read-api-key-staging"
REPOSITORY = "teleo"
WIF_POOL = "github-actions"
DEPLOY_WIF_PROVIDER = "observatory-read-adapter-main"
DEPLOY_WORKFLOW_REF = (
"living-ip/teleo-infrastructure/.github/workflows/"
"gcp-observatory-read-adapter.yml@refs/heads/main"
)
DEPLOY_WIF_ATTRIBUTE_CONDITION = (
"assertion.repository=='living-ip/teleo-infrastructure' && "
"assertion.ref=='refs/heads/main' && "
f"assertion.workflow_ref=='{DEPLOY_WORKFLOW_REF}'"
)
DEPLOY_WIF_MEMBER = (
f"principal://iam.googleapis.com/projects/{PROJECT_NUMBER}/locations/global/"
f"workloadIdentityPools/{WIF_POOL}/subject/"
"repo:living-ip/teleo-infrastructure:ref:refs/heads/main"
)
PREFLIGHT_ROLE = f"projects/{PROJECT}/roles/observatoryStagingPreflight"
DEPLOY_ROLE = f"projects/{PROJECT}/roles/observatoryStagingDeployer"
PREFLIGHT_PERMISSIONS = {
"artifactregistry.repositories.getIamPolicy",
"cloudsql.instances.get",
"cloudsql.users.list",
"compute.networks.get",
"compute.subnetworks.get",
"iam.serviceAccounts.get",
"iam.serviceAccounts.getIamPolicy",
"iam.roles.get",
"iam.workloadIdentityPoolProviders.get",
"resourcemanager.projects.get",
"resourcemanager.projects.getIamPolicy",
"run.operations.get",
"run.services.get",
"run.services.getIamPolicy",
"secretmanager.secrets.getIamPolicy",
"serviceusage.services.get",
"serviceusage.services.use",
}
DEPLOY_PERMISSIONS = {
"run.operations.get",
"run.services.create",
"run.services.get",
"run.services.setIamPolicy",
"run.services.update",
}
REQUIRED_APIS = (
"artifactregistry.googleapis.com",
"compute.googleapis.com",
"iamcredentials.googleapis.com",
"run.googleapis.com",
"secretmanager.googleapis.com",
"sqladmin.googleapis.com",
"sts.googleapis.com",
)
IMAGE_RE = re.compile(
rf"^europe-west6-docker[.]pkg[.]dev/{PROJECT}/teleo/observatory-read-adapter:"
r"[0-9a-f]{40}-[0-9]+-[1-9][0-9]*@sha256:[0-9a-f]{64}$"
)
@dataclass(frozen=True)
class Check:
name: str
status: str
detail: str
def sanitize_error(value: str) -> str:
value = re.sub(r"/[^\s]*/gha-creds-[^\s]+[.]json", "<ephemeral-wif-credential>", value)
return " ".join(value.strip().split())[-600:] or "command_failed_without_stderr"
def run(command: list[str]) -> subprocess.CompletedProcess[str]:
try:
return subprocess.run(command, text=True, capture_output=True, timeout=30, check=False)
except subprocess.TimeoutExpired:
return subprocess.CompletedProcess(command, 124, stdout="", stderr="command_timed_out_after_30_seconds")
except OSError as exc:
return subprocess.CompletedProcess(command, 127, stdout="", stderr=f"command_unavailable:{exc}")
def command_check(
name: str,
command: list[str],
validate: Callable[[str], bool],
success_detail: str,
) -> Check:
result = run(command)
if result.returncode != 0:
return Check(name, "blocked", sanitize_error(result.stderr))
try:
valid = validate(result.stdout)
except (AttributeError, IndexError, KeyError, TypeError, ValueError, json.JSONDecodeError) as exc:
return Check(name, "blocked", f"invalid_readback:{type(exc).__name__}")
return Check(name, "pass" if valid else "blocked", success_detail if valid else "unexpected_readback")
def cloud_sql_is_private_and_iam_enabled(value: str) -> bool:
payload = json.loads(value)
flags = {
item.get("name"): str(item.get("value", "")).lower()
for item in payload.get("settings", {}).get("databaseFlags", [])
}
ip_configuration = payload.get("settings", {}).get("ipConfiguration", {})
address_types = {item.get("type") for item in payload.get("ipAddresses", [])}
return (
payload.get("name") == INSTANCE
and payload.get("region") == REGION
and str(payload.get("databaseVersion", "")).startswith("POSTGRES_")
and ip_configuration.get("ipv4Enabled") is False
and str(ip_configuration.get("privateNetwork", "")).endswith(f"/networks/{NETWORK}")
and "PRIVATE" in address_types
and "PRIMARY" not in address_types
and flags.get("cloudsql.iam_authentication") == "on"
)
def cloud_sql_iam_user_exists(value: str) -> bool:
users = json.loads(value)
return any(
user.get("name") == DB_IAM_USER and user.get("type") == "CLOUD_IAM_SERVICE_ACCOUNT" for user in users
)
def subnet_is_exact(value: str) -> bool:
payload = json.loads(value)
return (
payload.get("name") == SUBNET
and str(payload.get("region", "")).endswith(f"/regions/{REGION}")
and str(payload.get("network", "")).endswith(f"/networks/{NETWORK}")
)
def secret_is_valid(value: str) -> bool:
try:
encoded = value.encode("ascii")
except UnicodeEncodeError:
return False
return value == value.strip() and 32 <= len(encoded) <= 512
def normalized(value: str) -> str:
return " ".join(value.split())
def policy_has_binding(
policy: dict[str, object],
role: str,
member: str,
*,
condition_title: str | None = None,
condition_expression: str | None = None,
) -> bool:
bindings = policy.get("bindings", [])
if not isinstance(bindings, list):
return False
for binding in bindings:
if not isinstance(binding, dict) or binding.get("role") != role:
continue
members = binding.get("members", [])
if not isinstance(members, list) or member not in members:
continue
condition = binding.get("condition")
if condition_title is None and condition_expression is None:
return condition in (None, {})
if not isinstance(condition, dict):
continue
if condition_title is not None and condition.get("title") != condition_title:
continue
if condition_expression is not None and normalized(str(condition.get("expression", ""))) != normalized(
condition_expression
):
continue
return True
return False
def member_roles(policy: dict[str, object], member: str) -> set[str]:
roles: set[str] = set()
bindings = policy.get("bindings", [])
if not isinstance(bindings, list):
return roles
for binding in bindings:
if not isinstance(binding, dict):
continue
members = binding.get("members", [])
role = binding.get("role")
if isinstance(members, list) and member in members and isinstance(role, str):
roles.add(role)
return roles
def project_iam_is_exact(value: str) -> bool:
policy = json.loads(value)
deployer = f"serviceAccount:{DEPLOY_SERVICE_ACCOUNT}"
runtime = f"serviceAccount:{RUNTIME_SERVICE_ACCOUNT}"
builder = f"serviceAccount:{BUILD_SERVICE_ACCOUNT}"
service_agent = (
f"serviceAccount:service-{PROJECT_NUMBER}@serverless-robot-prod.iam.gserviceaccount.com"
)
sql_expression = (
f"resource.name == 'projects/{PROJECT}/instances/{INSTANCE}' && "
"resource.service == 'sqladmin.googleapis.com'"
)
forbidden_deployer = {
"roles/artifactregistry.writer",
"roles/cloudsql.admin",
"roles/compute.admin",
"roles/editor",
"roles/owner",
"roles/run.admin",
"roles/run.developer",
"roles/secretmanager.admin",
}
forbidden_builder = forbidden_deployer | {
DEPLOY_ROLE,
PREFLIGHT_ROLE,
"roles/iam.serviceAccountUser",
"roles/secretmanager.secretAccessor",
}
return (
policy_has_binding(policy, PREFLIGHT_ROLE, deployer)
and policy_has_binding(policy, DEPLOY_ROLE, deployer)
and policy_has_binding(
policy,
"roles/cloudsql.client",
runtime,
condition_title="observatory-exact-cloudsql-instance",
condition_expression=sql_expression,
)
and policy_has_binding(
policy,
"roles/cloudsql.instanceUser",
runtime,
condition_title="observatory-exact-cloudsql-instance",
condition_expression=sql_expression,
)
and policy_has_binding(policy, "roles/run.serviceAgent", service_agent)
and not (member_roles(policy, deployer) & forbidden_deployer)
and not (member_roles(policy, builder) & forbidden_builder)
)
def role_has_exact_permissions(value: str, expected: set[str]) -> bool:
payload = json.loads(value)
permissions = payload.get("includedPermissions", [])
return isinstance(permissions, list) and set(permissions) == expected and payload.get("deleted") is not True
def wif_provider_is_exact(value: str) -> bool:
payload = json.loads(value)
mapping = payload.get("attributeMapping", {})
expected_mapping = {
"google.subject": "assertion.sub",
"attribute.repository": "assertion.repository",
"attribute.ref": "assertion.ref",
"attribute.workflow_ref": "assertion.workflow_ref",
}
return (
payload.get("state") == "ACTIVE"
and mapping == expected_mapping
and normalized(str(payload.get("attributeCondition", ""))) == normalized(DEPLOY_WIF_ATTRIBUTE_CONDITION)
)
def deployer_service_account_policy_is_exact(value: str) -> bool:
policy = json.loads(value)
return policy_has_binding(policy, "roles/iam.workloadIdentityUser", DEPLOY_WIF_MEMBER)
def runtime_service_account_policy_is_exact(value: str) -> bool:
policy = json.loads(value)
deployer = f"serviceAccount:{DEPLOY_SERVICE_ACCOUNT}"
builder = f"serviceAccount:{BUILD_SERVICE_ACCOUNT}"
return policy_has_binding(policy, "roles/iam.serviceAccountUser", deployer) and not member_roles(policy, builder)
def artifact_policy_is_exact(value: str) -> bool:
policy = json.loads(value)
deployer = f"serviceAccount:{DEPLOY_SERVICE_ACCOUNT}"
return policy_has_binding(policy, "roles/artifactregistry.reader", deployer)
def secret_policy_is_exact(value: str) -> bool:
policy = json.loads(value)
deployer = f"serviceAccount:{DEPLOY_SERVICE_ACCOUNT}"
runtime = f"serviceAccount:{RUNTIME_SERVICE_ACCOUNT}"
builder = f"serviceAccount:{BUILD_SERVICE_ACCOUNT}"
return (
policy_has_binding(policy, "roles/secretmanager.secretAccessor", deployer)
and policy_has_binding(policy, "roles/secretmanager.secretAccessor", runtime)
and policy_has_binding(policy, "roles/secretmanager.viewer", deployer)
and not member_roles(policy, builder)
)
def api_key_secret_check() -> Check:
version_result = run(
[
"gcloud",
"secrets",
"versions",
"list",
SECRET,
"--project",
PROJECT,
"--filter=state=ENABLED",
"--sort-by=~createTime",
"--limit=1",
"--format=value(name)",
]
)
if version_result.returncode != 0:
return Check("api_key_secret", "blocked", sanitize_error(version_result.stderr))
version = version_result.stdout.strip().rsplit("/", 1)[-1]
if not version.isdigit():
return Check("api_key_secret", "blocked", "enabled_secret_version_missing")
secret_result = run(
[
"gcloud",
"secrets",
"versions",
"access",
version,
"--secret",
SECRET,
"--project",
PROJECT,
]
)
if secret_result.returncode != 0:
return Check("api_key_secret", "blocked", sanitize_error(secret_result.stderr))
valid = secret_is_valid(secret_result.stdout)
detail = f"enabled_version_{version}_valid_length_value_redacted" if valid else "invalid_secret_value"
return Check("api_key_secret", "pass" if valid else "blocked", detail)
def existing_service_policy_check() -> Check:
describe = run(
[
"gcloud",
"run",
"services",
"describe",
SERVICE,
"--project",
PROJECT,
"--region",
REGION,
"--format=value(metadata.name)",
]
)
if describe.returncode != 0:
error = sanitize_error(describe.stderr)
if "not found" in error.lower() or "not_found" in error.lower():
return Check("existing_service_policy", "pass", "service_not_created_yet")
return Check("existing_service_policy", "blocked", error)
if describe.stdout.strip() != SERVICE:
return Check("existing_service_policy", "blocked", "unexpected_service_readback")
policy_result = run(
[
"gcloud",
"run",
"services",
"get-iam-policy",
SERVICE,
"--project",
PROJECT,
"--region",
REGION,
"--format=json",
]
)
if policy_result.returncode != 0:
return Check("existing_service_policy", "blocked", sanitize_error(policy_result.stderr))
try:
policy = json.loads(policy_result.stdout)
builder = f"serviceAccount:{BUILD_SERVICE_ACCOUNT}"
valid = not member_roles(policy, builder)
except (AttributeError, TypeError, ValueError, json.JSONDecodeError) as exc:
return Check("existing_service_policy", "blocked", f"invalid_readback:{type(exc).__name__}")
return Check(
"existing_service_policy",
"pass" if valid else "blocked",
"artifact_builder_absent" if valid else "artifact_builder_has_service_binding",
)
def build_checks(image_ref: str) -> list[Check]:
image_name, image_digest = image_ref.rsplit("@", 1) if "@" in image_ref else (image_ref, "")
digest_ref = f"{image_name.rsplit(':', 1)[0]}@{image_digest}" if image_digest else image_ref
checks = [
command_check(
"active_identity",
["gcloud", "auth", "list", "--filter=status:ACTIVE", "--format=value(account)"],
lambda value: value.strip() == DEPLOY_SERVICE_ACCOUNT,
"dedicated_observatory_deployer",
),
command_check(
"project",
["gcloud", "projects", "describe", PROJECT, "--format=value(projectId)"],
lambda value: value.strip() == PROJECT,
PROJECT,
),
]
checks.extend(
command_check(
f"api_{api.removesuffix('.googleapis.com')}",
["gcloud", "services", "describe", api, "--project", PROJECT, "--format=value(state)"],
lambda value: value.strip() == "ENABLED",
"enabled",
)
for api in REQUIRED_APIS
)
checks.extend(
[
command_check(
"deployer_wif_provider",
[
"gcloud",
"iam",
"workload-identity-pools",
"providers",
"describe",
DEPLOY_WIF_PROVIDER,
"--project",
PROJECT,
"--location",
"global",
"--workload-identity-pool",
WIF_POOL,
"--format=json",
],
wif_provider_is_exact,
"main_and_exact_workflow_only",
),
command_check(
"preflight_custom_role",
[
"gcloud",
"iam",
"roles",
"describe",
"observatoryStagingPreflight",
"--project",
PROJECT,
"--format=json",
],
lambda value: role_has_exact_permissions(value, PREFLIGHT_PERMISSIONS),
"exact_read_only_permissions",
),
command_check(
"deploy_custom_role",
[
"gcloud",
"iam",
"roles",
"describe",
"observatoryStagingDeployer",
"--project",
PROJECT,
"--format=json",
],
lambda value: role_has_exact_permissions(value, DEPLOY_PERMISSIONS),
"five_permissions_no_delete",
),
command_check(
"project_iam",
["gcloud", "projects", "get-iam-policy", PROJECT, "--format=json"],
project_iam_is_exact,
"required_bindings_present_broad_roles_absent",
),
command_check(
"deployer_wif_binding",
[
"gcloud",
"iam",
"service-accounts",
"get-iam-policy",
DEPLOY_SERVICE_ACCOUNT,
"--project",
PROJECT,
"--format=json",
],
deployer_service_account_policy_is_exact,
"exact_main_subject_workload_identity_user",
),
command_check(
"runtime_act_as_policy",
[
"gcloud",
"iam",
"service-accounts",
"get-iam-policy",
RUNTIME_SERVICE_ACCOUNT,
"--project",
PROJECT,
"--format=json",
],
runtime_service_account_policy_is_exact,
"deployer_only_artifact_builder_absent",
),
command_check(
"artifact_repository_policy",
[
"gcloud",
"artifacts",
"repositories",
"get-iam-policy",
REPOSITORY,
"--project",
PROJECT,
"--location",
REGION,
"--format=json",
],
artifact_policy_is_exact,
"deployer_reader",
),
command_check(
"secret_policy",
[
"gcloud",
"secrets",
"get-iam-policy",
SECRET,
"--project",
PROJECT,
"--format=json",
],
secret_policy_is_exact,
"runtime_and_deployer_only_artifact_builder_absent",
),
existing_service_policy_check(),
]
)
checks.extend(
[
command_check(
"runtime_service_account",
[
"gcloud",
"iam",
"service-accounts",
"describe",
RUNTIME_SERVICE_ACCOUNT,
"--project",
PROJECT,
"--format=value(email)",
],
lambda value: value.strip() == RUNTIME_SERVICE_ACCOUNT,
RUNTIME_SERVICE_ACCOUNT,
),
command_check(
"vpc_network",
[
"gcloud",
"compute",
"networks",
"describe",
NETWORK,
"--project",
PROJECT,
"--format=value(name)",
],
lambda value: value.strip() == NETWORK,
NETWORK,
),
command_check(
"vpc_subnet",
[
"gcloud",
"compute",
"networks",
"subnets",
"describe",
SUBNET,
"--project",
PROJECT,
"--region",
REGION,
"--format=json",
],
subnet_is_exact,
f"{NETWORK}/{REGION}/{SUBNET}",
),
command_check(
"cloud_sql_private_iam",
["gcloud", "sql", "instances", "describe", INSTANCE, "--project", PROJECT, "--format=json"],
cloud_sql_is_private_and_iam_enabled,
f"{PROJECT}:{REGION}:{INSTANCE}:private_ip_only:iam_authentication_on",
),
command_check(
"cloud_sql_iam_user",
["gcloud", "sql", "users", "list", "--instance", INSTANCE, "--project", PROJECT, "--format=json"],
cloud_sql_iam_user_exists,
DB_IAM_USER,
),
api_key_secret_check(),
command_check(
"immutable_image",
["gcloud", "artifacts", "docker", "images", "describe", digest_ref, "--project", PROJECT, "--format=json"],
lambda _value: bool(IMAGE_RE.fullmatch(image_ref)),
image_digest or "missing_digest",
),
]
)
return checks
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--image-ref", required=True)
parser.add_argument("--output", type=Path)
args = parser.parse_args()
checks = build_checks(args.image_ref)
pass_count = sum(check.status == "pass" for check in checks)
blocked_count = len(checks) - pass_count
receipt = {
"schema": "livingip.observatory-read-adapter-gcp-preflight.v1",
"project": PROJECT,
"required_tier": "T3_live_readonly",
"current_tier": "T2_authenticated_gcp_preflight",
"ready_for_staging_deploy": blocked_count == 0,
"claim_ceiling": "Preflight only; T3 requires the live private Cloud SQL claim and negative receipts.",
"identity": DEPLOY_SERVICE_ACCOUNT,
"checks": [asdict(check) for check in checks],
"pass_count": pass_count,
"blocked_count": blocked_count,
"secret_values_retained": False,
"database_role_live_verification_deferred_to_fail_closed_canary": True,
"production_repoint_executed": False,
}
rendered = json.dumps(receipt, indent=2, sort_keys=True) + "\n"
if args.output:
args.output.write_text(rendered, encoding="utf-8")
else:
print(rendered, end="")
return 0 if blocked_count == 0 else 1
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,183 @@
\set ON_ERROR_STOP on
\getenv observatory_iam_user OBSERVATORY_DB_IAM_USER
-- Provision only after Cloud SQL has created the dedicated IAM database user.
-- The service-account username omits the .gserviceaccount.com suffix.
select set_config('observatory.iam_user', :'observatory_iam_user', false);
do $preflight$
declare
principal text := current_setting('observatory.iam_user');
begin
if current_database() <> 'teleo_canonical' then
raise exception 'observatory_read_role must run only in teleo_canonical';
end if;
if principal !~ '^[a-z0-9-]+@teleo-501523[.]iam$' then
raise exception 'OBSERVATORY_DB_IAM_USER is not the scoped GCP service-account database user';
end if;
if not exists (select 1 from pg_catalog.pg_roles where rolname = principal) then
raise exception 'Cloud SQL IAM database user does not exist: %', principal;
end if;
end
$preflight$;
select 'create role kb_observatory_read nologin nosuperuser nocreatedb nocreaterole noinherit noreplication nobypassrls connection limit -1'
where not exists (select 1 from pg_catalog.pg_roles where rolname = 'kb_observatory_read')
\gexec
alter role kb_observatory_read
with nologin nosuperuser nocreatedb nocreaterole noinherit noreplication nobypassrls connection limit -1
password null;
alter role kb_observatory_read reset all;
revoke all privileges on database teleo_canonical from kb_observatory_read;
grant connect on database teleo_canonical to kb_observatory_read;
revoke all on schema public, kb_stage from kb_observatory_read;
revoke all privileges on all tables in schema public, kb_stage from kb_observatory_read;
revoke all privileges on all sequences in schema public, kb_stage from kb_observatory_read;
revoke all privileges on all functions in schema public, kb_stage from kb_observatory_read;
revoke all privileges on all procedures in schema public, kb_stage from kb_observatory_read;
select format(
'revoke all privileges (%s) on table %I.%I from kb_observatory_read',
pg_catalog.string_agg(pg_catalog.quote_ident(attribute.attname), ', ' order by attribute.attnum),
namespace.nspname,
relation.relname
)
from pg_catalog.pg_class relation
join pg_catalog.pg_namespace namespace on namespace.oid = relation.relnamespace
join pg_catalog.pg_attribute attribute on attribute.attrelid = relation.oid
where namespace.nspname in ('public', 'kb_stage')
and relation.relkind in ('r', 'p', 'v', 'm', 'f')
and attribute.attnum > 0
and not attribute.attisdropped
group by namespace.nspname, relation.relname
\gexec
grant usage on schema public, kb_stage to kb_observatory_read;
grant select on
public.claims,
public.sources,
public.claim_evidence,
public.claim_edges,
kb_stage.kb_proposals
to kb_observatory_read;
do $membership$
declare
principal text := current_setting('observatory.iam_user');
unexpected text;
begin
select pg_catalog.string_agg(granted.rolname, ', ' order by granted.rolname)
into unexpected
from pg_catalog.pg_auth_members membership
join pg_catalog.pg_roles granted on granted.oid = membership.roleid
join pg_catalog.pg_roles member on member.oid = membership.member
where member.rolname = principal
and granted.rolname <> 'kb_observatory_read';
if unexpected is not null then
raise exception 'dedicated Observatory principal has unexpected role memberships: %', unexpected;
end if;
select pg_catalog.string_agg(member.rolname, ', ' order by member.rolname)
into unexpected
from pg_catalog.pg_auth_members membership
join pg_catalog.pg_roles granted on granted.oid = membership.roleid
join pg_catalog.pg_roles member on member.oid = membership.member
where granted.rolname = 'kb_observatory_read'
and member.rolname <> principal;
if unexpected is not null then
raise exception 'kb_observatory_read has unexpected members: %', unexpected;
end if;
execute pg_catalog.format('grant kb_observatory_read to %I', principal);
execute pg_catalog.format(
'alter role %I in database teleo_canonical set default_transaction_read_only = on',
principal
);
execute pg_catalog.format(
'alter role %I in database teleo_canonical set statement_timeout = %L',
principal,
'5s'
);
execute pg_catalog.format(
'alter role %I in database teleo_canonical set lock_timeout = %L',
principal,
'1s'
);
end
$membership$;
do $verify$
declare
principal text := current_setting('observatory.iam_user');
unexpected text;
begin
if not pg_catalog.pg_has_role(principal, 'kb_observatory_read', 'member') then
raise exception 'Observatory principal is not a member of kb_observatory_read';
end if;
if not exists (
select 1 from pg_catalog.pg_roles
where rolname = principal and rolinherit and not rolsuper and not rolcreatedb
and not rolcreaterole and not rolreplication and not rolbypassrls
) then
raise exception 'Observatory principal has unsafe role attributes or cannot inherit read grants';
end if;
select pg_catalog.string_agg(
pg_catalog.format('%I.%I:%s', namespace.nspname, relation.relname, privilege.name),
', ' order by namespace.nspname, relation.relname, privilege.name
)
into unexpected
from pg_catalog.pg_class relation
join pg_catalog.pg_namespace namespace on namespace.oid = relation.relnamespace
cross join (values ('INSERT'), ('UPDATE'), ('DELETE'), ('TRUNCATE'), ('REFERENCES'), ('TRIGGER')) privilege(name)
where namespace.nspname in ('public', 'kb_stage')
and relation.relkind in ('r', 'p', 'v', 'm', 'f')
and pg_catalog.has_table_privilege(principal, relation.oid, privilege.name);
if unexpected is not null then
raise exception 'Observatory principal has effective table writes: %', unexpected;
end if;
select pg_catalog.string_agg(
pg_catalog.format('%I.%I', namespace.nspname, relation.relname),
', ' order by namespace.nspname, relation.relname
)
into unexpected
from pg_catalog.pg_class relation
join pg_catalog.pg_namespace namespace on namespace.oid = relation.relnamespace
where namespace.nspname in ('public', 'kb_stage')
and relation.relkind in ('r', 'p', 'v', 'm', 'f')
and pg_catalog.has_table_privilege(principal, relation.oid, 'SELECT')
and (namespace.nspname, relation.relname) not in (
('public', 'claims'),
('public', 'sources'),
('public', 'claim_evidence'),
('public', 'claim_edges'),
('kb_stage', 'kb_proposals')
);
if unexpected is not null then
raise exception 'Observatory principal can SELECT outside its allowlist: %', unexpected;
end if;
if not (
pg_catalog.has_table_privilege(principal, 'public.claims', 'SELECT')
and pg_catalog.has_table_privilege(principal, 'public.sources', 'SELECT')
and pg_catalog.has_table_privilege(principal, 'public.claim_evidence', 'SELECT')
and pg_catalog.has_table_privilege(principal, 'public.claim_edges', 'SELECT')
and pg_catalog.has_table_privilege(principal, 'kb_stage.kb_proposals', 'SELECT')
) then
raise exception 'Observatory principal is missing a required read grant';
end if;
end
$verify$;
select jsonb_build_object(
'database', current_database(),
'authorization_role', 'kb_observatory_read',
'database_principal', current_setting('observatory.iam_user'),
'required_reads', true,
'effective_table_writes_denied', true,
'default_transaction_read_only', true
)::text;

View file

@ -0,0 +1,475 @@
#!/usr/bin/env python3
"""Emit the unexecuted least-privilege GCP staging packet for Observatory."""
from __future__ import annotations
import argparse
import json
import shlex
PROJECT = "teleo-501523"
PROJECT_NUMBER = "785938879453"
REGION = "europe-west6"
GITHUB_REPOSITORY = "living-ip/teleo-infrastructure"
WIF_POOL = "github-actions"
DEPLOY_WIF_PROVIDER = "observatory-read-adapter-main"
DEPLOY_WORKFLOW_REF = (
f"{GITHUB_REPOSITORY}/.github/workflows/gcp-observatory-read-adapter.yml@refs/heads/main"
)
DEPLOY_WIF_ATTRIBUTE_MAPPING = (
"google.subject=assertion.sub,attribute.repository=assertion.repository,"
"attribute.ref=assertion.ref,attribute.workflow_ref=assertion.workflow_ref"
)
DEPLOY_WIF_ATTRIBUTE_CONDITION = (
"assertion.repository=='living-ip/teleo-infrastructure' && "
"assertion.ref=='refs/heads/main' && "
f"assertion.workflow_ref=='{DEPLOY_WORKFLOW_REF}'"
)
BUILD_SERVICE_ACCOUNT = f"sa-artifact-builder@{PROJECT}.iam.gserviceaccount.com"
DEPLOY_SERVICE_ACCOUNT_ID = "sa-observatory-deployer"
DEPLOY_SERVICE_ACCOUNT = f"{DEPLOY_SERVICE_ACCOUNT_ID}@{PROJECT}.iam.gserviceaccount.com"
RUNTIME_SERVICE_ACCOUNT_ID = "sa-observatory-read-adapter"
RUNTIME_SERVICE_ACCOUNT = f"{RUNTIME_SERVICE_ACCOUNT_ID}@{PROJECT}.iam.gserviceaccount.com"
DB_IAM_USER = f"{RUNTIME_SERVICE_ACCOUNT_ID}@{PROJECT}.iam"
SERVICE = "observatory-read-adapter-staging"
INSTANCE = "teleo-pgvector-standby"
NETWORK = "teleo-staging-net"
SUBNET = "teleo-staging-europe-west6"
SECRET = "observatory-read-api-key-staging"
REPOSITORY = "teleo"
PREFLIGHT_ROLE_ID = "observatoryStagingPreflight"
PREFLIGHT_ROLE = f"projects/{PROJECT}/roles/{PREFLIGHT_ROLE_ID}"
DEPLOY_ROLE_ID = "observatoryStagingDeployer"
DEPLOY_ROLE = f"projects/{PROJECT}/roles/{DEPLOY_ROLE_ID}"
PREFLIGHT_PERMISSIONS = (
"artifactregistry.repositories.getIamPolicy",
"cloudsql.instances.get",
"cloudsql.users.list",
"compute.networks.get",
"compute.subnetworks.get",
"iam.serviceAccounts.get",
"iam.serviceAccounts.getIamPolicy",
"iam.roles.get",
"iam.workloadIdentityPoolProviders.get",
"resourcemanager.projects.get",
"resourcemanager.projects.getIamPolicy",
"run.operations.get",
"run.services.get",
"run.services.getIamPolicy",
"secretmanager.secrets.getIamPolicy",
"serviceusage.services.get",
"serviceusage.services.use",
)
DEPLOY_PERMISSIONS = (
"run.operations.get",
"run.services.create",
"run.services.get",
"run.services.setIamPolicy",
"run.services.update",
)
REQUIRED_APIS = (
"artifactregistry.googleapis.com",
"compute.googleapis.com",
"iamcredentials.googleapis.com",
"run.googleapis.com",
"secretmanager.googleapis.com",
"sqladmin.googleapis.com",
"sts.googleapis.com",
)
FORBIDDEN_DEPLOYER_ROLES = (
"roles/artifactregistry.writer",
"roles/cloudsql.admin",
"roles/compute.admin",
"roles/editor",
"roles/owner",
"roles/run.admin",
"roles/run.developer",
"roles/secretmanager.admin",
)
def shell_join(parts: list[str]) -> str:
return " ".join(shlex.quote(part) for part in parts)
def github_wif_member() -> str:
return (
f"principal://iam.googleapis.com/projects/{PROJECT_NUMBER}/locations/global/"
f"workloadIdentityPools/{WIF_POOL}/subject/repo:{GITHUB_REPOSITORY}:ref:refs/heads/main"
)
def service_account_member(account: str) -> str:
return f"serviceAccount:{account}"
def project_binding(member: str, role: str, condition: str | None = None) -> str:
command = [
"gcloud",
"projects",
"add-iam-policy-binding",
PROJECT,
"--member",
member,
"--role",
role,
]
if condition:
command.extend(["--condition", condition])
return shell_join(command)
def custom_role_commands(
role_id: str,
title: str,
description: str,
permissions: tuple[str, ...],
) -> list[str]:
common = [
"--project",
PROJECT,
"--title",
title,
"--description",
description,
"--permissions",
",".join(permissions),
"--stage",
"GA",
]
return [
(
f"gcloud iam roles describe {shlex.quote(role_id)} --project {shlex.quote(PROJECT)} "
"|| "
+ shell_join(["gcloud", "iam", "roles", "create", role_id, *common])
),
shell_join(["gcloud", "iam", "roles", "update", role_id, *common]),
]
def build_plan() -> dict[str, object]:
deployer_member = service_account_member(DEPLOY_SERVICE_ACCOUNT)
runtime_member = service_account_member(RUNTIME_SERVICE_ACCOUNT)
cloud_sql_condition = (
"expression=resource.name == "
f"'projects/{PROJECT}/instances/{INSTANCE}' && resource.service == 'sqladmin.googleapis.com',"
"title=observatory-exact-cloudsql-instance"
)
create_accounts = [
(
DEPLOY_SERVICE_ACCOUNT,
DEPLOY_SERVICE_ACCOUNT_ID,
"Observatory staging deploy and canary",
),
(
RUNTIME_SERVICE_ACCOUNT,
RUNTIME_SERVICE_ACCOUNT_ID,
"Observatory private Cloud SQL reader",
),
]
commands = [
shell_join(["gcloud", "projects", "describe", PROJECT, "--format=value(projectId)"]),
shell_join(["gcloud", "services", "enable", *REQUIRED_APIS, "--project", PROJECT]),
project_binding(
f"serviceAccount:service-{PROJECT_NUMBER}@serverless-robot-prod.iam.gserviceaccount.com",
"roles/run.serviceAgent",
),
]
for email, account_id, display_name in create_accounts:
commands.append(
f"gcloud iam service-accounts describe {shlex.quote(email)} --project {shlex.quote(PROJECT)} "
f"|| {shell_join(['gcloud', 'iam', 'service-accounts', 'create', account_id, '--project', PROJECT, '--display-name', display_name])}"
)
commands.extend(
[
(
"gcloud iam workload-identity-pools providers describe "
+ shlex.quote(DEPLOY_WIF_PROVIDER)
+ " --project "
+ shlex.quote(PROJECT)
+ " --location global --workload-identity-pool "
+ shlex.quote(WIF_POOL)
+ " || "
+ shell_join(
[
"gcloud",
"iam",
"workload-identity-pools",
"providers",
"create-oidc",
DEPLOY_WIF_PROVIDER,
"--project",
PROJECT,
"--location",
"global",
"--workload-identity-pool",
WIF_POOL,
"--issuer-uri",
"https://token.actions.githubusercontent.com/",
"--attribute-mapping",
DEPLOY_WIF_ATTRIBUTE_MAPPING,
"--attribute-condition",
DEPLOY_WIF_ATTRIBUTE_CONDITION,
]
)
),
shell_join(
[
"gcloud",
"iam",
"workload-identity-pools",
"providers",
"update-oidc",
DEPLOY_WIF_PROVIDER,
"--project",
PROJECT,
"--location",
"global",
"--workload-identity-pool",
WIF_POOL,
"--attribute-mapping",
DEPLOY_WIF_ATTRIBUTE_MAPPING,
"--attribute-condition",
DEPLOY_WIF_ATTRIBUTE_CONDITION,
]
),
shell_join(
[
"gcloud",
"iam",
"service-accounts",
"add-iam-policy-binding",
DEPLOY_SERVICE_ACCOUNT,
"--project",
PROJECT,
"--member",
github_wif_member(),
"--role",
"roles/iam.workloadIdentityUser",
]
),
]
)
commands.extend(
custom_role_commands(
PREFLIGHT_ROLE_ID,
"Observatory staging preflight",
"Read only the exact resource classes required before the private staging deploy",
PREFLIGHT_PERMISSIONS,
)
)
commands.extend(
custom_role_commands(
DEPLOY_ROLE_ID,
"Observatory staging deployer",
"Create or update Cloud Run without delete or broad infrastructure permissions",
DEPLOY_PERMISSIONS,
)
)
commands.extend(
[
project_binding(deployer_member, PREFLIGHT_ROLE),
project_binding(deployer_member, DEPLOY_ROLE),
shell_join(
[
"gcloud",
"artifacts",
"repositories",
"add-iam-policy-binding",
REPOSITORY,
"--project",
PROJECT,
"--location",
REGION,
"--member",
deployer_member,
"--role",
"roles/artifactregistry.reader",
]
),
shell_join(
[
"gcloud",
"iam",
"service-accounts",
"add-iam-policy-binding",
RUNTIME_SERVICE_ACCOUNT,
"--project",
PROJECT,
"--member",
deployer_member,
"--role",
"roles/iam.serviceAccountUser",
]
),
project_binding(runtime_member, "roles/cloudsql.client", cloud_sql_condition),
project_binding(runtime_member, "roles/cloudsql.instanceUser", cloud_sql_condition),
f"gcloud secrets describe {shlex.quote(SECRET)} --project {shlex.quote(PROJECT)} "
f"|| {shell_join(['gcloud', 'secrets', 'create', SECRET, '--project', PROJECT, '--replication-policy', 'automatic'])}",
]
)
for member in (runtime_member, deployer_member):
commands.append(
shell_join(
[
"gcloud",
"secrets",
"add-iam-policy-binding",
SECRET,
"--project",
PROJECT,
"--member",
member,
"--role",
"roles/secretmanager.secretAccessor",
]
)
)
commands.extend(
[
shell_join(
[
"gcloud",
"secrets",
"add-iam-policy-binding",
SECRET,
"--project",
PROJECT,
"--member",
deployer_member,
"--role",
"roles/secretmanager.viewer",
]
),
(
"if ! gcloud secrets versions list "
+ shlex.quote(SECRET)
+ " --project "
+ shlex.quote(PROJECT)
+ " --filter='state=ENABLED' --limit=1 --format='value(name)' | grep -q .; then "
+ "openssl rand -hex 32 | tr -d '\\n' | gcloud secrets versions add "
+ shlex.quote(SECRET)
+ " --project "
+ shlex.quote(PROJECT)
+ " --data-file=-; fi"
),
(
"if ! gcloud sql users list --instance "
+ shlex.quote(INSTANCE)
+ " --project "
+ shlex.quote(PROJECT)
+ " --filter='type=CLOUD_IAM_SERVICE_ACCOUNT' --format='value(name)' | grep -Fxq "
+ shlex.quote(DB_IAM_USER)
+ "; then "
+ shell_join(
[
"gcloud",
"sql",
"users",
"create",
DB_IAM_USER,
"--instance",
INSTANCE,
"--project",
PROJECT,
"--type",
"CLOUD_IAM_SERVICE_ACCOUNT",
]
)
+ "; fi"
),
]
)
return {
"schema": "livingip.observatory-read-adapter-gcp-plan.v1",
"project": PROJECT,
"required_tier": "T3_live_readonly",
"current_tier": "T2_unexecuted_least_privilege_packet",
"claim_ceiling": "Plan only; no IAM, API, secret, Cloud SQL, Cloud Run, or routing mutation has run.",
"identities": {
"build": BUILD_SERVICE_ACCOUNT,
"deploy_and_canary": DEPLOY_SERVICE_ACCOUNT,
"runtime": RUNTIME_SERVICE_ACCOUNT,
"database_principal": DB_IAM_USER,
},
"kept_narrow": {
"artifact_builder": "image build and push only; never deploy or receive broad infra roles",
"deployer": "workflow-specific main-only WIF plus a five-permission Cloud Run role, repository read, exact runtime actAs, exact secret access",
"runtime": "exact Cloud SQL instance connect/login plus exact secret access",
},
"github_wif_provider": (
f"projects/{PROJECT_NUMBER}/locations/global/workloadIdentityPools/{WIF_POOL}/providers/{DEPLOY_WIF_PROVIDER}"
),
"github_wif_member": github_wif_member(),
"required_apis": list(REQUIRED_APIS),
"preflight_custom_role": {
"name": PREFLIGHT_ROLE,
"permissions": list(PREFLIGHT_PERMISSIONS),
},
"deploy_custom_role": {
"name": DEPLOY_ROLE,
"permissions": list(DEPLOY_PERMISSIONS),
},
"conditions": {
"cloud_sql": cloud_sql_condition,
"deployer_wif": DEPLOY_WIF_ATTRIBUTE_CONDITION,
},
"commands": commands,
"private_database_action": {
"location": "existing authenticated private GCP VM database-admin path",
"command": (
f"OBSERVATORY_DB_IAM_USER={DB_IAM_USER} psql --dbname=teleo_canonical "
"--set=ON_ERROR_STOP=1 --file=ops/observatory_read_role.sql"
),
"required_receipt": (
"database=teleo_canonical, authorization_role=kb_observatory_read, exact database principal, "
"required_reads=true, effective_table_writes_denied=true"
),
},
"cloud_run_service_agent_check": {
"principal": f"service-{PROJECT_NUMBER}@serverless-robot-prod.iam.gserviceaccount.com",
"required_role": "roles/run.serviceAgent",
"reason": "Default Cloud Run service-agent role carries Direct VPC permissions; do not grant them to the runtime identity.",
"empty_readback_action": "Stop. Repair the Google-managed service-agent grant as an administrator before preflight.",
},
"post_apply_checks": [
f"gcloud projects describe {PROJECT} --format=value(projectId)",
"python3 ops/check_gcp_infra_readiness.py",
"Require the adapter preflight to verify the dedicated WIF provider, custom roles, IAM bindings, private Cloud SQL, secret, and immutable image.",
(
"gh workflow run gcp-observatory-read-adapter.yml --repo "
f"{GITHUB_REPOSITORY} --ref main -f action=preflight_staging"
),
"Require a passing observatory-read-adapter-preflight artifact before action=deploy_staging.",
],
"forbidden_deployer_roles": list(FORBIDDEN_DEPLOYER_ROLES),
"forbidden_actions": [
"grant deploy or infra roles to sa-artifact-builder",
"reuse a pre-existing image tag instead of building the current workflow revision",
"add a public Cloud SQL address",
"expose a secret value in Git, logs, or a receipt",
"add a write route",
"change Vercel or production routing",
],
"production_repoint_executed": False,
}
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--format", choices=("json", "shell"), default="json")
args = parser.parse_args()
plan = build_plan()
if args.format == "shell":
print("# Unexecuted staging packet. Review and run only as an authenticated teleo-501523 administrator.")
print("set -euo pipefail")
for command in plan["commands"]:
print(command)
else:
print(json.dumps(plan, indent=2, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,29 @@
{
schema,
read_only,
provenance: {
gcp_project: .provenance.gcp_project,
cloud_sql_instance: .provenance.cloud_sql_instance,
database: .provenance.database,
database_principal: .provenance.database_principal,
authorization_role: .provenance.authorization_role,
transaction_read_only: .provenance.transaction_read_only,
write_privileges_denied: .provenance.write_privileges_denied,
service_revision: .provenance.service_revision
},
canonical: {
claim: {
id: .canonical.claim.id,
type: .canonical.claim.type,
status: .canonical.claim.status
},
evidence_count: (.canonical.evidence | length),
incoming_edge_count: ([.canonical.edges[] | select(.direction == "incoming")] | length),
outgoing_edge_count: ([.canonical.edges[] | select(.direction == "outgoing")] | length)
},
proposal_ledger: {
distinct_from_canonical: .proposal_ledger.distinct_from_canonical,
status_counts: .proposal_ledger.status_counts,
related_count: (.proposal_ledger.related | length)
}
}

View file

@ -1,12 +1,14 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
"""Deterministically rebuild a disposable Postgres from genesis plus a strict ledger. """Deterministically rebuild a disposable Postgres from genesis plus a strict ledger.
The v1 replay boundary is intentionally narrow. It supports strict, insert-only The v1 replay boundary supports strict ``add_edge``, ``attach_evidence``,
``add_edge``, ``attach_evidence``, and ``approve_claim`` receipts. Each ledger ``approve_claim``, and ``revise_strategy`` receipts. Insert-only actions seed
entry must also retain the exact approved and applied proposal rows plus the their receipt-pinned rows before the guarded transition. ``revise_strategy``
immutable approval snapshot. Legacy/freeform entries and ``revise_strategy`` instead captures the exact prestate identities, executes the exact hash-matched
fail before Docker starts because their retained material is not a complete guarded SQL, validates the generated delta, and normalizes only that delta to the
database delta. receipt-pinned transaction timestamp, IDs, and rows. Every entry must retain the
full approved and applied proposal rows plus its immutable approval snapshot.
Legacy and freeform entries still fail before Docker starts.
""" """
from __future__ import annotations from __future__ import annotations
@ -46,15 +48,18 @@ LEDGER_ARTIFACT = "teleo_genesis_plus_ledger"
MATERIAL_ARTIFACT = "teleo_strict_proposal_replay_material" MATERIAL_ARTIFACT = "teleo_strict_proposal_replay_material"
LEDGER_CONTRACT_VERSION = 1 LEDGER_CONTRACT_VERSION = 1
MATERIAL_CONTRACT_VERSION = 1 MATERIAL_CONTRACT_VERSION = 1
SUPPORTED_PROPOSAL_TYPES = frozenset({"add_edge", "attach_evidence", "approve_claim"}) DEFAULT_REBUILD_IMAGE = (
"docker.io/library/postgres:16-alpine@sha256:57c72fd2a128e416c7fcc499958864df5301e940bca0a56f58fddf30ffc07777"
)
SUPPORTED_PROPOSAL_TYPES = frozenset({"add_edge", "attach_evidence", "approve_claim", "revise_strategy"})
CLAIM_CEILING = ( CLAIM_CEILING = (
"exact genesis plus ordered strict insert-only proposal replay; supported types are " "exact genesis plus ordered strict proposal replay; supported types are add_edge, "
"add_edge, attach_evidence, and approve_claim; full approved/applied proposal rows " "attach_evidence, approve_claim, and revise_strategy; mutating strategy replay "
"and immutable approval snapshots are required" "captures prestate identities and normalizes the exact receipt-pinned poststate; "
"full approved/applied proposal rows and immutable approval snapshots are required"
) )
NOT_PROVEN = ( NOT_PROVEN = (
"legacy or freeform proposal replay", "legacy or freeform proposal replay",
"revise_strategy replay because prior-row mutations are absent from v1 receipts",
"source-corpus recompilation from a blank schema", "source-corpus recompilation from a blank schema",
"VPS, GCP, Telegram, or any live database mutation", "VPS, GCP, Telegram, or any live database mutation",
) )
@ -77,6 +82,7 @@ FIXED_ENGINE_PATHS = frozenset(
) )
SHA256_RE = re.compile(r"[0-9a-f]{64}\Z") SHA256_RE = re.compile(r"[0-9a-f]{64}\Z")
IMAGE_DIGEST_RE = re.compile(r"\S+@sha256:[0-9a-f]{64}\Z")
PROPOSAL_TRANSITION_FIELDS = frozenset( PROPOSAL_TRANSITION_FIELDS = frozenset(
{"status", "applied_by_handle", "applied_by_agent_id", "applied_at", "updated_at"} {"status", "applied_by_handle", "applied_by_agent_id", "applied_at", "updated_at"}
) )
@ -121,6 +127,35 @@ CANONICAL_TABLE_ORDER = (
"claim_evidence", "claim_evidence",
"claim_edges", "claim_edges",
) )
STRATEGY_REQUIRED_FIELDS = frozenset(
{
"id",
"agent_id",
"diagnosis",
"guiding_policy",
"proximate_objectives",
"version",
"active",
"created_at",
}
)
STRATEGY_NODE_REQUIRED_FIELDS = frozenset(
{
"id",
"agent_id",
"node_type",
"title",
"body",
"rank",
"status",
"horizon",
"measure",
"source_ref",
"metadata",
"created_at",
"updated_at",
}
)
class ReconstructionError(RuntimeError): class ReconstructionError(RuntimeError):
@ -308,6 +343,116 @@ def _validate_proposal_rows(
) )
def _parse_aware_timestamp(value: Any, field: str, *, code: str = "invalid_mutating_receipt") -> datetime:
if not isinstance(value, str) or not value:
raise ReconstructionError(code, f"{field} must be an ISO-8601 timestamp")
try:
parsed = datetime.fromisoformat(value.replace("Z", "+00:00"))
except ValueError as exc:
raise ReconstructionError(code, f"{field} must be an ISO-8601 timestamp") from exc
if parsed.tzinfo is None:
raise ReconstructionError(code, f"{field} must include a timezone")
return parsed
def _validated_uuid_list(value: Any, field: str, *, code: str = "invalid_mutating_state") -> list[str]:
if not isinstance(value, list):
raise ReconstructionError(code, f"{field} must be a UUID list")
normalized: list[str] = []
for item in value:
try:
normalized.append(str(uuid.UUID(str(item))))
except (TypeError, ValueError, AttributeError) as exc:
raise ReconstructionError(code, f"{field} must contain only UUIDs") from exc
if len(normalized) != len(set(normalized)):
raise ReconstructionError(code, f"{field} contains duplicate UUIDs")
return normalized
def _validate_revise_strategy_receipt_rows(
proposal: dict[str, Any], canonical_rows: dict[str, Any]
) -> tuple[dict[str, Any], list[dict[str, Any]]]:
payload = proposal.get("payload")
apply_payload = payload.get("apply_payload") if isinstance(payload, dict) else None
if not isinstance(apply_payload, dict):
raise ReconstructionError("invalid_mutating_receipt", "revise_strategy receipt requires a strict apply payload")
try:
agent_id = str(uuid.UUID(str(apply_payload.get("agent_id"))))
except (TypeError, ValueError, AttributeError) as exc:
raise ReconstructionError(
"invalid_mutating_receipt", "revise_strategy receipt requires one agent UUID"
) from exc
strategies = canonical_rows.get("strategies")
nodes = canonical_rows.get("strategy_nodes")
if not isinstance(strategies, list) or len(strategies) != 1 or not isinstance(strategies[0], dict):
raise ReconstructionError("invalid_mutating_receipt", "revise_strategy receipt must pin one fresh strategy row")
expected_nodes = apply_payload.get("strategy_nodes")
if (
not isinstance(expected_nodes, list)
or not isinstance(nodes, list)
or len(nodes) != len(expected_nodes)
or any(not isinstance(row, dict) for row in nodes)
):
raise ReconstructionError(
"invalid_mutating_receipt", "revise_strategy receipt must pin every fresh strategy node row"
)
strategy = strategies[0]
if frozenset(strategy) != STRATEGY_REQUIRED_FIELDS:
raise ReconstructionError(
"invalid_mutating_receipt", "revise_strategy receipt strategy row fields are not canonical"
)
if any(frozenset(row) != STRATEGY_NODE_REQUIRED_FIELDS for row in nodes):
raise ReconstructionError(
"invalid_mutating_receipt", "revise_strategy receipt strategy node row fields are not canonical"
)
strategy_id = _validated_uuid_list([strategy.get("id")], "receipt strategy id", code="invalid_mutating_receipt")[0]
node_ids = _validated_uuid_list(
[row.get("id") for row in nodes],
"receipt strategy node ids",
code="invalid_mutating_receipt",
)
if strategy.get("agent_id") != agent_id or any(row.get("agent_id") != agent_id for row in nodes):
raise ReconstructionError(
"invalid_mutating_receipt", "revise_strategy receipt rows do not belong to the payload agent"
)
if strategy.get("active") is not True or any(row.get("status") != "active" for row in nodes):
raise ReconstructionError(
"invalid_mutating_receipt", "revise_strategy receipt must pin the fresh active poststate"
)
version = strategy.get("version")
if isinstance(version, bool) or not isinstance(version, int) or version < 1:
raise ReconstructionError(
"invalid_mutating_receipt", "revise_strategy receipt strategy version must be positive"
)
transaction_timestamp = strategy.get("created_at")
transaction_time = _parse_aware_timestamp(transaction_timestamp, "receipt strategy created_at")
for row in nodes:
if row.get("created_at") != transaction_timestamp or row.get("updated_at") != transaction_timestamp:
raise ReconstructionError(
"invalid_mutating_receipt",
"revise_strategy fresh strategy and node timestamps must share one transaction timestamp",
)
reviewed_time = _parse_aware_timestamp(proposal.get("reviewed_at"), "receipt proposal reviewed_at")
applied_time = _parse_aware_timestamp(proposal.get("applied_at"), "receipt proposal applied_at")
if reviewed_time > applied_time:
raise ReconstructionError("invalid_mutating_receipt", "revise_strategy proposal approval is after apply time")
if transaction_time < reviewed_time:
raise ReconstructionError(
"invalid_mutating_receipt", "revise_strategy transaction timestamp is before proposal approval"
)
if transaction_time > applied_time:
raise ReconstructionError(
"invalid_mutating_receipt", "revise_strategy transaction timestamp is after proposal apply time"
)
return {**strategy, "id": strategy_id}, [
{**row, "id": normalized_id} for row, normalized_id in zip(nodes, node_ids, strict=True)
]
def _validate_entry_material( def _validate_entry_material(
material: dict[str, Any], material: dict[str, Any],
*, *,
@ -340,11 +485,6 @@ def _validate_entry_material(
if not isinstance(proposal, dict): if not isinstance(proposal, dict):
raise ReconstructionError("invalid_material", "replay receipt has no proposal object") raise ReconstructionError("invalid_material", "replay receipt has no proposal object")
proposal_type = proposal.get("proposal_type") proposal_type = proposal.get("proposal_type")
if proposal_type == "revise_strategy":
raise ReconstructionError(
"unsupported_mutating_receipt",
"revise_strategy receipts omit prior strategy and node mutations and cannot replay exactly",
)
if proposal_type not in SUPPORTED_PROPOSAL_TYPES: if proposal_type not in SUPPORTED_PROPOSAL_TYPES:
raise ReconstructionError( raise ReconstructionError(
"unsupported_proposal_type", "ledger entry proposal type is not supported by v1 reconstruction" "unsupported_proposal_type", "ledger entry proposal type is not supported by v1 reconstruction"
@ -358,6 +498,8 @@ def _validate_entry_material(
canonical_rows = receipt.get("canonical_rows") canonical_rows = receipt.get("canonical_rows")
if not isinstance(apply_metadata, dict) or not isinstance(canonical_rows, dict): if not isinstance(apply_metadata, dict) or not isinstance(canonical_rows, dict):
raise ReconstructionError("invalid_replay_receipt", "replay receipt is missing apply or row material") raise ReconstructionError("invalid_replay_receipt", "replay receipt is missing apply or row material")
if proposal_type == "revise_strategy":
_validate_revise_strategy_receipt_rows(proposal, canonical_rows)
try: try:
rebuilt = replay_receipt.build_replay_receipt( rebuilt = replay_receipt.build_replay_receipt(
proposal, proposal,
@ -382,6 +524,7 @@ def _validate_entry_material(
raise ReconstructionError( raise ReconstructionError(
"replay_material_hash_mismatch", "ledger replay-material pin does not match the private receipt" "replay_material_hash_mismatch", "ledger replay-material pin does not match the private receipt"
) )
receipt = {**receipt, "canonical_rows": rebuilt["canonical_rows"]}
approved = material["approved_proposal"] approved = material["approved_proposal"]
approval = material["approval_snapshot"] approval = material["approval_snapshot"]
@ -394,6 +537,15 @@ def _validate_entry_material(
"current_apply_engine_rejected_material", "current_apply_engine_rejected_material",
"current guarded apply engine rejected the strict replay material", "current guarded apply engine rejected the strict replay material",
) from exc ) from exc
current_apply_sql_sha256 = _sha256_text(current_apply_sql)
if proposal_type == "revise_strategy" and (
apply_metadata.get("source") != "exact_executed_sql"
or apply_metadata.get("apply_sql_sha256") != current_apply_sql_sha256
):
raise ReconstructionError(
"mutating_apply_engine_mismatch",
"revise_strategy replay requires the exact executed SQL to match the current guarded apply engine",
)
return LedgerEntry( return LedgerEntry(
sequence=expected_sequence, sequence=expected_sequence,
@ -405,7 +557,7 @@ def _validate_entry_material(
applied_proposal=applied, applied_proposal=applied,
receipt=receipt, receipt=receipt,
current_apply_sql=current_apply_sql, current_apply_sql=current_apply_sql,
current_apply_sql_sha256=_sha256_text(current_apply_sql), current_apply_sql_sha256=current_apply_sql_sha256,
) )
@ -550,6 +702,266 @@ def build_seed_sql(entry: LedgerEntry) -> str:
return "\n".join(statements) + "\n" return "\n".join(statements) + "\n"
def _uuid_membership_sql(column: str, values: list[str], *, negate: bool = False) -> str:
if not values:
return "true" if negate else "false"
rendered = ", ".join(f"{apply_engine.sql_literal(value)}::uuid" for value in values)
operator = "not in" if negate else "in"
return f"{column} {operator} ({rendered})"
def _uuid_array_sql(values: list[str]) -> str:
if not values:
return "array[]::uuid[]"
rendered = ", ".join(f"{apply_engine.sql_literal(value)}::uuid" for value in values)
return f"array[{rendered}]::uuid[]"
def build_revise_strategy_prestate_sql(entry: LedgerEntry) -> str:
apply_payload = entry.receipt["proposal"]["payload"]["apply_payload"]
agent = apply_engine.sql_literal(apply_payload["agent_id"])
return f"""with strategy_state as (
select coalesce(jsonb_agg(s.id::text order by s.id::text), '[]'::jsonb) as strategy_ids,
coalesce(
jsonb_agg(s.id::text order by s.id::text) filter (where s.active),
'[]'::jsonb
) as active_strategy_ids,
coalesce(max(s.version), 0) as max_strategy_version
from public.strategies s
where s.agent_id = {agent}::uuid
), node_state as (
select coalesce(jsonb_agg(n.id::text order by n.id::text), '[]'::jsonb) as strategy_node_ids,
coalesce(
jsonb_agg(n.id::text order by n.id::text) filter (where n.status <> 'retired'),
'[]'::jsonb
) as non_retired_strategy_node_ids
from public.strategy_nodes n
where n.agent_id = {agent}::uuid
)
select jsonb_build_object(
'strategy_ids', s.strategy_ids,
'active_strategy_ids', s.active_strategy_ids,
'max_strategy_version', s.max_strategy_version,
'strategy_node_ids', n.strategy_node_ids,
'non_retired_strategy_node_ids', n.non_retired_strategy_node_ids
)::text
from strategy_state s cross join node_state n;
"""
def _validate_revise_strategy_prestate(value: Any) -> dict[str, Any]:
expected = frozenset(
{
"strategy_ids",
"active_strategy_ids",
"max_strategy_version",
"strategy_node_ids",
"non_retired_strategy_node_ids",
}
)
state = _require_exact_keys(value, expected, "revise_strategy prestate")
strategy_ids = _validated_uuid_list(state["strategy_ids"], "prestate strategy ids")
active_strategy_ids = _validated_uuid_list(state["active_strategy_ids"], "prestate active strategy ids")
strategy_node_ids = _validated_uuid_list(state["strategy_node_ids"], "prestate strategy node ids")
non_retired_node_ids = _validated_uuid_list(
state["non_retired_strategy_node_ids"], "prestate non-retired strategy node ids"
)
max_version = state["max_strategy_version"]
if isinstance(max_version, bool) or not isinstance(max_version, int) or max_version < 0:
raise ReconstructionError(
"invalid_mutating_state", "prestate maximum strategy version must be a non-negative integer"
)
if len(active_strategy_ids) > 1 or not set(active_strategy_ids).issubset(strategy_ids):
raise ReconstructionError(
"invalid_mutating_state", "prestate active strategies violate the one-active invariant"
)
if not set(non_retired_node_ids).issubset(strategy_node_ids):
raise ReconstructionError(
"invalid_mutating_state", "prestate non-retired strategy nodes are not a subset of all nodes"
)
return {
"strategy_ids": strategy_ids,
"active_strategy_ids": active_strategy_ids,
"max_strategy_version": max_version,
"strategy_node_ids": strategy_node_ids,
"non_retired_strategy_node_ids": non_retired_node_ids,
}
def build_revise_strategy_generated_delta_sql(entry: LedgerEntry, prestate: dict[str, Any]) -> str:
state = _validate_revise_strategy_prestate(prestate)
apply_payload = entry.receipt["proposal"]["payload"]["apply_payload"]
agent = apply_engine.sql_literal(apply_payload["agent_id"])
strategy_filter = _uuid_membership_sql("s.id", state["strategy_ids"], negate=True)
node_filter = _uuid_membership_sql("n.id", state["strategy_node_ids"], negate=True)
return f"""select jsonb_build_object(
'strategies', coalesce((
select jsonb_agg(to_jsonb(s) order by s.id::text)
from public.strategies s
where s.agent_id = {agent}::uuid and {strategy_filter}
), '[]'::jsonb),
'strategy_nodes', coalesce((
select jsonb_agg(to_jsonb(n) order by n.id::text)
from public.strategy_nodes n
where n.agent_id = {agent}::uuid and {node_filter}
), '[]'::jsonb)
)::text;
"""
def _validate_revise_strategy_generated_delta(
entry: LedgerEntry,
prestate: dict[str, Any],
generated_rows: Any,
) -> tuple[dict[str, Any], list[dict[str, Any]]]:
state = _validate_revise_strategy_prestate(prestate)
if not isinstance(generated_rows, dict):
raise ReconstructionError("invalid_mutating_delta", "revise_strategy generated delta must be a row object")
try:
replay_receipt.build_replay_receipt(
entry.receipt["proposal"],
generated_rows,
apply_sql_sha256=entry.current_apply_sql_sha256,
apply_sql_source="exact_executed_sql",
exported_at_utc=entry.receipt.get("exported_at_utc"),
)
except (KeyError, TypeError, ValueError) as exc:
raise ReconstructionError(
"invalid_mutating_delta",
"revise_strategy generated rows do not match the strict payload",
) from exc
strategies = generated_rows.get("strategies")
nodes = generated_rows.get("strategy_nodes")
if not isinstance(strategies, list) or len(strategies) != 1 or not isinstance(strategies[0], dict):
raise ReconstructionError(
"invalid_mutating_delta", "revise_strategy apply did not generate exactly one strategy"
)
if not isinstance(nodes, list) or any(not isinstance(row, dict) for row in nodes):
raise ReconstructionError("invalid_mutating_delta", "revise_strategy apply generated invalid strategy nodes")
strategy = strategies[0]
if strategy.get("version") != state["max_strategy_version"] + 1:
raise ReconstructionError("invalid_mutating_delta", "revise_strategy generated an unexpected strategy version")
transaction_timestamp = strategy.get("created_at")
_parse_aware_timestamp(transaction_timestamp, "generated strategy created_at", code="invalid_mutating_delta")
if any(
row.get("created_at") != transaction_timestamp or row.get("updated_at") != transaction_timestamp
for row in nodes
):
raise ReconstructionError(
"invalid_mutating_delta",
"revise_strategy generated rows do not share one transaction timestamp",
)
_validated_uuid_list([strategy.get("id")], "generated strategy id", code="invalid_mutating_delta")
_validated_uuid_list(
[row.get("id") for row in nodes],
"generated strategy node ids",
code="invalid_mutating_delta",
)
return strategy, nodes
def build_revise_strategy_normalization_sql(
entry: LedgerEntry,
prestate: dict[str, Any],
generated_rows: dict[str, Any],
) -> str:
state = _validate_revise_strategy_prestate(prestate)
generated_strategy, generated_nodes = _validate_revise_strategy_generated_delta(entry, state, generated_rows)
receipt_strategy, receipt_nodes = _validate_revise_strategy_receipt_rows(
entry.receipt["proposal"], entry.receipt["canonical_rows"]
)
if receipt_strategy["version"] != state["max_strategy_version"] + 1:
raise ReconstructionError(
"mutating_receipt_version_mismatch",
"revise_strategy receipt version does not follow the observed prestate",
)
if receipt_strategy["id"] in state["strategy_ids"] or set(row["id"] for row in receipt_nodes).intersection(
state["strategy_node_ids"]
):
raise ReconstructionError(
"mutating_receipt_id_collision", "revise_strategy receipt IDs collide with the observed prestate"
)
apply_payload = entry.receipt["proposal"]["payload"]["apply_payload"]
agent = apply_engine.sql_literal(apply_payload["agent_id"])
generated_strategy_id = str(uuid.UUID(str(generated_strategy["id"])))
generated_node_ids = [str(uuid.UUID(str(row["id"]))) for row in generated_nodes]
previous_active = state["active_strategy_ids"]
changed_node_ids = state["non_retired_strategy_node_ids"]
transaction_timestamp = apply_engine.sql_literal(receipt_strategy["created_at"])
generated_node_array = _uuid_array_sql(generated_node_ids)
previous_active_array = _uuid_array_sql(previous_active)
changed_node_array = _uuid_array_sql(changed_node_ids)
prior_strategy_assertion = ""
if previous_active:
prior_strategy_assertion = f"""
if (select count(*) from public.strategies
where agent_id = {agent}::uuid and id = any(previous_active_ids) and not active) <> {len(previous_active)} then
raise exception 'revise_strategy prior active strategy transition mismatch';
end if;"""
prior_node_normalization = ""
if changed_node_ids:
prior_node_normalization = f"""
if (select count(*) from public.strategy_nodes
where agent_id = {agent}::uuid and id = any(changed_node_ids) and status = 'retired') <> {len(changed_node_ids)} then
raise exception 'revise_strategy prior node transition mismatch';
end if;
update public.strategy_nodes
set status = 'retired', updated_at = {transaction_timestamp}::timestamptz
where agent_id = {agent}::uuid and id = any(changed_node_ids);
get diagnostics changed_rows = row_count;
if changed_rows <> {len(changed_node_ids)} then
raise exception 'revise_strategy prior node normalization mismatch';
end if;"""
return f"""begin;
set local standard_conforming_strings = on;
do $reconstruction$
declare
changed_rows integer;
generated_strategy_id constant uuid := {apply_engine.sql_literal(generated_strategy_id)}::uuid;
generated_node_ids constant uuid[] := {generated_node_array};
previous_active_ids constant uuid[] := {previous_active_array};
changed_node_ids constant uuid[] := {changed_node_array};
begin{prior_strategy_assertion}
if exists (
select 1 from public.strategy_node_anchors
where from_node_id = any(generated_node_ids) or to_node_id = any(generated_node_ids)
) then
raise exception 'revise_strategy generated nodes unexpectedly have anchors';
end if;
delete from public.strategy_nodes
where agent_id = {agent}::uuid and id = any(generated_node_ids);
get diagnostics changed_rows = row_count;
if changed_rows <> {len(generated_node_ids)} then
raise exception 'revise_strategy generated node delta mismatch';
end if;
delete from public.strategies
where agent_id = {agent}::uuid and id = generated_strategy_id;
get diagnostics changed_rows = row_count;
if changed_rows <> 1 then
raise exception 'revise_strategy generated strategy delta mismatch';
end if;{prior_node_normalization}
insert into public.strategies
select seeded.* from jsonb_populate_record(
null::public.strategies, {_jsonb_literal(receipt_strategy)}
) seeded;
insert into public.strategy_nodes
select seeded.* from jsonb_populate_recordset(
null::public.strategy_nodes, {_jsonb_literal(receipt_nodes)}
) seeded;
if (select count(*) from public.strategies
where agent_id = {agent}::uuid and active) <> 1 then
raise exception 'revise_strategy normalized one-active invariant mismatch';
end if;
end
$reconstruction$;
commit;
"""
def build_proposal_readback_sql(proposal_id: str) -> str: def build_proposal_readback_sql(proposal_id: str) -> str:
literal = apply_engine.sql_literal(proposal_id) literal = apply_engine.sql_literal(proposal_id)
return f"""select jsonb_build_object( return f"""select jsonb_build_object(
@ -694,7 +1106,12 @@ def _entry_summary(entry: LedgerEntry) -> dict[str, Any]:
"current_apply_sql_sha256": entry.current_apply_sql_sha256, "current_apply_sql_sha256": entry.current_apply_sql_sha256,
"expected_row_counts": entry.receipt["expected_row_counts"], "expected_row_counts": entry.receipt["expected_row_counts"],
"seed_exact": False, "seed_exact": False,
"proposal_seed_exact": False,
"canonical_seed_exact": False,
"guarded_apply_executed": False, "guarded_apply_executed": False,
"mutating_prestate_captured": False,
"mutating_delta_validated": False,
"mutating_poststate_normalized": False,
"proposal_exact": False, "proposal_exact": False,
"canonical_rows_exact": False, "canonical_rows_exact": False,
"status": "pending", "status": "pending",
@ -707,6 +1124,7 @@ def apply_entry(
entry: LedgerEntry, entry: LedgerEntry,
summary: dict[str, Any], summary: dict[str, Any],
) -> None: ) -> None:
mutating_prestate: dict[str, Any] | None = None
try: try:
_psql( _psql(
args, args,
@ -733,20 +1151,34 @@ def apply_entry(
code="entry_seed_mismatch", code="entry_seed_mismatch",
action=f"ledger entry {entry.sequence} proposal seed", action=f"ledger entry {entry.sequence} proposal seed",
) )
seeded_rows = _read_json( summary["proposal_seed_exact"] = True
args, if entry.applied_proposal["proposal_type"] == "revise_strategy":
container, mutating_prestate = _validate_revise_strategy_prestate(
replay_receipt.build_postflight_sql(entry.receipt["proposal"]), _read_json(
code="entry_seed_readback_failed", args,
action=f"ledger entry {entry.sequence} canonical seed readback", container,
) build_revise_strategy_prestate_sql(entry),
_assert_exact_json( code="mutating_prestate_readback_failed",
seeded_rows, action=f"ledger entry {entry.sequence} revise_strategy prestate readback",
entry.receipt["canonical_rows"], )
code="entry_seed_mismatch", )
action=f"ledger entry {entry.sequence} canonical seed", summary["mutating_prestate_captured"] = True
) else:
summary["seed_exact"] = True seeded_rows = _read_json(
args,
container,
replay_receipt.build_postflight_sql(entry.receipt["proposal"]),
code="entry_seed_readback_failed",
action=f"ledger entry {entry.sequence} canonical seed readback",
)
_assert_exact_json(
seeded_rows,
entry.receipt["canonical_rows"],
code="entry_seed_mismatch",
action=f"ledger entry {entry.sequence} canonical seed",
)
summary["canonical_seed_exact"] = True
summary["seed_exact"] = summary["proposal_seed_exact"] and summary["canonical_seed_exact"]
_psql( _psql(
args, args,
@ -759,6 +1191,27 @@ def apply_entry(
) )
summary["guarded_apply_executed"] = True summary["guarded_apply_executed"] = True
if mutating_prestate is not None:
generated_rows = _read_json(
args,
container,
build_revise_strategy_generated_delta_sql(entry, mutating_prestate),
code="mutating_delta_readback_failed",
action=f"ledger entry {entry.sequence} revise_strategy generated delta readback",
)
normalization_sql = build_revise_strategy_normalization_sql(entry, mutating_prestate, generated_rows)
summary["mutating_delta_validated"] = True
_psql(
args,
container,
normalization_sql,
role="postgres",
timeout=args.apply_timeout,
code="mutating_poststate_normalization_failed",
action=f"ledger entry {entry.sequence} revise_strategy exact poststate normalization",
)
summary["mutating_poststate_normalized"] = True
_psql( _psql(
args, args,
container, container,
@ -1199,7 +1652,7 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
parser.add_argument("--ledger", required=True, type=Path) parser.add_argument("--ledger", required=True, type=Path)
parser.add_argument("--ledger-sha256", required=True) parser.add_argument("--ledger-sha256", required=True)
parser.add_argument("--database", default="teleo") parser.add_argument("--database", default="teleo")
parser.add_argument("--image", default=canonical_rebuild.DEFAULT_IMAGE) parser.add_argument("--image", default=DEFAULT_REBUILD_IMAGE)
parser.add_argument("--container-prefix", default="teleo-genesis-ledger-rebuild") parser.add_argument("--container-prefix", default="teleo-genesis-ledger-rebuild")
parser.add_argument("--tmpfs-mb", default=1024, type=int) parser.add_argument("--tmpfs-mb", default=1024, type=int)
parser.add_argument("--startup-timeout", default=60.0, type=float) parser.add_argument("--startup-timeout", default=60.0, type=float)
@ -1218,8 +1671,8 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
parser.error("--database must be a safe PostgreSQL identifier up to 63 characters") parser.error("--database must be a safe PostgreSQL identifier up to 63 characters")
if not canonical_rebuild.CONTAINER_PREFIX_RE.fullmatch(args.container_prefix): if not canonical_rebuild.CONTAINER_PREFIX_RE.fullmatch(args.container_prefix):
parser.error("--container-prefix must be 1-40 Docker-safe characters") parser.error("--container-prefix must be 1-40 Docker-safe characters")
if not args.image or any(character.isspace() for character in args.image): if not IMAGE_DIGEST_RE.fullmatch(args.image):
parser.error("--image must be a non-empty Docker image reference without whitespace") parser.error("--image must be pinned by a lowercase sha256 digest")
if not args.docker_bin or any(character.isspace() for character in args.docker_bin): if not args.docker_bin or any(character.isspace() for character in args.docker_bin):
parser.error("--docker-bin must be one executable name or path without whitespace") parser.error("--docker-bin must be one executable name or path without whitespace")
if not 64 <= args.tmpfs_mb <= 65536: if not 64 <= args.tmpfs_mb <= 65536:

View file

@ -14,13 +14,17 @@ dependencies = [
[project.optional-dependencies] [project.optional-dependencies]
dev = [ dev = [
"hypothesis>=6,<7",
"pytest>=8", "pytest>=8",
"pytest-asyncio>=0.23", "pytest-asyncio>=0.23",
"ruff>=0.3", "ruff>=0.3",
] ]
observatory = [
"cloud-sql-python-connector[pg8000]>=1.20.4,<1.21",
]
[tool.setuptools] [tool.setuptools]
packages = ["lib"] packages = ["lib", "observatory_read_adapter"]
[tool.ruff] [tool.ruff]
target-version = "py311" target-version = "py311"

View file

@ -111,8 +111,17 @@ CLAIM_TYPES = {"empirical", "structural", "normative", "meta", "concept"}
SOURCE_TYPES = {"paper", "article", "transcript", "observation", "dataset", "post", "dm", "other"} SOURCE_TYPES = {"paper", "article", "transcript", "observation", "dataset", "post", "dm", "other"}
EVIDENCE_ROLES = {"grounds", "illustrates", "contradicts"} EVIDENCE_ROLES = {"grounds", "illustrates", "contradicts"}
EDGE_TYPES = { EDGE_TYPES = {
"supports", "challenges", "requires", "relates", "contradicts", "supports",
"supersedes", "derives_from", "cites", "causes", "constrains", "accelerates", "challenges",
"requires",
"relates",
"contradicts",
"supersedes",
"derives_from",
"cites",
"causes",
"constrains",
"accelerates",
} }
MAX_BUNDLE_ROWS = { MAX_BUNDLE_ROWS = {
@ -143,6 +152,21 @@ def _jsonb(value: Any) -> str:
return sql_literal(json.dumps(value, sort_keys=True)) + "::jsonb" return sql_literal(json.dumps(value, sort_keys=True)) + "::jsonb"
def deterministic_row_uuid(proposal_id: str, row_kind: str, *semantic_key: Any) -> str:
"""Derive a stable persisted row id from the proposal and semantic key.
Evidence and edge ids are not part of the reviewed v2 payload. Deriving
them here makes clone/production receipts and a pre-authorized rollback
packet bind the same exact ids instead of relying on database randomness.
"""
material = json.dumps(
["livingip", "kb-apply", str(proposal_id), row_kind, *semantic_key],
ensure_ascii=True,
separators=(",", ":"),
)
return str(uuid.uuid5(uuid.NAMESPACE_URL, material))
def _text_array(values: list[str]) -> str: def _text_array(values: list[str]) -> str:
if not values: if not values:
return "'{}'::text[]" return "'{}'::text[]"
@ -196,9 +220,7 @@ def _reject_unknown(mapping: dict[str, Any], allowed: set[str], path: str) -> No
raise ValueError(f"{path} contains unknown fields: {unknown}") raise ValueError(f"{path} contains unknown fields: {unknown}")
def _validate_approval_meta( def _validate_approval_meta(approval: dict[str, Any], proposal_type: str, apply_payload: dict[str, Any]) -> None:
approval: dict[str, Any], proposal_type: str, apply_payload: dict[str, Any]
) -> None:
if not isinstance(approval, dict): if not isinstance(approval, dict):
raise ValueError("approved proposal metadata is required") raise ValueError("approved proposal metadata is required")
if approval.get("proposal_type") != proposal_type: if approval.get("proposal_type") != proposal_type:
@ -222,12 +244,12 @@ def _validate_approval_meta(
def _approval_guard_sql(proposal_id: str, approval: dict[str, Any]) -> str: def _approval_guard_sql(proposal_id: str, approval: dict[str, Any]) -> str:
return f"""select kb_stage.assert_approved_proposal( return f"""select kb_stage.assert_approved_proposal(
{sql_literal(proposal_id)}::uuid, {sql_literal(proposal_id)}::uuid,
{sql_literal(approval['proposal_type'])}, {sql_literal(approval["proposal_type"])},
{_jsonb(approval['payload'])}, {_jsonb(approval["payload"])},
{sql_literal(approval['reviewed_by_handle'])}, {sql_literal(approval["reviewed_by_handle"])},
{sql_literal(approval.get('reviewed_by_agent_id'))}::uuid, {sql_literal(approval.get("reviewed_by_agent_id"))}::uuid,
{sql_literal(approval['reviewed_at'])}::timestamptz, {sql_literal(approval["reviewed_at"])}::timestamptz,
{sql_literal(approval['review_note'])} {sql_literal(approval["review_note"])}
);""" );"""
@ -245,12 +267,12 @@ end
$verify$;""" $verify$;"""
finish_sql = f"""select kb_stage.finish_approved_proposal( finish_sql = f"""select kb_stage.finish_approved_proposal(
{sql_literal(proposal_id)}::uuid, {sql_literal(proposal_id)}::uuid,
{sql_literal(approval['proposal_type'])}, {sql_literal(approval["proposal_type"])},
{_jsonb(approval['payload'])}, {_jsonb(approval["payload"])},
{sql_literal(approval['reviewed_by_handle'])}, {sql_literal(approval["reviewed_by_handle"])},
{sql_literal(approval.get('reviewed_by_agent_id'))}::uuid, {sql_literal(approval.get("reviewed_by_agent_id"))}::uuid,
{sql_literal(approval['reviewed_at'])}::timestamptz, {sql_literal(approval["reviewed_at"])}::timestamptz,
{sql_literal(approval['review_note'])}, {sql_literal(approval["review_note"])},
{sql_literal(applied_by)} {sql_literal(applied_by)}
);""" );"""
return checks_sql + "\n" + finish_sql return checks_sql + "\n" + finish_sql
@ -301,9 +323,9 @@ update public.strategies
insert into public.strategies insert into public.strategies
(agent_id, diagnosis, guiding_policy, proximate_objectives, version, active) (agent_id, diagnosis, guiding_policy, proximate_objectives, version, active)
select {sql_literal(agent_id)}::uuid, select {sql_literal(agent_id)}::uuid,
{sql_literal(strategy['diagnosis'])}, {sql_literal(strategy["diagnosis"])},
{sql_literal(strategy['guiding_policy'])}, {sql_literal(strategy["guiding_policy"])},
{_jsonb(strategy['proximate_objectives'])}, {_jsonb(strategy["proximate_objectives"])},
coalesce(max(version), 0) + 1, coalesce(max(version), 0) + 1,
true true
from public.strategies from public.strategies
@ -325,9 +347,7 @@ values
raise exception 'apply_proposal: expected exactly one active strategy for agent %', {sql_literal(agent_id)}; raise exception 'apply_proposal: expected exactly one active strategy for agent %', {sql_literal(agent_id)};
end if;""" end if;"""
ledger = _ledger_and_verify( ledger = _ledger_and_verify(proposal_id, applied_by or SERVICE_AGENT_HANDLE, checks, approval)
proposal_id, applied_by or SERVICE_AGENT_HANDLE, checks, approval
)
return _wrap_txn(canonical, ledger, _approval_guard_sql(proposal_id, approval)) return _wrap_txn(canonical, ledger, _approval_guard_sql(proposal_id, approval))
@ -338,14 +358,16 @@ def build_add_edge_sql(
approval: dict[str, Any], approval: dict[str, Any],
) -> str: ) -> str:
_validate_approval_meta(approval, "add_edge", apply_payload) _validate_approval_meta(approval, "add_edge", apply_payload)
f = apply_payload.get("from_claim") _reject_unknown(apply_payload, {"from_claim", "to_claim", "edge_type", "weight"}, "add_edge apply_payload")
t = apply_payload.get("to_claim") f = _uuid(apply_payload.get("from_claim"), "add_edge.from_claim")
t = _uuid(apply_payload.get("to_claim"), "add_edge.to_claim")
et = apply_payload.get("edge_type") et = apply_payload.get("edge_type")
w = apply_payload.get("weight") if et not in EDGE_TYPES:
if not (f and t and et): raise ValueError(f"add_edge.edge_type must be one of {sorted(EDGE_TYPES)}")
raise ValueError("add_edge apply_payload requires 'from_claim', 'to_claim', 'edge_type'") w = _weight(apply_payload.get("weight"), "add_edge.weight")
if f == t: if f == t:
raise ValueError("add_edge from_claim and to_claim must differ") raise ValueError("add_edge from_claim and to_claim must differ")
row_id = deterministic_row_uuid(proposal_id, "claim_edge", f, t, et)
edge_lock_key = f"claim_edge:{f}:{t}:{et}" edge_lock_key = f"claim_edge:{f}:{t}:{et}"
canonical = f""" canonical = f"""
@ -354,8 +376,8 @@ def build_add_edge_sql(
select pg_advisory_xact_lock(hashtextextended({sql_literal(edge_lock_key)}, 0)); select pg_advisory_xact_lock(hashtextextended({sql_literal(edge_lock_key)}, 0));
-- insert the edge unless an identical (from,to,type) edge already exists -- insert the edge unless an identical (from,to,type) edge already exists
insert into public.claim_edges (from_claim, to_claim, edge_type, weight) insert into public.claim_edges (id, from_claim, to_claim, edge_type, weight)
select {sql_literal(f)}::uuid, {sql_literal(t)}::uuid, select {sql_literal(row_id)}::uuid, {sql_literal(f)}::uuid, {sql_literal(t)}::uuid,
{sql_literal(et)}::edge_type, {sql_literal(w)} {sql_literal(et)}::edge_type, {sql_literal(w)}
where not exists ( where not exists (
select 1 from public.claim_edges select 1 from public.claim_edges
@ -364,7 +386,15 @@ select {sql_literal(f)}::uuid, {sql_literal(t)}::uuid,
and edge_type = {sql_literal(et)}::edge_type); and edge_type = {sql_literal(et)}::edge_type);
""".rstrip() """.rstrip()
checks = f""" if exists (select 1 from public.claim_edges checks = f""" -- Historical replay receipts can carry a pre-deterministic row id.
-- Require one exact semantic row; fresh applies still insert row_id above.
if (select count(*) from public.claim_edges
where from_claim = {sql_literal(f)}::uuid
and to_claim = {sql_literal(t)}::uuid
and edge_type = {sql_literal(et)}::edge_type) <> 1 then
raise exception 'apply_proposal: claim_edge row does not match strict apply payload';
end if;
if exists (select 1 from public.claim_edges
where from_claim = {sql_literal(f)}::uuid where from_claim = {sql_literal(f)}::uuid
and to_claim = {sql_literal(t)}::uuid and to_claim = {sql_literal(t)}::uuid
and edge_type = {sql_literal(et)}::edge_type and edge_type = {sql_literal(et)}::edge_type
@ -379,9 +409,7 @@ select {sql_literal(f)}::uuid, {sql_literal(t)}::uuid,
raise exception 'apply_proposal: claim_edge row does not match strict apply payload'; raise exception 'apply_proposal: claim_edge row does not match strict apply payload';
end if;""" end if;"""
ledger = _ledger_and_verify( ledger = _ledger_and_verify(proposal_id, applied_by or SERVICE_AGENT_HANDLE, checks, approval)
proposal_id, applied_by or SERVICE_AGENT_HANDLE, checks, approval
)
return _wrap_txn(canonical, ledger, _approval_guard_sql(proposal_id, approval)) return _wrap_txn(canonical, ledger, _approval_guard_sql(proposal_id, approval))
@ -392,6 +420,7 @@ def build_attach_evidence_sql(
approval: dict[str, Any], approval: dict[str, Any],
) -> str: ) -> str:
_validate_approval_meta(approval, "attach_evidence", apply_payload) _validate_approval_meta(approval, "attach_evidence", apply_payload)
_reject_unknown(apply_payload, {"evidence"}, "attach_evidence apply_payload")
evidence: list[dict[str, Any]] = apply_payload.get("evidence") or [] evidence: list[dict[str, Any]] = apply_payload.get("evidence") or []
if not evidence: if not evidence:
raise ValueError("attach_evidence apply_payload requires non-empty 'evidence'") raise ValueError("attach_evidence apply_payload requires non-empty 'evidence'")
@ -399,17 +428,17 @@ def build_attach_evidence_sql(
statements = [] statements = []
checks = [] checks = []
for i, ev in enumerate(evidence): for i, ev in enumerate(evidence):
claim_id = ev.get("claim_id") _reject_unknown(
source_id = ev.get("source_id") ev,
{"claim_id", "source_id", "role", "weight"},
f"attach_evidence.evidence[{i}]",
)
claim_id = _uuid(ev.get("claim_id"), f"attach_evidence.evidence[{i}].claim_id")
source_id = _uuid(ev.get("source_id"), f"attach_evidence.evidence[{i}].source_id")
role = ev.get("role") or "grounds" role = ev.get("role") or "grounds"
weight = ev.get("weight") if role not in EVIDENCE_ROLES:
if not claim_id: raise ValueError(f"attach_evidence.evidence[{i}].role must be one of {sorted(EVIDENCE_ROLES)}")
raise ValueError(f"evidence[{i}] requires 'claim_id'") weight = _weight(ev.get("weight"), f"attach_evidence.evidence[{i}].weight")
if not source_id:
raise ValueError(
f"evidence[{i}] requires an existing 'source_id'. "
"kb_apply cannot create public.sources; mint the source upstream first."
)
statements.append( statements.append(
f"""insert into public.claim_evidence (claim_id, source_id, role, weight) f"""insert into public.claim_evidence (claim_id, source_id, role, weight)
select {sql_literal(claim_id)}::uuid, {sql_literal(source_id)}::uuid, select {sql_literal(claim_id)}::uuid, {sql_literal(source_id)}::uuid,
@ -417,7 +446,14 @@ select {sql_literal(claim_id)}::uuid, {sql_literal(source_id)}::uuid,
on conflict (claim_id, source_id, role) do nothing;""" on conflict (claim_id, source_id, role) do nothing;"""
) )
checks.append( checks.append(
f""" if exists (select 1 from public.claim_evidence f""" -- Accept a legacy receipt id only when exactly one semantic row matches.
if (select count(*) from public.claim_evidence
where claim_id = {sql_literal(claim_id)}::uuid
and source_id = {sql_literal(source_id)}::uuid
and role = {sql_literal(role)}::evidence_role) <> 1 then
raise exception 'apply_proposal: evidence row % does not match strict apply payload', {i};
end if;
if exists (select 1 from public.claim_evidence
where claim_id = {sql_literal(claim_id)}::uuid where claim_id = {sql_literal(claim_id)}::uuid
and source_id = {sql_literal(source_id)}::uuid and source_id = {sql_literal(source_id)}::uuid
and role = {sql_literal(role)}::evidence_role and role = {sql_literal(role)}::evidence_role
@ -434,9 +470,7 @@ on conflict (claim_id, source_id, role) do nothing;"""
) )
canonical = "\n".join(statements) canonical = "\n".join(statements)
ledger = _ledger_and_verify( ledger = _ledger_and_verify(proposal_id, applied_by or SERVICE_AGENT_HANDLE, "\n".join(checks), approval)
proposal_id, applied_by or SERVICE_AGENT_HANDLE, "\n".join(checks), approval
)
return _wrap_txn(canonical, ledger, _approval_guard_sql(proposal_id, approval)) return _wrap_txn(canonical, ledger, _approval_guard_sql(proposal_id, approval))
@ -445,6 +479,9 @@ def build_approve_claim_sql(
proposal_id: str, proposal_id: str,
applied_by: str | None, applied_by: str | None,
approval: dict[str, Any], approval: dict[str, Any],
*,
fresh_owned: bool = False,
fresh_preflight_sha256: str | None = None,
) -> str: ) -> str:
"""Build one conflict-safe transaction for a reviewed canonical graph bundle.""" """Build one conflict-safe transaction for a reviewed canonical graph bundle."""
_validate_approval_meta(approval, "approve_claim", apply_payload) _validate_approval_meta(approval, "approve_claim", apply_payload)
@ -509,12 +546,8 @@ def build_approve_claim_sql(
"status": status, "status": status,
"confidence": _weight(row.get("confidence"), f"{path}.confidence"), "confidence": _weight(row.get("confidence"), f"{path}.confidence"),
"tags": tags, "tags": tags,
"created_by": _uuid( "created_by": _uuid(row.get("created_by", agent_id), f"{path}.created_by", nullable=True),
row.get("created_by", agent_id), f"{path}.created_by", nullable=True "superseded_by": _uuid(row.get("superseded_by"), f"{path}.superseded_by", nullable=True),
),
"superseded_by": _uuid(
row.get("superseded_by"), f"{path}.superseded_by", nullable=True
),
} }
) )
@ -543,9 +576,7 @@ def build_approve_claim_sql(
"storage_path": row.get("storage_path"), "storage_path": row.get("storage_path"),
"excerpt": row.get("excerpt"), "excerpt": row.get("excerpt"),
"hash": source_hash, "hash": source_hash,
"created_by": _uuid( "created_by": _uuid(row.get("created_by", agent_id), f"{path}.created_by", nullable=True),
row.get("created_by", agent_id), f"{path}.created_by", nullable=True
),
} }
) )
@ -566,9 +597,7 @@ def build_approve_claim_sql(
"source_id": _uuid(row.get("source_id"), f"{path}.source_id"), "source_id": _uuid(row.get("source_id"), f"{path}.source_id"),
"role": role, "role": role,
"weight": _weight(row.get("weight"), f"{path}.weight"), "weight": _weight(row.get("weight"), f"{path}.weight"),
"created_by": _uuid( "created_by": _uuid(row.get("created_by", agent_id), f"{path}.created_by", nullable=True),
row.get("created_by", agent_id), f"{path}.created_by", nullable=True
),
} }
) )
@ -589,13 +618,12 @@ def build_approve_claim_sql(
raise ValueError(f"{path} cannot be a self-edge") raise ValueError(f"{path} cannot be a self-edge")
edges.append( edges.append(
{ {
"id": deterministic_row_uuid(proposal_id, "claim_edge", from_claim, to_claim, edge_type),
"from_claim": from_claim, "from_claim": from_claim,
"to_claim": to_claim, "to_claim": to_claim,
"edge_type": edge_type, "edge_type": edge_type,
"weight": _weight(row.get("weight"), f"{path}.weight"), "weight": _weight(row.get("weight"), f"{path}.weight"),
"created_by": _uuid( "created_by": _uuid(row.get("created_by", agent_id), f"{path}.created_by", nullable=True),
row.get("created_by", agent_id), f"{path}.created_by", nullable=True
),
} }
) )
@ -639,169 +667,212 @@ def build_approve_claim_sql(
) )
_dedupe([row["id"] for row in reasoning_tools], "approve_claim.reasoning_tools ids") _dedupe([row["id"] for row in reasoning_tools], "approve_claim.reasoning_tools ids")
if fresh_owned:
if (
not isinstance(fresh_preflight_sha256, str)
or len(fresh_preflight_sha256) != 64
or any(character not in "0123456789abcdef" for character in fresh_preflight_sha256)
):
raise ValueError("fresh-owned approve_claim requires an exact preflight SHA-256")
elif fresh_preflight_sha256 is not None:
raise ValueError("fresh preflight SHA-256 is only valid for fresh-owned approve_claim")
statements: list[str] = [] statements: list[str] = []
checks: list[str] = [] checks: list[str] = []
if fresh_owned:
statements.extend(
[
f"-- fresh-owned preflight SHA-256: {fresh_preflight_sha256}",
(
"select pg_advisory_xact_lock(hashtextextended("
f"'proposal-fresh-apply:' || {sql_literal(proposal_id)}, 0));"
),
]
)
if sources: if sources:
collision_checks = [] collision_checks = []
for row in sources: for row in sources:
collision_checks.append( collision_checks.append(
f""" if exists (select 1 from public.sources f""" if exists (select 1 from public.sources
where hash = {sql_literal(row['hash'])} where hash = {sql_literal(row["hash"])}
and id <> {sql_literal(row['id'])}::uuid) then and id <> {sql_literal(row["id"])}::uuid) then
raise exception 'approve_claim: source hash collision for source %', {sql_literal(row['id'])}; raise exception 'approve_claim: source hash collision for source %', {sql_literal(row["id"])};
end if;""" end if;"""
) )
statements.append( statements.append("do $source_conflicts$\nbegin\n" + "\n".join(collision_checks) + "\nend\n$source_conflicts$;")
"do $source_conflicts$\nbegin\n"
+ "\n".join(collision_checks)
+ "\nend\n$source_conflicts$;"
)
for row in claims: for row in claims:
tags = _text_array(row["tags"]) tags = _text_array(row["tags"])
conflict_clause = ";" if fresh_owned else "\non conflict (id) do nothing;"
statements.append( statements.append(
f"""insert into public.claims (id, type, text, status, confidence, tags, created_by, superseded_by) f"""insert into public.claims (id, type, text, status, confidence, tags, created_by, superseded_by)
select {sql_literal(row['id'])}::uuid, {sql_literal(row['type'])}, {sql_literal(row['text'])}, select {sql_literal(row["id"])}::uuid, {sql_literal(row["type"])}, {sql_literal(row["text"])},
{sql_literal(row['status'])}, {sql_literal(row['confidence'])}, {tags}, {sql_literal(row["status"])}, {sql_literal(row["confidence"])}, {tags},
{sql_literal(row['created_by'])}::uuid, {sql_literal(row['superseded_by'])}::uuid {sql_literal(row["created_by"])}::uuid, {sql_literal(row["superseded_by"])}::uuid{conflict_clause}"""
on conflict (id) do nothing;"""
) )
checks.append( checks.append(
f""" if not exists (select 1 from public.claims f""" if not exists (select 1 from public.claims
where id = {sql_literal(row['id'])}::uuid where id = {sql_literal(row["id"])}::uuid
and type = {sql_literal(row['type'])} and type = {sql_literal(row["type"])}
and text = {sql_literal(row['text'])} and text = {sql_literal(row["text"])}
and status = {sql_literal(row['status'])} and status = {sql_literal(row["status"])}
and confidence is not distinct from {sql_literal(row['confidence'])} and confidence is not distinct from {sql_literal(row["confidence"])}
and tags is not distinct from {tags} and tags is not distinct from {tags}
and created_by is not distinct from {sql_literal(row['created_by'])}::uuid and created_by is not distinct from {sql_literal(row["created_by"])}::uuid
and superseded_by is not distinct from {sql_literal(row['superseded_by'])}::uuid) then and superseded_by is not distinct from {sql_literal(row["superseded_by"])}::uuid) then
raise exception 'approve_claim: claim row does not match strict apply payload: %', {sql_literal(row['id'])}; raise exception 'approve_claim: claim row does not match strict apply payload: %', {sql_literal(row["id"])};
end if;""" end if;"""
) )
for row in sources: for row in sources:
conflict_clause = ";" if fresh_owned else "\non conflict do nothing;"
statements.append( statements.append(
f"""insert into public.sources (id, source_type, url, storage_path, excerpt, hash, created_by) f"""insert into public.sources (id, source_type, url, storage_path, excerpt, hash, created_by)
select {sql_literal(row['id'])}::uuid, {sql_literal(row['source_type'])}, {sql_literal(row['url'])}, select {sql_literal(row["id"])}::uuid, {sql_literal(row["source_type"])}, {sql_literal(row["url"])},
{sql_literal(row['storage_path'])}, {sql_literal(row['excerpt'])}, {sql_literal(row['hash'])}, {sql_literal(row["storage_path"])}, {sql_literal(row["excerpt"])}, {sql_literal(row["hash"])},
{sql_literal(row['created_by'])}::uuid {sql_literal(row["created_by"])}::uuid{conflict_clause}"""
on conflict do nothing;"""
) )
checks.append( checks.append(
f""" if exists (select 1 from public.sources f""" if exists (select 1 from public.sources
where hash = {sql_literal(row['hash'])} where hash = {sql_literal(row["hash"])}
and id <> {sql_literal(row['id'])}::uuid) then and id <> {sql_literal(row["id"])}::uuid) then
raise exception 'approve_claim: source hash collision for source %', {sql_literal(row['id'])}; raise exception 'approve_claim: source hash collision for source %', {sql_literal(row["id"])};
end if; end if;
if not exists (select 1 from public.sources if not exists (select 1 from public.sources
where id = {sql_literal(row['id'])}::uuid where id = {sql_literal(row["id"])}::uuid
and source_type = {sql_literal(row['source_type'])} and source_type = {sql_literal(row["source_type"])}
and url is not distinct from {sql_literal(row['url'])} and url is not distinct from {sql_literal(row["url"])}
and storage_path is not distinct from {sql_literal(row['storage_path'])} and storage_path is not distinct from {sql_literal(row["storage_path"])}
and excerpt is not distinct from {sql_literal(row['excerpt'])} and excerpt is not distinct from {sql_literal(row["excerpt"])}
and hash = {sql_literal(row['hash'])} and hash = {sql_literal(row["hash"])}
and created_by is not distinct from {sql_literal(row['created_by'])}::uuid) then and created_by is not distinct from {sql_literal(row["created_by"])}::uuid) then
raise exception 'approve_claim: source row does not match strict apply payload: %', {sql_literal(row['id'])}; raise exception 'approve_claim: source row does not match strict apply payload: %', {sql_literal(row["id"])};
end if;""" end if;"""
) )
for row in reasoning_tools: for row in reasoning_tools:
conflict_clause = ";" if fresh_owned else "\non conflict (id) do nothing;"
statements.append( statements.append(
f"""insert into public.reasoning_tools (id, agent_id, name, description, category) f"""insert into public.reasoning_tools (id, agent_id, name, description, category)
select {sql_literal(row['id'])}::uuid, {sql_literal(row['agent_id'])}::uuid, select {sql_literal(row["id"])}::uuid, {sql_literal(row["agent_id"])}::uuid,
{sql_literal(row['name'])}, {sql_literal(row['description'])}, {sql_literal(row['category'])} {sql_literal(row["name"])}, {sql_literal(row["description"])}, {sql_literal(row["category"])}{conflict_clause}"""
on conflict (id) do nothing;"""
) )
checks.append( checks.append(
f""" if not exists (select 1 from public.reasoning_tools f""" if not exists (select 1 from public.reasoning_tools
where id = {sql_literal(row['id'])}::uuid where id = {sql_literal(row["id"])}::uuid
and agent_id is not distinct from {sql_literal(row['agent_id'])}::uuid and agent_id is not distinct from {sql_literal(row["agent_id"])}::uuid
and name = {sql_literal(row['name'])} and name = {sql_literal(row["name"])}
and description = {sql_literal(row['description'])} and description = {sql_literal(row["description"])}
and category is not distinct from {sql_literal(row['category'])}) then and category is not distinct from {sql_literal(row["category"])}) then
raise exception 'approve_claim: reasoning tool row does not match strict apply payload: %', {sql_literal(row['id'])}; raise exception 'approve_claim: reasoning tool row does not match strict apply payload: %', {sql_literal(row["id"])};
end if;""" end if;"""
) )
for row in evidence: for row in evidence:
conflict_clause = ";" if fresh_owned else "\non conflict (claim_id, source_id, role) do nothing;"
statements.append( statements.append(
f"""insert into public.claim_evidence (claim_id, source_id, role, weight, created_by) f"""insert into public.claim_evidence (claim_id, source_id, role, weight, created_by)
select {sql_literal(row['claim_id'])}::uuid, {sql_literal(row['source_id'])}::uuid, select {sql_literal(row["claim_id"])}::uuid, {sql_literal(row["source_id"])}::uuid,
{sql_literal(row['role'])}::evidence_role, {sql_literal(row['weight'])}, {sql_literal(row["role"])}::evidence_role, {sql_literal(row["weight"])},
{sql_literal(row['created_by'])}::uuid {sql_literal(row["created_by"])}::uuid{conflict_clause}"""
on conflict (claim_id, source_id, role) do nothing;"""
) )
checks.append( checks.append(
f""" if exists (select 1 from public.claim_evidence f""" -- Accept a legacy receipt id only when exactly one semantic row matches.
where claim_id = {sql_literal(row['claim_id'])}::uuid if (select count(*) from public.claim_evidence
and source_id = {sql_literal(row['source_id'])}::uuid where claim_id = {sql_literal(row["claim_id"])}::uuid
and role = {sql_literal(row['role'])}::evidence_role and source_id = {sql_literal(row["source_id"])}::uuid
and (weight is distinct from {sql_literal(row['weight'])} and role = {sql_literal(row["role"])}::evidence_role) <> 1 then
or created_by is distinct from {sql_literal(row['created_by'])}::uuid)) then raise exception 'approve_claim: evidence row does not match strict apply payload';
end if;
if exists (select 1 from public.claim_evidence
where claim_id = {sql_literal(row["claim_id"])}::uuid
and source_id = {sql_literal(row["source_id"])}::uuid
and role = {sql_literal(row["role"])}::evidence_role
and (weight is distinct from {sql_literal(row["weight"])}
or created_by is distinct from {sql_literal(row["created_by"])}::uuid)) then
raise exception 'approve_claim: evidence row does not match strict apply payload'; raise exception 'approve_claim: evidence row does not match strict apply payload';
end if; end if;
if not exists (select 1 from public.claim_evidence if not exists (select 1 from public.claim_evidence
where claim_id = {sql_literal(row['claim_id'])}::uuid where claim_id = {sql_literal(row["claim_id"])}::uuid
and source_id = {sql_literal(row['source_id'])}::uuid and source_id = {sql_literal(row["source_id"])}::uuid
and role = {sql_literal(row['role'])}::evidence_role and role = {sql_literal(row["role"])}::evidence_role
and weight is not distinct from {sql_literal(row['weight'])} and weight is not distinct from {sql_literal(row["weight"])}
and created_by is not distinct from {sql_literal(row['created_by'])}::uuid) then and created_by is not distinct from {sql_literal(row["created_by"])}::uuid) then
raise exception 'approve_claim: evidence row does not match strict apply payload'; raise exception 'approve_claim: evidence row does not match strict apply payload';
end if;""" end if;"""
) )
for row in edges: for row in edges:
edge_lock_key = ( edge_lock_key = f"claim_edge:{row['from_claim']}:{row['to_claim']}:{row['edge_type']}"
f"claim_edge:{row['from_claim']}:{row['to_claim']}:{row['edge_type']}" edge_insert_guard = (
";"
if fresh_owned
else f"""\n where not exists (
select 1 from public.claim_edges
where from_claim = {sql_literal(row["from_claim"])}::uuid
and to_claim = {sql_literal(row["to_claim"])}::uuid
and edge_type = {sql_literal(row["edge_type"])}::edge_type);"""
) )
statements.append( statements.append(
f"""select pg_advisory_xact_lock(hashtextextended({sql_literal(edge_lock_key)}, 0)); f"""select pg_advisory_xact_lock(hashtextextended({sql_literal(edge_lock_key)}, 0));
insert into public.claim_edges (from_claim, to_claim, edge_type, weight, created_by) insert into public.claim_edges (id, from_claim, to_claim, edge_type, weight, created_by)
select {sql_literal(row['from_claim'])}::uuid, {sql_literal(row['to_claim'])}::uuid, select {sql_literal(row["id"])}::uuid, {sql_literal(row["from_claim"])}::uuid, {sql_literal(row["to_claim"])}::uuid,
{sql_literal(row['edge_type'])}::edge_type, {sql_literal(row['weight'])}, {sql_literal(row["edge_type"])}::edge_type, {sql_literal(row["weight"])},
{sql_literal(row['created_by'])}::uuid {sql_literal(row["created_by"])}::uuid{edge_insert_guard}"""
where not exists (
select 1 from public.claim_edges
where from_claim = {sql_literal(row['from_claim'])}::uuid
and to_claim = {sql_literal(row['to_claim'])}::uuid
and edge_type = {sql_literal(row['edge_type'])}::edge_type);"""
) )
checks.append( checks.append(
f""" if exists (select 1 from public.claim_edges f""" -- Accept a legacy receipt id only when exactly one semantic row matches.
where from_claim = {sql_literal(row['from_claim'])}::uuid if (select count(*) from public.claim_edges
and to_claim = {sql_literal(row['to_claim'])}::uuid where from_claim = {sql_literal(row["from_claim"])}::uuid
and edge_type = {sql_literal(row['edge_type'])}::edge_type and to_claim = {sql_literal(row["to_claim"])}::uuid
and (weight is distinct from {sql_literal(row['weight'])} and edge_type = {sql_literal(row["edge_type"])}::edge_type) <> 1 then
or created_by is distinct from {sql_literal(row['created_by'])}::uuid)) then raise exception 'approve_claim: edge row does not match strict apply payload';
end if;
if exists (select 1 from public.claim_edges
where from_claim = {sql_literal(row["from_claim"])}::uuid
and to_claim = {sql_literal(row["to_claim"])}::uuid
and edge_type = {sql_literal(row["edge_type"])}::edge_type
and (weight is distinct from {sql_literal(row["weight"])}
or created_by is distinct from {sql_literal(row["created_by"])}::uuid)) then
raise exception 'approve_claim: edge row does not match strict apply payload'; raise exception 'approve_claim: edge row does not match strict apply payload';
end if; end if;
if not exists (select 1 from public.claim_edges if not exists (select 1 from public.claim_edges
where from_claim = {sql_literal(row['from_claim'])}::uuid where from_claim = {sql_literal(row["from_claim"])}::uuid
and to_claim = {sql_literal(row['to_claim'])}::uuid and to_claim = {sql_literal(row["to_claim"])}::uuid
and edge_type = {sql_literal(row['edge_type'])}::edge_type and edge_type = {sql_literal(row["edge_type"])}::edge_type
and weight is not distinct from {sql_literal(row['weight'])} and weight is not distinct from {sql_literal(row["weight"])}
and created_by is not distinct from {sql_literal(row['created_by'])}::uuid) then and created_by is not distinct from {sql_literal(row["created_by"])}::uuid) then
raise exception 'approve_claim: edge row does not match strict apply payload'; raise exception 'approve_claim: edge row does not match strict apply payload';
end if;""" end if;"""
) )
canonical = "\n\n".join(statements) canonical = "\n\n".join(statements)
ledger = _ledger_and_verify( ledger = _ledger_and_verify(proposal_id, applied_by or SERVICE_AGENT_HANDLE, "\n".join(checks), approval)
proposal_id, applied_by or SERVICE_AGENT_HANDLE, "\n".join(checks), approval return _wrap_txn(
canonical,
ledger,
_approval_guard_sql(proposal_id, approval),
serializable=fresh_owned,
) )
return _wrap_txn(canonical, ledger, _approval_guard_sql(proposal_id, approval))
def _wrap_txn(canonical_sql: str, ledger_sql: str, approval_guard_sql: str) -> str: def _wrap_txn(
canonical_sql: str,
ledger_sql: str,
approval_guard_sql: str,
*,
serializable: bool = False,
) -> str:
return ( return (
"begin;\n" "begin;\n"
"set local standard_conforming_strings = on;\n" + ("set transaction isolation level serializable;\n" if serializable else "")
f"{approval_guard_sql}\n" + "set local standard_conforming_strings = on;\n"
f"{canonical_sql}\n" + f"{approval_guard_sql}\n"
f"{ledger_sql}\n" + f"{canonical_sql}\n"
"commit;\n" + f"{ledger_sql}\n"
+ "commit;\n"
) )
@ -813,7 +884,13 @@ BUILDERS = {
} }
def build_apply_sql(proposal: dict[str, Any], applied_by: str | None) -> str: def build_apply_sql(
proposal: dict[str, Any],
applied_by: str | None,
*,
fresh_owned: bool = False,
fresh_preflight_sha256: str | None = None,
) -> str:
ptype = proposal["proposal_type"] ptype = proposal["proposal_type"]
if ptype not in BUILDERS: if ptype not in BUILDERS:
raise ValueError(f"apply_proposal cannot apply proposal_type {ptype!r}") raise ValueError(f"apply_proposal cannot apply proposal_type {ptype!r}")
@ -824,6 +901,17 @@ def build_apply_sql(proposal: dict[str, Any], applied_by: str | None) -> str:
"proposal payload has no 'apply_payload' strict contract. " "proposal payload has no 'apply_payload' strict contract. "
"Run the normalizer to produce apply_payload before applying." "Run the normalizer to produce apply_payload before applying."
) )
if fresh_owned and ptype != "approve_claim":
raise ValueError("fresh-owned apply is supported only for approve_claim")
if ptype == "approve_claim":
return build_approve_claim_sql(
apply_payload,
proposal["id"],
applied_by or SERVICE_AGENT_HANDLE,
proposal,
fresh_owned=fresh_owned,
fresh_preflight_sha256=fresh_preflight_sha256,
)
return BUILDERS[ptype]( return BUILDERS[ptype](
apply_payload, apply_payload,
proposal["id"], proposal["id"],
@ -837,9 +925,7 @@ def assert_applyable(proposal: dict[str, Any]) -> None:
if status == "applied": if status == "applied":
raise SystemExit(f"proposal {proposal['id']} is already applied (idempotent no-op)") raise SystemExit(f"proposal {proposal['id']} is already applied (idempotent no-op)")
if status != "approved": if status != "approved":
raise SystemExit( raise SystemExit(f"proposal {proposal['id']} has status {status!r}; only 'approved' proposals apply")
f"proposal {proposal['id']} has status {status!r}; only 'approved' proposals apply"
)
def assert_receiptable(proposal: dict[str, Any]) -> None: def assert_receiptable(proposal: dict[str, Any]) -> None:
@ -877,23 +963,36 @@ def run_psql(
) -> str: ) -> str:
docker_binary = shutil.which("docker") or "docker" docker_binary = shutil.which("docker") or "docker"
command = [ command = [
docker_binary, "exec", "-e", "PGPASSWORD", "-i", args.container, docker_binary,
"psql", "-U", args.role, "-h", args.host, "-d", args.db, "exec",
"-v", "ON_ERROR_STOP=1", "-At", "-q", "-e",
"PGPASSWORD",
"-i",
args.container,
"psql",
"-U",
args.role,
"-h",
args.host,
"-d",
args.db,
"-v",
"ON_ERROR_STOP=1",
"-At",
"-q",
] ]
result = subprocess.run( result = subprocess.run(
command, input=sql, text=True, capture_output=True, command,
input=sql,
text=True,
capture_output=True,
env={"PGPASSWORD": password, "PATH": "/usr/bin:/bin:/usr/local/bin"}, env={"PGPASSWORD": password, "PATH": "/usr/bin:/bin:/usr/local/bin"},
check=False, check=False,
) )
if result.returncode != 0: if result.returncode != 0:
if redact_output_on_error: if redact_output_on_error:
raise SystemExit( raise SystemExit(f"psql failed ({result.returncode}); private postflight output redacted")
f"psql failed ({result.returncode}); private postflight output redacted" raise SystemExit(f"psql failed ({result.returncode})\nSTDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}")
)
raise SystemExit(
f"psql failed ({result.returncode})\nSTDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}"
)
return result.stdout return result.stdout
@ -940,7 +1039,7 @@ def capture_replay_receipt(
raise RuntimeError("postflight query did not return a JSON object") raise RuntimeError("postflight query did not return a JSON object")
apply_sql_source = "exact_executed_sql" apply_sql_source = "exact_executed_sql"
if apply_sql is None: if apply_sql is None:
apply_sql = build_apply_sql(proposal, proposal.get("applied_by_handle")) apply_sql = build_apply_sql_for_args(proposal, args, proposal.get("applied_by_handle"))
apply_sql_source = "reconstructed_current_engine" apply_sql_source = "reconstructed_current_engine"
receipt = replay_receipt.build_replay_receipt( receipt = replay_receipt.build_replay_receipt(
proposal, proposal,
@ -972,6 +1071,14 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
p.add_argument("--db", default=DEFAULT_DB) p.add_argument("--db", default=DEFAULT_DB)
p.add_argument("--host", default=DEFAULT_HOST) p.add_argument("--host", default=DEFAULT_HOST)
p.add_argument("--role", default=DEFAULT_ROLE) p.add_argument("--role", default=DEFAULT_ROLE)
p.add_argument(
"--fresh-preflight",
type=Path,
help=(
"exact proposal_apply_fresh_preflight JSON; makes approve_claim use strict fresh-owned inserts "
"bound to the timestamped preflight"
),
)
p.add_argument( p.add_argument(
"--receipt-only", "--receipt-only",
action="store_true", action="store_true",
@ -980,8 +1087,7 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
p.add_argument( p.add_argument(
"--receipt-dir", "--receipt-dir",
default=None, default=None,
help="private receipt directory (default: KB_APPLY_RECEIPT_DIR or " help=f"private receipt directory (default: KB_APPLY_RECEIPT_DIR or {replay_receipt.DEFAULT_RECEIPT_DIR})",
f"{replay_receipt.DEFAULT_RECEIPT_DIR})",
) )
p.add_argument( p.add_argument(
"--receipt-out", "--receipt-out",
@ -994,6 +1100,28 @@ def parse_args(argv: list[str]) -> argparse.Namespace:
return args return args
def build_apply_sql_for_args(
proposal: dict[str, Any],
args: argparse.Namespace,
applied_by: str | None,
) -> str:
fresh_preflight_path = getattr(args, "fresh_preflight", None)
if fresh_preflight_path is None:
return build_apply_sql(proposal, applied_by)
if not fresh_preflight_path.is_file():
raise SystemExit(f"fresh preflight file not found: {fresh_preflight_path}")
try:
preflight = json.loads(fresh_preflight_path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as exc:
raise SystemExit(f"fresh preflight is unreadable: {fresh_preflight_path}") from exc
import proposal_apply_lifecycle as lifecycle
try:
return lifecycle.build_fresh_owned_apply_sql(proposal, preflight, applied_by)
except ValueError as exc:
raise SystemExit(f"fresh preflight refused: {exc}") from exc
def main(argv: list[str] | None = None) -> int: def main(argv: list[str] | None = None) -> int:
args = parse_args(sys.argv[1:] if argv is None else argv) args = parse_args(sys.argv[1:] if argv is None else argv)
@ -1020,13 +1148,13 @@ def main(argv: list[str] | None = None) -> int:
password = load_password(args.secrets_file) password = load_password(args.secrets_file)
proposal = load_proposal(args, password) proposal = load_proposal(args, password)
assert_applyable(proposal) assert_applyable(proposal)
print(build_apply_sql(proposal, args.applied_by)) print(build_apply_sql_for_args(proposal, args, args.applied_by))
return 0 return 0
password = load_password(args.secrets_file) password = load_password(args.secrets_file)
proposal = load_proposal(args, password) proposal = load_proposal(args, password)
assert_applyable(proposal) assert_applyable(proposal)
sql = build_apply_sql(proposal, args.applied_by) sql = build_apply_sql_for_args(proposal, args, args.applied_by)
run_psql(args, sql, password) run_psql(args, sql, password)
applied_proposal = load_proposal(args, password) applied_proposal = load_proposal(args, password)
try: try:

View file

@ -35,6 +35,7 @@ from __future__ import annotations
import argparse import argparse
import json import json
import os import os
import stat
import subprocess import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
@ -53,6 +54,13 @@ WORKER_TYPES = ap.APPLYABLE_TYPES
# bundles and evidence/edge applies do not trigger a generic identity render. # bundles and evidence/edge applies do not trigger a generic identity render.
RENDER_TYPES = ("revise_strategy",) RENDER_TYPES = ("revise_strategy",)
POSTCOMMIT_RECEIPT_FAILURE_MARKER = "committed, but private replay receipt capture failed"
POSTCOMMIT_RECEIPT_RECOVERY_MARKER = ". Recover without reapplying via: "
class PostCommitReceiptError(RuntimeError):
"""The proposal committed, but its private row-level receipt is unavailable."""
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Pure helpers (unit-tested without a DB) # # Pure helpers (unit-tested without a DB) #
@ -160,14 +168,69 @@ def partition_candidates(
return {"poisoned": poisoned, "to_apply": eligible[: max(0, max_per_tick)]} return {"poisoned": poisoned, "to_apply": eligible[: max(0, max_per_tick)]}
def has_exact_postcommit_receipt_failure(stderr: str | None, proposal_id: str) -> bool:
"""Recognize only the proposal-bound post-COMMIT message from apply_proposal.
The old marker can occur inside payload-validation tracebacks (for example,
as an attacker-controlled unknown field name). Requiring the complete
engine message shape prevents those pre-COMMIT failures from bypassing the
normal failure and poison-pill accounting.
"""
prefix = f"proposal {proposal_id} {POSTCOMMIT_RECEIPT_FAILURE_MARKER}: "
recovery_suffix = f" {proposal_id} --receipt-only"
for line in (stderr or "").splitlines():
candidate = line.rstrip("\r")
if (
candidate.startswith(prefix)
and POSTCOMMIT_RECEIPT_RECOVERY_MARKER in candidate[len(prefix) :]
and candidate.endswith(recovery_suffix)
):
return True
return False
def receipt_path_for_proposal(args: argparse.Namespace, proposal_id: str) -> Path:
"""Return the explicit, deterministic private receipt path for one proposal."""
receipt_dir = (
getattr(args, "receipt_dir", None)
or os.environ.get("KB_APPLY_WORKER_RECEIPT_DIR")
or os.environ.get("KB_APPLY_RECEIPT_DIR")
or ap.replay_receipt.DEFAULT_RECEIPT_DIR
)
return Path(receipt_dir).expanduser().resolve() / f"{proposal_id}.json"
def assert_private_replay_receipt(path: Path, proposal_id: str) -> None:
"""Verify the worker can rely on the exact private row-level receipt."""
try:
path_stat = path.lstat()
except OSError as exc:
raise RuntimeError("private replay receipt was not written") from exc
if not stat.S_ISREG(path_stat.st_mode) or path.is_symlink():
raise RuntimeError("private replay receipt is not a regular file")
if stat.S_IMODE(path_stat.st_mode) & 0o077:
raise RuntimeError("private replay receipt permissions are broader than 0600")
try:
receipt = json.loads(path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as exc:
raise RuntimeError("private replay receipt is unreadable or invalid") from exc
if not isinstance(receipt, dict):
raise RuntimeError("private replay receipt is not a JSON object")
try:
ap.replay_receipt.validate_replay_receipt(
receipt,
expected_proposal_id=str(proposal_id),
)
except ValueError as exc:
raise RuntimeError("private replay receipt row-level contract is invalid") from exc
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
# Side-effecting steps # # Side-effecting steps #
# --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- #
def _psql_args(args: argparse.Namespace) -> argparse.Namespace: def _psql_args(args: argparse.Namespace) -> argparse.Namespace:
"""Namespace shaped for ap.run_psql (reuses the kb_apply connection path).""" """Namespace shaped for ap.run_psql (reuses the kb_apply connection path)."""
return argparse.Namespace( return argparse.Namespace(container=args.container, db=args.db, host=args.host, role=args.role)
container=args.container, db=args.db, host=args.host, role=args.role
)
def fetch_candidates( def fetch_candidates(
@ -181,20 +244,73 @@ def fetch_candidates(
def apply_one(args: argparse.Namespace, proposal_id: str) -> None: def apply_one(args: argparse.Namespace, proposal_id: str) -> None:
"""Apply via the audited apply_proposal.py CLI -- same txn + rowcount guard.""" """Apply once and retain or safely recover the exact private replay receipt."""
receipt_path = receipt_path_for_proposal(args, proposal_id)
cmd = [ cmd = [
sys.executable, str(args.apply_script), proposal_id, sys.executable,
"--applied-by", args.applied_by, str(args.apply_script),
"--secrets-file", args.secrets_file, proposal_id,
"--container", args.container, "--db", args.db, "--applied-by",
"--host", args.host, "--role", args.role, args.applied_by,
"--secrets-file",
args.secrets_file,
"--container",
args.container,
"--db",
args.db,
"--host",
args.host,
"--role",
args.role,
"--receipt-dir",
str(receipt_path.parent),
"--receipt-out",
str(receipt_path),
] ]
result = subprocess.run(cmd, text=True, capture_output=True, check=False) result = subprocess.run(cmd, text=True, capture_output=True, check=False)
if result.returncode != 0: committed = result.returncode == 0 or has_exact_postcommit_receipt_failure(
result.stderr,
proposal_id,
)
if not committed:
raise RuntimeError( raise RuntimeError(
f"apply failed for {proposal_id}: {result.stdout.strip()} {result.stderr.strip()}" f"apply failed for {proposal_id}: {(result.stdout or '').strip()} {(result.stderr or '').strip()}"
) )
if result.returncode == 0:
try:
assert_private_replay_receipt(receipt_path, proposal_id)
return
except RuntimeError:
# The engine returned only after COMMIT. A missing/invalid receipt is
# recoverable without replaying the apply transaction.
pass
try:
recovery = subprocess.run(
[*cmd, "--receipt-only"],
text=True,
capture_output=True,
check=False,
)
except OSError as exc:
raise PostCommitReceiptError(
f"proposal {proposal_id} committed, but the read-only receipt recovery "
"command could not start; do not retry the apply transaction"
) from exc
if recovery.returncode != 0:
raise PostCommitReceiptError(
f"proposal {proposal_id} committed, but read-only receipt recovery "
f"failed (exit {recovery.returncode}); do not retry the apply transaction"
)
try:
assert_private_replay_receipt(receipt_path, proposal_id)
except RuntimeError as exc:
raise PostCommitReceiptError(
f"proposal {proposal_id} committed, but receipt recovery did not produce "
"a valid private row-level receipt; do not retry the apply transaction"
) from exc
def render_one(args: argparse.Namespace, agent_id: str | None) -> str: def render_one(args: argparse.Namespace, agent_id: str | None) -> str:
cmd = build_render_command(args.render_cmd, agent_id) cmd = build_render_command(args.render_cmd, agent_id)
@ -202,9 +318,7 @@ def render_one(args: argparse.Namespace, agent_id: str | None) -> str:
return "render skipped (no render-cmd configured; PR2 renderer not deployed)" return "render skipped (no render-cmd configured; PR2 renderer not deployed)"
result = subprocess.run(cmd, text=True, capture_output=True, check=False) result = subprocess.run(cmd, text=True, capture_output=True, check=False)
if result.returncode != 0: if result.returncode != 0:
raise RuntimeError( raise RuntimeError(f"render failed for agent {agent_id}: {result.stdout.strip()} {result.stderr.strip()}")
f"render failed for agent {agent_id}: {result.stdout.strip()} {result.stderr.strip()}"
)
return f"rendered agent {agent_id}" return f"rendered agent {agent_id}"
@ -214,11 +328,7 @@ def render_one(args: argparse.Namespace, agent_id: str | None) -> str:
def run(args: argparse.Namespace) -> int: def run(args: argparse.Namespace) -> int:
password = ap.load_password(args.secrets_file) password = ap.load_password(args.secrets_file)
failure_counts = load_failure_state(args.failure_state_file) failure_counts = load_failure_state(args.failure_state_file)
exhausted_ids = tuple( exhausted_ids = tuple(proposal_id for proposal_id, count in failure_counts.items() if count >= args.max_attempts)
proposal_id
for proposal_id, count in failure_counts.items()
if count >= args.max_attempts
)
candidates = fetch_candidates(args, password, exhausted_ids) candidates = fetch_candidates(args, password, exhausted_ids)
for proposal_id in exhausted_ids: for proposal_id in exhausted_ids:
@ -263,6 +373,15 @@ def run(args: argparse.Namespace) -> int:
print(f"applied {pid} ({ptype})") print(f"applied {pid} ({ptype})")
if ptype in RENDER_TYPES: if ptype in RENDER_TYPES:
print(" " + render_one(args, agent_id)) print(" " + render_one(args, agent_id))
except PostCommitReceiptError as exc:
failures += 1
# The canonical transaction already committed. Do not classify this
# as an apply failure or poison/retry the proposal; receipt-only is
# the sole safe recovery path.
print(
f"POST-COMMIT RECEIPT ERROR for {pid} ({ptype}): {exc}",
file=sys.stderr,
)
except Exception as exc: except Exception as exc:
failures += 1 failures += 1
# Leave the proposal at 'approved' so a fixed one reapplies next tick # Leave the proposal at 'approved' so a fixed one reapplies next tick
@ -270,48 +389,65 @@ def run(args: argparse.Namespace) -> int:
# so a deterministically-failing proposal hits the ceiling instead of # so a deterministically-failing proposal hits the ceiling instead of
# retrying forever. Surface loudly for the operator. # retrying forever. Surface loudly for the operator.
failure_counts[pid] = failure_counts.get(pid, 0) + 1 failure_counts[pid] = failure_counts.get(pid, 0) + 1
print(f"ERROR applying {pid} ({ptype}) [attempt {failure_counts[pid]}/" print(
f"{args.max_attempts}]: {exc}", file=sys.stderr) f"ERROR applying {pid} ({ptype}) [attempt {failure_counts[pid]}/{args.max_attempts}]: {exc}",
file=sys.stderr,
)
save_failure_state(args.failure_state_file, failure_counts) save_failure_state(args.failure_state_file, failure_counts)
return 1 if failures else 0 return 1 if failures else 0
def parse_args(argv: list[str]) -> argparse.Namespace: def parse_args(argv: list[str]) -> argparse.Namespace:
p = argparse.ArgumentParser( p = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
)
p.add_argument( p.add_argument(
"--enable", action="store_true", "--enable",
action="store_true",
help="actually apply (default: report-only). Also honored via KB_APPLY_WORKER_ENABLED=1.", help="actually apply (default: report-only). Also honored via KB_APPLY_WORKER_ENABLED=1.",
) )
p.add_argument("--limit", type=int, default=20, help="max candidates fetched per tick") p.add_argument("--limit", type=int, default=20, help="max candidates fetched per tick")
p.add_argument( p.add_argument(
"--max-per-tick", type=int, default=1, "--max-per-tick",
type=int,
default=1,
help="max proposals actually APPLIED per tick (default 1: applies land " help="max proposals actually APPLIED per tick (default 1: applies land "
"one-at-a-time and observably, not a whole-queue drain)", "one-at-a-time and observably, not a whole-queue drain)",
) )
p.add_argument( p.add_argument(
"--max-attempts", type=int, default=3, "--max-attempts",
type=int,
default=3,
help="consecutive apply failures before a proposal is treated as a " help="consecutive apply failures before a proposal is treated as a "
"poison pill and skipped (needs a human fix, not endless retries)", "poison pill and skipped (needs a human fix, not endless retries)",
) )
p.add_argument( p.add_argument(
"--failure-state-file", "--failure-state-file",
default=os.environ.get("KB_APPLY_WORKER_STATE", "/opt/teleo-eval/logs/kb-apply-worker-failures.json"), default=os.environ.get("KB_APPLY_WORKER_STATE", "/opt/teleo-eval/logs/kb-apply-worker-failures.json"),
help="persisted per-proposal failure counts (survives oneshot ticks so " help="persisted per-proposal failure counts (survives oneshot ticks so the poison-pill ceiling actually bites)",
"the poison-pill ceiling actually bites)",
) )
p.add_argument( p.add_argument(
"--applied-by", default=ap.SERVICE_AGENT_HANDLE, "--applied-by",
default=ap.SERVICE_AGENT_HANDLE,
help="handle recorded as applied_by (default: the kb-apply service agent)", help="handle recorded as applied_by (default: the kb-apply service agent)",
) )
p.add_argument( p.add_argument(
"--apply-script", default=str(HERE / "apply_proposal.py"), "--apply-script",
default=str(HERE / "apply_proposal.py"),
help="path to the apply_proposal.py engine (the sole apply path)", help="path to the apply_proposal.py engine (the sole apply path)",
) )
p.add_argument( p.add_argument(
"--render-cmd", default=os.environ.get("KB_APPLY_RENDER_CMD", ""), "--receipt-dir",
default=(
os.environ.get("KB_APPLY_WORKER_RECEIPT_DIR")
or os.environ.get("KB_APPLY_RECEIPT_DIR")
or ap.replay_receipt.DEFAULT_RECEIPT_DIR
),
help="private replay receipt directory; each apply writes the deterministic "
"<proposal-id>.json path and verifies 0600 permissions",
)
p.add_argument(
"--render-cmd",
default=os.environ.get("KB_APPLY_RENDER_CMD", ""),
help="render hook template, e.g. 'python3 render_soul.py --agent-id {agent_id}'. " help="render hook template, e.g. 'python3 render_soul.py --agent-id {agent_id}'. "
"Empty (default) skips render until the SOUL renderer is deployed.", "Empty (default) skips render until the SOUL renderer is deployed.",
) )

View file

@ -0,0 +1,406 @@
#!/usr/bin/env python3
"""Build the exact no-send packet for Leo's unseen Telegram reasoning chain."""
from __future__ import annotations
import argparse
import hashlib
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
try:
import verify_leo_unseen_reasoning_chain as unseen
except ImportError: # pragma: no cover - imported as scripts.* in tests
from scripts import verify_leo_unseen_reasoning_chain as unseen
SCHEMA = "livingip.telegramVisibleUnseenChainPacket.v2"
REPO_ROOT = Path(__file__).resolve().parents[1]
REPORT_DIR = Path("docs/reports/leo-working-state-20260709")
DEFAULT_HANDLER_RECEIPT = REPORT_DIR / "leo-unseen-reasoning-chain-canary-current.json"
DEFAULT_OUT = REPORT_DIR / "telegram-visible-unseen-chain-authorization-packet-current.json"
DEFAULT_MARKDOWN_OUT = REPORT_DIR / "telegram-visible-unseen-chain-authorization-packet-current.md"
DEFAULT_CAPTURE_RECEIPT = REPORT_DIR / "telegram-visible-unseen-chain-capture-receipt-current.json"
DEFAULT_PREFLIGHT = REPORT_DIR / "telegram-visible-unseen-chain-preflight-current.json"
DEFAULT_POSTFLIGHT = REPORT_DIR / "telegram-visible-unseen-chain-postflight-current.json"
DEFAULT_CHAT_ID = "-5146042086"
DEFAULT_CHAT_LABEL = "Leo"
DEFAULT_PROOF_DIR = "outputs/telegram-visible-unseen-chain-20260715"
DEFAULT_MANIFEST_SQL = Path("ops/postgres_parity_manifest.sql")
READ_ONLY_DB_ROLE = "pg_read_all_data"
DEFAULT_CODEX_THREAD_ID = "019f6350-3350-7040-b223-c5c22673fece"
TOOLING_PATHS = {
"packet_builder": Path("scripts/build_telegram_visible_unseen_chain_packet.py"),
"state_collector": Path("scripts/collect_telegram_visible_unseen_chain_state.py"),
"capture_verifier": Path("scripts/verify_telegram_visible_unseen_chain.py"),
}
def _load_json(path: Path) -> dict[str, Any]:
return json.loads(path.read_text(encoding="utf-8"))
def _sha256_bytes(value: bytes) -> str:
return hashlib.sha256(value).hexdigest()
def _sha256_file(path: Path) -> str:
return _sha256_bytes(path.read_bytes())
def _canonical_sha256(value: Any) -> str:
encoded = json.dumps(value, sort_keys=True, separators=(",", ":")).encode("utf-8")
return _sha256_bytes(encoded)
def current_git_sha(repo_root: Path = Path(".")) -> str:
proc = subprocess.run(
["git", "rev-parse", "HEAD"],
cwd=repo_root,
text=True,
capture_output=True,
check=False,
)
return proc.stdout.strip() if proc.returncode == 0 else ""
def exact_messages() -> list[dict[str, Any]]:
messages = []
for sequence, prompt in enumerate(unseen.PROMPTS, start=1):
message = str(prompt["message"])
messages.append(
{
"sequence": sequence,
"prompt_id": prompt["id"],
"dimension": prompt["dimension"],
"message": message,
"message_sha256": _sha256_bytes(message.encode("utf-8")),
"wait_for_visible_reply_before_next": True,
}
)
return messages
def tooling_binding(repo_root: Path = REPO_ROOT) -> dict[str, dict[str, Any]]:
return {name: {"path": str(path), "sha256": _sha256_file(repo_root / path)} for name, path in TOOLING_PATHS.items()}
def manifest_binding(repo_root: Path = REPO_ROOT) -> dict[str, Any]:
return {
"path": str(DEFAULT_MANIFEST_SQL),
"sha256": _sha256_file(repo_root / DEFAULT_MANIFEST_SQL),
"execution_contract": {
"database": "teleo",
"authenticated_role": "postgres",
"effective_role": READ_ONLY_DB_ROLE,
"default_transaction_read_only": "on",
"transaction_read_only": "on",
"psql_rc_disabled": True,
"arbitrary_manifest_override_allowed": False,
},
}
def _handler_checks(receipt: dict[str, Any]) -> dict[str, bool]:
safety = receipt.get("safety_gate") if isinstance(receipt.get("safety_gate"), dict) else {}
safety_checks = safety.get("checks") if isinstance(safety.get("checks"), dict) else {}
database = receipt.get("database") if isinstance(receipt.get("database"), dict) else {}
prompt_ids = [str(item["id"]) for item in unseen.PROMPTS]
return {
"handler_receipt_passed": receipt.get("status") == "pass",
"handler_receipt_schema_supported": receipt.get("schema") == unseen.SCHEMA,
"handler_prompt_ids_exact": receipt.get("prompt_ids") == prompt_ids,
"handler_outcomes_all_pass": bool(receipt.get("outcomes"))
and all(value is True for value in receipt.get("outcomes", {}).values()),
"handler_checks_all_pass": bool(receipt.get("checks"))
and all(value is True for value in receipt.get("checks", {}).values()),
"handler_safety_gate_passed": safety.get("status") == "pass",
"handler_proved_no_telegram_post": safety_checks.get("no_telegram_post") is True,
"handler_proved_read_only_tool_traces": safety_checks.get("all_tool_traces_read_only_and_bound") is True,
"handler_proved_unchanged_fingerprint": database.get("fingerprint_unchanged") is True
and isinstance(database.get("fingerprint_sha256"), str)
and len(database["fingerprint_sha256"]) == 64,
"handler_tier_remains_below_telegram_visible": "Telegram-visible message delivery"
in (receipt.get("claim_ceiling") or {}).get("not_proven", []),
}
def _authorization_text(*, chat_label: str, chat_id: str, messages: list[dict[str, Any]]) -> str:
quoted = " ".join(f"[{item['prompt_id']}] {json.dumps(item['message'], ensure_ascii=True)}" for item in messages)
return (
"I authorize Codex to use the already-authenticated Chrome Telegram UI to send exactly these three "
f"messages, in order and with no additional messages, to the Telegram group {chat_label} (chat ID "
f"{chat_id}), waiting for Leo's visible reply after each turn: {quoted} Capture the visible replies, "
"message IDs, timestamps, screenshot and accessibility evidence, plus an independently retained Chrome "
"control provenance receipt bound to the Codex rollout's user-authorization and Chrome tool events; "
"perform only read-only DB/service "
"readbacks; do not use the Bot API; do not stage, approve, apply, or otherwise mutate knowledge."
)
def build_packet(
*,
handler_receipt_path: Path = DEFAULT_HANDLER_RECEIPT,
chat_id: str = DEFAULT_CHAT_ID,
chat_label: str = DEFAULT_CHAT_LABEL,
proof_dir: str = DEFAULT_PROOF_DIR,
codex_thread_id: str = DEFAULT_CODEX_THREAD_ID,
git_sha: str | None = None,
) -> dict[str, Any]:
handler_receipt = _load_json(handler_receipt_path)
messages = exact_messages()
handler_checks = _handler_checks(handler_receipt)
target = {
"platform": "telegram",
"chat_label": chat_label,
"chat_id": chat_id,
"allowed_transport": "authenticated_chrome_telegram_ui",
"forbidden_transports": ["telegram_bot_api", "copied_transcript", "handler_substitution"],
"message_count": len(messages),
"expected_prompt_ids": [item["prompt_id"] for item in messages],
}
handler_binding = {
"path": str(handler_receipt_path),
"sha256": _sha256_file(handler_receipt_path),
"schema": handler_receipt.get("schema"),
"proof_tier": handler_receipt.get("proof_tier"),
"remote_run_id": handler_receipt.get("remote_run_id"),
"deployed_git_head": handler_receipt.get("deployed_git_head"),
"fingerprint_sha256": (handler_receipt.get("database") or {}).get("fingerprint_sha256"),
}
tooling = tooling_binding()
manifest = manifest_binding()
browser_provenance_contract = {
"schema": "livingip.authenticatedChromeTelegramCaptureProvenance.v1",
"capture_channel": "codex_chrome_extension",
"requires_preflight_challenge_nonce": True,
"requires_codex_rollout_log_outside_evidence_root": True,
"requires_chrome_backend_tool_receipts": True,
"requires_provenance_sha256_in_final_chrome_tool_receipt": True,
"requires_codex_user_message_authorization_receipt": True,
"requires_browser_session_tab_and_capture_identifiers": True,
"requires_telegram_web_origin_and_chat_identity": True,
"requires_hashes_for_every_screenshot_and_accessibility_artifact": True,
}
protocol = {
"target": target,
"exact_messages": messages,
"handler_binding": handler_binding,
"tooling_binding": tooling,
"manifest_binding": manifest,
"browser_provenance_contract": browser_provenance_contract,
"operator_context": {
"codex_thread_id": codex_thread_id,
"authorization_source": "codex_platform_user_message",
},
"state_contract": {
"preflight": "two identical repeatable-read read-only canonical fingerprints",
"postflight": "same canonical fingerprint plus independent selected-object readback",
"service": "same active gateway process before and after",
"ordering": "preflight < authorization < send1 < reply1 < send2 < reply2 < send3 < reply3 < final/postflight",
},
}
protocol_sha256 = _canonical_sha256(protocol)
checks = {
**handler_checks,
"exact_three_turn_sequence": len(messages) == 3 and [item["sequence"] for item in messages] == [1, 2, 3],
"exact_prompts_imported_from_handler_verifier": [item["message"] for item in messages]
== [item["message"] for item in unseen.PROMPTS],
"first_prompt_supplies_no_row_id": unseen.UUID_RE.search(messages[0]["message"]) is None,
"authenticated_chrome_is_only_send_transport": target["allowed_transport"]
== "authenticated_chrome_telegram_ui",
"canonical_manifest_path_and_sha_bound": manifest == manifest_binding(),
"database_session_and_role_fail_closed_read_only": manifest["execution_contract"]["effective_role"]
== READ_ONLY_DB_ROLE
and manifest["execution_contract"]["default_transaction_read_only"] == "on"
and manifest["execution_contract"]["transaction_read_only"] == "on"
and manifest["execution_contract"]["arbitrary_manifest_override_allowed"] is False,
"independent_browser_provenance_required": browser_provenance_contract[
"requires_codex_rollout_log_outside_evidence_root"
]
is True,
"packet_does_not_send": True,
"packet_does_not_mutate_database": True,
}
ready = all(checks.values())
authorization_text = _authorization_text(chat_label=chat_label, chat_id=chat_id, messages=messages)
proof_paths = {
"preflight_json": str(DEFAULT_PREFLIGHT),
"postflight_json": str(DEFAULT_POSTFLIGHT),
"capture_receipt_json": str(DEFAULT_CAPTURE_RECEIPT),
"capture_json": f"{proof_dir}/capture.json",
"turn_screenshots": [f"{proof_dir}/turn-{index}.png" for index in range(1, 4)],
"turn_accessibility": [f"{proof_dir}/turn-{index}-accessibility.txt" for index in range(1, 4)],
"final_screenshot": f"{proof_dir}/final.png",
"final_accessibility": f"{proof_dir}/final-accessibility.txt",
"browser_provenance": f"{proof_dir}/browser-provenance.json",
}
return {
"schema": SCHEMA,
"generated_at_utc": datetime.now(timezone.utc).isoformat(),
"mode": "telegram_visible_unseen_chain_exact_packet_not_sent",
"packet_generation_git_sha": git_sha if git_sha is not None else current_git_sha(),
"protocol_sha256": protocol_sha256,
"protocol": protocol,
"ready_to_request_action_time_authorization": ready,
"authorization_gate_status": "ready_to_request_exact_authorization" if ready else "not_ready",
"telegram_visible_messages_sent": False,
"telegram_visible_message_authorization_present": False,
"production_apply_executed": False,
"mutates_db": False,
"target": target,
"exact_messages": messages,
"handler_receipt_binding": handler_binding,
"tooling_binding": tooling,
"manifest_binding": manifest,
"browser_provenance_contract": browser_provenance_contract,
"operator_context": protocol["operator_context"],
"checks": checks,
"expected_proof_paths_after_authorized_run": proof_paths,
"explicit_operator_authorization_text": authorization_text,
"clear_CTA": (
"Reply with the exact authorization sentence in this packet. That sentence names the destination, "
"transport, complete message bodies, ordering, evidence, and no-mutation boundary."
),
"next_non_user_action_after_authorization": [
"Re-run the zero-mutation preflight and confirm its packet file hash is current.",
"Use authenticated Chrome only and verify the Leo chat ID before typing anything.",
"Send one exact message, wait for Leo's visible reply, then continue to the next exact message.",
"Capture message IDs, timestamps, screenshot, accessibility text, and the Chrome-control provenance receipt without copying handler output.",
"Retain the Codex rollout path whose Chrome tool receipt contains the provenance SHA256.",
"Extract the selected DB object reference and run the read-only postflight with that reference.",
"Run the Telegram-visible verifier and accept T3 only if every visible and state check passes.",
],
"claim_ceiling": {
"current_tier": "T0_spec_plus_prior_T2_handler_evidence",
"required_tier": "T3_live_readonly",
"proven": "The exact three-turn Chrome send packet is bound to a passing no-send handler receipt.",
"not_proven": [
"Telegram-visible delivery of these three messages",
"Telegram-visible replies from Leo",
"post-send canonical fingerprint equality",
],
},
}
def write_json(path: Path, data: dict[str, Any]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8")
def write_markdown(path: Path, data: dict[str, Any]) -> None:
target = data["target"]
lines = [
"# Telegram-Visible Unseen Chain Authorization Packet",
"",
f"Generated UTC: `{data['generated_at_utc']}`",
f"Protocol SHA256: `{data['protocol_sha256']}`",
f"Ready to request action-time authorization: `{data['ready_to_request_action_time_authorization']}`",
f"Telegram-visible messages sent: `{data['telegram_visible_messages_sent']}`",
f"Mutates DB: `{data['mutates_db']}`",
"",
"## Exact Destination",
"",
f"- Chat: `{target['chat_label']}` (`{target['chat_id']}`)",
f"- Transport: `{target['allowed_transport']}`",
"",
"## Exact Messages",
"",
]
for item in data["exact_messages"]:
lines.extend(
[
f"### {item['sequence']}. {item['prompt_id']}",
"",
item["message"],
"",
f"SHA256: `{item['message_sha256']}`",
"",
]
)
manifest = data["manifest_binding"]
execution = manifest["execution_contract"]
lines.extend(
[
"## Read-Only State Contract",
"",
f"- Manifest: `{manifest['path']}`",
f"- Manifest SHA256: `{manifest['sha256']}`",
f"- Effective DB role: `{execution['effective_role']}`",
f"- Transaction read only: `{execution['transaction_read_only']}`",
f"- Arbitrary manifest override allowed: `{execution['arbitrary_manifest_override_allowed']}`",
"",
"## Independent Capture Contract",
"",
f"- Codex thread: `{data['operator_context']['codex_thread_id']}`",
"- Authorization must be an exact platform user-message event in that thread's rollout.",
"- Each turn and final artifact must be bound by Chrome-backend tool receipts in that rollout.",
"",
"## Checks",
"",
]
)
lines.extend(f"- `{key}`: `{value}`" for key, value in sorted(data["checks"].items()))
lines.extend(
[
"",
"## Exact Action-Time Authorization",
"",
data["explicit_operator_authorization_text"],
"",
"## Clear CTA",
"",
data["clear_CTA"],
"",
"## Claim Ceiling",
"",
f"Current tier: `{data['claim_ceiling']['current_tier']}`",
f"Required tier: `{data['claim_ceiling']['required_tier']}`",
"",
]
)
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(lines), encoding="utf-8")
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--handler-receipt", type=Path, default=DEFAULT_HANDLER_RECEIPT)
parser.add_argument("--chat-id", default=DEFAULT_CHAT_ID)
parser.add_argument("--chat-label", default=DEFAULT_CHAT_LABEL)
parser.add_argument("--proof-dir", default=DEFAULT_PROOF_DIR)
parser.add_argument("--out", type=Path, default=DEFAULT_OUT)
parser.add_argument("--markdown-out", type=Path, default=DEFAULT_MARKDOWN_OUT)
return parser.parse_args(argv)
def main(argv: list[str] | None = None) -> int:
args = parse_args(argv)
data = build_packet(
handler_receipt_path=args.handler_receipt,
chat_id=args.chat_id,
chat_label=args.chat_label,
proof_dir=args.proof_dir,
)
write_json(args.out, data)
write_markdown(args.markdown_out, data)
print(
json.dumps(
{
"out": str(args.out),
"markdown_out": str(args.markdown_out),
"ready_to_request_action_time_authorization": data["ready_to_request_action_time_authorization"],
"telegram_visible_messages_sent": False,
},
indent=2,
sort_keys=True,
)
)
return 0 if data["ready_to_request_action_time_authorization"] else 2
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,788 @@
#!/usr/bin/env python3
"""Collect fail-closed read-only state for the unseen Telegram chain."""
from __future__ import annotations
import argparse
import hashlib
import json
import re
import secrets
import shlex
import subprocess
from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
try:
import build_telegram_visible_unseen_chain_packet as packet_builder
import verify_leo_unseen_reasoning_chain as unseen
except ImportError: # pragma: no cover - imported as scripts.* in tests
from scripts import build_telegram_visible_unseen_chain_packet as packet_builder
from scripts import verify_leo_unseen_reasoning_chain as unseen
SCHEMA = "livingip.telegramVisibleUnseenChainState.v2"
REPO_ROOT = Path(__file__).resolve().parents[1]
REPORT_DIR = Path("docs/reports/leo-working-state-20260709")
DEFAULT_PACKET = packet_builder.DEFAULT_OUT
DEFAULT_PREFLIGHT_OUT = REPORT_DIR / "telegram-visible-unseen-chain-preflight-current.json"
DEFAULT_PREFLIGHT_MARKDOWN_OUT = REPORT_DIR / "telegram-visible-unseen-chain-preflight-current.md"
DEFAULT_POSTFLIGHT_OUT = REPORT_DIR / "telegram-visible-unseen-chain-postflight-current.json"
DEFAULT_POSTFLIGHT_MARKDOWN_OUT = REPORT_DIR / "telegram-visible-unseen-chain-postflight-current.md"
DEFAULT_SSH_TARGET = "root@77.42.65.182"
DEFAULT_SSH_KEY = Path.home() / ".ssh/livingip_hetzner_20260604_ed25519"
DEFAULT_MANIFEST_SQL = packet_builder.DEFAULT_MANIFEST_SQL
REMOTE_REPO = "/opt/teleo-eval/workspaces/deploy-infra"
SUBJECT_REF_RE = re.compile(
r"^(?:[0-9a-f]{8}|[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})$",
re.IGNORECASE,
)
SHA40_RE = re.compile(r"^[0-9a-f]{40}$")
SHA64_RE = re.compile(r"^[0-9a-f]{64}$")
FORBIDDEN_MANIFEST_SQL_RE = re.compile(
r"\b(?:insert|update|delete|merge|create|alter|drop|truncate|grant|revoke|copy|call|do|vacuum|"
r"refresh|reindex|cluster|commit|prepare|execute)\b|"
r"\\(?:!|i|ir|include|include_relative|copy)\b|"
r"\bset\s+(?:session\s+authorization|role)\b|"
r"\breset\s+(?:session\s+authorization|role)\b|"
r"\b(?:default_)?transaction_read_only\s*=\s*(?:off|false|0)\b|"
r"\btransaction\s+read\s+write\b",
re.IGNORECASE,
)
@dataclass(frozen=True)
class CommandResult:
returncode: int
stdout: str
stderr: str
Runner = Callable[[list[str], str, int], CommandResult]
def subprocess_runner(command: list[str], input_text: str, timeout: int) -> CommandResult:
try:
proc = subprocess.run(
command,
input=input_text,
text=True,
capture_output=True,
timeout=timeout,
check=False,
)
except subprocess.TimeoutExpired as exc:
return CommandResult(124, str(exc.stdout or ""), f"command timed out after {timeout}s")
return CommandResult(proc.returncode, proc.stdout, proc.stderr)
def _load_json(path: Path) -> dict[str, Any]:
return json.loads(path.read_text(encoding="utf-8"))
def _canonical_sha256(value: Any) -> str:
encoded = json.dumps(value, sort_keys=True, separators=(",", ":")).encode("utf-8")
return hashlib.sha256(encoded).hexdigest()
def _sha256_file(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def canonical_manifest_path() -> Path:
return (REPO_ROOT / DEFAULT_MANIFEST_SQL).resolve()
def _manifest_sql_is_statically_read_only(sql: str) -> bool:
normalized = re.sub(r"\s+", " ", sql).strip().casefold()
return (
normalized.startswith(r"\set on_error_stop on")
and "begin transaction isolation level repeatable read read only;" in normalized
and normalized.endswith("rollback;")
and FORBIDDEN_MANIFEST_SQL_RE.search(sql) is None
)
def manifest_checks(packet: dict[str, Any], requested_path: Path | None = None) -> dict[str, bool]:
canonical_path = canonical_manifest_path()
binding = packet.get("manifest_binding") if isinstance(packet.get("manifest_binding"), dict) else {}
protocol = packet.get("protocol") if isinstance(packet.get("protocol"), dict) else {}
execution = binding.get("execution_contract") if isinstance(binding.get("execution_contract"), dict) else {}
try:
sql = canonical_path.read_text(encoding="utf-8")
actual_sha256 = _sha256_file(canonical_path)
except OSError:
sql = ""
actual_sha256 = ""
override_path = requested_path.resolve() if requested_path is not None else canonical_path
return {
"manifest_canonical_path_exists": canonical_path.is_file(),
"manifest_override_absent_or_exact_canonical_path": override_path == canonical_path,
"manifest_packet_path_is_exact_canonical_relative_path": binding.get("path") == str(DEFAULT_MANIFEST_SQL),
"manifest_packet_sha256_matches_canonical_file": bool(actual_sha256) and binding.get("sha256") == actual_sha256,
"manifest_protocol_binding_matches_packet": protocol.get("manifest_binding") == binding,
"manifest_sql_statically_read_only": bool(sql) and _manifest_sql_is_statically_read_only(sql),
"manifest_effective_role_is_read_only": execution.get("effective_role") == packet_builder.READ_ONLY_DB_ROLE,
"manifest_default_transaction_read_only_enforced": execution.get("default_transaction_read_only") == "on",
"manifest_transaction_read_only_enforced": execution.get("transaction_read_only") == "on",
"manifest_psql_rc_disabled": execution.get("psql_rc_disabled") is True,
"manifest_arbitrary_override_forbidden": execution.get("arbitrary_manifest_override_allowed") is False,
}
def parse_key_value_lines(text: str) -> dict[str, str]:
values: dict[str, str] = {}
for line in text.splitlines():
if "=" not in line:
continue
key, value = line.split("=", 1)
values[key] = value.strip()
return values
def parse_manifest_output(raw: str) -> dict[str, Any]:
rows = []
try:
for line in raw.splitlines():
candidate = line.strip()
if not candidate or candidate in {"BEGIN", "SET", "ROLLBACK"}:
continue
value = json.loads(candidate)
if isinstance(value, dict):
rows.append(value)
except (TypeError, json.JSONDecodeError) as exc:
return {"status": "error", "error": f"manifest_parse_error:{type(exc).__name__}"}
tables = {
f"{row['schema']}.{row['table']}": {
"row_count": int(row["row_count"]),
"rowset_md5": row["rowset_md5"],
}
for row in rows
if row.get("kind") == "table"
}
singleton_kinds = {
"schemas",
"extensions",
"application_roles",
"columns",
"constraints",
"indexes",
"sequences",
"views",
"functions",
"triggers",
"types",
"policies",
}
singleton = {str(row["kind"]): row.get("items", []) for row in rows if row.get("kind") in singleton_kinds}
identity_rows = [row for row in rows if row.get("kind") == "identity"]
if len(identity_rows) != 1 or not tables or singleton_kinds - set(singleton):
return {"status": "error", "error": "canonical_database_fingerprint_manifest_incomplete"}
identity = identity_rows[0]
stable = {
"identity": {
key: identity.get(key)
for key in (
"database",
"server_version_num",
"server_encoding",
"database_collation",
"database_ctype",
"transaction_read_only",
)
},
"singleton_sha256": {key: _canonical_sha256(value) for key, value in sorted(singleton.items())},
"tables": tables,
}
return {
"schema": "livingip.teleoCanonicalDatabaseFingerprint.v1",
"status": "ok",
"fingerprint_sha256": _canonical_sha256(stable),
"table_count": len(tables),
"total_rows": sum(item["row_count"] for item in tables.values()),
"table_rows_sha256": _canonical_sha256(tables),
"structure_sha256": _canonical_sha256(stable["singleton_sha256"]),
"transaction_read_only": identity.get("transaction_read_only"),
"current_user": identity.get("current_user"),
}
def packet_checks(packet: dict[str, Any], *, requested_manifest_path: Path | None = None) -> dict[str, bool]:
target = packet.get("target") if isinstance(packet.get("target"), dict) else {}
protocol = packet.get("protocol") if isinstance(packet.get("protocol"), dict) else {}
packet_check_section = packet.get("checks") if isinstance(packet.get("checks"), dict) else {}
exact = packet_builder.exact_messages()
expected_tooling = packet_builder.tooling_binding()
checks = {
"packet_schema_supported": packet.get("schema") == packet_builder.SCHEMA,
"packet_check_section_present_and_passing": bool(packet_check_section)
and all(value is True for value in packet_check_section.values()),
"packet_ready_for_authorization_request": packet.get("ready_to_request_action_time_authorization") is True,
"packet_not_sent": packet.get("telegram_visible_messages_sent") is False,
"packet_has_no_authorization_recorded": packet.get("telegram_visible_message_authorization_present") is False,
"packet_does_not_mutate_db": packet.get("mutates_db") is False,
"packet_targets_exact_leo_chat": target.get("chat_label") == packet_builder.DEFAULT_CHAT_LABEL
and target.get("chat_id") == packet_builder.DEFAULT_CHAT_ID,
"packet_requires_authenticated_chrome": target.get("allowed_transport") == "authenticated_chrome_telegram_ui",
"packet_prompt_ids_exact": target.get("expected_prompt_ids") == [item["id"] for item in unseen.PROMPTS],
"packet_messages_exact": [item.get("message") for item in packet.get("exact_messages", [])]
== [item["message"] for item in exact],
"packet_protocol_sha256_present": bool(SHA64_RE.fullmatch(str(packet.get("protocol_sha256") or ""))),
"packet_protocol_sha256_derivation_valid": bool(protocol)
and packet.get("protocol_sha256") == _canonical_sha256(protocol),
"packet_protocol_top_level_bindings_match": protocol.get("target") == packet.get("target")
and protocol.get("exact_messages") == packet.get("exact_messages")
and protocol.get("handler_binding") == packet.get("handler_receipt_binding")
and protocol.get("tooling_binding") == packet.get("tooling_binding")
and protocol.get("browser_provenance_contract") == packet.get("browser_provenance_contract")
and protocol.get("operator_context") == packet.get("operator_context"),
"packet_tooling_hashes_match_current_sources": packet.get("tooling_binding") == expected_tooling,
}
checks.update(manifest_checks(packet, requested_path=requested_manifest_path))
return checks
def ssh_command(args: argparse.Namespace, remote_command: str) -> list[str]:
return [
"ssh",
"-i",
str(args.ssh_key),
"-o",
"BatchMode=yes",
"-o",
"StrictHostKeyChecking=accept-new",
"-o",
f"ConnectTimeout={args.connect_timeout}",
args.ssh_target,
remote_command,
]
def deploy_readback_command() -> str:
repo = shlex.quote(REMOTE_REPO)
return (
f"cd {repo} && "
"deploy_head=$(git rev-parse HEAD) && "
"last_deploy_sha=$(cat /opt/teleo-eval/.last-deploy-sha) && "
'printf \'deploy_head=%s\\nlast_deploy_sha=%s\\n\' "$deploy_head" "$last_deploy_sha" && '
'if git merge-base --is-ancestor "$last_deploy_sha" "$deploy_head"; then '
"printf 'deploy_stamp_ancestor=true\\n'; else printf 'deploy_stamp_ancestor=false\\n'; fi"
)
def service_readback_command() -> str:
return (
"systemctl show leoclean-gateway.service "
"-p ActiveState -p SubState -p MainPID -p NRestarts -p ExecMainStartTimestamp --no-pager"
)
def fingerprint_readback_command() -> str:
pgoptions = shlex.quote(
"PGOPTIONS=-c default_transaction_read_only=on -c transaction_read_only=on "
f"-c role={packet_builder.READ_ONLY_DB_ROLE}"
)
return f"docker exec -e {pgoptions} -i teleo-pg psql -X -U postgres -d teleo -At -q -v ON_ERROR_STOP=1"
def subject_readback_sql(subject_ref: str) -> str:
if not SUBJECT_REF_RE.fullmatch(subject_ref):
raise ValueError("subject_ref must be an eight-hex prefix or UUID")
prefix = subject_ref.casefold()
return f"""
\\set ON_ERROR_STOP on
begin transaction isolation level repeatable read read only;
select jsonb_build_object(
'subject_ref', '{prefix}',
'matches', coalesce(jsonb_agg(item order by item->>'table', item->'row'->>'id'), '[]'::jsonb)
)::text
from (
select jsonb_build_object(
'table', 'public.claims',
'row', to_jsonb(claim_row),
'evidence_count', (select count(*) from public.claim_evidence evidence where evidence.claim_id = claim_row.id)
) as item
from public.claims claim_row
where lower(claim_row.id::text) like '{prefix}%'
union all
select jsonb_build_object(
'table', 'public.beliefs',
'row', to_jsonb(belief_row),
'evidence_count', null
) as item
from public.beliefs belief_row
where lower(belief_row.id::text) like '{prefix}%'
) matched;
rollback;
""".strip()
def _parse_single_json_line(raw: str) -> dict[str, Any] | None:
for line in raw.splitlines():
candidate = line.strip()
if not candidate or candidate in {"BEGIN", "SET", "ROLLBACK"}:
continue
try:
value = json.loads(candidate)
except json.JSONDecodeError:
continue
if isinstance(value, dict):
return value
return None
def collect_remote(
args: argparse.Namespace,
runner: Runner,
*,
manifest_sql: str,
) -> tuple[dict[str, Any], int, str]:
calls: list[tuple[str, list[str], str, int]] = [
("deploy", ssh_command(args, deploy_readback_command()), "", args.timeout),
("service_before", ssh_command(args, service_readback_command()), "", args.timeout),
(
"fingerprint_before",
ssh_command(args, fingerprint_readback_command()),
manifest_sql,
args.fingerprint_timeout,
),
(
"fingerprint_after",
ssh_command(args, fingerprint_readback_command()),
manifest_sql,
args.fingerprint_timeout,
),
("service_after", ssh_command(args, service_readback_command()), "", args.timeout),
]
if args.subject_ref:
calls.append(
(
"subject",
ssh_command(args, fingerprint_readback_command()),
subject_readback_sql(args.subject_ref),
args.timeout,
)
)
results: dict[str, CommandResult] = {}
attempts: dict[str, int] = {}
for name, command, input_text, timeout in calls:
result = CommandResult(1, "", "not attempted")
for attempt in range(1, max(1, args.ssh_attempts) + 1):
result = runner(command, input_text, timeout)
attempts[name] = attempt
if result.returncode == 0:
break
results[name] = result
deploy_values = parse_key_value_lines(results["deploy"].stdout)
service_before = parse_key_value_lines(results["service_before"].stdout)
service_after = parse_key_value_lines(results["service_after"].stdout)
fingerprint_before = parse_manifest_output(results["fingerprint_before"].stdout)
fingerprint_after = parse_manifest_output(results["fingerprint_after"].stdout)
subject = _parse_single_json_line(results["subject"].stdout) if "subject" in results else None
returncode = next((result.returncode for result in results.values() if result.returncode != 0), 0)
stderr = "\n".join(f"{name}: {result.stderr.strip()}" for name, result in results.items() if result.stderr.strip())
return (
{
"deploy_head": deploy_values.get("deploy_head", ""),
"last_deploy_sha": deploy_values.get("last_deploy_sha", ""),
"deploy_stamp_ancestor": deploy_values.get("deploy_stamp_ancestor") == "true",
"workspace_head_matches_deployed_stamp": deploy_values.get("deploy_head")
== deploy_values.get("last_deploy_sha"),
"service_before": service_before,
"service_after": service_after,
"fingerprint_before": fingerprint_before,
"fingerprint_after": fingerprint_after,
"subject_readback": subject,
"readback_attempts": attempts,
},
returncode,
stderr,
)
def _service_active(state: dict[str, Any]) -> bool:
return state.get("ActiveState") == "active" and state.get("SubState") == "running"
def _service_identity(state: dict[str, Any]) -> dict[str, Any]:
return {key: state.get(key) for key in ("MainPID", "NRestarts", "ExecMainStartTimestamp")}
def _remote_checks(
remote: dict[str, Any],
*,
returncode: int,
subject_required: bool,
expected_subject_ref: str | None,
) -> dict[str, bool]:
before = remote.get("fingerprint_before") or {}
after = remote.get("fingerprint_after") or {}
service_before = remote.get("service_before") or {}
service_after = remote.get("service_after") or {}
subject = remote.get("subject_readback") or {}
matches = subject.get("matches") if isinstance(subject, dict) else None
checks = {
"ssh_readbacks_succeeded": returncode == 0,
"workspace_head_is_sha": bool(SHA40_RE.fullmatch(str(remote.get("deploy_head") or ""))),
"deployed_stamp_is_sha": bool(SHA40_RE.fullmatch(str(remote.get("last_deploy_sha") or ""))),
"deployed_stamp_is_ancestor_of_workspace_head": remote.get("deploy_stamp_ancestor") is True,
"service_active_before_and_after": _service_active(service_before) and _service_active(service_after),
"service_identity_complete": all(
value
for value in (
service_before.get("MainPID"),
service_before.get("NRestarts"),
service_before.get("ExecMainStartTimestamp"),
service_after.get("MainPID"),
service_after.get("NRestarts"),
service_after.get("ExecMainStartTimestamp"),
)
),
"service_process_unchanged_during_probe": _service_identity(service_before) == _service_identity(service_after),
"first_fingerprint_complete": before.get("status") == "ok" and int(before.get("table_count") or 0) > 0,
"second_fingerprint_complete": after.get("status") == "ok" and int(after.get("table_count") or 0) > 0,
"fingerprints_are_read_only": before.get("transaction_read_only") == "on"
and after.get("transaction_read_only") == "on",
"fingerprints_use_independent_read_only_role": before.get("current_user") == packet_builder.READ_ONLY_DB_ROLE
and after.get("current_user") == packet_builder.READ_ONLY_DB_ROLE,
"canonical_fingerprint_unchanged_during_probe": bool(before.get("fingerprint_sha256"))
and before.get("fingerprint_sha256") == after.get("fingerprint_sha256"),
}
if subject_required:
checks.update(
{
"subject_readback_present": isinstance(subject, dict),
"subject_reference_matches_request": subject.get("subject_ref")
== str(expected_subject_ref or "").casefold(),
"subject_resolved_to_exactly_one_db_object": isinstance(matches, list) and len(matches) == 1,
}
)
return checks
def derive_state_token(artifact: dict[str, Any]) -> str:
return _canonical_sha256(
{
"schema": artifact.get("schema"),
"generated_at_utc": artifact.get("generated_at_utc"),
"phase": artifact.get("phase"),
"packet_file_sha256": artifact.get("packet_file_sha256"),
"protocol_sha256": artifact.get("protocol_sha256"),
"manifest_binding": artifact.get("manifest_binding"),
"capture_challenge_nonce": artifact.get("capture_challenge_nonce"),
"baseline_state_token_sha256": artifact.get("baseline_state_token_sha256"),
"subject_ref": artifact.get("subject_ref"),
"packet_checks": artifact.get("packet_checks"),
"remote_checks": artifact.get("remote_checks"),
"baseline_checks": artifact.get("baseline_checks"),
"remote": {
"deploy_head": (artifact.get("remote") or {}).get("deploy_head"),
"last_deploy_sha": (artifact.get("remote") or {}).get("last_deploy_sha"),
"service_after": _service_identity((artifact.get("remote") or {}).get("service_after") or {}),
"fingerprint_after": (artifact.get("remote") or {}).get("fingerprint_after"),
"subject_readback": (artifact.get("remote") or {}).get("subject_readback"),
},
}
)
def state_token_is_valid(artifact: dict[str, Any]) -> bool:
token = artifact.get("state_token_sha256")
return bool(SHA64_RE.fullmatch(str(token or ""))) and token == derive_state_token(artifact)
def _empty_remote() -> dict[str, Any]:
return {
"deploy_head": "",
"last_deploy_sha": "",
"deploy_stamp_ancestor": False,
"workspace_head_matches_deployed_stamp": False,
"service_before": {},
"service_after": {},
"fingerprint_before": {},
"fingerprint_after": {},
"subject_readback": None,
"readback_attempts": {},
}
def collect_state(args: argparse.Namespace, *, runner: Runner = subprocess_runner) -> dict[str, Any]:
packet = _load_json(args.packet)
requested_manifest_path = getattr(args, "manifest_sql", None)
local_packet_checks = packet_checks(packet, requested_manifest_path=requested_manifest_path)
manifest_sql = ""
if all(local_packet_checks.values()):
try:
manifest_sql = canonical_manifest_path().read_text(encoding="utf-8")
except OSError:
manifest_sql = ""
loaded_sha256 = hashlib.sha256(manifest_sql.encode("utf-8")).hexdigest()
local_packet_checks.update(
{
"manifest_loaded_bytes_match_bound_sha256": loaded_sha256
== (packet.get("manifest_binding") or {}).get("sha256"),
"manifest_loaded_bytes_revalidated_read_only": _manifest_sql_is_statically_read_only(manifest_sql),
}
)
if all(local_packet_checks.values()):
remote, remote_returncode, remote_stderr = collect_remote(
args,
runner,
manifest_sql=manifest_sql,
)
else:
remote = _empty_remote()
remote_returncode = 1
remote_stderr = "local fail-closed validation rejected execution before SSH"
remote_checks = _remote_checks(
remote,
returncode=remote_returncode,
subject_required=args.phase == "postflight",
expected_subject_ref=args.subject_ref,
)
baseline = _load_json(args.baseline) if args.baseline else None
baseline_checks: dict[str, bool] = {}
if args.phase == "postflight":
baseline_packet_checks = baseline.get("packet_checks") if isinstance(baseline, dict) else {}
baseline_remote_checks = baseline.get("remote_checks") if isinstance(baseline, dict) else {}
baseline_nonce = str((baseline or {}).get("capture_challenge_nonce") or "")
baseline_checks = {
"baseline_supplied": baseline is not None,
"baseline_schema_supported": bool(baseline and baseline.get("schema") == SCHEMA),
"baseline_is_passing_preflight": bool(
baseline and baseline.get("phase") == "preflight" and baseline.get("status") == "pass"
),
"baseline_check_sections_all_pass": bool(baseline_packet_checks)
and all(value is True for value in baseline_packet_checks.values())
and bool(baseline_remote_checks)
and all(value is True for value in baseline_remote_checks.values()),
"baseline_state_token_derivation_valid": bool(baseline and state_token_is_valid(baseline)),
"baseline_capture_challenge_nonce_valid": bool(SHA64_RE.fullmatch(baseline_nonce)),
"baseline_protocol_matches_packet": bool(
baseline and baseline.get("protocol_sha256") == packet.get("protocol_sha256")
),
"baseline_packet_file_matches": bool(
baseline and baseline.get("packet_file_sha256") == _sha256_file(args.packet)
),
"baseline_manifest_binding_matches_packet": bool(
baseline and baseline.get("manifest_binding") == packet.get("manifest_binding")
),
"canonical_fingerprint_matches_preflight": bool(
baseline
and (baseline.get("remote") or {}).get("fingerprint_after", {}).get("fingerprint_sha256")
== remote.get("fingerprint_after", {}).get("fingerprint_sha256")
),
"gateway_process_matches_preflight": bool(
baseline
and _service_identity((baseline.get("remote") or {}).get("service_after") or {})
== _service_identity(remote.get("service_after") or {})
),
}
status = (
"pass"
if all(local_packet_checks.values()) and all(remote_checks.values()) and all(baseline_checks.values())
else "fail"
)
packet_file_sha256 = _sha256_file(args.packet)
generated_at_utc = datetime.now(timezone.utc).isoformat()
capture_challenge_nonce = (
secrets.token_hex(32)
if args.phase == "preflight"
else str((baseline or {}).get("capture_challenge_nonce") or "")
)
baseline_state_token_sha256 = (
str((baseline or {}).get("state_token_sha256") or "") if args.phase == "postflight" else ""
)
exact_gate = ""
if status != "pass":
failed = [
key
for checks in (local_packet_checks, remote_checks, baseline_checks)
for key, value in checks.items()
if value is not True
]
exact_gate = "; ".join(part for part in (remote_stderr.strip(), ", ".join(failed)) if part)
current_canary = (
"Read-only pre-send readiness for the exact three-turn unseen Leo chain in Telegram"
if args.phase == "preflight"
else "Read-only post-send DB grounding and unchanged-state proof for the exact Telegram chain"
)
artifact = {
"schema": SCHEMA,
"generated_at_utc": generated_at_utc,
"mode": "telegram_visible_unseen_chain_zero_mutation_state_readback",
"phase": args.phase,
"status": status,
"ready_for_action_time_authorization": args.phase == "preflight" and status == "pass",
"ready_for_visible_capture_verification": args.phase == "postflight" and status == "pass",
"telegram_visible_messages_sent_by_collector": False,
"production_apply_executed": False,
"mutates_db": False,
"packet_path": str(args.packet),
"packet_file_sha256": packet_file_sha256,
"protocol_sha256": packet.get("protocol_sha256"),
"manifest_binding": packet.get("manifest_binding"),
"capture_challenge_nonce": capture_challenge_nonce,
"baseline_state_token_sha256": baseline_state_token_sha256,
"baseline_path": str(args.baseline) if args.baseline else "",
"subject_ref": args.subject_ref or "",
"packet_checks": local_packet_checks,
"remote_checks": remote_checks,
"baseline_checks": baseline_checks,
"remote": remote,
"remote_returncode": remote_returncode,
"remote_stderr": remote_stderr,
"blocker_readback": {
"current_canary": current_canary,
"attempted_routes": [
"local exact packet validation",
*(
[
"SSH deploy stamp and gateway service readback",
"two canonical repeatable-read read-only Postgres parity manifests",
*(["independent selected-object DB readback"] if args.subject_ref else []),
]
if remote.get("readback_attempts")
else []
),
],
"exact_gate": exact_gate,
"clear_CTA": (
"No user action is needed; repair the named readback check and rerun this collector."
if exact_gate
else "Use the packet's exact authorization sentence only when ready to cross the send boundary."
),
"next_non_user_action": (
"Run the authenticated-Chrome three-turn flow only after exact authorization, then collect postflight."
if args.phase == "preflight" and status == "pass"
else "Repair the failed preflight check and rerun before requesting authorization."
if args.phase == "preflight"
else "Run the visible capture verifier against this postflight and the retained Chrome evidence."
),
},
"claim_ceiling": {
"current_tier": "T3_live_readonly" if status == "pass" else "T0_failed_preflight",
"proven": (
"Two canonical read-only snapshots and the gateway process were unchanged during this probe."
if status == "pass"
else "No live readiness claim; one or more fail-closed checks did not pass."
),
"not_proven": [
"Telegram-visible delivery or reply behavior",
"authorization to send Telegram messages",
"canonical mutation",
],
},
}
artifact["state_token_sha256"] = derive_state_token(artifact)
return artifact
def write_json(path: Path, data: dict[str, Any]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8")
def write_markdown(path: Path, data: dict[str, Any]) -> None:
remote = data.get("remote") or {}
service = remote.get("service_after") or {}
fingerprint = remote.get("fingerprint_after") or {}
lines = [
f"# Telegram-Visible Unseen Chain {data['phase'].title()}",
"",
f"Generated UTC: `{data['generated_at_utc']}`",
f"Status: `{data['status']}`",
f"Protocol SHA256: `{data['protocol_sha256']}`",
f"Packet file SHA256: `{data['packet_file_sha256']}`",
f"State token SHA256: `{data['state_token_sha256']}`",
f"Messages sent by collector: `{data['telegram_visible_messages_sent_by_collector']}`",
f"Mutates DB: `{data['mutates_db']}`",
"",
"## Checks",
"",
]
for section in ("packet_checks", "remote_checks", "baseline_checks"):
for key, value in sorted(data.get(section, {}).items()):
lines.append(f"- `{key}`: `{value}`")
lines.extend(
[
"",
"## Live Readback",
"",
f"- Deploy head: `{remote.get('deploy_head', '')}`",
f"- Deploy stamp: `{remote.get('last_deploy_sha', '')}`",
f"- Gateway MainPID: `{service.get('MainPID', '')}`",
f"- Gateway NRestarts: `{service.get('NRestarts', '')}`",
f"- Manifest: `{(data.get('manifest_binding') or {}).get('path', '')}`",
f"- Manifest SHA256: `{(data.get('manifest_binding') or {}).get('sha256', '')}`",
f"- Effective DB role: `{fingerprint.get('current_user', '')}`",
f"- Transaction read only: `{fingerprint.get('transaction_read_only', '')}`",
f"- Canonical fingerprint: `{fingerprint.get('fingerprint_sha256', '')}`",
f"- Canonical tables: `{fingerprint.get('table_count', '')}`",
f"- Canonical rows: `{fingerprint.get('total_rows', '')}`",
f"- Selected object ref: `{data.get('subject_ref', '')}`",
"",
"## Claim Ceiling",
"",
data["claim_ceiling"]["proven"],
"",
]
)
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("\n".join(lines), encoding="utf-8")
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--phase", choices=("preflight", "postflight"), default="preflight")
parser.add_argument("--packet", type=Path, default=DEFAULT_PACKET)
parser.add_argument("--baseline", type=Path)
parser.add_argument("--subject-ref")
parser.add_argument("--ssh-target", default=DEFAULT_SSH_TARGET)
parser.add_argument("--ssh-key", type=Path, default=DEFAULT_SSH_KEY)
parser.add_argument("--connect-timeout", type=int, default=10)
parser.add_argument("--timeout", type=int, default=60)
parser.add_argument("--fingerprint-timeout", type=int, default=240)
parser.add_argument("--ssh-attempts", type=int, default=3)
parser.add_argument("--out", type=Path)
parser.add_argument("--markdown-out", type=Path)
args = parser.parse_args(argv)
if args.phase == "postflight" and (not args.baseline or not args.subject_ref):
parser.error("postflight requires --baseline and --subject-ref")
if args.subject_ref and not SUBJECT_REF_RE.fullmatch(args.subject_ref):
parser.error("--subject-ref must be an eight-hex prefix or UUID")
if args.out is None:
args.out = DEFAULT_PREFLIGHT_OUT if args.phase == "preflight" else DEFAULT_POSTFLIGHT_OUT
if args.markdown_out is None:
args.markdown_out = (
DEFAULT_PREFLIGHT_MARKDOWN_OUT if args.phase == "preflight" else DEFAULT_POSTFLIGHT_MARKDOWN_OUT
)
return args
def main(argv: list[str] | None = None) -> int:
args = parse_args(argv)
data = collect_state(args)
write_json(args.out, data)
write_markdown(args.markdown_out, data)
print(
json.dumps(
{
"out": str(args.out),
"markdown_out": str(args.markdown_out),
"phase": args.phase,
"status": data["status"],
"mutates_db": False,
},
indent=2,
sort_keys=True,
)
)
return 0 if data["status"] == "pass" else 2
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,230 @@
#!/usr/bin/env python3
"""Finalize outer isolation and cleanup evidence for the clone canary."""
from __future__ import annotations
import hashlib
import json
import os
import sys
from collections.abc import Mapping
from pathlib import Path
from typing import Any
def _service(raw: str) -> dict[str, str]:
return dict(line.split("=", 1) for line in raw.splitlines() if "=" in line)
def _table_deltas(before: dict[str, int], after: dict[str, int]) -> dict[str, int]:
if set(before) != set(after):
raise ValueError(
f"live source count keys changed during the canary: before={sorted(before)} after={sorted(after)}"
)
return {key: after[key] - before[key] for key in sorted(before)}
def _verify_source_binding(root: Path, records: list[dict[str, object]]) -> dict[str, object]:
readbacks = []
for record in records:
relative_text = str(record.get("repo_relative_path", ""))
relative = Path(relative_text)
if not relative_text or relative.is_absolute() or ".." in relative.parts:
raise ValueError(f"unsafe repo-relative source path: {relative_text!r}")
candidate = (root / relative).resolve()
try:
candidate.relative_to(root)
except ValueError as exc:
raise ValueError(f"source path escaped repository root: {relative_text}") from exc
if not candidate.is_file():
readbacks.append(
{
"repo_relative_path": relative.as_posix(),
"expected_sha256": record.get("sha256"),
"actual_sha256": None,
"matches": False,
}
)
continue
content = candidate.read_bytes()
actual_sha256 = hashlib.sha256(content).hexdigest()
readbacks.append(
{
"repo_relative_path": relative.as_posix(),
"expected_sha256": record.get("sha256"),
"actual_sha256": actual_sha256,
"size_bytes": len(content),
"matches": (actual_sha256 == record.get("sha256") and len(content) == record.get("size_bytes")),
}
)
return {
"files": readbacks,
"all_match": bool(readbacks) and all(bool(row["matches"]) for row in readbacks),
}
def _contains_ephemeral_path(value: object) -> bool:
if isinstance(value, str):
return "/tmp/" in value
if isinstance(value, dict):
return any(_contains_ephemeral_path(item) for item in value.values())
if isinstance(value, list):
return any(_contains_ephemeral_path(item) for item in value)
return False
def finalize(path: Path, env: Mapping[str, str]) -> dict[str, Any]:
if not path.is_file():
raise ValueError("inner canary did not produce a report")
data = json.loads(path.read_text(encoding="utf-8"))
if not isinstance(data, dict):
raise ValueError("inner canary report must be a JSON object")
before_counts = json.loads(env["SOURCE_COUNTS_BEFORE"])
after_counts = json.loads(env["SOURCE_COUNTS_AFTER"])
live_table_deltas = _table_deltas(before_counts, after_counts)
before_service = _service(env["SERVICE_BEFORE"])
after_service = _service(env["SERVICE_AFTER"])
source_tier = env["SOURCE_TIER"]
source_network_mode = env["SOURCE_NETWORK_MODE"]
source_canary_label = env["SOURCE_CANARY_LABEL"]
container_network_mode = env["CANARY_NETWORK_MODE"]
container_mounts = json.loads(env["CANARY_MOUNTS_JSON"])
container_canary_label = env["CANARY_LABEL"]
container_instance_label = env["CANARY_INSTANCE_LABEL"]
container_volume_mounts = [mount for mount in container_mounts if mount.get("Type") == "volume"]
container_isolated = container_network_mode == "none" and not container_volume_mounts
container_labeled = container_canary_label == "proposal-apply-lifecycle" and container_instance_label.startswith(
"working-leo-approve-claim-"
)
source_tier_enforced = source_tier != "isolated-local" or (
source_network_mode == "none" and source_canary_label == "working-leo-approved-source"
)
service_observable = before_service.get("Available") == "true" and after_service.get("Available") == "true"
service_stable = (
all(
before_service.get(key) == after_service.get(key)
for key in ("ActiveState", "SubState", "MainPID", "NRestarts")
)
if service_observable
else None
)
service_gate_passes = service_stable is True if source_tier == "live-readonly" else service_stable is not False
container_absent = int(env["CONTAINER_NAME_READBACK_RC"]) == 0 and not env["CONTAINER_NAME_READBACK"].strip()
label_scoped_orphan_count = int(env["CONTAINER_LABEL_ORPHAN_COUNT"])
label_scoped_container_absent = (
int(env["CONTAINER_LABEL_READBACK_RC"]) == 0
and label_scoped_orphan_count == 0
and not env["CONTAINER_LABEL_READBACK"].strip()
)
workdir_absent = env["OUTER_WORKDIR_LEXISTS"] == "false"
source_binding = _verify_source_binding(
Path(env["REPO_ROOT"]).resolve(),
data.get("source_binding", {}).get("files", []),
)
data["source_binding"]["independent_post_cleanup_verification"] = source_binding
source_binding_ok = (
data["source_binding"].get("unchanged_during_run") is True and source_binding["all_match"] is True
)
stale_ephemeral_paths_absent = not _contains_ephemeral_path(data)
inner_runtime_pass = data.get("status") == "pass" and int(env["CANARY_RC"]) == 0
outer_ok = (
before_counts == after_counts
and all(delta == 0 for delta in live_table_deltas.values())
and service_gate_passes
and container_absent
and label_scoped_container_absent
and workdir_absent
and source_binding_ok
and stale_ephemeral_paths_absent
and container_isolated
and container_labeled
and source_tier_enforced
)
if source_tier == "isolated-local":
data["required_tier"] = "T2_runtime"
data["required_tiers"] = ["T2_runtime"]
data["runtime_scope"] = "isolated_postgres_container_from_readonly_local_fixture"
else:
data["required_tier"] = "T3_live_readonly"
data["required_tiers"] = ["T2_runtime", "T3_live_readonly"]
data["runtime_scope"] = "isolated_postgres_container_from_readonly_live_schema"
data["outer_isolation"] = {
"source_container": env.get("SOURCE_CONTAINER", "teleo-pg"),
"source_database": env.get("SOURCE_DB", "teleo"),
"source_counts_before": before_counts,
"source_counts_after": after_counts,
"canonical_table_deltas": live_table_deltas,
"source_counts_unchanged": before_counts == after_counts,
"service_before": before_service,
"service_after": after_service,
"service_required": source_tier == "live-readonly",
"service_observable": service_observable,
"service_stable": service_stable,
"service_gate_passes": service_gate_passes,
"source_boundary": {
"source_tier": source_tier,
"network_mode": source_network_mode,
"canary_label": source_canary_label,
"tier_enforced": source_tier_enforced,
},
"container_isolation": {
"network_mode": container_network_mode,
"volume_mounts": container_volume_mounts,
"canary_label": container_canary_label,
"instance_label": container_instance_label,
"lifecycle_labeled": container_labeled,
"network_disabled": container_network_mode == "none",
"no_docker_volumes": not container_volume_mounts,
},
"cleanup_readback": {
"container_remove_returncode": int(env["OUTER_CONTAINER_REMOVE_RC"]),
"container_name_query_returncode": int(env["CONTAINER_NAME_READBACK_RC"]),
"container_name_query_stdout": env["CONTAINER_NAME_READBACK"],
"temporary_container_absent": container_absent,
"label_scoped_query_returncode": int(env["CONTAINER_LABEL_READBACK_RC"]),
"label_scoped_query_stdout": env["CONTAINER_LABEL_READBACK"],
"label_scoped_orphan_count": label_scoped_orphan_count,
"label_scoped_temporary_container_absent": label_scoped_container_absent,
"workdir_remove_returncode": int(env["OUTER_WORKDIR_REMOVE_RC"]),
"workdir_lexists_after_cleanup": not workdir_absent,
"temporary_workdir_absent": workdir_absent,
},
}
checks = data["checks"]
checks["outer_live_counts_exactly_unchanged"] = before_counts == after_counts
checks["outer_live_table_deltas_exactly_zero"] = all(delta == 0 for delta in live_table_deltas.values())
checks["outer_service_observed_if_required"] = source_tier != "live-readonly" or service_observable
checks["outer_service_stable_if_observed"] = service_gate_passes
checks["outer_container_absent_independent_readback"] = container_absent
checks["outer_labeled_container_absent_independent_readback"] = label_scoped_container_absent
checks["outer_workdir_absent_independent_readback"] = workdir_absent
checks["source_binding_independently_verified"] = source_binding_ok
checks["stale_ephemeral_paths_absent"] = stale_ephemeral_paths_absent
checks["outer_source_tier_enforced"] = source_tier_enforced
checks["outer_container_network_disabled"] = container_network_mode == "none"
checks["outer_container_lifecycle_labeled"] = container_labeled
checks["outer_container_has_no_docker_volumes"] = not container_volume_mounts
checks["outer_isolation_complete"] = outer_ok
if outer_ok and inner_runtime_pass:
data["current_tier"] = "T2_runtime" if source_tier == "isolated-local" else "T3_live_readonly"
else:
data["status"] = "fail"
data["current_tier"] = "T2_runtime" if inner_runtime_pass else "T1_model"
path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8")
return data
def main(argv: list[str] | None = None) -> int:
arguments = sys.argv[1:] if argv is None else argv
if len(arguments) != 1:
raise SystemExit("usage: finalize_approve_claim_isolated_canary.py REPORT.json")
try:
data = finalize(Path(arguments[0]), os.environ)
except (KeyError, OSError, ValueError, json.JSONDecodeError) as exc:
raise SystemExit(str(exc)) from exc
return 0 if data["status"] == "pass" else 1
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -315,8 +315,9 @@ alter table kb_stage.kb_review_principals owner to kb_gate_owner;
alter table kb_stage.kb_proposal_approvals owner to kb_gate_owner; alter table kb_stage.kb_proposal_approvals owner to kb_gate_owner;
insert into kb_stage.kb_review_principals insert into kb_stage.kb_review_principals
(db_role, reviewed_by_handle, reviewed_by_agent_id, active) (db_role, reviewed_by_handle, reviewed_by_agent_id, active, created_at)
select 'kb_review'::name, a.handle, a.id, true select 'kb_review'::name, a.handle, a.id, true,
'1970-01-01 00:00:00+00'::timestamptz
from public.agents a from public.agents a
where a.handle = 'm3ta' where a.handle = 'm3ta'
on conflict (db_role) do nothing; on conflict (db_role) do nothing;

View file

@ -446,6 +446,41 @@ def build_replay_receipt(
} }
def validate_replay_receipt(
receipt: dict[str, Any],
*,
expected_proposal_id: str | None = None,
) -> dict[str, Any]:
"""Rebuild and require the exact private replay-receipt contract.
Canonical JSON comparison is deliberate: Python equality treats booleans
and integers as interchangeable, which is unsafe for authorization and
receipt fields.
"""
if not isinstance(receipt, dict):
raise ValueError("replay receipt must be an object")
proposal = receipt.get("proposal")
rows = receipt.get("canonical_rows")
apply_engine = receipt.get("apply_engine")
if not isinstance(proposal, dict) or not isinstance(rows, dict) or not isinstance(apply_engine, dict):
raise ValueError("replay receipt is missing proposal, canonical rows, or apply-engine metadata")
if expected_proposal_id is not None and proposal.get("id") != expected_proposal_id:
raise ValueError("replay receipt proposal id does not match")
try:
rebuilt = build_replay_receipt(
proposal,
rows,
apply_sql_sha256=apply_engine.get("apply_sql_sha256"),
apply_sql_source=apply_engine.get("source"),
exported_at_utc=receipt.get("exported_at_utc"),
)
except (KeyError, TypeError, ValueError) as exc:
raise ValueError("replay receipt failed full contract validation") from exc
if _canonical_json(receipt) != _canonical_json(rebuilt):
raise ValueError("replay receipt hashes, counts, rows, or contract fields are internally inconsistent")
return rebuilt
def resolve_receipt_path( def resolve_receipt_path(
proposal_id: str, proposal_id: str,
*, *,

View file

@ -11,9 +11,13 @@ from __future__ import annotations
import argparse import argparse
import hashlib import hashlib
import importlib.metadata
import json import json
import os import os
import platform
import re
import subprocess import subprocess
import sys
from datetime import datetime, timezone from datetime import datetime, timezone
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
@ -24,6 +28,54 @@ SCHEMA = "livingip.leoBehaviorManifest.v1"
DEFAULT_PROFILE = Path("/home/teleo/.hermes/profiles/leoclean") DEFAULT_PROFILE = Path("/home/teleo/.hermes/profiles/leoclean")
DEFAULT_HERMES_ROOT = Path("/home/teleo/.hermes/hermes-agent") DEFAULT_HERMES_ROOT = Path("/home/teleo/.hermes/hermes-agent")
DEFAULT_DEPLOYMENT_ROOT = Path("/opt/teleo-eval/workspaces/deploy-infra") DEFAULT_DEPLOYMENT_ROOT = Path("/opt/teleo-eval/workspaces/deploy-infra")
STATIC_RUNTIME_COMPONENTS = (
"profile_config",
"procedural_skills",
"runtime_middleware",
"database_tools",
)
IDENTITY_RUNTIME_COMPONENTS = (
"procedural_skills",
"runtime_middleware",
"database_tools",
)
STABLE_MANIFEST_FIELDS = (
"schema",
"model_runtime",
"hermes_runtime",
"teleo_infrastructure_runtime",
"components",
"python_runtime",
"canonical_database",
)
SECRET_KEYS = frozenset(
{
"access_key",
"access_token",
"api_key",
"authorization",
"bot_token",
"client_secret",
"credential",
"credentials",
"password",
"private_key",
"refresh_token",
"secret",
"token",
}
)
SECRET_KEY_SUFFIXES = (
"api_key",
"access_key",
"private_key",
"password",
"secret",
"token",
"credential",
)
RUNTIME_DISTRIBUTIONS = ("PyYAML",)
SAFE_CONFIG_SCALAR = re.compile(r"^[A-Za-z0-9._:/-]+$")
def sha256_bytes(value: bytes) -> str: def sha256_bytes(value: bytes) -> str:
@ -50,7 +102,9 @@ def _safe_relative(path: Path, root: Path) -> str:
return str(path) return str(path)
def _resolved_node_fingerprint(path: Path, seen_directories: frozenset[tuple[int, int]] = frozenset()) -> dict[str, Any]: def _resolved_node_fingerprint(
path: Path, seen_directories: frozenset[tuple[int, int]] = frozenset()
) -> dict[str, Any]:
"""Hash a symlink target, following nested links while stopping directory cycles.""" """Hash a symlink target, following nested links while stopping directory cycles."""
try: try:
@ -141,21 +195,139 @@ def _nested(config: dict[str, Any], *path: str) -> Any:
return value return value
def secret_free_config(value: Any) -> Any:
"""Return a semantic config projection with secret-bearing fields omitted."""
if isinstance(value, dict):
return {
str(key): secret_free_config(item)
for key, item in sorted(value.items(), key=lambda pair: str(pair[0]))
if not _is_secret_key(str(key))
}
if isinstance(value, list):
return [secret_free_config(item) for item in value]
return value
def _validate_identity_config_value(value: Any, *, path: str) -> None:
if value is None or isinstance(value, (bool, int)):
return
if isinstance(value, str):
if not SAFE_CONFIG_SCALAR.fullmatch(value) or "://" in value or "@" in value:
raise ValueError(f"unsafe identity config scalar: {path}")
return
if isinstance(value, list):
for index, item in enumerate(value):
_validate_identity_config_value(item, path=f"{path}[{index}]")
return
if isinstance(value, dict):
for key, item in value.items():
if _is_secret_key(str(key)):
raise ValueError(f"secret-bearing identity config key: {path}.{key}")
_validate_identity_config_value(item, path=f"{path}.{key}")
return
raise ValueError(f"unsupported identity config value: {path}")
def identity_config_projection(raw: dict[str, Any]) -> dict[str, Any]:
"""Build the only configuration surface copied into a disposable identity profile."""
section_fields = {
"model": ("provider", "default", "smart_routing", "smart_routing_model", "max_tokens"),
"agent": ("reasoning_effort",),
"memory": ("enabled", "search"),
"tools": ("allowed", "write_enabled"),
"identity_runtime": ("network_send_enabled", "database_write_enabled", "allowed_tools"),
}
projection: dict[str, Any] = {}
for section, fields in section_fields.items():
source = raw.get(section)
if source is None:
continue
if not isinstance(source, dict):
raise ValueError(f"identity config section must be a mapping: {section}")
selected = {field: source[field] for field in fields if field in source}
_validate_identity_config_value(selected, path=section)
projection[section] = selected
gateway = raw.get("gateway")
if gateway is not None:
if not isinstance(gateway, dict):
raise ValueError("identity config section must be a mapping: gateway")
selected_gateway = {key: gateway[key] for key in ("execution_mode",) if key in gateway}
telegram = gateway.get("telegram")
if telegram is not None:
if not isinstance(telegram, dict):
raise ValueError("identity config section must be a mapping: gateway.telegram")
selected_telegram = {key: telegram[key] for key in ("posting_enabled",) if key in telegram}
if selected_telegram:
selected_gateway["telegram"] = selected_telegram
_validate_identity_config_value(selected_gateway, path="gateway")
projection["gateway"] = selected_gateway
if "smart_model_routing" in raw:
routing = raw["smart_model_routing"]
if not isinstance(routing, bool):
raise ValueError("smart_model_routing must be boolean")
projection["smart_model_routing"] = routing
return projection
def _is_secret_key(key: str) -> bool:
snake_case = re.sub(r"(?<=[a-z0-9])(?=[A-Z])", "_", key)
normalized = re.sub(r"[^a-z0-9]+", "_", snake_case.casefold()).strip("_")
return normalized in SECRET_KEYS or any(normalized.endswith(f"_{suffix}") for suffix in SECRET_KEY_SUFFIXES)
def python_runtime_manifest() -> dict[str, Any]:
distributions: dict[str, str | None] = {}
for name in RUNTIME_DISTRIBUTIONS:
try:
distributions[name] = importlib.metadata.version(name)
except importlib.metadata.PackageNotFoundError:
distributions[name] = None
return {
"implementation": platform.python_implementation(),
"python_version": platform.python_version(),
"abi_tag": sys.implementation.cache_tag,
"runtime_distributions": distributions,
"runtime_distributions_sha256": canonical_sha256(distributions),
}
def safe_model_config(config_path: Path) -> dict[str, Any]: def safe_model_config(config_path: Path) -> dict[str, Any]:
try: try:
raw = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {} raw = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {}
except (OSError, TypeError, yaml.YAMLError) as exc: except (OSError, TypeError, yaml.YAMLError) as exc:
return {"status": "unavailable", "error": type(exc).__name__} return {"status": "unavailable", "error": type(exc).__name__}
if not isinstance(raw, dict):
return {"status": "unavailable", "error": "ConfigNotMapping"}
semantic = secret_free_config(raw)
try:
identity_config = identity_config_projection(raw)
except ValueError:
return {"status": "unavailable", "error": "UnsafeIdentityConfig"}
model_semantic = identity_config.get("model") or {}
return { return {
"status": "observed", "status": "observed",
"provider": _nested(raw, "model", "provider"), "config_sha256": file_sha256(config_path),
"default_model": _nested(raw, "model", "default"), "semantic_config_sha256": canonical_sha256(semantic),
"smart_routing": _nested(raw, "model", "smart_routing"), "identity_config_sha256": canonical_sha256(identity_config),
"smart_routing_model": _nested(raw, "model", "smart_routing_model"), "model_section_sha256": canonical_sha256(model_semantic),
"max_tokens": _nested(raw, "model", "max_tokens"), "gateway_permissions_sha256": canonical_sha256(identity_config.get("gateway")),
"reasoning_effort": _nested(raw, "agent", "reasoning_effort"), "tool_permissions_sha256": canonical_sha256(identity_config.get("tools")),
"memory_enabled": _nested(raw, "memory", "enabled"), "memory_section_sha256": canonical_sha256(identity_config.get("memory")),
"memory_search": _nested(raw, "memory", "search"), "agent_runtime_sha256": canonical_sha256(identity_config.get("agent")),
"identity_runtime_policy": identity_config.get("identity_runtime"),
"provider": _nested(identity_config, "model", "provider"),
"default_model": _nested(identity_config, "model", "default"),
"smart_routing": _nested(identity_config, "model", "smart_routing"),
"smart_routing_model": _nested(identity_config, "model", "smart_routing_model"),
"gateway_smart_model_routing": identity_config.get("smart_model_routing"),
"max_tokens": _nested(identity_config, "model", "max_tokens"),
"reasoning_effort": _nested(identity_config, "agent", "reasoning_effort"),
"memory_enabled": _nested(identity_config, "memory", "enabled"),
"memory_search": _nested(identity_config, "memory", "search"),
} }
@ -196,7 +368,13 @@ def git_state(repo: Path) -> dict[str, Any]:
} }
def source_code_manifest(profile: Path, paths: tuple[Path, ...]) -> dict[str, Any]: def source_code_manifest(
profile: Path,
paths: tuple[Path, ...],
*,
source_root: Path | None = None,
namespace: str = "source",
) -> dict[str, Any]:
"""Hash executable source while excluding generated caches and environments.""" """Hash executable source while excluding generated caches and environments."""
allowed_suffixes = { allowed_suffixes = {
@ -216,12 +394,21 @@ def source_code_manifest(profile: Path, paths: tuple[Path, ...]) -> dict[str, An
excluded_parts = {".git", ".pytest_cache", "__pycache__", "node_modules", "venv", ".venv"} excluded_parts = {".git", ".pytest_cache", "__pycache__", "node_modules", "venv", ".venv"}
files: list[dict[str, Any]] = [] files: list[dict[str, Any]] = []
missing: list[str] = [] missing: list[str] = []
symlinks: list[str] = []
source_root = (source_root or profile).resolve()
def source_label(path: Path) -> str:
return f"{namespace}:{_safe_relative(path, source_root)}"
for requested in paths: for requested in paths:
if not requested.exists() and not requested.is_symlink(): if not requested.exists() and not requested.is_symlink():
missing.append(_safe_relative(requested, profile)) missing.append(source_label(requested))
continue continue
candidates = [requested] if requested.is_file() else sorted(requested.rglob("*")) candidates = [requested] if requested.is_file() else sorted(requested.rglob("*"))
for path in candidates: for path in candidates:
if path.is_symlink():
symlinks.append(source_label(path))
continue
if not path.is_file() or excluded_parts & set(path.parts): if not path.is_file() or excluded_parts & set(path.parts):
continue continue
stat = path.stat() stat = path.stat()
@ -229,14 +416,14 @@ def source_code_manifest(profile: Path, paths: tuple[Path, ...]) -> dict[str, An
continue continue
files.append( files.append(
{ {
"path": _safe_relative(path, profile), "path": source_label(path),
"bytes": stat.st_size, "bytes": stat.st_size,
"mode": oct(stat.st_mode & 0o777), "mode": oct(stat.st_mode & 0o777),
"sha256": file_sha256(path), "sha256": file_sha256(path),
} }
) )
files.sort(key=lambda item: item["path"]) files.sort(key=lambda item: item["path"])
stable = {"files": files, "missing": sorted(missing)} stable = {"files": files, "missing": sorted(missing), "symlinks": sorted(symlinks)}
return { return {
**stable, **stable,
"file_count": len(files), "file_count": len(files),
@ -261,6 +448,72 @@ def component(
} }
def stable_manifest_payload(manifest: dict[str, Any]) -> dict[str, Any]:
"""Return the canonical, path-independent behavior payload."""
return {field: manifest.get(field) for field in STABLE_MANIFEST_FIELDS}
def static_runtime_payload(manifest: dict[str, Any]) -> dict[str, Any]:
"""Return the exact payload committed by ``static_runtime_sha256``."""
components = manifest.get("components") or {}
return {
"schema": manifest.get("schema"),
"model_runtime": manifest.get("model_runtime"),
"hermes_runtime": manifest.get("hermes_runtime"),
"teleo_infrastructure_runtime": manifest.get("teleo_infrastructure_runtime"),
"components": {name: components.get(name) for name in STATIC_RUNTIME_COMPONENTS},
"python_runtime": manifest.get("python_runtime"),
"canonical_database": manifest.get("canonical_database"),
}
def identity_runtime_payload(manifest: dict[str, Any]) -> dict[str, Any]:
"""Return the exact payload committed by ``identity_runtime_sha256``."""
model = manifest.get("model_runtime") or {}
components = manifest.get("components") or {}
teleo = manifest.get("teleo_infrastructure_runtime") or {}
identity_model_runtime = {
key: model.get(key)
for key in (
"status",
"identity_config_sha256",
"model_section_sha256",
"gateway_permissions_sha256",
"tool_permissions_sha256",
"memory_section_sha256",
"agent_runtime_sha256",
"identity_runtime_policy",
"provider",
"default_model",
"smart_routing",
"smart_routing_model",
"gateway_smart_model_routing",
"max_tokens",
"reasoning_effort",
"memory_enabled",
"memory_search",
"base_model_weights",
"actual_per_turn_model_must_be_recorded_by_the_call_receipt",
)
}
return {
"schema": manifest.get("schema"),
"model_runtime": identity_model_runtime,
"hermes_runtime": manifest.get("hermes_runtime"),
"teleo_infrastructure_runtime": {
"git_head": teleo.get("git_head"),
"git_state": teleo.get("git_state"),
"source_tree": teleo.get("identity_source_tree"),
},
"components": {name: components.get(name) for name in IDENTITY_RUNTIME_COMPONENTS},
"python_runtime": manifest.get("python_runtime"),
"canonical_database": manifest.get("canonical_database"),
}
def build_manifest( def build_manifest(
profile: Path = DEFAULT_PROFILE, profile: Path = DEFAULT_PROFILE,
hermes_root: Path = DEFAULT_HERMES_ROOT, hermes_root: Path = DEFAULT_HERMES_ROOT,
@ -270,6 +523,12 @@ def build_manifest(
hermes_root = hermes_root.resolve() hermes_root = hermes_root.resolve()
deployment_root = deployment_root.resolve() deployment_root = deployment_root.resolve()
config = safe_model_config(profile / "config.yaml") config = safe_model_config(profile / "config.yaml")
identity_runtime_sources = (
deployment_root / "scripts" / "leo_behavior_manifest.py",
deployment_root / "scripts" / "leo_identity_manifest.py",
deployment_root / "scripts" / "leo_identity_profile.py",
deployment_root / "scripts" / "run_leo_identity_reconstruction_canary.py",
)
components = { components = {
"profile_config": component( "profile_config": component(
profile, profile,
@ -294,10 +553,10 @@ def build_manifest(
), ),
"runtime_middleware": component( "runtime_middleware": component(
profile, profile,
role="Pre-LLM context injection and post-LLM validation or response replacement.", role="Profile plugins for pre-LLM context injection and post-LLM validation or response replacement.",
mutability="deployment_static", mutability="deployment_static",
replayability="fully_hashable", replayability="fully_hashable",
paths=(profile / "plugins", hermes_root / "run_agent.py"), paths=(profile / "plugins",),
), ),
"database_tools": component( "database_tools": component(
profile, profile,
@ -353,14 +612,28 @@ def build_manifest(
hermes_root / "hermes_cli", hermes_root / "hermes_cli",
hermes_root / "tools", hermes_root / "tools",
), ),
source_root=hermes_root,
namespace="hermes",
), ),
}, },
"teleo_infrastructure_runtime": { "teleo_infrastructure_runtime": {
"git_head": git_head(deployment_root), "git_head": git_head(deployment_root),
"git_state": git_state(deployment_root), "git_state": git_state(deployment_root),
"source_tree": source_code_manifest(profile, (deployment_root,)), "source_tree": source_code_manifest(
profile,
(deployment_root,),
source_root=deployment_root,
namespace="teleo",
),
"identity_source_tree": source_code_manifest(
profile,
identity_runtime_sources,
source_root=deployment_root,
namespace="teleo-identity",
),
}, },
"components": components, "components": components,
"python_runtime": python_runtime_manifest(),
"canonical_database": { "canonical_database": {
"included": False, "included": False,
"reason": "Fingerprint through a read-only Postgres manifest in the database-owning harness.", "reason": "Fingerprint through a read-only Postgres manifest in the database-owning harness.",
@ -372,7 +645,9 @@ def build_manifest(
"profile_root": str(profile), "profile_root": str(profile),
"hermes_root": str(hermes_root), "hermes_root": str(hermes_root),
"deployment_root": str(deployment_root), "deployment_root": str(deployment_root),
"behavior_sha256": canonical_sha256(stable), "static_runtime_sha256": canonical_sha256(static_runtime_payload(stable)),
"identity_runtime_sha256": canonical_sha256(identity_runtime_payload(stable)),
"behavior_sha256": canonical_sha256(stable_manifest_payload(stable)),
} }

View file

@ -0,0 +1,878 @@
#!/usr/bin/env python3
"""Build and verify Leo's pinned, reproducible identity manifest."""
from __future__ import annotations
import argparse
import json
import re
import sys
from pathlib import Path
from typing import Any
if __package__ in {None, ""}:
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from scripts import leo_behavior_manifest as behavior
SCHEMA = "livingip.leoIdentityManifest.v1"
CONSTITUTION_SCHEMA = "livingip.leoConstitutionSource.v1"
DATABASE_IDENTITY_SCHEMA = "livingip.leoDatabaseIdentitySource.v1"
STRUCTURED_VIEW_SCHEMA = "livingip.leoCompiledIdentityView.v1"
DATABASE_FINGERPRINT_SCHEMA = "livingip.teleoCanonicalDatabaseFingerprint.v1"
SYNTHETIC_DATABASE_MODE = "synthetic_noncanonical_fixture"
CANONICAL_DATABASE_MODE = "canonical_database_same_transaction_export"
HEX_64 = re.compile(r"^[0-9a-f]{64}$")
HEX_40 = re.compile(r"^[0-9a-f]{40}$")
IDENTITY_TABLES = frozenset(
{
"public.personas",
"public.strategies",
"public.beliefs",
"public.shared_root",
"public.strategy_nodes",
"public.strategy_node_anchors",
"public.claims",
}
)
def expected_runtime_policy() -> dict[str, Any]:
return {
"network_send_enabled": False,
"database_write_enabled": False,
"allowed_tools": ["identity_readback"],
}
def expected_session_boundary() -> dict[str, Any]:
return {
"classification": "temporary_noncanonical",
"included_in_identity_inputs": False,
"may_be_used_as_evidence": False,
"restart_policy": "fresh_process_with_session_state_outside_identity_authority",
}
def expected_gatewayrunner_contract() -> dict[str, Any]:
return {
"profile_surfaces": ["config.yaml", "generated SOUL.md", "skills", "plugins", "bin tools"],
"required_absent_or_empty": {
"persistent_memory": behavior.canonical_sha256([]),
"pairing_store": behavior.canonical_sha256([]),
"project_context": behavior.canonical_sha256([]),
"generated_skill_prompt_cache": behavior.canonical_sha256([]),
"prior_sessions_at_first_start": behavior.canonical_sha256([]),
},
"fixed_message_context": {
"auto_skill": None,
"reply_context": None,
"media_or_file_context": None,
},
"required_t3_turn_receipt_fields": [
"runner_class",
"authorization_decision",
"effective_system_prompt_sha256",
"compiled_skills_prompt_sha256",
"tool_registry_schema_sha256",
"plugin_registry_sha256",
"selected_model",
"selected_provider",
"api_mode",
"base_url_host",
"database_retrieval_receipt",
"session_key_sha256",
"persisted_session_id_sha256",
],
}
class IdentityManifestError(ValueError):
"""An identity input is incomplete, inconsistent, or drifted."""
def _require(condition: bool, message: str) -> None:
if not condition:
raise IdentityManifestError(message)
def _is_sha256(value: Any) -> bool:
return isinstance(value, str) and bool(HEX_64.fullmatch(value))
def load_json(path: Path, label: str) -> dict[str, Any]:
try:
value = json.loads(path.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError) as exc:
raise IdentityManifestError(f"cannot read {label}: {type(exc).__name__}") from exc
if not isinstance(value, dict):
raise IdentityManifestError(f"{label} must be a JSON object")
return value
def canonical_rules(value: dict[str, Any]) -> list[dict[str, str]]:
_require(value.get("schema") == CONSTITUTION_SCHEMA, "unsupported constitution schema")
_require(value.get("identity_name") == "Leo", "constitution identity_name must be Leo")
raw_rules = value.get("rules")
_require(isinstance(raw_rules, list) and bool(raw_rules), "constitution rules must be non-empty")
rules: list[dict[str, str]] = []
for raw in raw_rules:
_require(isinstance(raw, dict), "each constitutional rule must be an object")
rule_id = str(raw.get("id") or "").strip()
text = str(raw.get("text") or "").strip()
_require(bool(rule_id and text), "each constitutional rule needs id and text")
rules.append({"id": rule_id, "text": text})
_require(len({item["id"] for item in rules}) == len(rules), "constitutional rule ids must be unique")
return sorted(rules, key=lambda item: item["id"])
def canonical_database_records(value: dict[str, Any], *, fingerprint_sha256: str) -> list[dict[str, str | int]]:
_require(value.get("schema") == DATABASE_IDENTITY_SCHEMA, "unsupported database identity schema")
_require(value.get("identity_name") == "Leo", "database identity_name must be Leo")
_require(
value.get("database_fingerprint_sha256") == fingerprint_sha256,
"database identity export is not bound to the supplied database fingerprint",
)
raw_records = value.get("records")
_require(isinstance(raw_records, list) and bool(raw_records), "database identity records must be non-empty")
records: list[dict[str, str | int]] = []
for raw in raw_records:
_require(isinstance(raw, dict), "each database identity record must be an object")
rank = raw.get("rank", 0)
record: dict[str, str | int] = {
"table": str(raw.get("table") or "").strip(),
"row_id": str(raw.get("row_id") or "").strip(),
"kind": str(raw.get("kind") or "").strip(),
"rank": rank if isinstance(rank, int) and not isinstance(rank, bool) else -1,
"text": str(raw.get("text") or "").strip(),
"status": str(raw.get("status") or "").strip(),
"evidence_sha256": str(raw.get("evidence_sha256") or "").strip(),
}
_require(record["table"] in IDENTITY_TABLES, "database identity table is outside the allowlist")
_require(bool(record["row_id"] and record["kind"] and record["text"]), "database record fields are incomplete")
_require(isinstance(record["rank"], int) and record["rank"] >= 0, "database record rank is invalid")
_require(record["status"] == "active", "database identity records must be active selected rows")
_require(_is_sha256(record["evidence_sha256"]), "database record evidence_sha256 is invalid")
records.append(record)
keys = {(item["table"], item["row_id"]) for item in records}
_require(len(keys) == len(records), "database identity row bindings must be unique")
return sorted(records, key=lambda item: (str(item["table"]), int(item["rank"]), str(item["row_id"])))
def database_fingerprint_semantic(value: dict[str, Any]) -> dict[str, Any]:
"""Bind immutable capture provenance while excluding only the volatile WAL position."""
result = {key: value[key] for key in sorted(value) if key != "read_consistency"}
consistency = value["read_consistency"]
result["read_consistency"] = {
"status": consistency["status"],
"before": {key: item for key, item in consistency["before"].items() if key != "wal_lsn"},
"after": {key: item for key, item in consistency["after"].items() if key != "wal_lsn"},
}
return result
def database_identity_provenance(
value: dict[str, Any],
*,
fingerprint: dict[str, Any],
) -> dict[str, Any]:
raw = value.get("source_provenance")
_require(isinstance(raw, dict), "database identity source provenance is missing")
mode = raw.get("mode")
if mode == SYNTHETIC_DATABASE_MODE:
_require(
raw
== {
"mode": SYNTHETIC_DATABASE_MODE,
"canonical_authority_granted": False,
"same_transaction_as_fingerprint": False,
"export_receipt_sha256": None,
},
"synthetic database provenance contract is invalid",
)
_require(
fingerprint.get("environment") == "disposable_fixture",
"synthetic rows require a fixture fingerprint",
)
_require("export_receipt" not in value, "synthetic database identity must not claim an export receipt")
return {**raw, "authority": "synthetic_noncanonical_fixture"}
if mode == CANONICAL_DATABASE_MODE:
raise IdentityManifestError(
"canonical authority requires independently verified output from the database-owning same-transaction "
"exporter; caller-supplied T2 JSON cannot grant it"
)
raise IdentityManifestError("unsupported database identity provenance mode")
def validate_database_fingerprint(value: dict[str, Any]) -> None:
_require(value.get("schema") == DATABASE_FINGERPRINT_SCHEMA, "unsupported database fingerprint schema")
_require(value.get("status") == "ok", "database fingerprint status must be ok")
for field in ("fingerprint_sha256", "table_rows_sha256", "structure_sha256"):
_require(_is_sha256(value.get(field)), f"database fingerprint {field} is invalid")
_require(isinstance(value.get("table_count"), int) and value["table_count"] > 0, "table_count must be positive")
_require(isinstance(value.get("total_rows"), int) and value["total_rows"] >= 0, "total_rows is invalid")
consistency = value.get("read_consistency")
_require(isinstance(consistency, dict), "database read_consistency is missing")
before = consistency.get("before")
after = consistency.get("after")
_require(consistency.get("status") == "stable_wal_marker", "database fingerprint was not read consistently")
_require(isinstance(before, dict) and before == after and bool(before), "database read markers differ")
for field in ("database", "database_user", "system_identifier", "wal_lsn"):
_require(bool(before.get(field)), f"database read marker {field} is missing")
def validate_content_manifest(value: Any, *, label: str) -> None:
"""Recompute the structural metadata of a replayable content manifest."""
_require(isinstance(value, dict), f"{label} is invalid")
_require(
set(value) == {"files", "missing", "symlinks", "file_count", "total_bytes", "sha256"},
f"{label} fields are invalid",
)
files = value.get("files")
missing = value.get("missing")
symlinks = value.get("symlinks")
_require(isinstance(files, list) and bool(files), f"{label} is empty")
_require(missing == [], f"{label} has missing inputs")
_require(symlinks == [], f"{label} contains unsupported symlinks")
paths: list[str] = []
total_bytes = 0
for item in files:
_require(isinstance(item, dict), f"{label} contains unreadable inputs")
_require(set(item) == {"path", "bytes", "mode", "sha256"}, f"{label} contains unreadable inputs")
path = item.get("path")
size = item.get("bytes")
mode = item.get("mode")
_require(isinstance(path, str) and bool(path), f"{label} contains an invalid path")
_require(isinstance(size, int) and not isinstance(size, bool) and size >= 0, f"{label} byte size is invalid")
_require(isinstance(mode, str) and bool(re.fullmatch(r"0o[0-7]{3}", mode)), f"{label} mode is invalid")
_require(_is_sha256(item.get("sha256")), f"{label} contains unreadable inputs")
paths.append(path)
total_bytes += size
_require(paths == sorted(paths) and len(paths) == len(set(paths)), f"{label} paths are not unique and sorted")
_require(value.get("file_count") == len(files), f"{label} file count is invalid")
_require(value.get("total_bytes") == total_bytes, f"{label} total bytes is invalid")
stable = {"files": files, "missing": missing, "symlinks": symlinks}
_require(behavior.canonical_sha256(stable) == value.get("sha256"), f"{label} content hash is invalid")
def validate_behavior_manifest(value: dict[str, Any]) -> None:
_require(value.get("schema") == behavior.SCHEMA, "unsupported behavior manifest schema")
for field in ("behavior_sha256", "static_runtime_sha256", "identity_runtime_sha256"):
_require(_is_sha256(value.get(field)), f"behavior manifest {field} is invalid")
_require(
behavior.canonical_sha256(behavior.identity_runtime_payload(value)) == value["identity_runtime_sha256"],
"behavior identity runtime hash drift detected",
)
_require(
behavior.canonical_sha256(behavior.static_runtime_payload(value)) == value["static_runtime_sha256"],
"behavior static runtime hash drift detected",
)
_require(
behavior.canonical_sha256(behavior.stable_manifest_payload(value)) == value["behavior_sha256"],
"behavior manifest stable payload hash drift detected",
)
model = value.get("model_runtime")
_require(isinstance(model, dict) and model.get("status") == "observed", "model runtime was not observed")
_require(bool(model.get("provider") and model.get("default_model")), "provider and default model must be pinned")
for field in (
"semantic_config_sha256",
"identity_config_sha256",
"model_section_sha256",
"gateway_permissions_sha256",
"tool_permissions_sha256",
"memory_section_sha256",
"agent_runtime_sha256",
):
_require(_is_sha256(model.get(field)), f"model runtime {field} is invalid")
_require(
model.get("base_model_weights") == "external_provider_managed_not_locally_hashable",
"hosted model weight boundary is missing",
)
_require(
model.get("actual_per_turn_model_must_be_recorded_by_the_call_receipt") is True, "model receipt gate missing"
)
policy = model.get("identity_runtime_policy")
_require(policy == expected_runtime_policy(), "identity runtime policy must be the exact local readback policy")
for field in ("hermes_runtime", "teleo_infrastructure_runtime"):
runtime = value.get(field)
_require(isinstance(runtime, dict), f"{field} is missing")
_require(bool(HEX_40.fullmatch(str(runtime.get("git_head") or ""))), f"{field} git_head is invalid")
git_state = runtime.get("git_state")
_require(
isinstance(git_state, dict) and git_state.get("worktree_clean") is True,
f"{field} is not reconstructible from clean Git",
)
tree = runtime.get("identity_source_tree" if field == "teleo_infrastructure_runtime" else "source_tree")
validate_content_manifest(tree, label=f"{field} source tree")
components = value.get("components")
_require(isinstance(components, dict), "behavior components are missing")
for name in behavior.IDENTITY_RUNTIME_COMPONENTS:
content = (components.get(name) or {}).get("content")
validate_content_manifest(content, label=f"component {name}")
python_runtime = value.get("python_runtime")
_require(isinstance(python_runtime, dict), "Python runtime binding is missing")
_require(
bool(python_runtime.get("implementation") and python_runtime.get("python_version")),
"Python runtime is incomplete",
)
_require(_is_sha256(python_runtime.get("runtime_distributions_sha256")), "runtime package binding is invalid")
_require(
all(python_runtime.get("runtime_distributions", {}).values()), "a required runtime distribution is missing"
)
def _repo_path(path: Path, source_root: Path) -> str:
try:
return path.resolve(strict=True).relative_to(source_root.resolve(strict=True)).as_posix()
except (OSError, ValueError) as exc:
raise IdentityManifestError(f"identity source is outside the pinned source root: {path}") from exc
def source_binding(
path: Path,
*,
source_root: Path,
semantic_value: Any,
count: int,
pin_content: bool = True,
) -> dict[str, Any]:
result = {
"repo_path": _repo_path(path, source_root),
"semantic_sha256": behavior.canonical_sha256(semantic_value),
"record_count": count,
}
if pin_content:
result["content_sha256"] = behavior.file_sha256(path)
return result
def render_identity_views(
*,
identity_inputs_sha256: str,
database_fingerprint_sha256: str,
database_provenance: dict[str, Any],
rules: list[dict[str, str]],
records: list[dict[str, str | int]],
) -> dict[str, str]:
soul = [
"<!-- GENERATED FILE: edit the pinned sources, never this view. -->",
"# Leo",
"",
f"Identity inputs: `{identity_inputs_sha256}`",
"",
"## Static constitutional rules",
"",
"These rules are static constitutional inputs, not database claims.",
"",
]
soul.extend(f"- **{item['id']}**: {item['text']}" for item in rules)
database_description = (
"canonical database capture"
if database_provenance["canonical_authority_granted"]
else "synthetic noncanonical fixture"
)
soul.extend(
[
"",
"## Database-derived identity",
"",
f"Generated from {database_description} fingerprint `{database_fingerprint_sha256}`.",
"",
]
)
soul.extend(
f"- `{item['table']}/{item['row_id']}` [{item['kind']}, rank {item['rank']}]: {item['text']} "
f"(evidence `{item['evidence_sha256']}`)"
for item in records
)
soul.extend(
[
"",
"## Authority and session boundary",
"",
"- This `SOUL.md` is a generated view and is never an authority by itself.",
"- Generated database identity is authoritative only when its same-transaction export receipt grants canonical authority.",
"- Runtime/session memory is temporary, noncanonical, and cannot serve as evidence.",
"- Hosted model weights are provider-managed and must be attributed by each turn receipt.",
"",
]
)
structured = {
"schema": STRUCTURED_VIEW_SCHEMA,
"identity_name": "Leo",
"identity_inputs_sha256": identity_inputs_sha256,
"static_constitution": {"authority": "pinned_static_source", "rules": rules},
"database_identity": {
"authority": database_provenance["authority"],
"canonical_authority_granted": database_provenance["canonical_authority_granted"],
"source_mode": database_provenance["mode"],
"database_fingerprint_sha256": database_fingerprint_sha256,
"records": records,
},
"session_boundary": {
"authority": "none",
"classification": "temporary_noncanonical",
"may_be_used_as_evidence": False,
},
}
return {
"SOUL.md": "\n".join(soul),
"identity.json": json.dumps(structured, indent=2, sort_keys=True) + "\n",
}
def build_identity_manifest(
*,
behavior_manifest: dict[str, Any],
database_fingerprint_path: Path,
constitution_path: Path,
database_identity_path: Path,
source_root: Path,
source_commit: str | None = None,
) -> dict[str, Any]:
validate_behavior_manifest(behavior_manifest)
database_fingerprint = load_json(database_fingerprint_path, "database fingerprint")
validate_database_fingerprint(database_fingerprint)
constitution = load_json(constitution_path, "constitution source")
database_identity = load_json(database_identity_path, "database identity source")
rules = canonical_rules(constitution)
records = canonical_database_records(
database_identity, fingerprint_sha256=database_fingerprint["fingerprint_sha256"]
)
database_provenance = database_identity_provenance(
database_identity,
fingerprint=database_fingerprint,
)
runtime_commit = behavior_manifest["teleo_infrastructure_runtime"]["git_head"]
source_commit = source_commit or runtime_commit
_require(bool(HEX_40.fullmatch(str(source_commit))), "source commit is invalid")
_require(source_commit == runtime_commit, "source commit does not match the behavior manifest")
model = behavior_manifest["model_runtime"]
components = behavior_manifest["components"]
marker = database_fingerprint["read_consistency"]["before"]
core = {
"identity_name": "Leo",
"source_commit": source_commit,
"runtime": {
"identity_runtime_sha256": behavior_manifest["identity_runtime_sha256"],
"hermes_git_head": behavior_manifest["hermes_runtime"]["git_head"],
"hermes_source_sha256": behavior_manifest["hermes_runtime"]["source_tree"]["sha256"],
"teleo_git_head": runtime_commit,
"teleo_source_sha256": behavior_manifest["teleo_infrastructure_runtime"]["identity_source_tree"]["sha256"],
"python": behavior_manifest["python_runtime"],
},
"model": {
"provider": model["provider"],
"default_model": model["default_model"],
"smart_routing": model.get("smart_routing"),
"smart_routing_model": model.get("smart_routing_model"),
"gateway_smart_model_routing": model.get("gateway_smart_model_routing"),
"model_section_sha256": model["model_section_sha256"],
"hosted_weights": "external_provider_managed_not_locally_hashable",
"actual_model_required_in_turn_receipt": True,
},
"skills": {
"content_sha256": components["procedural_skills"]["content"]["sha256"],
"file_count": components["procedural_skills"]["content"]["file_count"],
},
"permissions": {
"identity_config_sha256": model["identity_config_sha256"],
"gateway_permissions_sha256": model["gateway_permissions_sha256"],
"tool_permissions_sha256": model["tool_permissions_sha256"],
"runtime_policy": model["identity_runtime_policy"],
"authorization_decision_required_in_runtime_receipt": True,
},
"canonical_database": {
"database": marker["database"],
"database_user": marker["database_user"],
"system_identifier": marker["system_identifier"],
"authority": database_provenance["authority"],
"canonical_authority_granted": database_provenance["canonical_authority_granted"],
**{
key: database_fingerprint[key]
for key in ("fingerprint_sha256", "table_rows_sha256", "structure_sha256", "table_count", "total_rows")
},
"source": source_binding(
database_fingerprint_path,
source_root=source_root,
semantic_value=database_fingerprint_semantic(database_fingerprint),
count=database_fingerprint["table_count"],
pin_content=False,
),
},
"identity_sources": {
"static_constitution": {
"authority": "pinned_static_source",
**source_binding(constitution_path, source_root=source_root, semantic_value=rules, count=len(rules)),
},
"database_derived_identity": {
"authority": database_provenance["authority"],
"provenance": database_provenance,
"database_fingerprint_sha256": database_fingerprint["fingerprint_sha256"],
**source_binding(
database_identity_path,
source_root=source_root,
semantic_value={"provenance": database_provenance, "records": records},
count=len(records),
),
},
},
"session_boundary": expected_session_boundary(),
"gatewayrunner_execution_contract": expected_gatewayrunner_contract(),
}
identity_inputs_sha256 = behavior.canonical_sha256(core)
views = render_identity_views(
identity_inputs_sha256=identity_inputs_sha256,
database_fingerprint_sha256=database_fingerprint["fingerprint_sha256"],
database_provenance=database_provenance,
rules=rules,
records=records,
)
stable = {
"schema": SCHEMA,
"identity_inputs": core,
"identity_inputs_sha256": identity_inputs_sha256,
"compiled_views": {
name: {
"role": "generated_view_not_authority",
"sha256": behavior.sha256_bytes(content.encode("utf-8")),
"generated_from_identity_inputs_sha256": identity_inputs_sha256,
}
for name, content in sorted(views.items())
},
}
return {**stable, "manifest_sha256": behavior.canonical_sha256(stable)}
def validate_identity_manifest(value: dict[str, Any]) -> None:
_require(value.get("schema") == SCHEMA, "unsupported identity manifest schema")
expected = value.get("manifest_sha256")
_require(_is_sha256(expected), "identity manifest sha256 is invalid")
stable = {key: item for key, item in value.items() if key != "manifest_sha256"}
_require(behavior.canonical_sha256(stable) == expected, "identity manifest hash drift detected")
core = value.get("identity_inputs")
_require(isinstance(core, dict), "identity inputs are missing")
_require(
set(core)
== {
"identity_name",
"source_commit",
"runtime",
"model",
"skills",
"permissions",
"canonical_database",
"identity_sources",
"session_boundary",
"gatewayrunner_execution_contract",
},
"identity input contract fields are invalid",
)
identity_hash = value.get("identity_inputs_sha256")
_require(_is_sha256(identity_hash), "identity input hash is invalid")
_require(behavior.canonical_sha256(core) == identity_hash, "identity input hash drift detected")
_require(core.get("identity_name") == "Leo", "identity name must be Leo")
runtime = core.get("runtime")
_require(isinstance(runtime, dict), "runtime binding is missing")
_require(
set(runtime)
== {
"identity_runtime_sha256",
"hermes_git_head",
"hermes_source_sha256",
"teleo_git_head",
"teleo_source_sha256",
"python",
},
"runtime binding fields are invalid",
)
_require(_is_sha256(runtime.get("identity_runtime_sha256")), "identity runtime binding is invalid")
for field in ("hermes_git_head", "teleo_git_head"):
_require(bool(HEX_40.fullmatch(str(runtime.get(field) or ""))), f"runtime {field} is invalid")
for field in ("hermes_source_sha256", "teleo_source_sha256"):
_require(_is_sha256(runtime.get(field)), f"runtime {field} is invalid")
_require(core.get("source_commit") == runtime["teleo_git_head"], "source commit is not bound to Teleo Git")
python_runtime = runtime.get("python")
_require(isinstance(python_runtime, dict), "Python runtime binding is missing")
_require(
bool(python_runtime.get("implementation") and python_runtime.get("python_version")),
"Python runtime binding is incomplete",
)
_require(_is_sha256(python_runtime.get("runtime_distributions_sha256")), "Python distribution binding is invalid")
model = core.get("model")
_require(isinstance(model, dict), "model binding is missing")
_require(
set(model)
== {
"provider",
"default_model",
"smart_routing",
"smart_routing_model",
"gateway_smart_model_routing",
"model_section_sha256",
"hosted_weights",
"actual_model_required_in_turn_receipt",
},
"model binding fields are invalid",
)
_require(bool(model.get("provider") and model.get("default_model")), "model provider and default must be pinned")
_require(_is_sha256(model.get("model_section_sha256")), "model section binding is invalid")
_require(
model.get("hosted_weights") == "external_provider_managed_not_locally_hashable",
"hosted model boundary is invalid",
)
_require(model.get("actual_model_required_in_turn_receipt") is True, "per-turn model receipt gate is invalid")
skills = core.get("skills")
_require(isinstance(skills, dict) and set(skills) == {"content_sha256", "file_count"}, "skills binding is invalid")
_require(_is_sha256(skills.get("content_sha256")), "skills content hash is invalid")
_require(
isinstance(skills.get("file_count"), int)
and not isinstance(skills.get("file_count"), bool)
and skills["file_count"] > 0,
"skills file count is invalid",
)
permissions = core.get("permissions")
_require(isinstance(permissions, dict), "permission binding is missing")
_require(
set(permissions)
== {
"identity_config_sha256",
"gateway_permissions_sha256",
"tool_permissions_sha256",
"runtime_policy",
"authorization_decision_required_in_runtime_receipt",
},
"permission binding fields are invalid",
)
for field in ("identity_config_sha256", "gateway_permissions_sha256", "tool_permissions_sha256"):
_require(_is_sha256(permissions.get(field)), f"permission binding {field} is invalid")
_require(
permissions.get("runtime_policy") == expected_runtime_policy(),
"identity runtime policy must be the exact local readback policy",
)
_require(
permissions.get("authorization_decision_required_in_runtime_receipt") is True,
"runtime authorization receipt gate is invalid",
)
database = core.get("canonical_database")
_require(isinstance(database, dict), "canonical database binding is missing")
for field in ("fingerprint_sha256", "table_rows_sha256", "structure_sha256"):
_require(_is_sha256(database.get(field)), f"canonical database {field} is invalid")
_require(
bool(database.get("database") and database.get("database_user") and database.get("system_identifier")),
"canonical database identity is incomplete",
)
allowed_authorities = {"synthetic_noncanonical_fixture": False}
_require(database.get("authority") in allowed_authorities, "database authority is invalid")
_require(
database.get("canonical_authority_granted") is allowed_authorities[database["authority"]],
"database canonical authority grant is invalid",
)
_require(
isinstance(database.get("table_count"), int)
and not isinstance(database.get("table_count"), bool)
and database["table_count"] > 0,
"canonical database table_count is invalid",
)
_require(
isinstance(database.get("total_rows"), int)
and not isinstance(database.get("total_rows"), bool)
and database["total_rows"] >= 0,
"canonical database total_rows is invalid",
)
def validate_source_binding(binding: Any, *, label: str, content_required: bool) -> None:
_require(isinstance(binding, dict), f"{label} source binding is missing")
repo_path = binding.get("repo_path")
_require(
isinstance(repo_path, str)
and bool(repo_path)
and not Path(repo_path).is_absolute()
and ".." not in Path(repo_path).parts,
f"{label} source path is invalid",
)
_require(_is_sha256(binding.get("semantic_sha256")), f"{label} semantic binding is invalid")
_require(
isinstance(binding.get("record_count"), int)
and not isinstance(binding.get("record_count"), bool)
and binding["record_count"] > 0,
f"{label} record count is invalid",
)
if content_required:
_require(_is_sha256(binding.get("content_sha256")), f"{label} content binding is invalid")
else:
_require("content_sha256" not in binding, f"{label} content binding must exclude volatile capture markers")
validate_source_binding(database.get("source"), label="database fingerprint", content_required=False)
sources = core.get("identity_sources")
_require(
isinstance(sources, dict) and set(sources) == {"static_constitution", "database_derived_identity"},
"identity source bindings are invalid",
)
constitution = sources["static_constitution"]
derived = sources["database_derived_identity"]
_require(isinstance(constitution, dict), "constitution source binding is invalid")
_require(isinstance(derived, dict), "database identity source binding is invalid")
_require(constitution.get("authority") == "pinned_static_source", "constitution authority is invalid")
_require(derived.get("authority") == database["authority"], "database identity authority is invalid")
provenance = derived.get("provenance")
_require(isinstance(provenance, dict), "database identity provenance is missing")
_require(provenance.get("authority") == database["authority"], "database identity provenance authority is invalid")
_require(
provenance.get("canonical_authority_granted") is database["canonical_authority_granted"],
"database identity provenance grant is invalid",
)
_require(provenance.get("mode") == SYNTHETIC_DATABASE_MODE, "synthetic database provenance mode is invalid")
_require(
provenance.get("same_transaction_as_fingerprint") is False,
"synthetic fixture transaction claim is invalid",
)
_require(provenance.get("export_receipt_sha256") is None, "synthetic fixture must not claim an export receipt")
_require(
derived.get("database_fingerprint_sha256") == database["fingerprint_sha256"],
"database identity source is misbound",
)
validate_source_binding(constitution, label="constitution", content_required=True)
validate_source_binding(derived, label="database identity", content_required=True)
_require(core.get("session_boundary") == expected_session_boundary(), "session authority boundary is invalid")
_require(
core.get("gatewayrunner_execution_contract") == expected_gatewayrunner_contract(),
"GatewayRunner execution contract is invalid",
)
views = value.get("compiled_views")
_require(isinstance(views, dict) and set(views) == {"SOUL.md", "identity.json"}, "compiled views are incomplete")
for name, view in views.items():
_require(isinstance(view, dict) and _is_sha256(view.get("sha256")), f"compiled view {name} is invalid")
_require(
set(view) == {"role", "sha256", "generated_from_identity_inputs_sha256"},
f"compiled view {name} fields are invalid",
)
_require(view.get("role") == "generated_view_not_authority", f"compiled view {name} authority is invalid")
_require(
view.get("generated_from_identity_inputs_sha256") == identity_hash, f"compiled view {name} is misbound"
)
def verify_bound_sources(value: dict[str, Any], source_root: Path) -> dict[str, str]:
validate_identity_manifest(value)
core = value["identity_inputs"]
bindings = {
"database fingerprint": core["canonical_database"]["source"],
"constitution source": core["identity_sources"]["static_constitution"],
"database identity source": core["identity_sources"]["database_derived_identity"],
}
paths = {label: source_root / binding["repo_path"] for label, binding in bindings.items()}
for label, binding in bindings.items():
path = paths[label]
_require(path.is_file(), f"bound {label} is missing")
if binding.get("content_sha256"):
_require(behavior.file_sha256(path) == binding["content_sha256"], f"bound {label} content drift detected")
fingerprint = load_json(paths["database fingerprint"], "database fingerprint")
validate_database_fingerprint(fingerprint)
_require(
behavior.canonical_sha256(database_fingerprint_semantic(fingerprint))
== bindings["database fingerprint"]["semantic_sha256"],
"database fingerprint semantic drift detected",
)
marker = fingerprint["read_consistency"]["before"]
for field in ("database", "database_user", "system_identifier"):
_require(marker[field] == core["canonical_database"][field], f"canonical database {field} drift detected")
rules = canonical_rules(load_json(paths["constitution source"], "constitution source"))
database_identity = load_json(paths["database identity source"], "database identity source")
records = canonical_database_records(
database_identity,
fingerprint_sha256=fingerprint["fingerprint_sha256"],
)
database_provenance = database_identity_provenance(
database_identity,
fingerprint=fingerprint,
)
_require(
behavior.canonical_sha256(rules) == bindings["constitution source"]["semantic_sha256"],
"constitution semantic drift detected",
)
_require(
behavior.canonical_sha256({"provenance": database_provenance, "records": records})
== bindings["database identity source"]["semantic_sha256"],
"database identity semantic drift detected",
)
_require(
database_provenance == core["identity_sources"]["database_derived_identity"]["provenance"],
"database identity provenance drift detected",
)
_require(
fingerprint["fingerprint_sha256"] == core["canonical_database"]["fingerprint_sha256"],
"canonical database fingerprint drift detected",
)
views = render_identity_views(
identity_inputs_sha256=value["identity_inputs_sha256"],
database_fingerprint_sha256=fingerprint["fingerprint_sha256"],
database_provenance=database_provenance,
rules=rules,
records=records,
)
for name, content in views.items():
_require(
behavior.sha256_bytes(content.encode("utf-8")) == value["compiled_views"][name]["sha256"],
f"compiled view contract drift detected for {name}",
)
return views
def write_json(path: Path, value: dict[str, Any]) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8")
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
subparsers = parser.add_subparsers(dest="command", required=True)
generate = subparsers.add_parser("generate")
generate.add_argument("--behavior-manifest", type=Path, required=True)
generate.add_argument("--database-fingerprint", type=Path, required=True)
generate.add_argument("--constitution", type=Path, required=True)
generate.add_argument("--database-identity", type=Path, required=True)
generate.add_argument("--source-root", type=Path, required=True)
generate.add_argument("--source-commit")
generate.add_argument("--output", type=Path, required=True)
verify = subparsers.add_parser("verify")
verify.add_argument("--manifest", type=Path, required=True)
verify.add_argument("--source-root", type=Path)
args = parser.parse_args()
try:
if args.command == "generate":
manifest = build_identity_manifest(
behavior_manifest=load_json(args.behavior_manifest, "behavior manifest"),
database_fingerprint_path=args.database_fingerprint,
constitution_path=args.constitution,
database_identity_path=args.database_identity,
source_root=args.source_root,
source_commit=args.source_commit,
)
write_json(args.output, manifest)
else:
manifest = load_json(args.manifest, "identity manifest")
validate_identity_manifest(manifest)
if args.source_root:
verify_bound_sources(manifest, args.source_root)
print(json.dumps({"status": "ok", "manifest_sha256": manifest["manifest_sha256"]}))
return 0
except IdentityManifestError as exc:
print(json.dumps({"status": "error", "error": "identity_manifest_invalid", "message": str(exc)}))
return 2
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -0,0 +1,495 @@
#!/usr/bin/env python3
"""Compile, verify, and query a disposable Leo identity profile."""
from __future__ import annotations
import argparse
import json
import os
import shutil
import sys
import uuid
from datetime import UTC, datetime
from pathlib import Path
from typing import Any
import yaml
if __package__ in {None, ""}:
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from scripts import leo_behavior_manifest as behavior
from scripts import leo_identity_manifest as identity
LOCK_SCHEMA = "livingip.leoIdentityProfileLock.v1"
COMPILE_RECEIPT_SCHEMA = "livingip.leoIdentityCompileReceipt.v1"
QUERY_RECEIPT_SCHEMA = "livingip.leoIdentityQueryReceipt.v1"
SESSION_RECORD_SCHEMA = "livingip.leoTemporarySessionRecord.v1"
FIXED_QUERY = "What defines Leo's identity, and what is temporary?"
STATIC_PROFILE_ENTRIES = ("config.yaml", "skills", "plugins", "bin")
COMPILED_PROFILE_ENTRIES = frozenset(
{
"config.yaml",
"skills",
"plugins",
"bin",
"SOUL.md",
"identity.json",
"identity-manifest.json",
"identity-lock.json",
"compile-receipt.json",
"sessions",
"state",
}
)
OMITTED_NONAUTHORITATIVE_ENTRIES = (
"memories",
"MEMORY.md",
"USER.md",
"platforms/pairing",
".skills_prompt_snapshot.json",
".hermes.md",
"HERMES.md",
"AGENTS.md",
"CLAUDE.md",
".cursorrules",
)
class IdentityProfileError(identity.IdentityManifestError):
"""A compiled profile cannot be trusted or started."""
def _require(condition: bool, message: str) -> None:
if not condition:
raise IdentityProfileError(message)
def _copy_static_profile(template: Path, target: Path) -> list[str]:
_require(template.is_dir(), "profile template is missing")
_require(not target.exists(), "compiled profile target already exists")
target.mkdir(parents=True, mode=0o700)
copied: list[str] = []
for name in STATIC_PROFILE_ENTRIES:
source = template / name
if not source.exists():
continue
destination = target / name
_require(not source.is_symlink(), f"unsafe symlinked static profile entry: {name}")
if source.is_dir():
_require(
not any(path.is_symlink() for path in source.rglob("*")),
f"unsafe symlink inside static profile entry: {name}",
)
shutil.copytree(source, destination, symlinks=False)
elif source.is_file() and not source.is_symlink():
if name == "config.yaml":
try:
raw_config = yaml.safe_load(source.read_text(encoding="utf-8")) or {}
except (OSError, TypeError, yaml.YAMLError) as exc:
raise IdentityProfileError(f"cannot sanitize profile config: {type(exc).__name__}") from exc
_require(isinstance(raw_config, dict), "profile config must be a mapping")
destination.write_text(
yaml.safe_dump(behavior.identity_config_projection(raw_config), sort_keys=False),
encoding="utf-8",
)
destination.chmod(0o600)
else:
shutil.copy2(source, destination)
else:
raise IdentityProfileError(f"unsafe static profile entry: {name}")
copied.append(name)
_require("config.yaml" in copied, "profile template config.yaml is missing")
return copied
def _behavior(profile: Path, hermes_root: Path, deployment_root: Path) -> dict[str, Any]:
return behavior.build_manifest(profile, hermes_root, deployment_root)
def _verify_runtime_binding(
manifest: dict[str, Any],
*,
profile: Path,
hermes_root: Path,
deployment_root: Path,
) -> dict[str, Any]:
observed = _behavior(profile, hermes_root, deployment_root)
identity.validate_behavior_manifest(observed)
expected = manifest["identity_inputs"]["runtime"]
_require(
observed["identity_runtime_sha256"] == expected["identity_runtime_sha256"], "identity runtime drift detected"
)
_require(observed["hermes_runtime"]["git_head"] == expected["hermes_git_head"], "Hermes Git drift detected")
_require(
observed["hermes_runtime"]["source_tree"]["sha256"] == expected["hermes_source_sha256"],
"Hermes source drift detected",
)
_require(
observed["teleo_infrastructure_runtime"]["git_head"] == expected["teleo_git_head"],
"Teleo Git drift detected",
)
_require(
observed["teleo_infrastructure_runtime"]["identity_source_tree"]["sha256"] == expected["teleo_source_sha256"],
"Teleo identity source drift detected",
)
_require(observed["python_runtime"] == expected["python"], "Python runtime drift detected")
_require(
manifest["identity_inputs"]["source_commit"] == observed["teleo_infrastructure_runtime"]["git_head"],
"source commit drift detected",
)
expected_model = manifest["identity_inputs"]["model"]
observed_model = observed["model_runtime"]
model_bindings = {
"provider": observed_model.get("provider"),
"default_model": observed_model.get("default_model"),
"smart_routing": observed_model.get("smart_routing"),
"smart_routing_model": observed_model.get("smart_routing_model"),
"gateway_smart_model_routing": observed_model.get("gateway_smart_model_routing"),
"model_section_sha256": observed_model.get("model_section_sha256"),
"hosted_weights": observed_model.get("base_model_weights"),
"actual_model_required_in_turn_receipt": observed_model.get(
"actual_per_turn_model_must_be_recorded_by_the_call_receipt"
),
}
for field, observed_value in model_bindings.items():
_require(expected_model.get(field) == observed_value, f"model runtime binding drift detected: {field}")
expected_permissions = manifest["identity_inputs"]["permissions"]
permission_bindings = {
"identity_config_sha256": observed_model.get("identity_config_sha256"),
"gateway_permissions_sha256": observed_model.get("gateway_permissions_sha256"),
"tool_permissions_sha256": observed_model.get("tool_permissions_sha256"),
"runtime_policy": observed_model.get("identity_runtime_policy"),
"authorization_decision_required_in_runtime_receipt": True,
}
for field, observed_value in permission_bindings.items():
_require(
expected_permissions.get(field) == observed_value, f"permission runtime binding drift detected: {field}"
)
observed_skills = observed["components"]["procedural_skills"]["content"]
expected_skills = manifest["identity_inputs"]["skills"]
_require(expected_skills["content_sha256"] == observed_skills["sha256"], "skills runtime binding drift detected")
_require(expected_skills["file_count"] == observed_skills["file_count"], "skills file count drift detected")
return observed
def _view_file_sha256(profile: Path, name: str) -> str:
path = profile / name
_require(path.is_file() and not path.is_symlink(), f"compiled view is missing or unsafe: {name}")
return behavior.file_sha256(path)
def _verify_nonauthoritative_surfaces(
profile: Path,
*,
require_empty_sessions: bool,
require_compile_receipt: bool,
) -> dict[str, Any]:
omitted = {
name: not (profile / name).exists() and not (profile / name).is_symlink()
for name in OMITTED_NONAUTHORITATIVE_ENTRIES
}
_require(all(omitted.values()), "profile contains a forbidden nonauthoritative input surface")
expected_entries = set(COMPILED_PROFILE_ENTRIES)
if not require_compile_receipt:
expected_entries.remove("compile-receipt.json")
profile_entries = list(profile.iterdir())
actual_entries = {path.name for path in profile_entries}
_require(actual_entries == expected_entries, "compiled profile entry set is not exact")
_require(not any(path.is_symlink() for path in profile_entries), "compiled profile entries must not be symlinks")
if require_compile_receipt:
compile_receipt = identity.load_json(profile / "compile-receipt.json", "identity compile receipt")
_require(compile_receipt.get("schema") == COMPILE_RECEIPT_SCHEMA, "identity compile receipt schema is invalid")
_require(compile_receipt.get("status") == "pass", "identity compile receipt status is invalid")
state = profile / "state"
sessions = profile / "sessions"
for path, label in ((state, "state"), (sessions, "sessions")):
_require(path.is_dir() and not path.is_symlink(), f"profile {label} directory is missing or unsafe")
_require(not any(state.iterdir()), "profile state directory must remain empty")
session_files = list(sessions.iterdir())
if require_empty_sessions:
_require(not session_files, "profile sessions must start empty")
for path in session_files:
_require(path.is_file() and not path.is_symlink() and path.suffix == ".json", "unsafe session entry detected")
record = identity.load_json(path, "temporary session record")
_require(
set(record)
== {
"schema",
"authority",
"classification",
"query_sha256",
"answer_sha256",
"may_be_used_as_evidence",
},
"temporary session record fields are invalid",
)
_require(record.get("schema") == SESSION_RECORD_SCHEMA, "temporary session record schema is invalid")
_require(record.get("authority") == "none", "temporary session authority is invalid")
_require(record.get("classification") == "temporary_noncanonical", "temporary session class is invalid")
_require(record.get("may_be_used_as_evidence") is False, "temporary session cannot be evidence")
_require(identity._is_sha256(record.get("query_sha256")), "temporary session query hash is invalid")
_require(identity._is_sha256(record.get("answer_sha256")), "temporary session answer hash is invalid")
return {
"nonauthoritative_inputs_omitted": omitted,
"session_file_count": len(session_files),
"state_empty": True,
}
def compile_profile(
manifest: dict[str, Any],
*,
source_root: Path,
profile_template: Path,
profile: Path,
hermes_root: Path,
deployment_root: Path,
) -> dict[str, Any]:
views = identity.verify_bound_sources(manifest, source_root)
template_behavior = _behavior(profile_template, hermes_root, deployment_root)
identity.validate_behavior_manifest(template_behavior)
_require(
template_behavior["identity_runtime_sha256"]
== manifest["identity_inputs"]["runtime"]["identity_runtime_sha256"],
"profile template does not match the pinned identity runtime",
)
copied = _copy_static_profile(profile_template, profile)
try:
for name, content in views.items():
path = profile / name
path.write_text(content, encoding="utf-8")
path.chmod(0o600)
identity.write_json(profile / "identity-manifest.json", manifest)
(profile / "identity-manifest.json").chmod(0o600)
for directory in (profile / "sessions", profile / "state"):
directory.mkdir(mode=0o700)
lock = {
"schema": LOCK_SCHEMA,
"manifest_sha256": manifest["manifest_sha256"],
"identity_inputs_sha256": manifest["identity_inputs_sha256"],
"compiled_views": {name: {"sha256": _view_file_sha256(profile, name)} for name in sorted(views)},
"session_boundary": manifest["identity_inputs"]["session_boundary"],
}
identity.write_json(profile / "identity-lock.json", lock)
(profile / "identity-lock.json").chmod(0o600)
observed = _verify_runtime_binding(
manifest,
profile=profile,
hermes_root=hermes_root,
deployment_root=deployment_root,
)
for name, expected in manifest["compiled_views"].items():
_require(_view_file_sha256(profile, name) == expected["sha256"], f"compiled {name} hash mismatch")
soul_files = observed["components"]["runtime_identity"]["content"]["files"]
soul = next((item for item in soul_files if item.get("path") == "SOUL.md"), None)
_require(
isinstance(soul, dict) and soul.get("sha256") == manifest["compiled_views"]["SOUL.md"]["sha256"],
"SOUL runtime binding failed",
)
surface_readback = _verify_nonauthoritative_surfaces(
profile,
require_empty_sessions=True,
require_compile_receipt=False,
)
receipt = {
"schema": COMPILE_RECEIPT_SCHEMA,
"status": "pass",
"manifest_sha256": manifest["manifest_sha256"],
"identity_inputs_sha256": manifest["identity_inputs_sha256"],
"profile_static_entries": copied,
"compiled_view_sha256": {
name: manifest["compiled_views"][name]["sha256"] for name in sorted(manifest["compiled_views"])
},
"runtime_identity_sha256": observed["identity_runtime_sha256"],
"session_directories_started_empty": all(
not any((profile / name).iterdir()) for name in ("sessions", "state")
),
"nonauthoritative_inputs_omitted": surface_readback["nonauthoritative_inputs_omitted"],
"generated_views_are_authority": False,
}
identity.write_json(profile / "compile-receipt.json", receipt)
return receipt
except BaseException:
shutil.rmtree(profile, ignore_errors=True)
raise
def verify_profile(
profile: Path,
*,
source_root: Path,
hermes_root: Path,
deployment_root: Path,
) -> tuple[dict[str, Any], dict[str, str], dict[str, Any]]:
manifest = identity.load_json(profile / "identity-manifest.json", "compiled identity manifest")
views = identity.verify_bound_sources(manifest, source_root)
lock = identity.load_json(profile / "identity-lock.json", "identity profile lock")
_verify_nonauthoritative_surfaces(
profile,
require_empty_sessions=False,
require_compile_receipt=True,
)
_require(lock.get("schema") == LOCK_SCHEMA, "identity profile lock schema is invalid")
_require(
lock.get("manifest_sha256") == manifest["manifest_sha256"], "identity profile lock manifest drift detected"
)
_require(
lock.get("identity_inputs_sha256") == manifest["identity_inputs_sha256"],
"identity profile lock input drift detected",
)
compile_receipt = identity.load_json(profile / "compile-receipt.json", "identity compile receipt")
_require(
compile_receipt.get("manifest_sha256") == manifest["manifest_sha256"],
"identity compile receipt manifest drift detected",
)
_require(
compile_receipt.get("identity_inputs_sha256") == manifest["identity_inputs_sha256"],
"identity compile receipt input drift detected",
)
for name, expected_content in views.items():
expected_hash = behavior.sha256_bytes(expected_content.encode("utf-8"))
_require(expected_hash == manifest["compiled_views"][name]["sha256"], f"manifest view drift detected: {name}")
_require(_view_file_sha256(profile, name) == expected_hash, f"compiled view drift detected: {name}")
_require(
(lock.get("compiled_views") or {}).get(name, {}).get("sha256") == expected_hash,
f"profile lock view drift detected: {name}",
)
observed = _verify_runtime_binding(
manifest,
profile=profile,
hermes_root=hermes_root,
deployment_root=deployment_root,
)
return manifest, views, observed
def query_profile(
profile: Path,
*,
query: str,
source_root: Path,
hermes_root: Path,
deployment_root: Path,
) -> dict[str, Any]:
_require(query == FIXED_QUERY, "only the pinned identity readback query is allowed")
manifest, _views, observed = verify_profile(
profile,
source_root=source_root,
hermes_root=hermes_root,
deployment_root=deployment_root,
)
structured = identity.load_json(profile / "identity.json", "compiled structured identity view")
rule_count = len(structured["static_constitution"]["rules"])
record_count = len(structured["database_identity"]["records"])
fingerprint = structured["database_identity"]["database_fingerprint_sha256"]
canonical_authority = structured["database_identity"]["canonical_authority_granted"]
database_description = "canonical database" if canonical_authority else "synthetic noncanonical fixture"
answer = (
f"Leo is defined by {rule_count} pinned static constitutional rules and {record_count} active "
f"database-derived identity rows from a {database_description} at fingerprint {fingerprint}. "
"SOUL.md is a generated view; "
"runtime/session memory is temporary, noncanonical, and cannot be evidence."
)
query_sha256 = behavior.sha256_bytes(query.encode("utf-8"))
answer_sha256 = behavior.sha256_bytes(answer.encode("utf-8"))
instance_id = uuid.uuid4().hex
session_record = {
"schema": SESSION_RECORD_SCHEMA,
"authority": "none",
"classification": "temporary_noncanonical",
"query_sha256": query_sha256,
"answer_sha256": answer_sha256,
"may_be_used_as_evidence": False,
}
session_path = profile / "sessions" / f"{instance_id}.json"
identity.write_json(session_path, session_record)
receipt = {
"schema": QUERY_RECEIPT_SCHEMA,
"status": "pass",
"started_at_utc": datetime.now(UTC).isoformat(),
"process_id": os.getpid(),
"runtime_instance_id": instance_id,
"query": query,
"query_sha256": query_sha256,
"answer": answer,
"answer_sha256": answer_sha256,
"manifest_sha256": manifest["manifest_sha256"],
"identity_inputs_sha256": manifest["identity_inputs_sha256"],
"output_provenance": {
"static_constitution_sha256": manifest["identity_inputs"]["identity_sources"]["static_constitution"][
"semantic_sha256"
],
"database_identity_sha256": manifest["identity_inputs"]["identity_sources"]["database_derived_identity"][
"semantic_sha256"
],
"database_fingerprint_sha256": fingerprint,
"database_authority": structured["database_identity"]["authority"],
"database_canonical_authority_granted": canonical_authority,
"compiled_identity_sha256": manifest["compiled_views"]["identity.json"]["sha256"],
"compiled_soul_sha256": manifest["compiled_views"]["SOUL.md"]["sha256"],
"runtime_identity_sha256": observed["identity_runtime_sha256"],
"actual_model_call_performed": False,
},
"authorization": {
"declared_runtime_policy": manifest["identity_inputs"]["permissions"]["runtime_policy"],
"authorization_decision_observed": False,
"claim": "local_policy_binding_not_an_authorizer_readback",
},
"session": {
"record_sha256": behavior.file_sha256(session_path),
"classification": "temporary_noncanonical",
"included_in_output_provenance": False,
"may_be_used_as_evidence": False,
},
}
return receipt
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
subparsers = parser.add_subparsers(dest="command", required=True)
compile_command = subparsers.add_parser("compile")
compile_command.add_argument("--manifest", type=Path, required=True)
compile_command.add_argument("--source-root", type=Path, required=True)
compile_command.add_argument("--profile-template", type=Path, required=True)
compile_command.add_argument("--profile", type=Path, required=True)
compile_command.add_argument("--hermes-root", type=Path, required=True)
compile_command.add_argument("--deployment-root", type=Path, required=True)
query_command = subparsers.add_parser("query")
query_command.add_argument("--profile", type=Path, required=True)
query_command.add_argument("--query", default=FIXED_QUERY)
query_command.add_argument("--source-root", type=Path, required=True)
query_command.add_argument("--hermes-root", type=Path, required=True)
query_command.add_argument("--deployment-root", type=Path, required=True)
args = parser.parse_args()
try:
if args.command == "compile":
result = compile_profile(
identity.load_json(args.manifest, "identity manifest"),
source_root=args.source_root,
profile_template=args.profile_template,
profile=args.profile,
hermes_root=args.hermes_root,
deployment_root=args.deployment_root,
)
else:
result = query_profile(
args.profile,
query=args.query,
source_root=args.source_root,
hermes_root=args.hermes_root,
deployment_root=args.deployment_root,
)
print(json.dumps(result, sort_keys=True))
return 0
except identity.IdentityManifestError as exc:
print(json.dumps({"status": "error", "error": "identity_drift", "message": str(exc)}))
return 3
if __name__ == "__main__":
raise SystemExit(main())

View file

@ -34,7 +34,7 @@ DEFAULT_MODEL = "anthropic/claude-sonnet-4.5"
EXTRACTOR_VERSION = "2" EXTRACTOR_VERSION = "2"
DEFAULT_OPENROUTER_URL = "https://openrouter.ai/api/v1/chat/completions" DEFAULT_OPENROUTER_URL = "https://openrouter.ai/api/v1/chat/completions"
DEFAULT_KEY_FILE = Path("/opt/teleo-eval/secrets/openrouter-key") DEFAULT_KEY_FILE = Path("/opt/teleo-eval/secrets/openrouter-key")
TEXT_SUFFIXES = {".csv", ".htm", ".html", ".json", ".md", ".rst", ".txt", ".xml"} TEXT_SUFFIXES = {".csv", ".htm", ".html", ".json", ".jsonl", ".md", ".rst", ".txt", ".xml"}
MAX_SOURCE_CHARS = 120_000 MAX_SOURCE_CHARS = 120_000
MAX_CANDIDATES = 20 MAX_CANDIDATES = 20
MAX_CLAIMS = 3 MAX_CLAIMS = 3
@ -124,20 +124,37 @@ def _load_context(path: Path) -> dict[str, Any]:
return {"database_search_query": query.strip(), "candidate_claims": normalized} return {"database_search_query": query.strip(), "candidate_claims": normalized}
def build_source_fragments(text: str) -> dict[str, str]: def build_source_fragment_index(text: str) -> tuple[dict[str, str], dict[str, dict[str, Any]]]:
"""Label non-empty source lines so the model selects text instead of copying it.""" """Return selectable lines plus exact line/character provenance."""
fragments: dict[str, str] = {} fragments: dict[str, str] = {}
for line in text.splitlines(): locations: dict[str, dict[str, Any]] = {}
if line.strip(): offset = 0
fragments[f"S{len(fragments) + 1:05d}"] = line for line_number, raw_line in enumerate(text.splitlines(keepends=True), start=1):
line = raw_line.rstrip("\r\n")
quote = line.strip()
if quote:
reference = f"S{len(fragments) + 1:05d}"
start = offset + line.find(quote)
fragments[reference] = quote
locations[reference] = {
"reference": reference,
"line": line_number,
"char_start": start,
"char_end": start + len(quote),
"quote_sha256": sha256_bytes(quote.encode("utf-8")),
}
offset += len(raw_line)
if not fragments: if not fragments:
raise PreparationError("extracted text has no selectable source lines") raise PreparationError("extracted text has no selectable source lines")
return fragments return fragments, locations
def build_prompt( def build_source_fragments(text: str) -> dict[str, str]:
fragments: dict[str, str], context: dict[str, Any], repair_error: str | None = None """Label non-empty source lines so the model selects text instead of copying it."""
) -> str: return build_source_fragment_index(text)[0]
def build_prompt(fragments: dict[str, str], context: dict[str, Any], repair_error: str | None = None) -> str:
candidates = json.dumps(context["candidate_claims"], indent=2, ensure_ascii=True) candidates = json.dumps(context["candidate_claims"], indent=2, ensure_ascii=True)
source = "\n".join(f"[{reference}] {line}" for reference, line in fragments.items()) source = "\n".join(f"[{reference}] {line}" for reference, line in fragments.items())
repair = "" repair = ""
@ -273,9 +290,7 @@ def parse_model_output(content: str) -> dict[str, Any]:
if not isinstance(claim, dict): if not isinstance(claim, dict):
raise PreparationError(f"model extraction claims[{index}] must be an object") raise PreparationError(f"model extraction claims[{index}] must be an object")
if set(claim) != MODEL_CLAIM_KEYS: if set(claim) != MODEL_CLAIM_KEYS:
raise PreparationError( raise PreparationError(f"model extraction claims[{index}] keys must equal {sorted(MODEL_CLAIM_KEYS)}")
f"model extraction claims[{index}] keys must equal {sorted(MODEL_CLAIM_KEYS)}"
)
confidence = claim.get("confidence") confidence = claim.get("confidence")
if confidence is not None and ( if confidence is not None and (
isinstance(confidence, bool) or not isinstance(confidence, (int, float)) or not 0 <= confidence <= 0.75 isinstance(confidence, bool) or not isinstance(confidence, (int, float)) or not 0 <= confidence <= 0.75
@ -304,27 +319,47 @@ def _resolve_reference(reference: Any, fragments: dict[str, str], label: str) ->
return fragments[reference] return fragments[reference]
def resolve_model_output(selection: dict[str, Any], fragments: dict[str, str]) -> dict[str, Any]: def resolve_model_output(
selection: dict[str, Any],
fragments: dict[str, str],
fragment_locations: dict[str, dict[str, Any]] | None = None,
) -> dict[str, Any]:
def selected(kind: str, reference: str, **identity: Any) -> dict[str, Any]:
result = {"kind": kind, "reference": reference, **identity}
if fragment_locations is not None:
result.update(fragment_locations[reference])
return result
claims: list[dict[str, Any]] = [] claims: list[dict[str, Any]] = []
selected_references: list[dict[str, str]] = [] selected_references: list[dict[str, Any]] = []
for claim_index, claim in enumerate(selection["claims"]): for claim_index, claim in enumerate(selection["claims"]):
quote_ref = claim["quote_ref"] quote_ref = claim["quote_ref"]
quote = _resolve_reference(quote_ref, fragments, f"claims[{claim_index}].quote_ref") quote = _resolve_reference(quote_ref, fragments, f"claims[{claim_index}].quote_ref")
selected_references.append({"kind": "claim", "reference": quote_ref}) selected_references.append(selected("claim", quote_ref, claim_key=claim["claim_key"], quote=quote))
evidence: list[dict[str, str]] = [] evidence: list[dict[str, str]] = []
for evidence_index, row in enumerate(claim["evidence"]): for evidence_index, row in enumerate(claim["evidence"]):
evidence_ref = row["quote_ref"] evidence_ref = row["quote_ref"]
evidence_quote = _resolve_reference(
evidence_ref,
fragments,
f"claims[{claim_index}].evidence[{evidence_index}].quote_ref",
)
evidence.append( evidence.append(
{ {
"quote": _resolve_reference( "quote": evidence_quote,
evidence_ref,
fragments,
f"claims[{claim_index}].evidence[{evidence_index}].quote_ref",
),
"role": row["role"], "role": row["role"],
} }
) )
selected_references.append({"kind": "evidence", "reference": evidence_ref}) selected_references.append(
selected(
"evidence",
evidence_ref,
claim_key=claim["claim_key"],
evidence_index=evidence_index,
evidence_role=row["role"],
quote=evidence_quote,
)
)
claims.append( claims.append(
{ {
"claim_key": claim["claim_key"], "claim_key": claim["claim_key"],
@ -351,7 +386,14 @@ def resolve_model_output(selection: dict[str, Any], fragments: dict[str, str]) -
"reason": duplicate["reason"], "reason": duplicate["reason"],
} }
) )
selected_references.append({"kind": "duplicate", "reference": source_quote_ref}) selected_references.append(
selected(
"duplicate",
source_quote_ref,
claim_id=duplicate["claim_id"],
quote=duplicates[-1]["source_quote"],
)
)
return { return {
"schema": RESOLVED_OUTPUT_SCHEMA, "schema": RESOLVED_OUTPUT_SCHEMA,
@ -362,6 +404,37 @@ def resolve_model_output(selection: dict[str, Any], fragments: dict[str, str]) -
} }
def validate_bundle_source_locations(bundle: dict[str, Any], selected_references: list[dict[str, Any]]) -> None:
"""Ensure compiler quote offsets match the exact selected fragment occurrence."""
available = list(bundle.get("quote_bindings") or [])
for selected in selected_references:
if selected.get("kind") not in {"claim", "evidence"}:
continue
match_index = next(
(
index
for index, binding in enumerate(available)
if binding.get("kind") == selected.get("kind")
and binding.get("claim_key") == selected.get("claim_key")
and binding.get("quote") == selected.get("quote")
and (
selected.get("kind") != "evidence" or binding.get("evidence_role") == selected.get("evidence_role")
)
),
None,
)
if match_index is None:
raise PreparationError("compiler dropped a selected claim/evidence source binding")
binding = available.pop(match_index)
if binding.get("first_start") != selected.get("char_start") or binding.get("first_end") != selected.get(
"char_end"
):
raise PreparationError(
f"selected {selected['reference']} is an ambiguous repeated quote; "
"the current compiler cannot preserve that exact occurrence"
)
def build_manifest( def build_manifest(
*, *,
args: argparse.Namespace, args: argparse.Namespace,
@ -427,7 +500,7 @@ def prepare(args: argparse.Namespace) -> dict[str, Any]:
artifact_bytes = _read_nonempty(args.artifact, "artifact") artifact_bytes = _read_nonempty(args.artifact, "artifact")
text_bytes = extract_utf8_text(args.artifact, args.text) text_bytes = extract_utf8_text(args.artifact, args.text)
text = text_bytes.decode("utf-8", errors="strict") text = text_bytes.decode("utf-8", errors="strict")
fragments = build_source_fragments(text) fragments, fragment_locations = build_source_fragment_index(text)
context = _load_context(args.kb_context) context = _load_context(args.kb_context)
requested_output_dir = args.output_dir.expanduser() requested_output_dir = args.output_dir.expanduser()
@ -464,7 +537,7 @@ def prepare(args: argparse.Namespace) -> dict[str, Any]:
attempts.append({"attempt": attempt, "response_sha256": sha256_bytes(raw.encode("utf-8")), "usage": usage}) attempts.append({"attempt": attempt, "response_sha256": sha256_bytes(raw.encode("utf-8")), "usage": usage})
try: try:
selection = parse_model_output(raw) selection = parse_model_output(raw)
extraction = resolve_model_output(selection, fragments) extraction = resolve_model_output(selection, fragments, fragment_locations)
compiler._validate_dedupe( compiler._validate_dedupe(
{ {
"database_search_query": context["database_search_query"], "database_search_query": context["database_search_query"],
@ -494,6 +567,7 @@ def prepare(args: argparse.Namespace) -> dict[str, Any]:
with os.fdopen(fd, "wb") as handle: with os.fdopen(fd, "wb") as handle:
handle.write(_json_bytes(manifest)) handle.write(_json_bytes(manifest))
bundle = compiler.compile_source_packet(args.artifact, temp_text, temp_manifest) bundle = compiler.compile_source_packet(args.artifact, temp_text, temp_manifest)
validate_bundle_source_locations(bundle, extraction["selected_source_references"])
finally: finally:
if temp_text.exists(): if temp_text.exists():
temp_text.unlink() temp_text.unlink()
@ -518,6 +592,7 @@ def prepare(args: argparse.Namespace) -> dict[str, Any]:
raise PreparationError("prepared extraction has no manifest") raise PreparationError("prepared extraction has no manifest")
_write_private(manifest_path, _json_bytes(manifest)) _write_private(manifest_path, _json_bytes(manifest))
bundle = compiler.compile_source_packet(args.artifact, text_path, manifest_path) bundle = compiler.compile_source_packet(args.artifact, text_path, manifest_path)
validate_bundle_source_locations(bundle, extraction["selected_source_references"])
receipt = { receipt = {
"schema": RECEIPT_SCHEMA, "schema": RECEIPT_SCHEMA,
@ -545,10 +620,20 @@ def prepare(args: argparse.Namespace) -> dict[str, Any]:
"model": args.model, "model": args.model,
"attempts": attempts, "attempts": attempts,
"claim_count": len(extraction["claims"]), "claim_count": len(extraction["claims"]),
"evidence_count": sum(len(claim["evidence"]) for claim in extraction["claims"]),
"duplicate_judgment_count": len(extraction["duplicates"]),
"selectable_source_line_count": len(fragments), "selectable_source_line_count": len(fragments),
"selected_source_references": extraction["selected_source_references"], "selected_source_references": extraction["selected_source_references"],
"notes": extraction["extraction_notes"], "notes": extraction["extraction_notes"],
}, },
"replay": {
"artifact_sha256": artifact_sha256,
"extracted_text_sha256": text_sha256,
"kb_context_sha256": sha256_bytes(_json_bytes(context)),
"fragment_index_sha256": sha256_bytes(_json_bytes(fragment_locations)),
"extractor": {"name": f"openrouter:{args.model}", "version": EXTRACTOR_VERSION},
"exact_selected_locations_validated": bundle is not None,
},
"outputs": { "outputs": {
"output_dir": str(output_dir), "output_dir": str(output_dir),
"extracted_text": str(text_path), "extracted_text": str(text_path),

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -9,6 +9,8 @@ image="${POSTGRES_CANARY_IMAGE:-postgres:16}"
source_tier="${SOURCE_TIER:-live-readonly}" source_tier="${SOURCE_TIER:-live-readonly}"
normalization_json="" normalization_json=""
output="${repo_root}/docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.json" output="${repo_root}/docs/reports/leo-working-state-20260709/approve-claim-clone-canary-current.json"
lifecycle_receipt_output=""
rollback_sql_output=""
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case "$1" in case "$1" in
@ -20,6 +22,14 @@ while [[ $# -gt 0 ]]; do
output="$2" output="$2"
shift 2 shift 2
;; ;;
--lifecycle-receipt-output)
lifecycle_receipt_output="$2"
shift 2
;;
--rollback-sql-output)
rollback_sql_output="$2"
shift 2
;;
--source-container) --source-container)
source_container="$2" source_container="$2"
shift 2 shift 2
@ -99,11 +109,19 @@ service_state() {
} }
mkdir -p "$workdir" "$(dirname "$output")" mkdir -p "$workdir" "$(dirname "$output")"
if [[ -n "$lifecycle_receipt_output" ]]; then
mkdir -p "$(dirname "$lifecycle_receipt_output")"
fi
if [[ -n "$rollback_sql_output" ]]; then
mkdir -p "$(dirname "$rollback_sql_output")"
fi
source_counts_before="$(source_counts)" source_counts_before="$(source_counts)"
service_before="$(service_state)" service_before="$(service_state)"
docker run -d --name "$container" \ docker run -d --name "$container" \
--network none \ --network none \
--label livingip.canary=proposal-apply-lifecycle \
--label "livingip.canary.instance=${container}" \
--tmpfs /var/lib/postgresql/data:rw,nosuid,size=512m \ --tmpfs /var/lib/postgresql/data:rw,nosuid,size=512m \
-e POSTGRES_PASSWORD="isolated-postgres-${RANDOM}-${RANDOM}" \ -e POSTGRES_PASSWORD="isolated-postgres-${RANDOM}-${RANDOM}" \
-e POSTGRES_DB=teleo \ -e POSTGRES_DB=teleo \
@ -127,6 +145,12 @@ if [[ "$ready_streak" -lt 2 ]]; then
fi fi
container_network_mode="$(docker inspect -f '{{.HostConfig.NetworkMode}}' "$container")" container_network_mode="$(docker inspect -f '{{.HostConfig.NetworkMode}}' "$container")"
container_mounts_json="$(docker inspect -f '{{json .Mounts}}' "$container")" container_mounts_json="$(docker inspect -f '{{json .Mounts}}' "$container")"
container_canary_label="$(
docker inspect -f '{{index .Config.Labels "livingip.canary"}}' "$container"
)"
container_instance_label="$(
docker inspect -f '{{index .Config.Labels "livingip.canary.instance"}}' "$container"
)"
docker exec "$source_container" pg_dump -U postgres -d "$source_db" \ docker exec "$source_container" pg_dump -U postgres -d "$source_db" \
--schema-only --no-owner --no-privileges >"$workdir/schema.sql" --schema-only --no-owner --no-privileges >"$workdir/schema.sql"
@ -165,6 +189,13 @@ normalization_args=()
if [[ -n "$normalization_json" ]]; then if [[ -n "$normalization_json" ]]; then
normalization_args=(--normalization-json "$normalization_json") normalization_args=(--normalization-json "$normalization_json")
fi fi
artifact_args=()
if [[ -n "$lifecycle_receipt_output" ]]; then
artifact_args+=(--lifecycle-receipt-output "$lifecycle_receipt_output")
fi
if [[ -n "$rollback_sql_output" ]]; then
artifact_args+=(--rollback-sql-output "$rollback_sql_output")
fi
set +e set +e
python3 "$repo_root/scripts/run_approve_claim_clone_canary.py" \ python3 "$repo_root/scripts/run_approve_claim_clone_canary.py" \
@ -178,6 +209,7 @@ python3 "$repo_root/scripts/run_approve_claim_clone_canary.py" \
--review-secrets-file "$workdir/kb-review.env" \ --review-secrets-file "$workdir/kb-review.env" \
--secrets-file "$workdir/kb-apply.env" \ --secrets-file "$workdir/kb-apply.env" \
"${normalization_args[@]}" \ "${normalization_args[@]}" \
"${artifact_args[@]}" \
--output "$output" \ --output "$output" \
>"$workdir/stdout.json" 2>"$workdir/stderr.log" >"$workdir/stdout.json" 2>"$workdir/stderr.log"
canary_rc=$? canary_rc=$?
@ -192,6 +224,20 @@ container_name_readback="$(
docker container ls -a --filter "name=^/${container}$" --format '{{.Names}}' 2>&1 docker container ls -a --filter "name=^/${container}$" --format '{{.Names}}' 2>&1
)" )"
container_name_readback_rc=$? container_name_readback_rc=$?
container_label_readback="$(
docker container ls -a \
--filter "label=livingip.canary=proposal-apply-lifecycle" \
--filter "label=livingip.canary.instance=${container}" \
--format '{{.Names}}' 2>&1
)"
container_label_readback_rc=$?
if [[ "$container_label_readback_rc" -eq 0 ]]; then
container_label_orphan_count="$(
awk 'NF { count += 1 } END { print count + 0 }' <<<"$container_label_readback"
)"
else
container_label_orphan_count=-1
fi
if [[ -e "$workdir" || -L "$workdir" ]]; then if [[ -e "$workdir" || -L "$workdir" ]]; then
outer_workdir_lexists=true outer_workdir_lexists=true
else else
@ -214,6 +260,9 @@ OUTER_CONTAINER_REMOVE_RC="$outer_container_remove_rc" \
OUTER_WORKDIR_REMOVE_RC="$outer_workdir_remove_rc" \ OUTER_WORKDIR_REMOVE_RC="$outer_workdir_remove_rc" \
CONTAINER_NAME_READBACK="$container_name_readback" \ CONTAINER_NAME_READBACK="$container_name_readback" \
CONTAINER_NAME_READBACK_RC="$container_name_readback_rc" \ CONTAINER_NAME_READBACK_RC="$container_name_readback_rc" \
CONTAINER_LABEL_READBACK="$container_label_readback" \
CONTAINER_LABEL_READBACK_RC="$container_label_readback_rc" \
CONTAINER_LABEL_ORPHAN_COUNT="$container_label_orphan_count" \
OUTER_WORKDIR_LEXISTS="$outer_workdir_lexists" \ OUTER_WORKDIR_LEXISTS="$outer_workdir_lexists" \
CANARY_RC="$canary_rc" \ CANARY_RC="$canary_rc" \
SOURCE_TIER="$source_tier" \ SOURCE_TIER="$source_tier" \
@ -221,219 +270,6 @@ SOURCE_NETWORK_MODE="$source_network_mode" \
SOURCE_CANARY_LABEL="$source_canary_label" \ SOURCE_CANARY_LABEL="$source_canary_label" \
CANARY_NETWORK_MODE="$container_network_mode" \ CANARY_NETWORK_MODE="$container_network_mode" \
CANARY_MOUNTS_JSON="$container_mounts_json" \ CANARY_MOUNTS_JSON="$container_mounts_json" \
python3 - "$output" <<'PY' CANARY_LABEL="$container_canary_label" \
import hashlib CANARY_INSTANCE_LABEL="$container_instance_label" \
import json python3 "$repo_root/scripts/finalize_approve_claim_isolated_canary.py" "$output"
import os
import sys
from pathlib import Path
path = Path(sys.argv[1])
if not path.is_file():
raise SystemExit("inner canary did not produce a report")
data = json.loads(path.read_text(encoding="utf-8"))
def service(raw: str) -> dict[str, str]:
return dict(line.split("=", 1) for line in raw.splitlines() if "=" in line)
def table_deltas(before: dict[str, int], after: dict[str, int]) -> dict[str, int]:
if set(before) != set(after):
raise SystemExit(
"live source count keys changed during the canary: "
f"before={sorted(before)} after={sorted(after)}"
)
return {key: after[key] - before[key] for key in sorted(before)}
def verify_source_binding(root: Path, records: list[dict[str, object]]) -> dict[str, object]:
readbacks = []
for record in records:
relative_text = str(record.get("repo_relative_path", ""))
relative = Path(relative_text)
if not relative_text or relative.is_absolute() or ".." in relative.parts:
raise SystemExit(f"unsafe repo-relative source path: {relative_text!r}")
candidate = (root / relative).resolve()
try:
candidate.relative_to(root)
except ValueError as exc:
raise SystemExit(
f"source path escaped repository root: {relative_text}"
) from exc
if not candidate.is_file():
readbacks.append(
{
"repo_relative_path": relative.as_posix(),
"expected_sha256": record.get("sha256"),
"actual_sha256": None,
"matches": False,
}
)
continue
content = candidate.read_bytes()
actual_sha256 = hashlib.sha256(content).hexdigest()
readbacks.append(
{
"repo_relative_path": relative.as_posix(),
"expected_sha256": record.get("sha256"),
"actual_sha256": actual_sha256,
"size_bytes": len(content),
"matches": (
actual_sha256 == record.get("sha256")
and len(content) == record.get("size_bytes")
),
}
)
return {
"files": readbacks,
"all_match": bool(readbacks) and all(row["matches"] for row in readbacks),
}
def contains_ephemeral_path(value: object) -> bool:
if isinstance(value, str):
return "/tmp/" in value
if isinstance(value, dict):
return any(contains_ephemeral_path(item) for item in value.values())
if isinstance(value, list):
return any(contains_ephemeral_path(item) for item in value)
return False
before_counts = json.loads(os.environ["SOURCE_COUNTS_BEFORE"])
after_counts = json.loads(os.environ["SOURCE_COUNTS_AFTER"])
live_table_deltas = table_deltas(before_counts, after_counts)
before_service = service(os.environ["SERVICE_BEFORE"])
after_service = service(os.environ["SERVICE_AFTER"])
source_tier = os.environ["SOURCE_TIER"]
source_network_mode = os.environ["SOURCE_NETWORK_MODE"]
source_canary_label = os.environ["SOURCE_CANARY_LABEL"]
container_network_mode = os.environ["CANARY_NETWORK_MODE"]
container_mounts = json.loads(os.environ["CANARY_MOUNTS_JSON"])
container_volume_mounts = [
mount for mount in container_mounts if mount.get("Type") == "volume"
]
container_isolated = (
container_network_mode == "none" and not container_volume_mounts
)
source_tier_enforced = (
source_tier != "isolated-local"
or (
source_network_mode == "none"
and source_canary_label == "working-leo-approved-source"
)
)
service_observable = (
before_service.get("Available") == "true"
and after_service.get("Available") == "true"
)
service_stable = (
all(
before_service.get(key) == after_service.get(key)
for key in ("ActiveState", "SubState", "MainPID", "NRestarts")
)
if service_observable
else None
)
service_gate_passes = (
service_stable is True
if source_tier == "live-readonly"
else service_stable is not False
)
container_absent = (
int(os.environ["CONTAINER_NAME_READBACK_RC"]) == 0
and not os.environ["CONTAINER_NAME_READBACK"].strip()
)
workdir_absent = os.environ["OUTER_WORKDIR_LEXISTS"] == "false"
source_binding = verify_source_binding(
Path(os.environ["REPO_ROOT"]).resolve(),
data.get("source_binding", {}).get("files", []),
)
data["source_binding"]["independent_post_cleanup_verification"] = source_binding
source_binding_ok = (
data["source_binding"].get("unchanged_during_run") is True
and source_binding["all_match"] is True
)
stale_ephemeral_paths_absent = not contains_ephemeral_path(data)
inner_runtime_pass = data.get("status") == "pass" and int(os.environ["CANARY_RC"]) == 0
outer_ok = (
before_counts == after_counts
and all(delta == 0 for delta in live_table_deltas.values())
and service_gate_passes
and container_absent
and workdir_absent
and source_binding_ok
and stale_ephemeral_paths_absent
and container_isolated
and source_tier_enforced
)
if source_tier == "isolated-local":
data["required_tier"] = "T2_runtime"
data["required_tiers"] = ["T2_runtime"]
data["runtime_scope"] = "isolated_postgres_container_from_readonly_local_fixture"
else:
data["required_tier"] = "T3_live_readonly"
data["required_tiers"] = ["T2_runtime", "T3_live_readonly"]
data["runtime_scope"] = "isolated_postgres_container_from_readonly_live_schema"
data["outer_isolation"] = {
"source_container": os.environ.get("SOURCE_CONTAINER", "teleo-pg"),
"source_database": os.environ.get("SOURCE_DB", "teleo"),
"source_counts_before": before_counts,
"source_counts_after": after_counts,
"canonical_table_deltas": live_table_deltas,
"source_counts_unchanged": before_counts == after_counts,
"service_before": before_service,
"service_after": after_service,
"service_required": source_tier == "live-readonly",
"service_observable": service_observable,
"service_stable": service_stable,
"service_gate_passes": service_gate_passes,
"source_boundary": {
"source_tier": source_tier,
"network_mode": source_network_mode,
"canary_label": source_canary_label,
"tier_enforced": source_tier_enforced,
},
"container_isolation": {
"network_mode": container_network_mode,
"volume_mounts": container_volume_mounts,
"network_disabled": container_network_mode == "none",
"no_docker_volumes": not container_volume_mounts,
},
"cleanup_readback": {
"container_remove_returncode": int(os.environ["OUTER_CONTAINER_REMOVE_RC"]),
"container_name_query_returncode": int(
os.environ["CONTAINER_NAME_READBACK_RC"]
),
"container_name_query_stdout": os.environ["CONTAINER_NAME_READBACK"],
"temporary_container_absent": container_absent,
"workdir_remove_returncode": int(os.environ["OUTER_WORKDIR_REMOVE_RC"]),
"workdir_lexists_after_cleanup": not workdir_absent,
"temporary_workdir_absent": workdir_absent,
},
}
data["checks"]["outer_live_counts_exactly_unchanged"] = before_counts == after_counts
data["checks"]["outer_live_table_deltas_exactly_zero"] = all(
delta == 0 for delta in live_table_deltas.values()
)
data["checks"]["outer_service_observed_if_required"] = (
source_tier != "live-readonly" or service_observable
)
data["checks"]["outer_service_stable_if_observed"] = service_gate_passes
data["checks"]["outer_container_absent_independent_readback"] = container_absent
data["checks"]["outer_workdir_absent_independent_readback"] = workdir_absent
data["checks"]["source_binding_independently_verified"] = source_binding_ok
data["checks"]["stale_ephemeral_paths_absent"] = stale_ephemeral_paths_absent
data["checks"]["outer_source_tier_enforced"] = source_tier_enforced
data["checks"]["outer_container_network_disabled"] = (
container_network_mode == "none"
)
data["checks"]["outer_container_has_no_docker_volumes"] = not container_volume_mounts
data["checks"]["outer_isolation_complete"] = outer_ok
if outer_ok and inner_runtime_pass:
data["current_tier"] = (
"T2_runtime" if source_tier == "isolated-local" else "T3_live_readonly"
)
else:
data["status"] = "fail"
data["current_tier"] = "T2_runtime" if inner_runtime_pass else "T1_model"
path.write_text(json.dumps(data, indent=2, sort_keys=True) + "\n", encoding="utf-8")
raise SystemExit(0 if data["status"] == "pass" else 1)
PY

View file

@ -0,0 +1,517 @@
#!/usr/bin/env python3
"""Prove manifest-driven Leo identity reconstruction across a cold restart."""
from __future__ import annotations
import argparse
import json
import os
import shutil
import signal
import subprocess
import sys
import tempfile
import time
from datetime import UTC, datetime
from pathlib import Path, PurePosixPath, PureWindowsPath
from typing import Any
if __package__ in {None, ""}:
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from scripts import leo_behavior_manifest as behavior
from scripts import leo_identity_manifest as identity
from scripts import leo_identity_profile as profile_runtime
SCHEMA = "livingip.leoIdentityReconstructionReceipt.v1"
PRIVATE_PATH_PREFIXES = tuple("/" + value for value in ("Users/", "private/tmp/", "var/folders/"))
class CanaryError(RuntimeError):
"""The disposable identity runtime did not satisfy its T2 contract."""
def _require(condition: bool, message: str) -> None:
if not condition:
raise CanaryError(message)
def _receipt_strings(value: object) -> list[str]:
if isinstance(value, dict):
keys = [key for key in value if isinstance(key, str)]
return keys + [text for item in value.values() for text in _receipt_strings(item)]
if isinstance(value, list):
return [text for item in value for text in _receipt_strings(item)]
return [value] if isinstance(value, str) else []
def _validate_portable_receipt(value: object) -> None:
for text in _receipt_strings(value):
if (
any(prefix in text for prefix in PRIVATE_PATH_PREFIXES)
or PurePosixPath(text).is_absolute()
or PureWindowsPath(text).is_absolute()
):
raise CanaryError("receipt contains a private or absolute filesystem path")
def _process_group_absent(process_group: int) -> bool:
try:
os.killpg(process_group, 0)
except ProcessLookupError:
return True
except PermissionError:
return False
return False
def _wait_for_process_group_absence(process_group: int, timeout_seconds: float = 5) -> bool:
deadline = time.monotonic() + timeout_seconds
while time.monotonic() < deadline:
if _process_group_absent(process_group):
return True
time.sleep(0.02)
return _process_group_absent(process_group)
def _signal_process_group(process_group: int, signal_number: signal.Signals) -> bool:
try:
os.killpg(process_group, signal_number)
return True
except (ProcessLookupError, PermissionError):
return False
def _cleanup_remaining_process_group(process_group: int) -> str | None:
if not _signal_process_group(process_group, signal.SIGTERM):
return None
if _wait_for_process_group_absence(process_group, timeout_seconds=1):
return "SIGTERM"
if not _signal_process_group(process_group, signal.SIGKILL):
return "SIGTERM"
return "SIGKILL"
def _logical_repo_path(path: Path, *, deployment_root: Path, placeholder: str) -> str:
"""Return a stable repo-relative path or a non-identifying placeholder."""
try:
relative = path.resolve().relative_to(deployment_root.resolve())
except (OSError, ValueError):
return placeholder
value = relative.as_posix()
return value if value != "." else "."
def _logical_query_command(
*,
deployment_root: Path,
source_root: Path,
hermes_root: Path,
) -> list[str]:
return [
"<python>",
"-m",
"scripts.leo_identity_profile",
"query",
"--profile",
"<temporary-profile>",
"--source-root",
_logical_repo_path(source_root, deployment_root=deployment_root, placeholder="<source-root>"),
"--hermes-root",
_logical_repo_path(hermes_root, deployment_root=deployment_root, placeholder="<hermes-root>"),
"--deployment-root",
".",
"--query",
profile_runtime.FIXED_QUERY,
]
def _run_query_child(
*,
deployment_root: Path,
profile: Path,
source_root: Path,
hermes_root: Path,
profile_role: str,
timeout_seconds: float = 60,
) -> dict[str, Any]:
deployment_root = deployment_root.resolve()
profile = profile.resolve()
source_root = source_root.resolve()
hermes_root = hermes_root.resolve()
actual_argv = [
sys.executable,
"-m",
"scripts.leo_identity_profile",
"query",
"--profile",
str(profile),
"--source-root",
str(source_root),
"--hermes-root",
str(hermes_root),
"--deployment-root",
str(deployment_root),
"--query",
profile_runtime.FIXED_QUERY,
]
process = subprocess.Popen(
actual_argv,
cwd=deployment_root,
env={**os.environ, "PYTHONDONTWRITEBYTECODE": "1"},
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
start_new_session=True,
)
timed_out = False
terminated_with: str | None = None
stdout = ""
stderr = ""
process_group_absent_after_wait = False
orphan_cleanup_required = False
try:
try:
stdout, stderr = process.communicate(timeout=timeout_seconds)
except subprocess.TimeoutExpired:
timed_out = True
if _signal_process_group(process.pid, signal.SIGTERM):
terminated_with = "SIGTERM"
try:
stdout, stderr = process.communicate(timeout=5)
except subprocess.TimeoutExpired:
if _signal_process_group(process.pid, signal.SIGKILL):
terminated_with = "SIGKILL"
stdout, stderr = process.communicate(timeout=5)
finally:
if process.poll() is None:
if _signal_process_group(process.pid, signal.SIGTERM):
terminated_with = terminated_with or "SIGTERM"
try:
process.communicate(timeout=5)
except subprocess.TimeoutExpired:
if _signal_process_group(process.pid, signal.SIGKILL):
terminated_with = "SIGKILL"
process.communicate(timeout=5)
orphan_cleanup_required = not _process_group_absent(process.pid)
if orphan_cleanup_required:
terminated_with = _cleanup_remaining_process_group(process.pid) or terminated_with
process_group_absent_after_wait = _wait_for_process_group_absence(process.pid)
try:
payload = json.loads(stdout.strip().splitlines()[-1]) if stdout.strip() else {}
except json.JSONDecodeError as exc:
raise CanaryError("identity child returned invalid JSON") from exc
return {
"logical_command": _logical_query_command(
deployment_root=deployment_root,
source_root=source_root,
hermes_root=hermes_root,
),
"command_serialization": "logical_redacted_v1",
"profile_role": profile_role,
"actual_argv_persisted": False,
"launcher_pid": process.pid,
"returncode": process.returncode,
"timed_out": timed_out,
"terminated_with": terminated_with,
"orphan_cleanup_required": orphan_cleanup_required,
"stdout": payload,
"stderr_sha256": behavior.sha256_bytes(stderr.encode("utf-8")),
"process_group_absent_after_wait": process_group_absent_after_wait,
}
def _query_passed(child: dict[str, Any]) -> bool:
payload = child.get("stdout") or {}
return bool(
child.get("returncode") == 0
and child.get("timed_out") is False
and child.get("orphan_cleanup_required") is False
and child.get("process_group_absent_after_wait") is True
and payload.get("schema") == profile_runtime.QUERY_RECEIPT_SCHEMA
and payload.get("status") == "pass"
)
def _drift_attempt(
*,
deployment_root: Path,
source_root: Path,
hermes_root: Path,
drift_profile: Path,
) -> dict[str, Any]:
with (drift_profile / "SOUL.md").open("a", encoding="utf-8") as handle:
handle.write("\nInjected drift must fail closed.\n")
child = _run_query_child(
deployment_root=deployment_root,
profile=drift_profile,
source_root=source_root,
hermes_root=hermes_root,
profile_role="drift_negative",
)
child["fail_closed"] = bool(
child["returncode"] == 3
and child["timed_out"] is False
and child["orphan_cleanup_required"] is False
and child["process_group_absent_after_wait"] is True
and (child.get("stdout") or {}).get("error") == "identity_drift"
and "compiled view drift detected" in str((child.get("stdout") or {}).get("message"))
)
child["answer_returned"] = bool((child.get("stdout") or {}).get("answer"))
return child
def run_canary(args: argparse.Namespace) -> tuple[dict[str, Any], int]:
output = args.output.resolve()
temporary_root = Path(tempfile.mkdtemp(prefix="leo-identity-reconstruction-"))
report: dict[str, Any] = {
"schema": SCHEMA,
"generated_at_utc": datetime.now(UTC).isoformat(),
"required_tier": "T2_runtime",
"mode": "drift_before_restart"
if args.inject_drift_before_restart
else "successful_restart_plus_drift_negative",
"fixed_query": profile_runtime.FIXED_QUERY,
"fixed_query_sha256": behavior.sha256_bytes(profile_runtime.FIXED_QUERY.encode("utf-8")),
"production_profile_replaced": False,
"production_database_contacted": False,
"telegram_message_sent": False,
"actual_hosted_model_call_performed": False,
"errors": [],
}
exit_code = 1
try:
behavior_manifest = behavior.build_manifest(args.profile_template, args.hermes_root, args.deployment_root)
identity.validate_behavior_manifest(behavior_manifest)
manifest = identity.build_identity_manifest(
behavior_manifest=behavior_manifest,
database_fingerprint_path=args.database_fingerprint,
constitution_path=args.constitution,
database_identity_path=args.database_identity,
source_root=args.source_root,
)
report["manifest"] = manifest
report["behavior_observation_before_compile"] = {
"behavior_sha256": behavior_manifest["behavior_sha256"],
"identity_runtime_sha256": behavior_manifest["identity_runtime_sha256"],
"source_commit": behavior_manifest["teleo_infrastructure_runtime"]["git_head"],
}
compiled_profile = temporary_root / "first-profile"
report["compile"] = profile_runtime.compile_profile(
manifest,
source_root=args.source_root,
profile_template=args.profile_template,
profile=compiled_profile,
hermes_root=args.hermes_root,
deployment_root=args.deployment_root,
)
compiled_behavior_before_query = behavior.build_manifest(
compiled_profile, args.hermes_root, args.deployment_root
)
report["compiled_profile_before_query"] = {
"behavior_sha256": compiled_behavior_before_query["behavior_sha256"],
"identity_runtime_sha256": compiled_behavior_before_query["identity_runtime_sha256"],
}
first = _run_query_child(
deployment_root=args.deployment_root,
profile=compiled_profile,
source_root=args.source_root,
hermes_root=args.hermes_root,
profile_role="first_start",
)
report["first_start"] = first
_require(_query_passed(first), "first disposable identity process did not answer successfully")
after_first = behavior.build_manifest(compiled_profile, args.hermes_root, args.deployment_root)
report["session_boundary_readback"] = {
"full_behavior_changed_after_session": after_first["behavior_sha256"]
!= compiled_behavior_before_query["behavior_sha256"],
"identity_runtime_unchanged_after_session": after_first["identity_runtime_sha256"]
== compiled_behavior_before_query["identity_runtime_sha256"],
"session_file_count": len(list((compiled_profile / "sessions").glob("*.json"))),
"session_classification": "temporary_noncanonical",
"session_used_as_output_provenance": False,
}
if args.inject_drift_before_restart:
with (compiled_profile / "SOUL.md").open("a", encoding="utf-8") as handle:
handle.write("\nInjected pre-restart drift.\n")
rejected = _run_query_child(
deployment_root=args.deployment_root,
profile=compiled_profile,
source_root=args.source_root,
hermes_root=args.hermes_root,
profile_role="pre_restart_drift",
)
report["pre_restart_drift"] = rejected
report["drift_target"] = "compiled SOUL.md generated view"
report["second_start_attempted"] = False
report["gates"] = {
"first_start_passed": True,
"first_process_stopped": first["process_group_absent_after_wait"],
"drift_detected_before_restart": rejected["returncode"] == 3
and (rejected.get("stdout") or {}).get("error") == "identity_drift",
"drift_returned_no_answer": not bool((rejected.get("stdout") or {}).get("answer")),
"drift_process_stopped": rejected["process_group_absent_after_wait"],
"drift_process_had_no_orphan_cleanup": rejected["orphan_cleanup_required"] is False,
"second_start_not_attempted": True,
}
report["status"] = "pass" if all(report["gates"].values()) else "fail"
else:
profile_runtime.verify_profile(
compiled_profile,
source_root=args.source_root,
hermes_root=args.hermes_root,
deployment_root=args.deployment_root,
)
report["pre_restart_verification"] = "pass"
report["second_start_attempted"] = True
restarted_profile = temporary_root / "restart-profile"
report["restart_compile"] = profile_runtime.compile_profile(
manifest,
source_root=args.source_root,
profile_template=args.profile_template,
profile=restarted_profile,
hermes_root=args.hermes_root,
deployment_root=args.deployment_root,
)
profile_runtime.verify_profile(
restarted_profile,
source_root=args.source_root,
hermes_root=args.hermes_root,
deployment_root=args.deployment_root,
)
second = _run_query_child(
deployment_root=args.deployment_root,
profile=restarted_profile,
source_root=args.source_root,
hermes_root=args.hermes_root,
profile_role="restart",
)
report["restart"] = second
_require(_query_passed(second), "restarted disposable identity process did not answer successfully")
first_payload = first["stdout"]
second_payload = second["stdout"]
drift_profile = temporary_root / "drift-profile"
report["drift_compile"] = profile_runtime.compile_profile(
manifest,
source_root=args.source_root,
profile_template=args.profile_template,
profile=drift_profile,
hermes_root=args.hermes_root,
deployment_root=args.deployment_root,
)
drift = _drift_attempt(
deployment_root=args.deployment_root,
source_root=args.source_root,
hermes_root=args.hermes_root,
drift_profile=drift_profile,
)
report["drift_negative"] = drift
report["drift_target"] = "compiled SOUL.md generated view"
report["gates"] = {
"manifest_generated": identity._is_sha256(manifest["manifest_sha256"]),
"views_compiled_and_bound": report["compile"]["status"] == "pass",
"first_start_passed": True,
"first_process_stopped": first["process_group_absent_after_wait"],
"pre_restart_verification_passed": True,
"restart_profile_recompiled_from_manifest": report["restart_compile"]["status"] == "pass",
"restart_profile_started_without_sessions": report["restart_compile"][
"session_directories_started_empty"
],
"restart_passed": True,
"restart_process_is_distinct": first_payload["process_id"] != second_payload["process_id"]
and first_payload["runtime_instance_id"] != second_payload["runtime_instance_id"],
"identity_inputs_reproduced": first_payload["identity_inputs_sha256"]
== second_payload["identity_inputs_sha256"],
"manifest_reproduced": first_payload["manifest_sha256"] == second_payload["manifest_sha256"],
"query_reproduced": first_payload["query_sha256"] == second_payload["query_sha256"],
"answer_and_provenance_explainable": first_payload["answer_sha256"] == second_payload["answer_sha256"]
and first_payload["output_provenance"] == second_payload["output_provenance"],
"session_excluded_from_identity": report["session_boundary_readback"][
"identity_runtime_unchanged_after_session"
],
"drift_failed_closed": drift["fail_closed"] and not drift["answer_returned"],
"drift_profile_started_without_sessions": report["drift_compile"]["session_directories_started_empty"],
"drift_process_stopped": drift["process_group_absent_after_wait"],
"drift_process_had_no_orphan_cleanup": drift["orphan_cleanup_required"] is False,
"restart_process_stopped": second["process_group_absent_after_wait"],
}
report["status"] = "pass" if all(report["gates"].values()) else "fail"
if report["status"] == "pass":
exit_code = 0
except (CanaryError, identity.IdentityManifestError, OSError, subprocess.SubprocessError) as exc:
report["status"] = "fail"
report["errors"].append(
{
"type": type(exc).__name__,
"message": "details_redacted",
"detail_sha256": behavior.sha256_bytes(str(exc).encode("utf-8")),
}
)
finally:
shutil.rmtree(temporary_root, ignore_errors=True)
report["cleanup"] = {
"temporary_root_removed": not temporary_root.exists(),
"no_profile_retained": not temporary_root.exists(),
}
if not all(report["cleanup"].values()):
report["status"] = "fail"
exit_code = 1
positive_restart_passed = report.get("status") == "pass" and not args.inject_drift_before_restart
report["current_tier"] = "T2_runtime" if positive_restart_passed else "T1_model"
report["goal_tier_satisfied"] = positive_restart_passed
report["runtime_component_proven"] = (
"fresh_profile_recompile_plus_distinct_process_restart"
if positive_restart_passed
else "first_local_process_plus_pre_restart_drift_refusal"
)
report["runtime_variant"] = "local_deterministic_identity_compiler_readback"
report["tier_basis"] = (
"Capability Tier Proof defines T2_runtime as local API/runtime behavior with restart where relevant; "
"this is compiler-process runtime proof and explicitly excludes GatewayRunner and hosted-model proof."
if positive_restart_passed
else "This negative component does not complete the required restart path, so it remains below T2_runtime."
)
report["claim_ceiling"] = (
"Local disposable identity compilation, fresh-profile reconstruction, and cold-process restart only; "
"not a live GatewayRunner, hosted-model, Telegram, production database, VPS restart, or T3 proof."
if positive_restart_passed
else "Local first-process and pre-restart drift-refusal component only; no successful restart proof, "
"GatewayRunner, hosted model, production database, VPS, or T3 claim."
)
_validate_portable_receipt(report)
stable = {key: value for key, value in report.items() if key != "receipt_sha256"}
report["receipt_sha256"] = behavior.canonical_sha256(stable)
identity.write_json(output, report)
return report, exit_code
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--profile-template", type=Path, required=True)
parser.add_argument("--hermes-root", type=Path, required=True)
parser.add_argument("--deployment-root", type=Path, required=True)
parser.add_argument("--source-root", type=Path, required=True)
parser.add_argument("--database-fingerprint", type=Path, required=True)
parser.add_argument("--constitution", type=Path, required=True)
parser.add_argument("--database-identity", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--inject-drift-before-restart", action="store_true")
args = parser.parse_args()
report, exit_code = run_canary(args)
print(
json.dumps(
{
"status": report.get("status"),
"current_tier": report.get("current_tier"),
"receipt_sha256": report.get("receipt_sha256"),
"output": str(args.output),
},
sort_keys=True,
)
)
return exit_code
if __name__ == "__main__":
raise SystemExit(main())

File diff suppressed because it is too large Load diff

View file

@ -57,6 +57,12 @@ def prepare_normalized_child(parent: dict[str, Any]) -> dict[str, Any]:
manifest = apply_payload.setdefault("normalization_manifest", {}) manifest = apply_payload.setdefault("normalization_manifest", {})
if not isinstance(manifest, dict): if not isinstance(manifest, dict):
raise bound.CheckpointError("normalized child normalization_manifest must be an object") raise bound.CheckpointError("normalized child normalization_manifest must be an object")
parent_payload = parent.get("payload")
ingestion_manifest = parent_payload.get("ingestion_manifest") if isinstance(parent_payload, dict) else None
if ingestion_manifest is not None:
if not isinstance(ingestion_manifest, dict):
raise bound.CheckpointError("parent payload.ingestion_manifest must be an object")
manifest["ingestion_manifest"] = json.loads(json.dumps(ingestion_manifest, sort_keys=True))
parent_packet_sha256 = canonical_sha256(parent) parent_packet_sha256 = canonical_sha256(parent)
manifest["parent_packet_sha256"] = parent_packet_sha256 manifest["parent_packet_sha256"] = parent_packet_sha256
child_payload_sha256 = canonical_sha256(payload) child_payload_sha256 = canonical_sha256(payload)

File diff suppressed because it is too large Load diff

View file

@ -30,6 +30,10 @@ sys.path.insert(0, str(REPO_ROOT / "scripts"))
import apply_proposal as ap # noqa: E402 import apply_proposal as ap # noqa: E402
CLAIM_A = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"
CLAIM_B = "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"
SOURCE_A = "cccccccc-cccc-4ccc-8ccc-cccccccccccc"
def _approval_meta(proposal_type, apply_payload): def _approval_meta(proposal_type, apply_payload):
return { return {
@ -112,7 +116,7 @@ def test_revise_strategy_rejects_bad_node_type():
# --- add_edge ------------------------------------------------------------- # # --- add_edge ------------------------------------------------------------- #
def test_add_edge_sql_dedup_guard(): def test_add_edge_sql_dedup_guard():
payload = {"from_claim": "aaaa", "to_claim": "bbbb", "edge_type": "supersedes", "weight": 0.9} payload = {"from_claim": CLAIM_A, "to_claim": CLAIM_B, "edge_type": "supersedes", "weight": 0.9}
sql = ap.build_add_edge_sql(payload, "pid-2", None, _approval_meta("add_edge", payload)) sql = ap.build_add_edge_sql(payload, "pid-2", None, _approval_meta("add_edge", payload))
assert "insert into public.claim_edges" in sql assert "insert into public.claim_edges" in sql
assert "not exists" in sql assert "not exists" in sql
@ -122,7 +126,7 @@ def test_add_edge_sql_dedup_guard():
def test_add_edge_semantic_row_accepts_match_and_rejects_weight_mismatch(): def test_add_edge_semantic_row_accepts_match_and_rejects_weight_mismatch():
payload = {"from_claim": "aaaa", "to_claim": "bbbb", "edge_type": "supports", "weight": 0.9} payload = {"from_claim": CLAIM_A, "to_claim": CLAIM_B, "edge_type": "supports", "weight": 0.9}
sql = ap.build_add_edge_sql(payload, "pid-2", None, _approval_meta("add_edge", payload)) sql = ap.build_add_edge_sql(payload, "pid-2", None, _approval_meta("add_edge", payload))
verify = sql[sql.index("do $verify$") : sql.index("kb_stage.finish_approved_proposal")] verify = sql[sql.index("do $verify$") : sql.index("kb_stage.finish_approved_proposal")]
@ -131,9 +135,7 @@ def test_add_edge_semantic_row_accepts_match_and_rejects_weight_mismatch():
assert "claim_edge row does not match strict apply payload" in verify assert "claim_edge row does not match strict apply payload" in verify
assert sql.startswith("begin;") assert sql.startswith("begin;")
assert sql.rstrip().endswith("commit;") assert sql.rstrip().endswith("commit;")
assert sql.index("raise exception 'apply_proposal: claim_edge row") < sql.index( assert sql.index("raise exception 'apply_proposal: claim_edge row") < sql.index("kb_stage.finish_approved_proposal")
"kb_stage.finish_approved_proposal"
)
def test_add_edge_rejects_self_loop(): def test_add_edge_rejects_self_loop():
@ -144,22 +146,18 @@ def test_add_edge_rejects_self_loop():
# --- attach_evidence ------------------------------------------------------ # # --- attach_evidence ------------------------------------------------------ #
def test_attach_evidence_sql_with_source_id(): def test_attach_evidence_sql_with_source_id():
payload = {"evidence": [{"claim_id": "cccc", "source_id": "dddd", "role": "grounds", "weight": 0.78}]} payload = {"evidence": [{"claim_id": CLAIM_A, "source_id": SOURCE_A, "role": "grounds", "weight": 0.78}]}
sql = ap.build_attach_evidence_sql(payload, "pid-3", None, _approval_meta("attach_evidence", payload)) sql = ap.build_attach_evidence_sql(payload, "pid-3", None, _approval_meta("attach_evidence", payload))
assert "insert into public.claim_evidence" in sql assert "insert into public.claim_evidence" in sql
assert "public.claim_evidence (id," not in sql
assert "public.claim_evidence (claim_id, source_id, role, weight)" in sql
assert "::evidence_role" in sql assert "::evidence_role" in sql
assert "not exists" in sql assert "not exists" in sql
def test_attach_evidence_semantic_row_accepts_match_and_rejects_weight_mismatch(): def test_attach_evidence_semantic_row_accepts_match_and_rejects_weight_mismatch():
payload = { payload = {"evidence": [{"claim_id": CLAIM_A, "source_id": SOURCE_A, "role": "grounds", "weight": 0.78}]}
"evidence": [ sql = ap.build_attach_evidence_sql(payload, "pid-3", None, _approval_meta("attach_evidence", payload))
{"claim_id": "cccc", "source_id": "dddd", "role": "grounds", "weight": 0.78}
]
}
sql = ap.build_attach_evidence_sql(
payload, "pid-3", None, _approval_meta("attach_evidence", payload)
)
verify = sql[sql.index("do $verify$") : sql.index("kb_stage.finish_approved_proposal")] verify = sql[sql.index("do $verify$") : sql.index("kb_stage.finish_approved_proposal")]
assert "weight is not distinct from 0.78" in verify assert "weight is not distinct from 0.78" in verify
@ -167,9 +165,7 @@ def test_attach_evidence_semantic_row_accepts_match_and_rejects_weight_mismatch(
assert "evidence row % does not match strict apply payload" in verify assert "evidence row % does not match strict apply payload" in verify
assert sql.startswith("begin;") assert sql.startswith("begin;")
assert sql.rstrip().endswith("commit;") assert sql.rstrip().endswith("commit;")
assert sql.index("raise exception 'apply_proposal: evidence row") < sql.index( assert sql.index("raise exception 'apply_proposal: evidence row") < sql.index("kb_stage.finish_approved_proposal")
"kb_stage.finish_approved_proposal"
)
def test_attach_evidence_requires_source_id(): def test_attach_evidence_requires_source_id():
@ -231,9 +227,7 @@ def _approve_claim_bundle():
{"claim_id": claim_a, "source_id": source_a, "role": "grounds", "weight": 0.9}, {"claim_id": claim_a, "source_id": source_a, "role": "grounds", "weight": 0.9},
{"claim_id": claim_b, "source_id": source_b, "role": "illustrates", "weight": None}, {"claim_id": claim_b, "source_id": source_b, "role": "illustrates", "weight": None},
], ],
"edges": [ "edges": [{"from_claim": claim_a, "to_claim": claim_b, "edge_type": "supports", "weight": 0.7}],
{"from_claim": claim_a, "to_claim": claim_b, "edge_type": "supports", "weight": 0.7}
],
"reasoning_tools": [ "reasoning_tools": [
{ {
"id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee", "id": "eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
@ -259,6 +253,8 @@ def test_approve_claim_bundle_sql_is_atomic_and_row_verified():
assert "insert into public.claims" in sql assert "insert into public.claims" in sql
assert "insert into public.sources" in sql assert "insert into public.sources" in sql
assert "insert into public.claim_evidence" in sql assert "insert into public.claim_evidence" in sql
assert "public.claim_evidence (id," not in sql
assert "public.claim_evidence (claim_id, source_id, role, weight, created_by)" in sql
assert "insert into public.claim_edges" in sql assert "insert into public.claim_edges" in sql
assert "insert into public.reasoning_tools" in sql assert "insert into public.reasoning_tools" in sql
assert "source hash collision" in sql assert "source hash collision" in sql
@ -291,9 +287,7 @@ def test_approve_claim_semantic_rows_accept_matches_and_reject_payload_mismatche
assert "approve_claim: edge row does not match strict apply payload" in verify assert "approve_claim: edge row does not match strict apply payload" in verify
assert sql.startswith("begin;") assert sql.startswith("begin;")
assert sql.rstrip().endswith("commit;") assert sql.rstrip().endswith("commit;")
assert sql.index("raise exception 'approve_claim: evidence row") < sql.index( assert sql.index("raise exception 'approve_claim: evidence row") < sql.index("kb_stage.finish_approved_proposal")
"kb_stage.finish_approved_proposal"
)
def test_approve_claim_bundle_rejects_duplicate_source_hashes(): def test_approve_claim_bundle_rejects_duplicate_source_hashes():
@ -388,6 +382,34 @@ def test_apply_sql_locks_and_binds_approval_before_canonical_write():
assert "Reviewed exact strict payload." in sql assert "Reviewed exact strict payload." in sql
def test_fresh_owned_apply_uses_strict_inserts_and_binds_preflight_hash():
payload = _approve_claim_bundle()
proposal = {
"id": "99999999-9999-4999-8999-999999999999",
"proposal_type": "approve_claim",
"status": "approved",
"payload": {"apply_payload": payload},
"reviewed_by_handle": "m3ta",
"reviewed_by_agent_id": None,
"reviewed_at": "2026-07-10T00:00:00+00:00",
"review_note": "Reviewed exact strict payload.",
}
preflight_sha256 = "a" * 64
sql = ap.build_apply_sql(
proposal,
"kb-apply",
fresh_owned=True,
fresh_preflight_sha256=preflight_sha256,
)
assert preflight_sha256 in sql
assert "set transaction isolation level serializable" in sql.lower()
assert "on conflict" not in sql.lower()
assert "where not exists" not in sql.lower()
assert sql.index("set transaction isolation level serializable") < sql.index("kb_stage.assert_approved_proposal")
def test_build_apply_sql_requires_review_provenance(): def test_build_apply_sql_requires_review_provenance():
proposal = { proposal = {
"id": "99999999-9999-4999-8999-999999999999", "id": "99999999-9999-4999-8999-999999999999",
@ -445,7 +467,7 @@ def test_assert_applyable_allows_approved():
# --- ledger flip: concurrency guard + FK stamp --------------------------- # # --- ledger flip: concurrency guard + FK stamp --------------------------- #
def test_ledger_transition_uses_payload_bound_security_functions(): def test_ledger_transition_uses_payload_bound_security_functions():
payload = {"from_claim": "a", "to_claim": "b", "edge_type": "supports"} payload = {"from_claim": CLAIM_A, "to_claim": CLAIM_B, "edge_type": "supports"}
sql = ap.build_add_edge_sql(payload, "pid", None, _approval_meta("add_edge", payload)) sql = ap.build_add_edge_sql(payload, "pid", None, _approval_meta("add_edge", payload))
assert "kb_stage.assert_approved_proposal" in sql assert "kb_stage.assert_approved_proposal" in sql
assert "kb_stage.finish_approved_proposal" in sql assert "kb_stage.finish_approved_proposal" in sql
@ -459,7 +481,7 @@ def test_ledger_transition_uses_payload_bound_security_functions():
def test_ledger_flip_stamps_agent_fk(): def test_ledger_flip_stamps_agent_fk():
payload = {"from_claim": "a", "to_claim": "b", "edge_type": "supports"} payload = {"from_claim": CLAIM_A, "to_claim": CLAIM_B, "edge_type": "supports"}
sql = ap.build_add_edge_sql(payload, "pid", "kb-apply", _approval_meta("add_edge", payload)) sql = ap.build_add_edge_sql(payload, "pid", "kb-apply", _approval_meta("add_edge", payload))
# Hard resolve into a variable + NOT-NULL assert, never a silent inline # Hard resolve into a variable + NOT-NULL assert, never a silent inline
# subselect that would stamp NULL on an unresolved handle. # subselect that would stamp NULL on an unresolved handle.
@ -468,7 +490,7 @@ def test_ledger_flip_stamps_agent_fk():
def test_build_apply_sql_defaults_applied_by_to_service_agent(): def test_build_apply_sql_defaults_applied_by_to_service_agent():
payload = {"from_claim": "a", "to_claim": "b", "edge_type": "supports"} payload = {"from_claim": CLAIM_A, "to_claim": CLAIM_B, "edge_type": "supports"}
proposal = { proposal = {
"id": "pid", "id": "pid",
"proposal_type": "add_edge", "proposal_type": "add_edge",

View file

@ -6,7 +6,10 @@ standalone (`python3 tests/test_apply_worker.py`).
""" """
import argparse import argparse
import json
import stat
import sys import sys
import tempfile
from pathlib import Path from pathlib import Path
try: try:
@ -40,19 +43,33 @@ sys.path.insert(0, str(REPO_ROOT / "scripts"))
import apply_worker as w # noqa: E402 import apply_worker as w # noqa: E402
@pytest.fixture(autouse=True) def _dependency_restore():
def restore_apply_worker_dependencies():
original_load_password = w.ap.load_password original_load_password = w.ap.load_password
original_load_failure_state = w.load_failure_state original_load_failure_state = w.load_failure_state
original_fetch_candidates = w.fetch_candidates original_fetch_candidates = w.fetch_candidates
original_apply_one = w.apply_one original_apply_one = w.apply_one
original_render_one = w.render_one original_render_one = w.render_one
original_subprocess_run = w.subprocess.run
yield yield
w.ap.load_password = original_load_password w.ap.load_password = original_load_password
w.load_failure_state = original_load_failure_state w.load_failure_state = original_load_failure_state
w.fetch_candidates = original_fetch_candidates w.fetch_candidates = original_fetch_candidates
w.apply_one = original_apply_one w.apply_one = original_apply_one
w.render_one = original_render_one w.render_one = original_render_one
w.subprocess.run = original_subprocess_run
@pytest.fixture(autouse=True)
def restore_apply_worker_dependencies():
restore = _dependency_restore()
next(restore)
try:
yield
finally:
try:
next(restore)
except StopIteration:
pass
# --- candidate query ------------------------------------------------------ # # --- candidate query ------------------------------------------------------ #
@ -116,22 +133,283 @@ def test_render_command_expands_agent_id():
# --- enablement gate ------------------------------------------------------ # # --- enablement gate ------------------------------------------------------ #
def _args(**over): def _args(**over):
base = dict( base = dict(
enable=False, limit=20, max_per_tick=1, max_attempts=3, enable=False,
failure_state_file=None, applied_by="kb-apply", limit=20,
apply_script="apply_proposal.py", render_cmd="", max_per_tick=1,
secrets_file="x", container="teleo-pg", db="teleo", max_attempts=3,
host="127.0.0.1", role="kb_apply", failure_state_file=None,
applied_by="kb-apply",
apply_script="apply_proposal.py",
render_cmd="",
receipt_dir="/private/tmp/kb-apply-worker-test-receipts",
secrets_file="x",
container="teleo-pg",
db="teleo",
host="127.0.0.1",
role="kb_apply",
) )
base.update(over) base.update(over)
return argparse.Namespace(**base) return argparse.Namespace(**base)
def _write_valid_private_receipt(path: Path, proposal_id: str) -> None:
from_claim = "11111111-1111-4111-8111-111111111111"
to_claim = "22222222-2222-4222-8222-222222222222"
proposal = {
"id": proposal_id,
"proposal_type": "add_edge",
"status": "applied",
"payload": {
"apply_payload": {
"from_claim": from_claim,
"to_claim": to_claim,
"edge_type": "supports",
"weight": 0.75,
}
},
"reviewed_by_handle": "reviewer",
"reviewed_by_agent_id": None,
"reviewed_at": "2026-07-15T10:00:00+00:00",
"review_note": "Approved for worker receipt testing.",
"applied_by_handle": "kb-apply",
"applied_by_agent_id": None,
"applied_at": "2026-07-15T10:01:00+00:00",
}
receipt = w.ap.replay_receipt.build_replay_receipt(
proposal,
{
"claim_edges": [
{
"id": "33333333-3333-4333-8333-333333333333",
"from_claim": from_claim,
"to_claim": to_claim,
"edge_type": "supports",
"weight": 0.75,
"created_by": None,
}
]
},
apply_sql_sha256="a" * 64,
apply_sql_source="exact_executed_sql",
exported_at_utc="2026-07-15T10:02:00+00:00",
)
path.parent.mkdir(parents=True, exist_ok=True, mode=0o700)
path.write_text(json.dumps(receipt), encoding="utf-8")
path.chmod(0o600)
def _load_private_receipt(path: Path) -> dict:
return json.loads(path.read_text(encoding="utf-8"))
def _write_private_receipt(path: Path, receipt: dict) -> None:
path.write_text(json.dumps(receipt), encoding="utf-8")
path.chmod(0o600)
def _completed(returncode: int, *, stdout: str = "", stderr: str = ""):
return w.subprocess.CompletedProcess([], returncode, stdout=stdout, stderr=stderr)
def _postcommit_receipt_failure(proposal_id: str, detail: str = "receipt write failed") -> str:
return (
f"proposal {proposal_id} {w.POSTCOMMIT_RECEIPT_FAILURE_MARKER}: {detail}"
f"{w.POSTCOMMIT_RECEIPT_RECOVERY_MARKER}"
f"apply_proposal.py {proposal_id} --receipt-only"
)
# --- private receipt and post-COMMIT recovery ---------------------------- #
def test_private_receipt_requires_complete_canonical_rows_and_hashes():
proposal_id = "99999999-9999-4999-8999-999999999999"
receipt_path = Path(tempfile.mkdtemp()) / "receipt.json"
_write_valid_private_receipt(receipt_path, proposal_id)
missing_rows = _load_private_receipt(receipt_path)
missing_rows.pop("canonical_rows")
_write_private_receipt(receipt_path, missing_rows)
with pytest.raises(RuntimeError, match="row-level contract is invalid"):
w.assert_private_replay_receipt(receipt_path, proposal_id)
_write_valid_private_receipt(receipt_path, proposal_id)
missing_hashes = _load_private_receipt(receipt_path)
missing_hashes.pop("hashes")
_write_private_receipt(receipt_path, missing_hashes)
with pytest.raises(RuntimeError, match="row-level contract is invalid"):
w.assert_private_replay_receipt(receipt_path, proposal_id)
def test_private_receipt_rejects_canonical_row_tampering_without_recomputed_hashes():
proposal_id = "88888888-8888-4888-8888-888888888888"
receipt_path = Path(tempfile.mkdtemp()) / "receipt.json"
_write_valid_private_receipt(receipt_path, proposal_id)
tampered = _load_private_receipt(receipt_path)
tampered["canonical_rows"]["claim_edges"][0]["weight"] = 0.5
_write_private_receipt(receipt_path, tampered)
with pytest.raises(RuntimeError, match="row-level contract is invalid|internally inconsistent"):
w.assert_private_replay_receipt(receipt_path, proposal_id)
def test_apply_one_supplies_deterministic_private_receipt_path():
proposal_id = "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa"
receipt_dir = Path(tempfile.mkdtemp()) / "receipts"
calls = []
def _run(cmd, **_kwargs):
calls.append(cmd)
receipt_path = Path(cmd[cmd.index("--receipt-out") + 1])
_write_valid_private_receipt(receipt_path, proposal_id)
return _completed(0, stdout='{"applied": true}')
w.subprocess.run = _run
w.apply_one(_args(receipt_dir=str(receipt_dir)), proposal_id)
expected = receipt_dir.resolve() / f"{proposal_id}.json"
assert len(calls) == 1
assert calls[0][calls[0].index("--receipt-dir") + 1] == str(expected.parent)
assert calls[0][calls[0].index("--receipt-out") + 1] == str(expected)
assert stat.S_IMODE(expected.stat().st_mode) == 0o600
def test_apply_one_recovers_postcommit_receipt_failure_without_reapplying():
proposal_id = "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb"
receipt_dir = Path(tempfile.mkdtemp()) / "receipts"
calls = []
def _run(cmd, **_kwargs):
calls.append(cmd)
if len(calls) == 1:
return _completed(
1,
stderr=_postcommit_receipt_failure(proposal_id),
)
assert "--receipt-only" in cmd
receipt_path = Path(cmd[cmd.index("--receipt-out") + 1])
_write_valid_private_receipt(receipt_path, proposal_id)
return _completed(0, stdout='{"replay_ready": true}')
w.subprocess.run = _run
w.apply_one(_args(receipt_dir=str(receipt_dir)), proposal_id)
assert len(calls) == 2
assert "--receipt-only" not in calls[0]
assert "--receipt-only" in calls[1]
assert calls[0][calls[0].index("--receipt-out") + 1] == calls[1][calls[1].index("--receipt-out") + 1]
def test_apply_one_does_not_recover_a_precommit_apply_failure():
calls = []
def _run(cmd, **_kwargs):
calls.append(cmd)
return _completed(1, stderr="psql transaction failed before commit")
w.subprocess.run = _run
try:
w.apply_one(_args(receipt_dir=tempfile.mkdtemp()), "p1")
except w.PostCommitReceiptError as exc:
raise AssertionError("pre-COMMIT failure was misclassified as committed") from exc
except RuntimeError:
pass
else:
raise AssertionError("expected pre-COMMIT apply failure")
assert len(calls) == 1
def test_apply_one_classifies_unrecovered_receipt_as_postcommit():
calls = []
def _run(cmd, **_kwargs):
calls.append(cmd)
if len(calls) == 1:
return _completed(1, stderr=_postcommit_receipt_failure("p1"))
return _completed(1, stderr="receipt directory remains unavailable")
w.subprocess.run = _run
with pytest.raises(w.PostCommitReceiptError):
w.apply_one(_args(receipt_dir=tempfile.mkdtemp()), "p1")
assert len(calls) == 2
assert "--receipt-only" in calls[1]
def test_forged_marker_in_unknown_field_traceback_is_a_normal_apply_failure():
proposal_id = "cccccccc-cccc-4ccc-8ccc-cccccccccccc"
calls = []
def _run(cmd, **_kwargs):
calls.append(cmd)
return _completed(
1,
stderr=(
"Traceback (most recent call last):\n"
"ValueError: approve_claim apply_payload contains unknown fields: "
f"['{w.POSTCOMMIT_RECEIPT_FAILURE_MARKER}']"
),
)
w.subprocess.run = _run
with pytest.raises(RuntimeError, match="apply failed"):
w.apply_one(_args(receipt_dir=tempfile.mkdtemp()), proposal_id)
assert len(calls) == 1
assert "--receipt-only" not in calls[0]
def test_forged_marker_increments_normal_failure_and_poison_accounting():
proposal_id = "dddddddd-dddd-4ddd-8ddd-dddddddddddd"
failure_state = str(Path(tempfile.mkdtemp()) / "failures.json")
calls = []
w.ap.load_password = lambda _path: "pw"
w.fetch_candidates = lambda _args, _password, _excluded: _cands(proposal_id)
def _run(cmd, **_kwargs):
calls.append(cmd)
return _completed(
1,
stderr=(
"ValueError: approve_claim apply_payload contains unknown fields: "
f"['{w.POSTCOMMIT_RECEIPT_FAILURE_MARKER}']"
),
)
w.subprocess.run = _run
rc = w.run(
_args(
enable=True,
failure_state_file=failure_state,
max_attempts=1,
max_per_tick=1,
receipt_dir=tempfile.mkdtemp(),
)
)
assert rc == 1
assert w.load_failure_state(failure_state) == {proposal_id: 1}
assert len(calls) == 1
def test_postcommit_receipt_error_does_not_increment_apply_failure_count():
path = str(Path(tempfile.mkdtemp()) / "failures.json")
w.ap.load_password = lambda _f: "pw"
w.fetch_candidates = lambda a, p, excluded: _cands("committed")
def _postcommit(_args, _proposal_id):
raise w.PostCommitReceiptError("committed; receipt recovery failed")
w.apply_one = _postcommit
rc = w.run(_args(enable=True, failure_state_file=path, max_per_tick=1))
assert rc == 1
assert w.load_failure_state(path) == {}
def test_report_only_gate_does_not_apply(monkeypatch=None): def test_report_only_gate_does_not_apply(monkeypatch=None):
calls = [] calls = []
w.ap.load_password = lambda _f: "pw" w.ap.load_password = lambda _f: "pw"
w.fetch_candidates = lambda a, p, excluded: [ w.fetch_candidates = lambda a, p, excluded: [{"id": "p1", "proposal_type": "revise_strategy", "agent_id": "ag"}]
{"id": "p1", "proposal_type": "revise_strategy", "agent_id": "ag"}
]
w.apply_one = lambda a, pid: calls.append(pid) w.apply_one = lambda a, pid: calls.append(pid)
rc = w.run(_args(enable=False)) rc = w.run(_args(enable=False))
@ -142,9 +420,7 @@ def test_report_only_gate_does_not_apply(monkeypatch=None):
def test_enabled_worker_applies_and_renders(): def test_enabled_worker_applies_and_renders():
applied, rendered = [], [] applied, rendered = [], []
w.ap.load_password = lambda _f: "pw" w.ap.load_password = lambda _f: "pw"
w.fetch_candidates = lambda a, p, excluded: [ w.fetch_candidates = lambda a, p, excluded: [{"id": "p1", "proposal_type": "revise_strategy", "agent_id": "ag"}]
{"id": "p1", "proposal_type": "revise_strategy", "agent_id": "ag"}
]
w.apply_one = lambda a, pid: applied.append(pid) w.apply_one = lambda a, pid: applied.append(pid)
w.render_one = lambda a, agent_id: rendered.append(agent_id) or "ok" w.render_one = lambda a, agent_id: rendered.append(agent_id) or "ok"
@ -157,9 +433,7 @@ def test_enabled_worker_applies_and_renders():
def test_enabled_worker_skips_render_for_add_edge(): def test_enabled_worker_skips_render_for_add_edge():
applied, rendered = [], [] applied, rendered = [], []
w.ap.load_password = lambda _f: "pw" w.ap.load_password = lambda _f: "pw"
w.fetch_candidates = lambda a, p, excluded: [ w.fetch_candidates = lambda a, p, excluded: [{"id": "e1", "proposal_type": "add_edge", "agent_id": None}]
{"id": "e1", "proposal_type": "add_edge", "agent_id": None}
]
w.apply_one = lambda a, pid: applied.append(pid) w.apply_one = lambda a, pid: applied.append(pid)
w.render_one = lambda a, agent_id: rendered.append(agent_id) or "ok" w.render_one = lambda a, agent_id: rendered.append(agent_id) or "ok"
@ -172,9 +446,7 @@ def test_enabled_worker_skips_render_for_add_edge():
def test_enabled_worker_skips_render_for_approve_claim(): def test_enabled_worker_skips_render_for_approve_claim():
applied, rendered = [], [] applied, rendered = [], []
w.ap.load_password = lambda _f: "pw" w.ap.load_password = lambda _f: "pw"
w.fetch_candidates = lambda a, p, excluded: [ w.fetch_candidates = lambda a, p, excluded: [{"id": "c1", "proposal_type": "approve_claim", "agent_id": "ag"}]
{"id": "c1", "proposal_type": "approve_claim", "agent_id": "ag"}
]
w.apply_one = lambda a, pid: applied.append(pid) w.apply_one = lambda a, pid: applied.append(pid)
w.render_one = lambda a, agent_id: rendered.append(agent_id) or "ok" w.render_one = lambda a, agent_id: rendered.append(agent_id) or "ok"
@ -263,7 +535,7 @@ if __name__ == "__main__":
failures = 0 failures = 0
for name, fn in sorted(globals().items()): for name, fn in sorted(globals().items()):
if name.startswith("test_") and callable(fn): if name.startswith("test_") and callable(fn):
restore = restore_apply_worker_dependencies() restore = _dependency_restore()
next(restore) next(restore)
try: try:
fn() fn()

View file

@ -0,0 +1,73 @@
from __future__ import annotations
import json
from pathlib import Path
from scripts import build_telegram_visible_unseen_chain_packet as packet
def test_packet_binds_handler_receipt_and_preserves_exact_messages() -> None:
data = packet.build_packet(git_sha="a" * 40)
assert data["schema"] == packet.SCHEMA
assert data["ready_to_request_action_time_authorization"] is True
assert data["telegram_visible_messages_sent"] is False
assert data["telegram_visible_message_authorization_present"] is False
assert data["mutates_db"] is False
assert data["target"]["chat_label"] == "Leo"
assert data["target"]["chat_id"] == "-5146042086"
assert data["target"]["allowed_transport"] == "authenticated_chrome_telegram_ui"
assert [item["message"] for item in data["exact_messages"]] == [item["message"] for item in packet.unseen.PROMPTS]
assert [item["sequence"] for item in data["exact_messages"]] == [1, 2, 3]
assert all(len(item["message_sha256"]) == 64 for item in data["exact_messages"])
assert data["handler_receipt_binding"]["sha256"] == packet._sha256_file(packet.DEFAULT_HANDLER_RECEIPT)
assert data["tooling_binding"] == packet.tooling_binding()
assert data["manifest_binding"] == packet.manifest_binding()
assert data["manifest_binding"]["path"] == "ops/postgres_parity_manifest.sql"
assert data["manifest_binding"]["execution_contract"]["effective_role"] == "pg_read_all_data"
assert data["manifest_binding"]["execution_contract"]["transaction_read_only"] == "on"
assert data["protocol"]["manifest_binding"] == data["manifest_binding"]
assert data["operator_context"]["codex_thread_id"] == packet.DEFAULT_CODEX_THREAD_ID
assert data["protocol"]["operator_context"] == data["operator_context"]
assert packet._canonical_sha256(data["protocol"]) == data["protocol_sha256"]
assert all(data["checks"].values())
def test_action_time_authorization_contains_destination_transport_and_full_messages() -> None:
data = packet.build_packet(git_sha="a" * 40)
authorization = data["explicit_operator_authorization_text"]
assert "Telegram group Leo (chat ID -5146042086)" in authorization
assert "already-authenticated Chrome Telegram UI" in authorization
assert "do not use the Bot API" in authorization
assert "Codex rollout's user-authorization and Chrome tool events" in authorization
assert "no additional messages" in authorization
for item in data["exact_messages"]:
assert item["prompt_id"] in authorization
assert json.dumps(item["message"], ensure_ascii=True) in authorization
def test_packet_fails_closed_when_handler_receipt_no_longer_passes(tmp_path: Path) -> None:
receipt = json.loads(packet.DEFAULT_HANDLER_RECEIPT.read_text(encoding="utf-8"))
receipt["status"] = "fail"
receipt_path = tmp_path / "handler.json"
receipt_path.write_text(json.dumps(receipt), encoding="utf-8")
data = packet.build_packet(handler_receipt_path=receipt_path, git_sha="a" * 40)
assert data["ready_to_request_action_time_authorization"] is False
assert data["authorization_gate_status"] == "not_ready"
assert data["checks"]["handler_receipt_passed"] is False
def test_markdown_retains_exact_cta_and_no_send_ceiling(tmp_path: Path) -> None:
data = packet.build_packet(git_sha="a" * 40)
out = tmp_path / "packet.md"
packet.write_markdown(out, data)
text = out.read_text(encoding="utf-8")
assert "Telegram-Visible Unseen Chain Authorization Packet" in text
assert "Telegram-visible messages sent: `False`" in text
assert "Exact Action-Time Authorization" in text
assert data["exact_messages"][2]["message"] in text

View file

@ -0,0 +1,320 @@
from __future__ import annotations
import argparse
import copy
import json
from pathlib import Path
import pytest
from scripts import build_telegram_visible_unseen_chain_packet as packet_builder
from scripts import collect_telegram_visible_unseen_chain_state as state
def manifest_output(*, row_count: int = 7) -> str:
rows = [
{
"kind": "identity",
"database": "teleo",
"current_user": packet_builder.READ_ONLY_DB_ROLE,
"server_version_num": 160014,
"server_encoding": "UTF8",
"database_collation": "C.UTF-8",
"database_ctype": "C.UTF-8",
"transaction_read_only": "on",
}
]
for kind in (
"schemas",
"extensions",
"application_roles",
"columns",
"constraints",
"indexes",
"sequences",
"views",
"functions",
"triggers",
"types",
"policies",
):
rows.append({"kind": kind, "items": []})
rows.append(
{
"kind": "table",
"schema": "public",
"table": "claims",
"row_count": row_count,
"rowset_md5": "f" * 32,
}
)
return "BEGIN\nSET\n" + "\n".join(json.dumps(item) for item in rows) + "\nROLLBACK\n"
def write_packet(tmp_path: Path) -> Path:
out = tmp_path / "packet.json"
packet_builder.write_json(
out,
packet_builder.build_packet(
handler_receipt_path=packet_builder.DEFAULT_HANDLER_RECEIPT.resolve(),
git_sha="a" * 40,
),
)
return out
def args_for(packet: Path, tmp_path: Path, *, phase: str = "preflight") -> argparse.Namespace:
return argparse.Namespace(
phase=phase,
packet=packet,
baseline=None,
subject_ref=None,
manifest_sql=Path("ops/postgres_parity_manifest.sql"),
ssh_target="root@example.invalid",
ssh_key=tmp_path / "key",
connect_timeout=1,
timeout=5,
fingerprint_timeout=5,
ssh_attempts=3,
out=tmp_path / f"{phase}.json",
markdown_out=tmp_path / f"{phase}.md",
)
class GoodRunner:
def __init__(self) -> None:
self.service_calls = 0
def __call__(self, command: list[str], input_text: str, _timeout: int) -> state.CommandResult:
remote_command = command[-1]
if "git rev-parse HEAD" in remote_command:
sha = "b" * 40
return state.CommandResult(
0,
f"deploy_head={sha}\nlast_deploy_sha={sha}\ndeploy_stamp_ancestor=true\n",
"",
)
if "systemctl show" in remote_command:
self.service_calls += 1
return state.CommandResult(
0,
"\n".join(
[
"ActiveState=active",
"SubState=running",
"MainPID=123",
"NRestarts=0",
"ExecMainStartTimestamp=Wed 2026-07-15 00:00:00 UTC",
]
),
"",
)
if "'subject_ref'" in input_text:
assert "default_transaction_read_only=on" in remote_command
assert "-c transaction_read_only=on" in remote_command
assert f"role={packet_builder.READ_ONLY_DB_ROLE}" in remote_command
assert "psql -X" in remote_command
payload = {
"subject_ref": "c0000000",
"matches": [
{
"table": "public.beliefs",
"row": {"id": "c0000000-0000-4000-8000-000000000001"},
"evidence_count": None,
}
],
}
return state.CommandResult(0, f"BEGIN\n{json.dumps(payload)}\nROLLBACK\n", "")
if "postgres_parity_manifest" not in remote_command and input_text.startswith("\\set ON_ERROR_STOP"):
assert "default_transaction_read_only=on" in remote_command
assert "-c transaction_read_only=on" in remote_command
assert f"role={packet_builder.READ_ONLY_DB_ROLE}" in remote_command
assert "psql -X" in remote_command
return state.CommandResult(0, manifest_output(), "")
raise AssertionError(f"unexpected command: {command} / input={input_text[:80]}")
def test_preflight_passes_with_two_identical_read_only_fingerprints(tmp_path: Path) -> None:
args = args_for(write_packet(tmp_path), tmp_path)
result = state.collect_state(args, runner=GoodRunner())
assert result["status"] == "pass"
assert result["ready_for_action_time_authorization"] is True
assert result["telegram_visible_messages_sent_by_collector"] is False
assert result["mutates_db"] is False
assert all(result["packet_checks"].values())
assert all(result["remote_checks"].values())
assert len(result["state_token_sha256"]) == 64
def test_preflight_fails_when_second_fingerprint_drifts(tmp_path: Path) -> None:
args = args_for(write_packet(tmp_path), tmp_path)
fingerprint_calls = 0
good = GoodRunner()
def drift_runner(command: list[str], input_text: str, timeout: int) -> state.CommandResult:
nonlocal fingerprint_calls
if input_text.startswith("\\set ON_ERROR_STOP") and "'subject_ref'" not in input_text:
fingerprint_calls += 1
return state.CommandResult(0, manifest_output(row_count=7 + fingerprint_calls - 1), "")
return good(command, input_text, timeout)
result = state.collect_state(args, runner=drift_runner)
assert result["status"] == "fail"
assert result["remote_checks"]["canonical_fingerprint_unchanged_during_probe"] is False
def test_preflight_accepts_newer_workspace_head_when_deployed_stamp_is_ancestor(tmp_path: Path) -> None:
args = args_for(write_packet(tmp_path), tmp_path)
class AheadRunner(GoodRunner):
def __call__(self, command: list[str], input_text: str, timeout: int) -> state.CommandResult:
if "git rev-parse HEAD" in command[-1]:
return state.CommandResult(
0,
f"deploy_head={'c' * 40}\nlast_deploy_sha={'b' * 40}\ndeploy_stamp_ancestor=true\n",
"",
)
return super().__call__(command, input_text, timeout)
result = state.collect_state(args, runner=AheadRunner())
assert result["status"] == "pass"
assert result["remote"]["workspace_head_matches_deployed_stamp"] is False
assert result["remote_checks"]["deployed_stamp_is_ancestor_of_workspace_head"] is True
def test_preflight_retries_transient_ssh_failure(tmp_path: Path) -> None:
args = args_for(write_packet(tmp_path), tmp_path)
good = GoodRunner()
deploy_attempts = 0
def transient_runner(command: list[str], input_text: str, timeout: int) -> state.CommandResult:
nonlocal deploy_attempts
if "git rev-parse HEAD" in command[-1]:
deploy_attempts += 1
if deploy_attempts == 1:
return state.CommandResult(255, "", "Connection timed out during banner exchange")
return good(command, input_text, timeout)
result = state.collect_state(args, runner=transient_runner)
assert result["status"] == "pass"
assert result["remote"]["readback_attempts"]["deploy"] == 2
def test_preflight_rejects_packet_bound_to_different_tooling_source(tmp_path: Path) -> None:
packet_path = write_packet(tmp_path)
packet = json.loads(packet_path.read_text(encoding="utf-8"))
packet["tooling_binding"]["capture_verifier"]["sha256"] = "0" * 64
packet_path.write_text(json.dumps(packet), encoding="utf-8")
result = state.collect_state(args_for(packet_path, tmp_path), runner=GoodRunner())
assert result["status"] == "fail"
assert result["packet_checks"]["packet_tooling_hashes_match_current_sources"] is False
def test_postflight_binds_baseline_fingerprint_service_and_subject(tmp_path: Path) -> None:
packet = write_packet(tmp_path)
pre_args = args_for(packet, tmp_path)
preflight = state.collect_state(pre_args, runner=GoodRunner())
baseline = tmp_path / "preflight.json"
state.write_json(baseline, preflight)
post_args = args_for(packet, tmp_path, phase="postflight")
post_args.baseline = baseline
post_args.subject_ref = "c0000000"
postflight = state.collect_state(post_args, runner=GoodRunner())
assert postflight["status"] == "pass"
assert postflight["ready_for_visible_capture_verification"] is True
assert all(postflight["baseline_checks"].values())
assert postflight["remote_checks"]["subject_resolved_to_exactly_one_db_object"] is True
def test_postflight_rejects_baseline_fingerprint_mismatch(tmp_path: Path) -> None:
packet = write_packet(tmp_path)
pre_args = args_for(packet, tmp_path)
preflight = state.collect_state(pre_args, runner=GoodRunner())
preflight = copy.deepcopy(preflight)
preflight["remote"]["fingerprint_after"]["fingerprint_sha256"] = "0" * 64
baseline = tmp_path / "preflight.json"
state.write_json(baseline, preflight)
post_args = args_for(packet, tmp_path, phase="postflight")
post_args.baseline = baseline
post_args.subject_ref = "c0000000"
postflight = state.collect_state(post_args, runner=GoodRunner())
assert postflight["status"] == "fail"
assert postflight["baseline_checks"]["canonical_fingerprint_matches_preflight"] is False
def test_subject_sql_rejects_untrusted_input() -> None:
try:
state.subject_readback_sql("c0000000'; delete from public.claims; --")
except ValueError as exc:
assert "subject_ref" in str(exc)
else:
raise AssertionError("unsafe subject ref was accepted")
class NoSshRunner:
def __init__(self) -> None:
self.calls = 0
def __call__(self, _command: list[str], _input_text: str, _timeout: int) -> state.CommandResult:
self.calls += 1
raise AssertionError("SSH runner must not be called after local fail-closed rejection")
def test_write_capable_manifest_override_is_rejected_before_ssh(tmp_path: Path) -> None:
packet = write_packet(tmp_path)
malicious = tmp_path / "write.sql"
malicious.write_text(
"\\set ON_ERROR_STOP on\nbegin;\nupdate public.claims set status = 'live';\ncommit;\n",
encoding="utf-8",
)
args = args_for(packet, tmp_path)
args.manifest_sql = malicious
runner = NoSshRunner()
result = state.collect_state(args, runner=runner)
assert result["status"] == "fail"
assert result["packet_checks"]["manifest_override_absent_or_exact_canonical_path"] is False
assert result["remote"]["readback_attempts"] == {}
assert runner.calls == 0
assert state._manifest_sql_is_statically_read_only(malicious.read_text(encoding="utf-8")) is False
def test_manifest_hash_mismatch_is_rejected_before_ssh(tmp_path: Path) -> None:
packet_path = write_packet(tmp_path)
packet = json.loads(packet_path.read_text(encoding="utf-8"))
packet["manifest_binding"]["sha256"] = "0" * 64
packet_path.write_text(json.dumps(packet), encoding="utf-8")
runner = NoSshRunner()
result = state.collect_state(args_for(packet_path, tmp_path), runner=runner)
assert result["status"] == "fail"
assert result["packet_checks"]["manifest_packet_sha256_matches_canonical_file"] is False
assert result["remote"]["readback_attempts"] == {}
assert runner.calls == 0
def test_cli_removes_arbitrary_manifest_override() -> None:
with pytest.raises(SystemExit):
state.parse_args(["--manifest-sql", "write.sql"])
def test_fingerprint_command_enforces_read_only_session_role_and_disables_psql_rc() -> None:
command = state.fingerprint_readback_command()
assert "default_transaction_read_only=on" in command
assert "-c transaction_read_only=on" in command
assert f"role={packet_builder.READ_ONLY_DB_ROLE}" in command
assert "psql -X" in command

View file

@ -203,6 +203,15 @@ def _lines(completed: subprocess.CompletedProcess[str]) -> set[str]:
return {line for line in completed.stdout.splitlines() if line} return {line for line in completed.stdout.splitlines() if line}
def test_reviewer_principal_seed_timestamp_is_deterministic(migrated_postgres: str) -> None:
created_at = _psql(
migrated_postgres,
"select created_at::text from kb_stage.kb_review_principals where db_role = 'kb_review';",
).stdout.strip()
assert created_at == "1970-01-01 00:00:00+00"
def _catalog_snapshot(container: str) -> str: def _catalog_snapshot(container: str) -> str:
return _psql( return _psql(
container, container,

View file

@ -4,6 +4,8 @@ import json
import subprocess import subprocess
from pathlib import Path from pathlib import Path
import pytest
from scripts import leo_behavior_manifest as manifest from scripts import leo_behavior_manifest as manifest
ROOT = Path(__file__).resolve().parents[1] ROOT = Path(__file__).resolve().parents[1]
@ -58,6 +60,11 @@ gateway:
assert '{"private":"conversation"}' not in encoded assert '{"private":"conversation"}' not in encoded
def test_identity_config_rejects_nonboolean_smart_model_routing() -> None:
with pytest.raises(ValueError, match="smart_model_routing must be boolean"):
manifest.identity_config_projection({"smart_model_routing": {"route": "untrusted"}})
def test_behavior_manifest_changes_when_a_behavior_layer_changes(tmp_path: Path) -> None: def test_behavior_manifest_changes_when_a_behavior_layer_changes(tmp_path: Path) -> None:
profile = tmp_path / "profile" profile = tmp_path / "profile"
hermes = tmp_path / "hermes" hermes = tmp_path / "hermes"
@ -156,3 +163,64 @@ def test_git_state_marks_untracked_files_dirty(tmp_path: Path) -> None:
assert state["worktree_clean"] is False assert state["worktree_clean"] is False
assert len(str(state["status_sha256"])) == 64 assert len(str(state["status_sha256"])) == 64
def test_identity_runtime_omits_secret_values_but_pins_semantic_model_settings(tmp_path: Path) -> None:
profile = tmp_path / "profile"
hermes = tmp_path / "hermes"
deployment = tmp_path / "deployment"
config = """model:
provider: fixture
default: identity-v1
max_tokens: 512
gateway:
telegram:
bot_token: token-a
botToken: camel-token-a
provider:
apiKey: camel-api-key-a
transport:
endpoint: https://fixture-user:fixture-password-a@example.invalid/v1
headers: ['Authorization: Bearer fixture-header-a']
tools:
allowed: [identity_readback]
identity_runtime:
network_send_enabled: false
database_write_enabled: false
allowed_tools: [identity_readback]
"""
_write(profile / "config.yaml", config)
_write(profile / "skills" / "identity" / "SKILL.md", "identity\n")
_write(profile / "plugins" / "identity" / "__init__.py", "BOUNDARY = True\n")
_write(profile / "bin" / "identity.py", "READ_ONLY = True\n")
_write(hermes / "run_agent.py", "runtime\n")
_write(hermes / "agent" / "prompt_builder.py", "prompts\n")
for name in (
"leo_behavior_manifest.py",
"leo_identity_manifest.py",
"leo_identity_profile.py",
"run_leo_identity_reconstruction_canary.py",
):
_write(deployment / "scripts" / name, f"# {name}\n")
before = manifest.build_manifest(profile, hermes, deployment)
_write(
profile / "config.yaml",
config.replace("token-a", "token-b")
.replace("camel-api-key-a", "camel-api-key-b")
.replace("fixture-password-a", "fixture-password-b")
.replace("fixture-header-a", "fixture-header-b"),
)
secret_rotated = manifest.build_manifest(profile, hermes, deployment)
_write(profile / "config.yaml", config.replace("max_tokens: 512", "max_tokens: 1024"))
model_changed = manifest.build_manifest(profile, hermes, deployment)
assert before["behavior_sha256"] != secret_rotated["behavior_sha256"]
assert before["identity_runtime_sha256"] == secret_rotated["identity_runtime_sha256"]
assert before["identity_runtime_sha256"] != model_changed["identity_runtime_sha256"]
encoded = json.dumps(before)
assert "token-a" not in encoded
assert "camel-token-a" not in encoded
assert "camel-api-key-a" not in encoded
assert "fixture-password-a" not in encoded
assert "fixture-header-a" not in encoded

View file

@ -0,0 +1,794 @@
from __future__ import annotations
import argparse
import copy
import json
import os
import subprocess
import time
from pathlib import Path, PureWindowsPath
import pytest
from scripts import leo_behavior_manifest as behavior
from scripts import leo_identity_manifest as identity
from scripts import leo_identity_profile as profile_runtime
from scripts import run_leo_identity_reconstruction_canary as canary
ROOT = Path(__file__).resolve().parents[1]
COMMITTED_RECEIPTS = (
ROOT / "docs/reports/leo-working-state-20260709/leo-reproducible-identity-t2-current.json",
ROOT / "docs/reports/leo-working-state-20260709/leo-reproducible-identity-drift-negative-current.json",
)
def _write(path: Path, value: str) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(value, encoding="utf-8")
def _write_json(path: Path, value: dict) -> None:
_write(path, json.dumps(value, indent=2, sort_keys=True) + "\n")
def _assert_path_portable_receipt(value: object) -> None:
canary._validate_portable_receipt(value)
def _assert_logical_child_execution(child: dict, *, profile_role: str) -> None:
logical_command = child["logical_command"]
assert "command" not in child
assert child["profile_role"] == profile_role
assert child["command_serialization"] == "logical_redacted_v1"
assert child["actual_argv_persisted"] is False
assert logical_command[0] == "<python>"
assert logical_command[logical_command.index("--profile") + 1] == "<temporary-profile>"
_assert_path_portable_receipt(child)
def _fixture(tmp_path: Path) -> dict[str, Path | dict]:
repo = tmp_path / "repo"
profile = repo / "profile-template"
hermes = repo / "hermes-runtime"
compiled = tmp_path / "compiled-profile"
_write(
profile / "config.yaml",
"""model:
provider: fixture-local
default: identity-v1
max_tokens: 512
memory:
enabled: false
gateway:
execution_mode: local_no_send
telegram:
bot_token: never-emit-this-fixture-value
transport:
endpoint: https://fixture-user:fixture-password@example.invalid/v1
headers: ['Authorization: Bearer fixture-secret']
tools:
allowed: [identity_readback]
write_enabled: false
identity_runtime:
network_send_enabled: false
database_write_enabled: false
allowed_tools: [identity_readback]
""",
)
_write(profile / "skills" / "identity" / "SKILL.md", "# identity readback\n")
_write(profile / "plugins" / "identity" / "__init__.py", "BOUNDARY = True\n")
_write(profile / "bin" / "identity_readback.py", "READ_ONLY = True\n")
_write(hermes / "run_agent.py", "RUNTIME = 'identity-v1'\n")
_write(hermes / "agent" / "prompt_builder.py", "SOUL_IS_GENERATED = True\n")
_write(hermes / "gateway" / "run.py", "SESSION_IS_IDENTITY = False\n")
_write(hermes / "hermes_cli" / "tools_config.py", "TOOLS = ('identity_readback',)\n")
_write(hermes / "tools" / "registry.py", "READ_ONLY = True\n")
for name in (
"leo_behavior_manifest.py",
"leo_identity_manifest.py",
"leo_identity_profile.py",
"run_leo_identity_reconstruction_canary.py",
):
_write(repo / "scripts" / name, (ROOT / "scripts" / name).read_text(encoding="utf-8"))
fingerprint_path = repo / "fixtures" / "database-fingerprint.json"
constitution_path = repo / "fixtures" / "constitution.json"
database_identity_path = repo / "fixtures" / "database-identity.json"
fingerprint = {
"schema": identity.DATABASE_FINGERPRINT_SCHEMA,
"status": "ok",
"environment": "disposable_fixture",
"fingerprint_sha256": "1" * 64,
"table_rows_sha256": "2" * 64,
"structure_sha256": "3" * 64,
"table_count": 2,
"total_rows": 2,
"read_consistency": {
"status": "stable_wal_marker",
"before": {
"database": "fixture",
"database_user": "reader",
"system_identifier": "12345",
"wal_lsn": "0/1",
},
"after": {
"database": "fixture",
"database_user": "reader",
"system_identifier": "12345",
"wal_lsn": "0/1",
},
},
}
constitution = {
"schema": identity.CONSTITUTION_SCHEMA,
"identity_name": "Leo",
"rules": [
{"id": "evidence", "text": "Never use temporary session memory as canonical evidence."},
{"id": "truth", "text": "Fail closed when a pinned identity input drifts."},
],
}
database_identity = {
"schema": identity.DATABASE_IDENTITY_SCHEMA,
"identity_name": "Leo",
"database_fingerprint_sha256": "1" * 64,
"source_provenance": {
"mode": identity.SYNTHETIC_DATABASE_MODE,
"canonical_authority_granted": False,
"same_transaction_as_fingerprint": False,
"export_receipt_sha256": None,
},
"records": [
{
"table": "public.personas",
"row_id": "persona-1",
"kind": "persona",
"rank": 0,
"text": "Leo is an evidence-bound reasoning interface.",
"status": "active",
"evidence_sha256": "a" * 64,
},
{
"table": "public.beliefs",
"row_id": "belief-1",
"kind": "belief",
"rank": 0,
"text": "Exact provenance is stronger than plausible recollection.",
"status": "active",
"evidence_sha256": "b" * 64,
},
],
}
_write_json(fingerprint_path, fingerprint)
_write_json(constitution_path, constitution)
_write_json(database_identity_path, database_identity)
subprocess.run(["git", "init", "-q", str(repo)], check=True)
subprocess.run(["git", "-C", str(repo), "config", "user.email", "test@example.com"], check=True)
subprocess.run(["git", "-C", str(repo), "config", "user.name", "Test"], check=True)
subprocess.run(["git", "-C", str(repo), "add", "."], check=True)
subprocess.run(
["git", "-C", str(repo), "commit", "-qm", "fixture"],
check=True,
env={
**dict(__import__("os").environ),
"GIT_AUTHOR_DATE": "2026-01-01T00:00:00Z",
"GIT_COMMITTER_DATE": "2026-01-01T00:00:00Z",
},
)
behavior_manifest = behavior.build_manifest(profile, hermes, repo)
manifest = identity.build_identity_manifest(
behavior_manifest=behavior_manifest,
database_fingerprint_path=fingerprint_path,
constitution_path=constitution_path,
database_identity_path=database_identity_path,
source_root=repo,
)
return {
"repo": repo,
"profile": profile,
"hermes": hermes,
"compiled": compiled,
"fingerprint": fingerprint_path,
"constitution": constitution_path,
"database_identity": database_identity_path,
"behavior": behavior_manifest,
"manifest": manifest,
}
def _fully_rehash_manifest(fixture: dict[str, Path | dict], manifest: dict) -> None:
identity_hash = behavior.canonical_sha256(manifest["identity_inputs"])
manifest["identity_inputs_sha256"] = identity_hash
fingerprint = identity.load_json(fixture["fingerprint"], "database fingerprint")
rules = identity.canonical_rules(identity.load_json(fixture["constitution"], "constitution"))
records = identity.canonical_database_records(
identity.load_json(fixture["database_identity"], "database identity"),
fingerprint_sha256=fingerprint["fingerprint_sha256"],
)
database_provenance = identity.database_identity_provenance(
identity.load_json(fixture["database_identity"], "database identity"),
fingerprint=fingerprint,
)
rendered = identity.render_identity_views(
identity_inputs_sha256=identity_hash,
database_fingerprint_sha256=fingerprint["fingerprint_sha256"],
database_provenance=database_provenance,
rules=rules,
records=records,
)
for name, content in rendered.items():
manifest["compiled_views"][name]["sha256"] = behavior.sha256_bytes(content.encode("utf-8"))
manifest["compiled_views"][name]["generated_from_identity_inputs_sha256"] = identity_hash
stable = {key: value for key, value in manifest.items() if key != "manifest_sha256"}
manifest["manifest_sha256"] = behavior.canonical_sha256(stable)
def _rehash_behavior_manifest(manifest: dict) -> None:
manifest["identity_runtime_sha256"] = behavior.canonical_sha256(behavior.identity_runtime_payload(manifest))
manifest["static_runtime_sha256"] = behavior.canonical_sha256(behavior.static_runtime_payload(manifest))
manifest["behavior_sha256"] = behavior.canonical_sha256(behavior.stable_manifest_payload(manifest))
def _canary_args(fixture: dict[str, Path | dict], output: Path, *, inject_drift: bool = False) -> argparse.Namespace:
return argparse.Namespace(
profile_template=fixture["profile"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
source_root=fixture["repo"],
database_fingerprint=fixture["fingerprint"],
constitution=fixture["constitution"],
database_identity=fixture["database_identity"],
output=output,
inject_drift_before_restart=inject_drift,
)
@pytest.mark.parametrize(
"private_path",
[
"/" + "Users/operator/checkout/profile",
"/" + "private/tmp/lane/.venv/bin/python",
"/" + "var/folders/cache/temporary-profile",
"/" + "tmp/temporary-profile",
"/" + "opt/checkout/interpreter",
"/" + "workspace/checkout/temporary-profile",
str(PureWindowsPath("C:/operator/checkout/temporary-profile")),
"\\\\" + "server\\share\\checkout\\temporary-profile",
],
)
def test_receipt_path_guard_recursively_rejects_private_and_absolute_paths(private_path: str) -> None:
with pytest.raises(canary.CanaryError, match="private or absolute filesystem path"):
_assert_path_portable_receipt({"outer": [{"logical_command": ["<python>", private_path]}]})
def test_receipt_path_guard_rejects_an_absolute_path_in_a_nested_key() -> None:
private_key = "/" + "tmp/checkout/temporary-profile"
with pytest.raises(canary.CanaryError, match="private or absolute filesystem path"):
_assert_path_portable_receipt({"outer": [{private_key: "<temporary-profile>"}]})
def test_logical_command_uses_placeholders_for_paths_outside_the_deployment_root(tmp_path: Path) -> None:
logical_command = canary._logical_query_command(
deployment_root=tmp_path / "checkout",
source_root=tmp_path / "outside-source",
hermes_root=tmp_path / "outside-hermes",
)
assert logical_command[logical_command.index("--source-root") + 1] == "<source-root>"
assert logical_command[logical_command.index("--hermes-root") + 1] == "<hermes-root>"
_assert_path_portable_receipt(logical_command)
@pytest.mark.parametrize("receipt_path", COMMITTED_RECEIPTS, ids=lambda path: path.name)
def test_committed_identity_receipts_are_path_portable_and_self_hashed(receipt_path: Path) -> None:
receipt = json.loads(receipt_path.read_text(encoding="utf-8"))
_assert_path_portable_receipt(receipt)
stable = {key: value for key, value in receipt.items() if key != "receipt_sha256"}
assert behavior.canonical_sha256(stable) == receipt["receipt_sha256"]
def test_manifest_compiles_generated_views_and_reproduces_identity_across_queries(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
manifest = fixture["manifest"]
assert isinstance(manifest, dict)
rebuilt = identity.build_identity_manifest(
behavior_manifest=fixture["behavior"],
database_fingerprint_path=fixture["fingerprint"],
constitution_path=fixture["constitution"],
database_identity_path=fixture["database_identity"],
source_root=fixture["repo"],
)
assert rebuilt == manifest
compile_receipt = profile_runtime.compile_profile(
manifest,
source_root=fixture["repo"],
profile_template=fixture["profile"],
profile=fixture["compiled"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
)
first = profile_runtime.query_profile(
fixture["compiled"],
query=profile_runtime.FIXED_QUERY,
source_root=fixture["repo"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
)
second = profile_runtime.query_profile(
fixture["compiled"],
query=profile_runtime.FIXED_QUERY,
source_root=fixture["repo"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
)
assert compile_receipt["status"] == "pass"
assert "never-emit-this-fixture-value" not in (fixture["compiled"] / "config.yaml").read_text(encoding="utf-8")
assert "fixture-password" not in (fixture["compiled"] / "config.yaml").read_text(encoding="utf-8")
assert "fixture-secret" not in (fixture["compiled"] / "config.yaml").read_text(encoding="utf-8")
assert (fixture["compiled"] / "SOUL.md").read_text(encoding="utf-8").startswith("<!-- GENERATED FILE")
assert first["manifest_sha256"] == second["manifest_sha256"]
assert first["identity_inputs_sha256"] == second["identity_inputs_sha256"]
assert first["answer_sha256"] == second["answer_sha256"]
assert first["output_provenance"] == second["output_provenance"]
assert first["runtime_instance_id"] != second["runtime_instance_id"]
assert first["session"]["included_in_output_provenance"] is False
assert first["output_provenance"]["database_canonical_authority_granted"] is False
assert first["authorization"]["authorization_decision_observed"] is False
assert "synthetic noncanonical fixture" in first["answer"]
assert len(list((fixture["compiled"] / "sessions").glob("*.json"))) == 2
def test_profile_and_bound_source_drift_fail_closed(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
profile_runtime.compile_profile(
fixture["manifest"],
source_root=fixture["repo"],
profile_template=fixture["profile"],
profile=fixture["compiled"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
)
with (fixture["compiled"] / "SOUL.md").open("a", encoding="utf-8") as handle:
handle.write("drift\n")
with pytest.raises(identity.IdentityManifestError, match="compiled view drift detected"):
profile_runtime.query_profile(
fixture["compiled"],
query=profile_runtime.FIXED_QUERY,
source_root=fixture["repo"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
)
_write(fixture["constitution"], fixture["constitution"].read_text(encoding="utf-8") + "\n")
with pytest.raises(identity.IdentityManifestError, match="constitution source content drift"):
identity.verify_bound_sources(fixture["manifest"], fixture["repo"])
@pytest.mark.parametrize(
("relative_path", "content", "message"),
[
("memories/USER.md", "untrusted memory\n", "forbidden nonauthoritative"),
("MEMORY.md", "untrusted top-level memory\n", "forbidden nonauthoritative"),
("USER.md", "untrusted top-level user memory\n", "forbidden nonauthoritative"),
("platforms/pairing/telegram.json", "{}\n", "forbidden nonauthoritative"),
(".env", "LEO_SECRET=untrusted\n", "profile entry set is not exact"),
("gateway.json", "{}\n", "profile entry set is not exact"),
("unexpected.txt", "untrusted input\n", "profile entry set is not exact"),
("sessions/injected.txt", "untrusted session\n", "unsafe session entry"),
("state/injected.json", "{}\n", "state directory must remain empty"),
],
)
def test_profile_rechecks_nonauthoritative_surfaces_before_every_query(
tmp_path: Path, relative_path: str, content: str, message: str
) -> None:
fixture = _fixture(tmp_path)
profile_runtime.compile_profile(
fixture["manifest"],
source_root=fixture["repo"],
profile_template=fixture["profile"],
profile=fixture["compiled"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
)
_write(fixture["compiled"] / relative_path, content)
with pytest.raises(profile_runtime.IdentityProfileError, match=message):
profile_runtime.query_profile(
fixture["compiled"],
query=profile_runtime.FIXED_QUERY,
source_root=fixture["repo"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
)
def test_manifest_rejects_rehashed_core_tampering(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
tampered = copy.deepcopy(fixture["manifest"])
tampered["identity_inputs"]["session_boundary"]["may_be_used_as_evidence"] = True
stable = {key: value for key, value in tampered.items() if key != "manifest_sha256"}
tampered["manifest_sha256"] = behavior.canonical_sha256(stable)
with pytest.raises(identity.IdentityManifestError, match="identity input hash drift"):
identity.validate_identity_manifest(tampered)
@pytest.mark.parametrize(
("path", "value", "message"),
[
(("permissions", "runtime_policy", "network_send_enabled"), True, "exact local readback policy"),
(("session_boundary", "may_be_used_as_evidence"), True, "session authority boundary"),
],
)
def test_manifest_rejects_fully_rehashed_safety_invariant_tampering(
tmp_path: Path, path: tuple[str, ...], value: object, message: str
) -> None:
fixture = _fixture(tmp_path)
tampered = copy.deepcopy(fixture["manifest"])
target = tampered["identity_inputs"]
for key in path[:-1]:
target = target[key]
target[path[-1]] = value
_fully_rehash_manifest(fixture, tampered)
with pytest.raises(identity.IdentityManifestError, match=message):
identity.verify_bound_sources(tampered, fixture["repo"])
def test_behavior_manifest_rejects_unhashed_model_claim_tampering(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
tampered_behavior = copy.deepcopy(fixture["behavior"])
tampered_behavior["model_runtime"]["default_model"] = "tampered-unobserved-model"
with pytest.raises(identity.IdentityManifestError, match="behavior identity runtime hash drift"):
identity.build_identity_manifest(
behavior_manifest=tampered_behavior,
database_fingerprint_path=fixture["fingerprint"],
constitution_path=fixture["constitution"],
database_identity_path=fixture["database_identity"],
source_root=fixture["repo"],
)
def test_profile_rejects_a_dangling_extra_symlink(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
profile_runtime.compile_profile(
fixture["manifest"],
source_root=fixture["repo"],
profile_template=fixture["profile"],
profile=fixture["compiled"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
)
(fixture["compiled"] / ".env").symlink_to(tmp_path / "missing-env")
with pytest.raises(profile_runtime.IdentityProfileError, match="profile entry set is not exact"):
profile_runtime.query_profile(
fixture["compiled"],
query=profile_runtime.FIXED_QUERY,
source_root=fixture["repo"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
)
def test_profile_rejects_a_symlink_in_an_allowed_entry(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
profile_runtime.compile_profile(
fixture["manifest"],
source_root=fixture["repo"],
profile_template=fixture["profile"],
profile=fixture["compiled"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
)
external_config = tmp_path / "external-config.yaml"
external_config.write_bytes((fixture["compiled"] / "config.yaml").read_bytes())
(fixture["compiled"] / "config.yaml").unlink()
(fixture["compiled"] / "config.yaml").symlink_to(external_config)
with pytest.raises(profile_runtime.IdentityProfileError, match="profile entries must not be symlinks"):
profile_runtime.query_profile(
fixture["compiled"],
query=profile_runtime.FIXED_QUERY,
source_root=fixture["repo"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
)
@pytest.mark.parametrize(
("mutation", "message"),
[
("unreadable_file", "unreadable inputs"),
("symlink", "unsupported symlinks"),
("forged_structure", "is empty"),
],
)
def test_behavior_manifest_rejects_unreplayable_identity_components(
tmp_path: Path, mutation: str, message: str
) -> None:
fixture = _fixture(tmp_path)
tampered_behavior = copy.deepcopy(fixture["behavior"])
content = tampered_behavior["components"]["procedural_skills"]["content"]
if mutation == "unreadable_file":
content["files"][0].pop("sha256")
content["files"][0]["status"] = "unavailable"
elif mutation == "symlink":
content["symlinks"].append(
{
"path": "skills/identity/link",
"target": "/outside/checkout",
"target_fingerprint": {"kind": "unavailable", "error": "FileNotFoundError"},
}
)
else:
content["files"] = []
content["sha256"] = behavior.canonical_sha256({key: content[key] for key in ("files", "missing", "symlinks")})
_rehash_behavior_manifest(tampered_behavior)
with pytest.raises(identity.IdentityManifestError, match=message):
identity.validate_behavior_manifest(tampered_behavior)
def test_fully_rehashed_model_claim_must_match_observed_runtime(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
tampered = copy.deepcopy(fixture["manifest"])
tampered["identity_inputs"]["model"]["default_model"] = "tampered-unobserved-model"
_fully_rehash_manifest(fixture, tampered)
identity.validate_identity_manifest(tampered)
with pytest.raises(
profile_runtime.IdentityProfileError, match="model runtime binding drift detected: default_model"
):
profile_runtime.compile_profile(
tampered,
source_root=fixture["repo"],
profile_template=fixture["profile"],
profile=fixture["compiled"],
hermes_root=fixture["hermes"],
deployment_root=fixture["repo"],
)
assert not fixture["compiled"].exists()
def test_restart_canary_uses_distinct_processes_and_cleans_up(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
output = tmp_path / "restart-receipt.json"
report, exit_code = canary.run_canary(_canary_args(fixture, output))
assert exit_code == 0
assert report["status"] == "pass"
assert report["gates"]["restart_process_is_distinct"] is True
assert report["gates"]["restart_profile_recompiled_from_manifest"] is True
assert report["restart_compile"]["session_directories_started_empty"] is True
assert report["drift_compile"]["session_directories_started_empty"] is True
_assert_logical_child_execution(report["first_start"], profile_role="first_start")
_assert_logical_child_execution(report["restart"], profile_role="restart")
_assert_logical_child_execution(report["drift_negative"], profile_role="drift_negative")
_assert_path_portable_receipt(report)
assert report["first_start"]["launcher_pid"] != report["restart"]["launcher_pid"]
assert report["first_start"]["process_group_absent_after_wait"] is True
assert report["restart"]["process_group_absent_after_wait"] is True
assert report["drift_negative"]["fail_closed"] is True
assert report["drift_negative"]["process_group_absent_after_wait"] is True
assert report["goal_tier_satisfied"] is True
assert report["current_tier"] == "T2_runtime"
assert report["cleanup"]["temporary_root_removed"] is True
assert behavior.git_state(fixture["repo"])["worktree_clean"] is True
assert json.loads(output.read_text(encoding="utf-8")) == report
def test_restart_canary_rejects_drift_before_second_start(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
output = tmp_path / "drift-receipt.json"
report, exit_code = canary.run_canary(_canary_args(fixture, output, inject_drift=True))
assert exit_code == 0
assert report["status"] == "pass"
assert report["gates"]["drift_detected_before_restart"] is True
assert report["second_start_attempted"] is False
assert "restart" not in report
_assert_logical_child_execution(report["first_start"], profile_role="first_start")
_assert_logical_child_execution(report["pre_restart_drift"], profile_role="pre_restart_drift")
_assert_path_portable_receipt(report)
assert report["pre_restart_drift"]["process_group_absent_after_wait"] is True
assert all(report["gates"].values())
assert report["goal_tier_satisfied"] is False
assert report["current_tier"] == "T1_model"
assert report["cleanup"]["temporary_root_removed"] is True
assert json.loads(output.read_text(encoding="utf-8")) == report
def test_query_child_timeout_terminates_process_group(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
marker = tmp_path / "descendant.pid"
sleeping_module = f"""import subprocess
import sys
import time
from pathlib import Path
child = subprocess.Popen([sys.executable, '-c', 'import time; time.sleep(60)'])
Path({str(marker)!r}).write_text(str(child.pid), encoding='utf-8')
time.sleep(60)
"""
_write(fixture["repo"] / "scripts" / "leo_identity_profile.py", sleeping_module)
result = canary._run_query_child(
deployment_root=fixture["repo"],
profile=fixture["compiled"],
source_root=fixture["repo"],
hermes_root=fixture["hermes"],
profile_role="timeout_test",
timeout_seconds=0.5,
)
assert result["timed_out"] is True
assert result["terminated_with"] in {"SIGTERM", "SIGKILL"}
assert result["returncode"] != 0
assert result["process_group_absent_after_wait"] is True
descendant_pid = int(marker.read_text(encoding="utf-8"))
deadline = time.monotonic() + 5
while time.monotonic() < deadline:
try:
os.kill(descendant_pid, 0)
except ProcessLookupError:
break
time.sleep(0.02)
with pytest.raises(ProcessLookupError):
os.kill(descendant_pid, 0)
def test_query_child_cleans_and_rejects_orphan_from_completed_launcher(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
marker = tmp_path / "completed-descendant.pid"
query_payload = {"schema": profile_runtime.QUERY_RECEIPT_SCHEMA, "status": "pass"}
leaking_module = f"""import json
import subprocess
import sys
from pathlib import Path
child = subprocess.Popen(
[sys.executable, '-c', 'import time; time.sleep(60)'],
stdin=subprocess.DEVNULL,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
Path({str(marker)!r}).write_text(str(child.pid), encoding='utf-8')
print(json.dumps({query_payload!r}))
"""
_write(fixture["repo"] / "scripts" / "leo_identity_profile.py", leaking_module)
result = canary._run_query_child(
deployment_root=fixture["repo"],
profile=fixture["compiled"],
source_root=fixture["repo"],
hermes_root=fixture["hermes"],
profile_role="orphan_cleanup_test",
timeout_seconds=5,
)
assert result["returncode"] == 0
assert result["orphan_cleanup_required"] is True
assert result["terminated_with"] in {"SIGTERM", "SIGKILL"}
assert result["process_group_absent_after_wait"] is True
assert canary._query_passed(result) is False
def test_wal_capture_marker_is_not_an_identity_input(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
original = fixture["manifest"]
fingerprint = json.loads(fixture["fingerprint"].read_text(encoding="utf-8"))
fingerprint["read_consistency"]["before"]["wal_lsn"] = "0/2"
fingerprint["read_consistency"]["after"]["wal_lsn"] = "0/2"
_write_json(fixture["fingerprint"], fingerprint)
rebuilt = identity.build_identity_manifest(
behavior_manifest=fixture["behavior"],
database_fingerprint_path=fixture["fingerprint"],
constitution_path=fixture["constitution"],
database_identity_path=fixture["database_identity"],
source_root=fixture["repo"],
)
assert rebuilt["identity_inputs_sha256"] == original["identity_inputs_sha256"]
assert rebuilt["manifest_sha256"] == original["manifest_sha256"]
def test_database_identity_and_system_markers_are_identity_inputs(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
original = fixture["manifest"]
fingerprint = json.loads(fixture["fingerprint"].read_text(encoding="utf-8"))
for marker in (fingerprint["read_consistency"]["before"], fingerprint["read_consistency"]["after"]):
marker["database"] = "different_database"
marker["database_user"] = "different_reader"
marker["system_identifier"] = "99999"
_write_json(fixture["fingerprint"], fingerprint)
rebuilt = identity.build_identity_manifest(
behavior_manifest=fixture["behavior"],
database_fingerprint_path=fixture["fingerprint"],
constitution_path=fixture["constitution"],
database_identity_path=fixture["database_identity"],
source_root=fixture["repo"],
)
assert rebuilt["identity_inputs_sha256"] != original["identity_inputs_sha256"]
with pytest.raises(identity.IdentityManifestError, match="database fingerprint semantic drift"):
identity.verify_bound_sources(original, fixture["repo"])
def test_synthetic_database_rows_cannot_claim_canonical_authority(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
database_identity = json.loads(fixture["database_identity"].read_text(encoding="utf-8"))
database_identity["source_provenance"] = {
"mode": identity.CANONICAL_DATABASE_MODE,
"canonical_authority_granted": True,
"same_transaction_as_fingerprint": True,
"export_receipt_sha256": "f" * 64,
}
_write_json(fixture["database_identity"], database_identity)
with pytest.raises(identity.IdentityManifestError, match="independently verified output"):
identity.build_identity_manifest(
behavior_manifest=fixture["behavior"],
database_fingerprint_path=fixture["fingerprint"],
constitution_path=fixture["constitution"],
database_identity_path=fixture["database_identity"],
source_root=fixture["repo"],
)
def test_self_hashed_database_export_receipt_cannot_grant_canonical_authority(tmp_path: Path) -> None:
fixture = _fixture(tmp_path)
fingerprint = json.loads(fixture["fingerprint"].read_text(encoding="utf-8"))
fingerprint["environment"] = "canonical_readonly_capture"
_write_json(fixture["fingerprint"], fingerprint)
database_identity = json.loads(fixture["database_identity"].read_text(encoding="utf-8"))
records = identity.canonical_database_records(
database_identity,
fingerprint_sha256=fingerprint["fingerprint_sha256"],
)
marker = fingerprint["read_consistency"]["before"]
receipt_stable = {
"schema": "livingip.untrustedCallerSuppliedExportReceipt.v1",
"read_only": True,
"same_transaction_as_fingerprint": True,
"transaction_isolation": "repeatable_read_read_only",
"database": marker["database"],
"database_user": marker["database_user"],
"system_identifier": marker["system_identifier"],
"database_fingerprint_sha256": fingerprint["fingerprint_sha256"],
"records_sha256": behavior.canonical_sha256(records),
}
receipt_hash = behavior.canonical_sha256(receipt_stable)
database_identity["source_provenance"] = {
"mode": identity.CANONICAL_DATABASE_MODE,
"canonical_authority_granted": True,
"same_transaction_as_fingerprint": True,
"export_receipt_sha256": receipt_hash,
}
database_identity["export_receipt"] = {**receipt_stable, "receipt_sha256": receipt_hash}
_write_json(fixture["database_identity"], database_identity)
with pytest.raises(identity.IdentityManifestError, match="independently verified output"):
identity.build_identity_manifest(
behavior_manifest=fixture["behavior"],
database_fingerprint_path=fixture["fingerprint"],
constitution_path=fixture["constitution"],
database_identity_path=fixture["database_identity"],
source_root=fixture["repo"],
)
def test_same_clean_commit_reproduces_identity_from_different_checkout_paths(tmp_path: Path) -> None:
first = _fixture(tmp_path / "checkout-a")
second = _fixture(tmp_path / "checkout-b")
assert (
first["behavior"]["teleo_infrastructure_runtime"]["git_head"]
== second["behavior"]["teleo_infrastructure_runtime"]["git_head"]
)
assert first["behavior"]["identity_runtime_sha256"] == second["behavior"]["identity_runtime_sha256"]
assert first["manifest"]["identity_inputs_sha256"] == second["manifest"]["identity_inputs_sha256"]
assert first["manifest"]["manifest_sha256"] == second["manifest"]["manifest_sha256"]

Some files were not shown because too many files have changed in this diff Show more