#!/usr/bin/env python3 """Cloud SQL memory and KB-proposal bridge for the GCP leoclean profile. Canonical claim/strategy application remains review-gated. Read commands query the canonical Teleo KB first, then fall back to the restored `teleo_restore` shadow schema in Cloud SQL. Proposal commands write staged review records into `kb_stage.kb_proposals`; they do not apply canonical truth directly. """ from __future__ import annotations import argparse import json import os import re import subprocess from typing import Any STOPWORDS = { "a", "about", "after", "all", "an", "and", "are", "as", "at", "be", "before", "by", "can", "cloud", "context", "do", "does", "for", "from", "gcp", "give", "how", "i", "in", "into", "is", "it", "leo", "me", "memory", "of", "on", "or", "our", "production", "should", "source", "that", "the", "their", "this", "to", "using", "what", "when", "where", "which", "who", "why", "with", "you", "your", } DEFAULT_CLAIM_BASE_URL = "https://leo.livingip.xyz" def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--host", default=os.environ.get("TELEO_CLOUDSQL_HOST", "10.61.0.3")) parser.add_argument("--port", default=os.environ.get("TELEO_CLOUDSQL_PORT", "5432")) parser.add_argument("--db", default=os.environ.get("TELEO_CLOUDSQL_DB", "teleo_kb")) parser.add_argument("--canonical-db", default=os.environ.get("TELEO_CANONICAL_CLOUDSQL_DB", "teleo_canonical")) parser.add_argument("--user", default=os.environ.get("TELEO_CLOUDSQL_USER", "postgres")) parser.add_argument( "--password-secret", default=os.environ.get("TELEO_CLOUDSQL_PASSWORD_SECRET", "gcp-teleo-pgvector-standby-postgres-password"), ) parser.add_argument("--project", default=os.environ.get("TELEO_GCP_PROJECT", "teleo-501523")) parser.add_argument("--format", choices=["markdown", "json"], default="markdown") parser.add_argument( "--include-excerpts", "--raw-ok", dest="include_excerpts", action="store_true", default=os.environ.get("TELEO_MEMORY_INCLUDE_EXCERPTS", "") == "1", help="Include short memory excerpts for agent context. Default proof mode is redacted.", ) parser.add_argument("--redacted", action="store_true", default=os.environ.get("TELEO_MEMORY_REDACT", "") == "1") sub = parser.add_subparsers(dest="command", required=True) search = sub.add_parser("search", help="Search restored Cloud SQL memory rows.") search.add_argument("query") search.add_argument("--limit", type=int, default=8) search.add_argument("--context-limit", type=int, default=argparse.SUPPRESS, help="Accepted for teleo-kb compatibility; ignored.") search.add_argument("--format", choices=["markdown", "json"], default=argparse.SUPPRESS) search.add_argument("--redacted", action="store_true", default=argparse.SUPPRESS) search.add_argument("--include-excerpts", "--raw-ok", dest="include_excerpts", action="store_true", default=argparse.SUPPRESS) context = sub.add_parser("context", help="Build an agent-ready memory context bundle.") context.add_argument("query") context.add_argument("--limit", type=int, default=8) context.add_argument("--context-limit", type=int, default=argparse.SUPPRESS, help="Accepted for teleo-kb compatibility; ignored.") context.add_argument("--format", choices=["markdown", "json"], default=argparse.SUPPRESS) context.add_argument("--redacted", action="store_true", default=argparse.SUPPRESS) context.add_argument("--include-excerpts", "--raw-ok", dest="include_excerpts", action="store_true", default=argparse.SUPPRESS) show = sub.add_parser("show", help="Show one canonical claim with evidence and edges.") show.add_argument("claim_id") show.add_argument("--format", choices=["markdown", "json"], default=argparse.SUPPRESS) show.add_argument("--redacted", action="store_true", default=argparse.SUPPRESS) show.add_argument("--include-excerpts", "--raw-ok", dest="include_excerpts", action="store_true", default=argparse.SUPPRESS) evidence = sub.add_parser("evidence", help="Show canonical evidence rows for one claim.") evidence.add_argument("claim_id") evidence.add_argument("--limit", type=int, default=8) evidence.add_argument("--format", choices=["markdown", "json"], default=argparse.SUPPRESS) evidence.add_argument("--redacted", action="store_true", default=argparse.SUPPRESS) evidence.add_argument("--include-excerpts", "--raw-ok", dest="include_excerpts", action="store_true", default=argparse.SUPPRESS) edges = sub.add_parser("edges", help="Show canonical graph edges for one claim.") edges.add_argument("claim_id") edges.add_argument("--limit", type=int, default=12) edges.add_argument("--format", choices=["markdown", "json"], default=argparse.SUPPRESS) edges.add_argument("--redacted", action="store_true", default=argparse.SUPPRESS) edges.add_argument("--include-excerpts", "--raw-ok", dest="include_excerpts", action="store_true", default=argparse.SUPPRESS) status = sub.add_parser("status", help="Read back Cloud SQL memory backend status.") status.add_argument("--format", choices=["markdown", "json"], default=argparse.SUPPRESS) status.add_argument("--redacted", action="store_true", default=argparse.SUPPRESS) propose = sub.add_parser( "propose-core-change", help="Stage a review-gated canonical KB change instead of writing core truth to runtime memory.", ) propose.add_argument("--proposal-type", choices=["revise_claim", "revise_strategy"], required=True) propose.add_argument("--target-kind", choices=["claim", "belief", "strategy", "identity", "role", "telos", "framework", "reasoning_tool", "other"], required=True) propose.add_argument("--target-ref", required=True, help="Claim id, strategy id/name, or unresolved target description.") propose.add_argument("--current", default="", help="Current/old claim or state, if known.") propose.add_argument("--proposed", required=True, help="Proposed replacement or correction.") propose.add_argument("--evidence", action="append", default=[], help="Evidence/source pointer. Can be repeated.") propose.add_argument("--implication", action="append", default=[], help="Downstream implication. Can be repeated.") propose.add_argument("--proposed-by", default="leo") propose.add_argument("--originator", default="", help="Human or agent who originated the correction.") propose.add_argument("--channel", default="telegram") propose.add_argument("--source-ref", required=True) propose.add_argument("--rationale", required=True) propose.add_argument("--format", choices=["markdown", "json"], default=argparse.SUPPRESS) propose_edge = sub.add_parser("propose-edge", help="Stage a strict add_edge proposal for reviewer approval.") propose_edge.add_argument("from_claim") propose_edge.add_argument("edge_type") propose_edge.add_argument("to_claim") propose_edge.add_argument("--proposed-by", default="leo") propose_edge.add_argument("--channel", default="telegram") propose_edge.add_argument("--source-ref", required=True) propose_edge.add_argument("--rationale", required=True) propose_edge.add_argument("--format", choices=["markdown", "json"], default=argparse.SUPPRESS) list_proposals = sub.add_parser("list-proposals", help="List staged KB proposals from Cloud SQL.") list_proposals.add_argument("--status", default="pending_review") list_proposals.add_argument("--limit", type=int, default=10) list_proposals.add_argument("--format", choices=["markdown", "json"], default=argparse.SUPPRESS) show_proposal = sub.add_parser("show-proposal", help="Show one staged KB proposal from Cloud SQL.") show_proposal.add_argument("proposal_id") show_proposal.add_argument("--format", choices=["markdown", "json"], default=argparse.SUPPRESS) return parser.parse_args() def terms_for(query: str) -> list[str]: terms: list[str] = [] for token in re.findall(r"[A-Za-z0-9][A-Za-z0-9.+#/-]*", query.lower()): token = token.strip("-/") if len(token) < 3 or token in STOPWORDS: continue if token not in terms: terms.append(token) return terms[:14] or [query.lower()] def claim_base_url() -> str: return os.environ.get("TELEO_KB_CLAIM_BASE_URL", DEFAULT_CLAIM_BASE_URL).rstrip("/") def claim_url(claim_id: str | None) -> str | None: if not claim_id: return None return f"{claim_base_url()}/kb/claims/{claim_id}" def markdown_claim_link(claim_id: str | None, label: str | None = None) -> str: if not claim_id: return "`unknown`" text = " ".join(str(label or claim_id).replace("`", "'").split()) return f"[`{text}`]({claim_url(claim_id)})" def sql_literal(value: str) -> str: return "'" + value.replace("'", "''") + "'" def sql_json_array(values: list[str]) -> str: return "'{}'::json".format(json.dumps(values).replace("'", "''")) def sql_array(values: list[str], cast: str = "text") -> str: return "array[" + ",".join(sql_literal(value) for value in values) + f"]::{cast}[]" def password(args: argparse.Namespace) -> str: if os.environ.get("PGPASSWORD"): return os.environ["PGPASSWORD"] result = subprocess.run( [ "gcloud", "secrets", "versions", "access", "latest", f"--secret={args.password_secret}", f"--project={args.project}", ], text=True, capture_output=True, check=False, ) if result.returncode != 0: raise SystemExit(f"Secret access failed: {result.stderr.strip()}") return result.stdout.strip() def run_psql(args: argparse.Namespace, sql: str, db: str | None = None) -> str: env = os.environ.copy() env["PGPASSWORD"] = password(args) conn = f"host={args.host} port={args.port} dbname={db or args.db} user={args.user} sslmode=require" result = subprocess.run( ["psql", conn, "-At", "-q", "-v", "ON_ERROR_STOP=1"], text=True, capture_output=True, input=sql, env=env, check=False, ) if result.returncode != 0: raise SystemExit( f"Cloud SQL query failed ({result.returncode})\nSTDOUT:\n{result.stdout}\nSTDERR:\n{result.stderr}" ) return result.stdout def psql_json_lines(args: argparse.Namespace, sql: str, db: str | None = None) -> list[dict[str, Any]]: rows: list[dict[str, Any]] = [] for line in run_psql(args, sql, db=db).splitlines(): line = line.strip() if line: rows.append(json.loads(line)) return rows def include_excerpts(args: argparse.Namespace) -> bool: return bool(getattr(args, "include_excerpts", False)) and not bool(getattr(args, "redacted", False)) def query_canonical_rows(args: argparse.Namespace, query: str, limit: int) -> dict[str, Any]: terms = terms_for(query) patterns = [f"%{term}%" for term in terms] min_score = 2 if len(patterns) >= 3 else 1 claim_limit = max(1, min(limit, 20)) context_limit = max(1, min(int(getattr(args, "context_limit", limit) or limit), 20)) claims_sql = f""" with params(patterns) as ( values ({sql_array(patterns)}) ), ranked as ( select c.id, c.type, c.text, c.status, c.confidence, c.tags, ( select count(*) from params p, unnest(p.patterns) pattern where lower(c.text) like pattern or exists ( select 1 from unnest(coalesce(c.tags, '{{}}'::text[])) tag where lower(tag) like pattern ) ) as score, (select count(*) from public.claim_evidence ce where ce.claim_id = c.id) as evidence_count, (select count(*) from public.claim_edges e where e.from_claim = c.id or e.to_claim = c.id) as edge_count from public.claims c where c.status = 'open' ) select jsonb_build_object( 'id', id::text, 'type', type, 'text', text, 'status', status, 'confidence', confidence, 'tags', coalesce(to_jsonb(tags), '[]'::jsonb), 'score', score, 'evidence_count', evidence_count, 'edge_count', edge_count )::text from ranked where score >= {min_score} order by score desc, evidence_count desc, edge_count desc, coalesce(confidence, 0) desc, length(text) limit {claim_limit}; """ context_sql = f""" with params(patterns) as ( values ({sql_array(patterns)}) ), corpus as ( select 'persona' as source, a.handle as owner, p.name as title, concat_ws(E'\\n', p.voice, p.role, p.source_ref, p.lens) as body from public.personas p join public.agents a on a.id = p.agent_id union all select 'strategy' as source, a.handle as owner, 'active strategy v' || s.version::text as title, concat_ws(E'\\n', s.diagnosis, s.guiding_policy, s.proximate_objectives::text) as body from public.strategies s join public.agents a on a.id = s.agent_id where s.active union all select 'belief' as source, a.handle as owner, concat_ws(' ', b.level::text, 'rank', b.rank::text) as title, concat_ws(E'\\n', b.statement, b.falsifier) as body from public.beliefs b join public.agents a on a.id = b.agent_id where b.status = 'active' union all select 'blindspot' as source, a.handle as owner, bs.name as title, concat_ws(E'\\n', bs.description, bs.correction, bs.kind) as body from public.blindspots bs join public.agents a on a.id = bs.agent_id where bs.status = 'active' union all select 'agent_role' as source, a.handle as owner, ar.title as title, ar.description as body from public.agent_roles ar join public.agents a on a.id = ar.agent_id union all select 'peer_model' as source, subject.handle as owner, 'peer ' || peer.handle || ': ' || pm.domain as title, concat_ws(E'\\n', pm.outranks_on, pm.deference_rule) as body from public.peer_models pm join public.agents subject on subject.id = pm.subject_id join public.agents peer on peer.id = pm.peer_id union all select 'behavioral_rule' as source, coalesce(a.handle, 'collective') as owner, br.category::text as title, concat_ws(E'\\n', br.rule, br.rationale) as body from public.behavioral_rules br left join public.agents a on a.id = br.agent_id union all select 'contributor_rule' as source, coalesce(a.handle, 'collective') as owner, cr.name as title, concat_ws(E'\\n', cr.directive, cr.ci_tier, cr.weighting, cr.rationale) as body from public.contributor_rules cr left join public.agents a on a.id = cr.agent_id union all select 'reasoning_tool' as source, coalesce(a.handle, 'collective') as owner, rt.name as title, concat_ws(E'\\n', rt.description, rt.category) as body from public.reasoning_tools rt left join public.agents a on a.id = rt.agent_id union all select 'governance_gate' as source, coalesce(a.handle, 'collective') as owner, gg.name as title, concat_ws(E'\\n', gg.criteria, gg.evidence_bar, gg.pass_condition) as body from public.governance_gates gg left join public.agents a on a.id = gg.agent_id ), ranked as ( select source, owner, title, body, ( select count(*) from params p, unnest(p.patterns) pattern where lower(concat_ws(E'\\n', source, owner, title, body)) like pattern ) as score from corpus ) select jsonb_build_object( 'source', source, 'owner', owner, 'title', title, 'body', left(coalesce(body, ''), 900), 'score', score )::text from ranked where score >= {min_score} order by score desc, source, owner, title limit {context_limit}; """ claims = psql_json_lines(args, claims_sql, db=args.canonical_db) claim_ids = [claim["id"] for claim in claims] evidence: dict[str, list[dict[str, Any]]] = {claim_id: [] for claim_id in claim_ids} edges: dict[str, list[dict[str, Any]]] = {claim_id: [] for claim_id in claim_ids} if claim_ids: ids = sql_array(claim_ids, "uuid") evidence_sql = f""" with ranked as ( select ce.claim_id, ce.role::text as role, ce.weight, s.source_type, s.url, s.storage_path, left(coalesce(s.excerpt, ''), 800) as excerpt, row_number() over ( partition by ce.claim_id order by (s.storage_path like 'inbox/archive/%') desc, ce.role::text, s.storage_path nulls last, s.url nulls last ) as rn from public.claim_evidence ce join public.sources s on s.id = ce.source_id where ce.claim_id = any({ids}) ) select jsonb_build_object( 'claim_id', claim_id::text, 'role', role, 'weight', weight, 'source_type', source_type, 'url', url, 'storage_path', storage_path, 'excerpt', excerpt )::text from ranked where rn <= 4 order by claim_id, rn; """ for row in psql_json_lines(args, evidence_sql, db=args.canonical_db): evidence.setdefault(row["claim_id"], []).append(row) edges_sql = f""" with base(id) as ( select unnest({ids}) ), edge_rows as ( select base.id as claim_id, case when e.from_claim = base.id then 'outgoing' else 'incoming' end as direction, e.edge_type::text as edge_type, other.id as connected_id, other.text as connected_text, other.tags as connected_tags, row_number() over ( partition by base.id order by case e.edge_type::text when 'supports' then 1 when 'challenges' then 2 when 'contradicts' then 3 when 'requires' then 4 when 'supersedes' then 5 when 'constrains' then 6 when 'causes' then 7 when 'accelerates' then 8 else 9 end, other.text ) as rn from base join public.claim_edges e on e.from_claim = base.id or e.to_claim = base.id join public.claims other on other.id = case when e.from_claim = base.id then e.to_claim else e.from_claim end ) select jsonb_build_object( 'claim_id', claim_id::text, 'direction', direction, 'edge_type', edge_type, 'connected_id', connected_id::text, 'connected_text', connected_text, 'connected_tags', coalesce(to_jsonb(connected_tags), '[]'::jsonb) )::text from edge_rows where rn <= 6 order by claim_id, rn; """ for row in psql_json_lines(args, edges_sql, db=args.canonical_db): edges.setdefault(row["claim_id"], []).append(row) for claim in claims: claim["claim_url"] = claim_url(claim["id"]) claim["evidence"] = evidence.get(claim["id"], []) claim["edges"] = edges.get(claim["id"], []) for edge in claim["edges"]: edge["connected_url"] = claim_url(edge.get("connected_id")) context_rows = psql_json_lines(args, context_sql, db=args.canonical_db) result: dict[str, Any] = { "artifact": "teleo_cloudsql_canonical_kb_context", "backend": f"cloudsql:teleo-pgvector-standby/{args.canonical_db}/public+kb_stage", "query": query, "terms": terms, "claims": claims, "context_rows": context_rows, "hit_count_total": len(claims) + len(context_rows), "hits": [ { "source_table": "public.claims", "row_id": claim["id"], "score": claim.get("score"), "claim_type": claim.get("type"), "claim_status": claim.get("status"), "confidence": claim.get("confidence"), "tags": claim.get("tags") or [], "evidence_count": claim.get("evidence_count"), "edge_count": claim.get("edge_count"), "excerpt": claim.get("text"), } for claim in claims ] + [ { "source_table": f"public.{row['source']}", "row_id": f"{row['owner']}:{row['title']}", "score": row.get("score"), "actor": row.get("owner"), "excerpt": row.get("body"), } for row in context_rows ], "privacy": "redacted proof mode by default; pass --include-excerpts/--raw-ok only for private agent context", } if not include_excerpts(args): for claim in result["claims"]: claim.pop("text", None) for row in claim.get("evidence", []): row.pop("excerpt", None) for row in claim.get("edges", []): row.pop("connected_text", None) for row in result["context_rows"]: row.pop("body", None) for hit in result["hits"]: hit.pop("excerpt", None) result["privacy"] = "redacted proof mode: raw body used only inside SQL matching; output has counts, hashes, canonical table, row id, timestamps, and evidence links" else: result["privacy"] = "private agent context mode: short excerpts included; do not retain or paste raw output into public artifacts" return result def query_audit_rows(args: argparse.Namespace, query: str, limit: int) -> dict[str, Any]: terms = terms_for(query) sql = f""" with q(term) as ( select lower(value) from json_array_elements_text({sql_json_array(terms)}) as value ), raw_hits as ( select 'response_audit'::text as source_table, id::text as row_id, coalesce(timestamp, created_at) as event_time, coalesce("user", agent, '') as actor, concat_ws(' ', query, conversation_window, entities_matched, claims_matched, retrieval_layers_hit, retrieval_gap, market_data, research_context, kb_context_text, tool_calls, raw_response, display_response, query_type) as body from teleo_restore.response_audit union all select 'sources'::text as source_table, path as row_id, coalesce(updated_at, created_at) as event_time, coalesce(submitted_by, original_author, original_author_handle, '') as actor, concat_ws(' ', path, status, priority, priority_log, extraction_model, last_error, feedback, content_type, original_author, original_author_handle) as body from teleo_restore.sources union all select 'agent_research_runs'::text as source_table, id as row_id, coalesce(completed_at, created_at) as event_time, coalesce(agent_slug, '') as actor, concat_ws(' ', source_surface, source_ref, request_kind, prompt_excerpt, selected_provider, selected_route, status, answer_excerpt, proof_ref) as body from teleo_restore.agent_research_runs union all select 'agent_tool_invocations'::text as source_table, id as row_id, created_at as event_time, coalesce(provider, tool_name, '') as actor, concat_ws(' ', provider, tool_name, tool_category, endpoint_host, decision, decision_reason, rail, network, currency, error_class) as body from teleo_restore.agent_tool_invocations ), matched as ( select *, (select count(*) from q where lower(raw_hits.body) like '%' || q.term || '%') as score from raw_hits where exists (select 1 from q where lower(raw_hits.body) like '%' || q.term || '%') ), ranked as ( select *, row_number() over (order by score desc, event_time desc nulls last, source_table, row_id) as rn from matched ) select json_build_object( 'hit_count_total', (select count(*) from matched), 'hits', coalesce((select json_agg(json_build_object( 'source_table', source_table, 'row_id', row_id, 'event_time', event_time, 'actor', actor, 'score', score, 'body_chars', length(body), 'body_md5', md5(body), 'excerpt', left(regexp_replace(body, '\\s+', ' ', 'g'), 700) ) order by rn) from ranked where rn <= {max(1, min(limit, 20))}), '[]'::json) )::text; """ text = run_psql(args, sql).strip() result = json.loads(text) result.update( { "artifact": "teleo_cloudsql_memory_context", "backend": "cloudsql:teleo-pgvector-standby/teleo_kb/teleo_restore", "query": query, "terms": terms, "privacy": "redacted proof mode by default; pass --include-excerpts/--raw-ok only for private agent context", } ) if not include_excerpts(args): for hit in result["hits"]: hit.pop("excerpt", None) result["privacy"] = "redacted proof mode: raw body used only inside SQL matching; output has counts, hashes, source table, row id, and timestamps" else: result["privacy"] = "private agent context mode: short excerpts included; do not retain or paste raw output into public artifacts" return result def query_rows(args: argparse.Namespace, query: str, limit: int) -> dict[str, Any]: canonical = query_canonical_rows(args, query, limit) if canonical.get("hit_count_total", 0) or canonical.get("hits"): return canonical audit = query_audit_rows(args, query, limit) audit["canonical_fallback_reason"] = "no matching canonical public/persona/strategy/belief rows" return audit def canonical_backend(args: argparse.Namespace) -> str: return f"cloudsql:teleo-pgvector-standby/{args.canonical_db}/public+kb_stage" def canonical_claim(args: argparse.Namespace, claim_id: str) -> dict[str, Any] | None: sql = f""" select jsonb_build_object( 'id', id::text, 'type', type, 'text', text, 'status', status, 'confidence', confidence, 'tags', coalesce(to_jsonb(tags), '[]'::jsonb), 'superseded_by', superseded_by::text, 'created_at', created_at::text, 'updated_at', updated_at::text )::text from public.claims where id = {sql_literal(claim_id)}::uuid; """ rows = psql_json_lines(args, sql, db=args.canonical_db) return rows[0] if rows else None def canonical_evidence(args: argparse.Namespace, claim_id: str, limit: int) -> list[dict[str, Any]]: sql = f""" with ranked as ( select ce.claim_id, ce.role::text as role, ce.weight, s.source_type, s.url, s.storage_path, left(coalesce(s.excerpt, ''), 800) as excerpt, row_number() over ( partition by ce.claim_id order by (s.storage_path like 'inbox/archive/%') desc, ce.role::text, s.storage_path nulls last, s.url nulls last ) as rn from public.claim_evidence ce join public.sources s on s.id = ce.source_id where ce.claim_id = {sql_literal(claim_id)}::uuid ) select jsonb_build_object( 'claim_id', claim_id::text, 'role', role, 'weight', weight, 'source_type', source_type, 'url', url, 'storage_path', storage_path, 'excerpt', excerpt )::text from ranked where rn <= {max(1, min(limit, 50))} order by rn; """ rows = psql_json_lines(args, sql, db=args.canonical_db) if not include_excerpts(args): for row in rows: row.pop("excerpt", None) return rows def canonical_edges(args: argparse.Namespace, claim_id: str, limit: int) -> list[dict[str, Any]]: sql = f""" with base(id) as ( values ({sql_literal(claim_id)}::uuid) ), edge_rows as ( select base.id as claim_id, case when e.from_claim = base.id then 'outgoing' else 'incoming' end as direction, e.edge_type::text as edge_type, other.id as connected_id, other.text as connected_text, other.tags as connected_tags, row_number() over ( partition by base.id order by case e.edge_type::text when 'supports' then 1 when 'challenges' then 2 when 'contradicts' then 3 when 'requires' then 4 when 'supersedes' then 5 when 'constrains' then 6 when 'causes' then 7 when 'accelerates' then 8 else 9 end, other.text ) as rn from base join public.claim_edges e on e.from_claim = base.id or e.to_claim = base.id join public.claims other on other.id = case when e.from_claim = base.id then e.to_claim else e.from_claim end ) select jsonb_build_object( 'claim_id', claim_id::text, 'direction', direction, 'edge_type', edge_type, 'connected_id', connected_id::text, 'connected_text', connected_text, 'connected_tags', coalesce(to_jsonb(connected_tags), '[]'::jsonb) )::text from edge_rows where rn <= {max(1, min(limit, 50))} order by rn; """ rows = psql_json_lines(args, sql, db=args.canonical_db) if not include_excerpts(args): for row in rows: row.pop("connected_text", None) return rows def show_canonical_claim(args: argparse.Namespace) -> dict[str, Any]: claim = canonical_claim(args, args.claim_id) if not claim: raise SystemExit(f"claim not found: {args.claim_id}") if not include_excerpts(args): claim.pop("text", None) claim["claim_url"] = claim_url(args.claim_id) edges = canonical_edges(args, args.claim_id, 12) for edge in edges: edge["connected_url"] = claim_url(edge.get("connected_id")) return { "artifact": "teleo_cloudsql_canonical_kb_claim", "backend": canonical_backend(args), "claim": claim, "evidence": canonical_evidence(args, args.claim_id, 8), "edges": edges, } def evidence_canonical_claim(args: argparse.Namespace) -> dict[str, Any]: return { "artifact": "teleo_cloudsql_canonical_kb_evidence", "backend": canonical_backend(args), "claim_id": args.claim_id, "evidence": canonical_evidence(args, args.claim_id, args.limit), } def edges_canonical_claim(args: argparse.Namespace) -> dict[str, Any]: edges = canonical_edges(args, args.claim_id, args.limit) for edge in edges: edge["connected_url"] = claim_url(edge.get("connected_id")) return { "artifact": "teleo_cloudsql_canonical_kb_edges", "backend": canonical_backend(args), "claim_id": args.claim_id, "claim_url": claim_url(args.claim_id), "edges": edges, } def propose_core_change(args: argparse.Namespace) -> dict[str, Any]: payload = { "target_kind": args.target_kind, "target_ref": args.target_ref, "current": args.current or None, "proposed": args.proposed, "evidence": args.evidence, "implications": args.implication, "originator": args.originator or None, "routing_rule": "core Teleo changes must be staged in kb_stage.kb_proposals, not saved as runtime memory", "canonical_apply_required": True, } payload_json = json.dumps(payload, sort_keys=True) sql = f""" with params as ( select {sql_literal(args.proposal_type)}::text as proposal_type, nullif({sql_literal(args.proposed_by)}, '') as proposed_by_handle, nullif({sql_literal(args.channel)}, '') as channel, nullif({sql_literal(args.source_ref)}, '') as source_ref, {sql_literal(args.rationale)} as rationale, {sql_literal(payload_json)}::jsonb as payload ), proposer as ( select a.id, a.handle from public.agents a, params p where a.handle = p.proposed_by_handle limit 1 ), inserted as ( insert into kb_stage.kb_proposals ( proposal_type, status, proposed_by_handle, proposed_by_agent_id, channel, source_ref, rationale, payload ) select p.proposal_type, 'pending_review', p.proposed_by_handle, proposer.id, coalesce(p.channel, 'telegram'), p.source_ref, p.rationale, p.payload from params p left join proposer on true returning * ) select jsonb_build_object( 'artifact', 'teleo_cloudsql_kb_core_change_proposal', 'backend', {sql_literal(canonical_backend(args))}, 'id', id::text, 'proposal_type', proposal_type, 'status', status, 'proposed_by_handle', proposed_by_handle, 'proposed_by_agent_id', proposed_by_agent_id::text, 'channel', channel, 'source_ref', source_ref, 'rationale', rationale, 'payload', payload, 'created_at', created_at::text, 'canonical_apply_done', false, 'runtime_memory_write_done', false )::text from inserted; """ rows = psql_json_lines(args, sql, db=args.canonical_db) if not rows: raise SystemExit("No core-change proposal inserted.") return rows[0] def propose_edge(args: argparse.Namespace) -> dict[str, Any]: sql = f""" with params as ( select {sql_literal(args.from_claim)}::uuid as from_claim, {sql_literal(args.to_claim)}::uuid as to_claim, {sql_literal(args.edge_type)}::edge_type as edge_type, nullif({sql_literal(args.proposed_by)}, '') as proposed_by_handle, nullif({sql_literal(args.channel)}, '') as channel, nullif({sql_literal(args.source_ref)}, '') as source_ref, {sql_literal(args.rationale)} as rationale ), from_row as ( select c.id, c.text from public.claims c, params p where c.id = p.from_claim ), to_row as ( select c.id, c.text from public.claims c, params p where c.id = p.to_claim ), proposer as ( select a.id, a.handle from public.agents a, params p where a.handle = p.proposed_by_handle limit 1 ), existing_edge as ( select e.id from public.claim_edges e, params p where e.from_claim = p.from_claim and e.to_claim = p.to_claim and e.edge_type = p.edge_type limit 1 ), inserted as ( insert into kb_stage.kb_proposals ( proposal_type, status, proposed_by_handle, proposed_by_agent_id, channel, source_ref, rationale, payload ) select 'add_edge', 'pending_review', p.proposed_by_handle, proposer.id, coalesce(p.channel, 'telegram'), p.source_ref, p.rationale, jsonb_build_object( 'from_claim', from_row.id::text, 'from_text', from_row.text, 'edge_type', p.edge_type::text, 'to_claim', to_row.id::text, 'to_text', to_row.text, 'existing_edge_id', (select id::text from existing_edge), 'apply_payload', jsonb_build_object( 'from_claim', from_row.id::text, 'to_claim', to_row.id::text, 'edge_type', p.edge_type::text ) ) from params p join from_row on true join to_row on true left join proposer on true returning * ) select jsonb_build_object( 'artifact', 'teleo_cloudsql_kb_edge_proposal', 'backend', {sql_literal(canonical_backend(args))}, 'id', id::text, 'proposal_type', proposal_type, 'status', status, 'proposed_by_handle', proposed_by_handle, 'proposed_by_agent_id', proposed_by_agent_id::text, 'channel', channel, 'source_ref', source_ref, 'rationale', rationale, 'payload', payload, 'created_at', created_at::text, 'canonical_apply_done', false, 'runtime_memory_write_done', false )::text from inserted; """ rows = psql_json_lines(args, sql, db=args.canonical_db) if not rows: raise SystemExit("No edge proposal inserted. Check that both claim ids exist and edge_type is valid.") return rows[0] def list_proposals(args: argparse.Namespace) -> dict[str, Any]: where = "" if args.status.lower() != "all": where = f"where status = {sql_literal(args.status)}" sql = f""" select jsonb_build_object( 'id', id::text, 'proposal_type', proposal_type, 'status', status, 'proposed_by_handle', proposed_by_handle, 'channel', channel, 'source_ref', source_ref, 'rationale', left(rationale, 500), 'payload', payload, 'created_at', created_at::text, 'reviewed_at', reviewed_at::text, 'applied_at', applied_at::text )::text from kb_stage.kb_proposals {where} order by created_at desc limit {max(1, min(args.limit, 100))}; """ return { "artifact": "teleo_cloudsql_kb_proposal_list", "backend": canonical_backend(args), "status_filter": args.status, "proposals": psql_json_lines(args, sql, db=args.canonical_db), } def show_proposal(args: argparse.Namespace) -> dict[str, Any]: sql = f""" select jsonb_build_object( 'artifact', 'teleo_cloudsql_kb_proposal', 'backend', {sql_literal(canonical_backend(args))}, 'id', id::text, 'proposal_type', proposal_type, 'status', status, 'proposed_by_handle', proposed_by_handle, 'proposed_by_agent_id', proposed_by_agent_id::text, 'channel', channel, 'source_ref', source_ref, 'rationale', rationale, 'payload', payload, 'reviewed_by_handle', reviewed_by_handle, 'reviewed_at', reviewed_at::text, 'review_note', review_note, 'applied_by_handle', applied_by_handle, 'applied_at', applied_at::text, 'created_at', created_at::text, 'updated_at', updated_at::text )::text from kb_stage.kb_proposals where id = {sql_literal(args.proposal_id)}::uuid; """ rows = psql_json_lines(args, sql, db=args.canonical_db) if not rows: raise SystemExit(f"proposal not found: {args.proposal_id}") return rows[0] def status(args: argparse.Namespace) -> dict[str, Any]: canonical_sql = """ select json_build_object( 'db_identity', current_database() || '|' || current_user, 'extensions', (select json_agg(extname order by extname) from pg_extension), 'schema_tables', ( select json_object_agg(table_schema, table_count) from ( select table_schema, count(*) as table_count from information_schema.tables where table_type='BASE TABLE' and table_schema in ('public','kb_stage') group by table_schema order by table_schema ) counts ), 'high_signal_rows', json_build_object( 'agents', (select count(*) from public.agents), 'personas', (select count(*) from public.personas), 'strategies', (select count(*) from public.strategies), 'beliefs', (select count(*) from public.beliefs), 'claims', (select count(*) from public.claims), 'claim_edges', (select count(*) from public.claim_edges), 'claim_evidence', (select count(*) from public.claim_evidence), 'sources', (select count(*) from public.sources), 'kb_proposals', (select count(*) from kb_stage.kb_proposals) ) )::text; """ audit_sql = """ select json_build_object( 'db_identity', current_database() || '|' || current_user, 'extensions', (select json_agg(extname order by extname) from pg_extension), 'teleo_restore_tables', (select count(*) from pg_tables where schemaname='teleo_restore'), 'total_rows', ( select sum(row_count) from ( select count(*)::bigint as row_count from teleo_restore.response_audit union all select count(*)::bigint from teleo_restore.sources union all select count(*)::bigint from teleo_restore.agent_research_runs union all select count(*)::bigint from teleo_restore.agent_tool_invocations union all select count(*)::bigint from teleo_restore.audit_log union all select count(*)::bigint from teleo_restore.metrics_snapshots union all select count(*)::bigint from teleo_restore.prs union all select count(*)::bigint from teleo_restore.review_records ) counts ), 'high_signal_rows', json_build_object( 'response_audit', (select count(*) from teleo_restore.response_audit), 'sources', (select count(*) from teleo_restore.sources), 'agent_research_runs', (select count(*) from teleo_restore.agent_research_runs), 'agent_tool_invocations', (select count(*) from teleo_restore.agent_tool_invocations) ) )::text; """ result = json.loads(run_psql(args, audit_sql).strip()) result["canonical"] = json.loads(run_psql(args, canonical_sql, db=args.canonical_db).strip()) result["artifact"] = "teleo_cloudsql_memory_status" result["backend"] = f"cloudsql:teleo-pgvector-standby/{args.canonical_db}/public+kb_stage primary; {args.db}/teleo_restore fallback" return result def emit_json(value: dict[str, Any]) -> None: print(json.dumps(value, indent=2)) def emit_markdown(value: dict[str, Any]) -> None: if value["artifact"] == "teleo_cloudsql_memory_status": print("# Teleo Cloud SQL Memory Status\n") print(f"- Backend: `{value['backend']}`") print(f"- DB: `{value['db_identity']}`") if "canonical" in value: canonical = value["canonical"] print(f"- Canonical DB: `{canonical['db_identity']}`") print(f"- Canonical tables: `{json.dumps(canonical.get('schema_tables'), sort_keys=True)}`") print(f"- Canonical high-signal rows: `{json.dumps(canonical.get('high_signal_rows'), sort_keys=True)}`") print(f"- Extensions: {', '.join(value.get('extensions') or [])}") print(f"- Restored tables: {value['teleo_restore_tables']}") print(f"- Approx restored rows checked: {value['total_rows']}") print(f"- High-signal rows: `{json.dumps(value['high_signal_rows'], sort_keys=True)}`") return if "claims" in value: print("# Teleo KB Context\n") print(f"- Backend: `{value['backend']}`") print(f"- Query: `{value['query']}`") print(f"- Terms: {', '.join(value['terms'])}") print(f"- Privacy: {value['privacy']}\n") if value.get("context_rows"): print("## Soul / Context Rows\n") for row in value["context_rows"]: print( f"- `{row.get('source')}` / `{row.get('owner')}` / `{row.get('title')}` " f"(score {row.get('score')}): {row.get('body', '[redacted]')}" ) print() print("## Claims\n") if not value.get("claims"): print("No matching canonical claims found.") return for i, claim in enumerate(value["claims"], 1): claim_label = claim.get("text") or "[redacted claim text]" print(f"### {i}. {markdown_claim_link(claim['id'], claim_label[:140])}\n") print(f"- claim id: {markdown_claim_link(claim['id'], claim['id'])}") print(f"- open full claim/body/edges: {markdown_claim_link(claim['id'], 'claim page')}") print(f"- type: `{claim.get('type')}`; confidence: `{claim.get('confidence')}`; score: `{claim.get('score')}`") print(f"- tags: `{', '.join(claim.get('tags') or [])}`") print(f"- evidence rows: `{claim.get('evidence_count', len(claim.get('evidence', [])))}`") print(f"- edge rows: `{claim.get('edge_count', len(claim.get('edges', [])))}`") if claim.get("evidence"): print("\nEvidence:") for ev in claim["evidence"]: source = ev.get("storage_path") or ev.get("url") or "(no source pointer)" excerpt = f" - {ev['excerpt']}" if ev.get("excerpt") else "" print(f"- `{ev.get('role')}` / `{ev.get('source_type')}` / `{source}`{excerpt}") if claim.get("edges"): print("\nEdges:") for edge in claim["edges"]: connected = edge.get("connected_id") connected_label = (edge.get("connected_text") or str(connected or ""))[:120] print( f"- `{edge.get('direction')}` `{edge.get('edge_type')}` " f"{markdown_claim_link(connected, connected_label)}" ) print() return if value["artifact"] == "teleo_cloudsql_canonical_kb_claim": claim = value["claim"] print("# Teleo KB Claim\n") print(f"- Backend: `{value['backend']}`") print(f"- claim id: {markdown_claim_link(claim['id'], claim['id'])}") print(f"- open full claim/body/edges: {markdown_claim_link(claim['id'], 'claim page')}") print(f"- type: `{claim.get('type')}`; status: `{claim.get('status')}`; confidence: `{claim.get('confidence')}`") print(f"- tags: `{', '.join(claim.get('tags') or [])}`") if claim.get("text"): print(f"\n{markdown_claim_link(claim['id'], claim['text'][:180])}\n") print("## Evidence\n") for ev in value.get("evidence", []): source = ev.get("storage_path") or ev.get("url") or "(no source pointer)" excerpt = f" - {ev['excerpt']}" if ev.get("excerpt") else "" print(f"- `{ev.get('role')}` / `{ev.get('source_type')}` / `{source}`{excerpt}") print("\n## Edges\n") for edge in value.get("edges", []): connected = edge.get("connected_id") connected_label = (edge.get("connected_text") or str(connected or ""))[:120] print( f"- `{edge.get('direction')}` `{edge.get('edge_type')}` " f"{markdown_claim_link(connected, connected_label)}" ) return if value["artifact"] in {"teleo_cloudsql_canonical_kb_evidence", "teleo_cloudsql_canonical_kb_edges"}: print(f"# {value['artifact']}\n") print(f"- Backend: `{value['backend']}`") print(f"- Claim: {markdown_claim_link(value['claim_id'], value['claim_id'])}\n") print(f"- Open full claim/body/edges: {markdown_claim_link(value['claim_id'], 'claim page')}\n") rows = value.get("evidence") or value.get("edges") or [] for row in rows: print(f"- `{json.dumps(row, sort_keys=True)}`") return if value["artifact"] in {"teleo_cloudsql_kb_core_change_proposal", "teleo_cloudsql_kb_edge_proposal"}: title = "Staged KB Edge Proposal" if value["artifact"] == "teleo_cloudsql_kb_edge_proposal" else "Staged KB Core-Change Proposal" print(f"# {title}\n") print(f"- Proposal id: `{value['id']}`") print(f"- Type: `{value['proposal_type']}`") print(f"- Status: `{value['status']}`") print(f"- Source: `{value.get('source_ref') or '-'}`") print(f"- Runtime memory write: `{value['runtime_memory_write_done']}`") print(f"- Canonical apply done: `{value['canonical_apply_done']}`") print("\n## Rationale\n") print(value["rationale"]) print("\n## Payload\n") print(json.dumps(value.get("payload") or {}, indent=2, sort_keys=True)) return if value["artifact"] == "teleo_cloudsql_kb_proposal_list": print("# Staged KB Proposals\n") rows = value.get("proposals") or [] if not rows: print("No matching proposals.") for row in rows: print(f"## {row['id']}\n") print(f"- Type: `{row['proposal_type']}`") print(f"- Status: `{row['status']}`") print(f"- Source: `{row.get('source_ref') or '-'}`") print(f"- Created: `{row.get('created_at')}`") print(f"- Rationale: {row.get('rationale') or ''}") print() return if value["artifact"] == "teleo_cloudsql_kb_proposal": print("# Staged KB Proposal\n") print(f"- Proposal id: `{value['id']}`") print(f"- Type: `{value['proposal_type']}`") print(f"- Status: `{value['status']}`") print(f"- Source: `{value.get('source_ref') or '-'}`") print(f"- Created: `{value.get('created_at')}`") print(f"- Applied at: `{value.get('applied_at') or '-'}`") print("\n## Rationale\n") print(value["rationale"]) print("\n## Payload\n") print(json.dumps(value.get("payload") or {}, indent=2, sort_keys=True)) return print("# Teleo Cloud SQL Memory Context\n") print(f"- Backend: `{value['backend']}`") print(f"- Query: `{value['query']}`") print(f"- Terms: {', '.join(value['terms'])}") print(f"- Total matching rows: {value['hit_count_total']}") print(f"- Privacy: {value['privacy']}\n") for i, hit in enumerate(value["hits"], 1): print(f"## Hit {i}: {hit['source_table']} / {hit['row_id']}") print(f"- Time: {hit.get('event_time') or 'unknown'}") print(f"- Actor/source: {hit.get('actor') or 'unknown'}") print(f"- Score: {hit.get('score')}") print(f"- Body chars: {hit.get('body_chars')}") print(f"- Body md5: `{hit.get('body_md5')}`") if "excerpt" in hit: print(f"- Excerpt: {hit['excerpt']}") print() def main() -> None: args = parse_args() if args.command == "status": result = status(args) elif args.command == "show": result = show_canonical_claim(args) elif args.command == "evidence": result = evidence_canonical_claim(args) elif args.command == "edges": result = edges_canonical_claim(args) elif args.command == "propose-core-change": result = propose_core_change(args) elif args.command == "propose-edge": result = propose_edge(args) elif args.command == "list-proposals": result = list_proposals(args) elif args.command == "show-proposal": result = show_proposal(args) else: result = query_rows(args, args.query, args.limit) if args.format == "json": emit_json(result) else: emit_markdown(result) if __name__ == "__main__": main()