teleo-infrastructure/scripts
Fawaz 7bb6fc417b
Some checks are pending
CI / lint-and-test (push) Waiting to run
feat(kb): apply_proposal engine (stage 2 of KB apply pipeline) (#35)
* feat(kb): apply_proposal engine to land approved proposals into canonical

Stage 2 of the KB apply pipeline (approve -> APPLY -> render -> surface).
Turns an approved kb_stage.kb_proposals row into canonical public.* rows and
flips the ledger to 'applied' in one verified transaction.

- Connects as the narrow kb_apply role (never superuser): writes only
  strategies, strategy_nodes, claim_evidence, claim_edges + kb_proposals ledger.
  Enforces "agents propose, do not self-apply" at the DB boundary.
- Per-type handlers: revise_strategy (versioned strategy + node replace),
  add_edge, attach_evidence (requires existing source_id; source minting is
  intentionally out of scope for kb_apply's grants).
- Strict apply_payload contract (v1); freeform eval packets are normalized
  upstream, not applied directly.
- --dry-run prints exact SQL; idempotent (refuses non-approved / already-applied);
  transactional with an in-txn DO-block invariant check that rolls back on failure.
- Unit tests cover SQL builders, validation, dispatch, and status guards.

* fix(kb): rowcount=1 apply guard + real applied_by FK stamp

Closes the three draft-exit review items on the apply engine:

- Ledger flip now runs in a DO block asserting exactly one 'approved'
  row moved to 'applied' (GET DIAGNOSTICS row_count). Closes the
  concurrent double-apply race — load_proposal (read) and the flip
  (write) are separate statements, so a row lock cannot span them; only
  one concurrent apply can match status='approved', so rowcount=1 is the
  authoritative guard. A loser RAISEs and the whole txn rolls back.
- applied_by_agent_id is stamped as a real FK resolved from public.agents
  by handle, defaulting to the kb-apply service agent — no more NULL FK,
  no backfill needed.
- scripts/kb_apply_prereqs.sql: one-time superuser bootstrap — inserts the
  kb-apply service-agent row (kb_apply never gets INSERT on agents), grants
  kb_apply SELECT on public.agents, and ensures the one-active-strategy
  unique index (idempotent; already present on prod).

18/18 unit tests pass.

* fix(kb): hard-resolve applied_by handle, RAISE on NULL FK

Resolve applied_by into a variable and assert NOT NULL before the ledger
flip, instead of an inline subselect that silently stamps a NULL
applied_by_agent_id on an unresolved handle. Since the FK is ON DELETE SET
NULL, a bad handle (typo/unseeded agent) was a legal silent NULL -- the
perpetually-NULL FK we eliminated. Unresolved handle now hard-fails ->
rollback. Non-default --applied-by (operator, future drafters) is the path
that goes through the lookup and could strand NULL.
2026-07-04 19:57:49 -04:00
..
apply_proposal.py feat(kb): apply_proposal engine (stage 2 of KB apply pipeline) (#35) 2026-07-04 19:57:49 -04:00
audit-wiki-links.py feat: add wiki-link audit script for codex graph integrity 2026-04-21 10:46:55 +01:00
backfill-ci.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
backfill-descriptions.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
backfill-domains.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
backfill-events.py fix(backfill): normalize commit_date via datetime() in time-proximity query 2026-04-24 16:16:03 +01:00
backfill-research-session-attribution.py fix(attribution): canonicalize submitted_by at write time + historical normalizer 2026-05-13 02:56:50 +00:00
backfill-reviewer-count.py fix: sync all code from VPS — repo is now authoritative source of truth 2026-04-15 13:18:01 +01:00
backfill-source-authors.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
backfill-sourcer-attribution.py fix(attribution): credit sourcer/extractor from claim frontmatter 2026-04-24 12:48:41 +01:00
backfill-sources.py fix(backfill): don't regress terminal source statuses to unprocessed 2026-04-22 21:29:33 +01:00
backfill-synthetic-recovery-prs.py fix(backfill): Ganymede review — fix tautological guard + origin='human' 2026-04-24 16:49:12 +01:00
bootstrap-contributors.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
check_crabbox_ci_contract.py Add Crabbox CI contract gate 2026-06-01 15:36:03 +02:00
check_llm_refinement_contract.py Add decision engine replay harness 2026-06-01 17:37:38 +02:00
check_telegram_leo_wallet_test_runtime.py Add Leo wallet-test Telegram runtime verifier (#14) 2026-06-22 21:41:17 +02:00
check_telegram_leo_x402_bridge.py Add Leo Telegram x402 bridge 2026-06-19 19:27:12 +02:00
check_telegram_leo_x402_smart_research_bridge.py Add Leo Telegram smart research bridge (#11) 2026-06-22 21:24:00 +02:00
classify-contributors.py fix(classify): Ganymede review fixes — alias cleanup + counter accuracy + handle alignment 2026-04-24 20:47:21 +01:00
contributor-graph.py feat: contributor graph PNG generator + API endpoint 2026-04-21 11:01:02 +01:00
crabbox_phase1b_proof.sh Add Crabbox CI contract gate 2026-06-01 15:36:03 +02:00
cumulative-growth.py feat: add /api/contributor-growth endpoint + cumulative growth script 2026-04-20 22:19:42 +01:00
embed-claims.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
extract-decisions.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
extract-graph-data.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
install_telegram_agent_token.py Add safe Telegram agent token installer 2026-06-22 20:47:44 +02:00
install_telegram_smart_research_gates.py Allow Leo paid research gate by chat title (#32) 2026-07-02 01:19:17 +02:00
kb_apply_prereqs.sql feat(kb): apply_proposal engine (stage 2 of KB apply pipeline) (#35) 2026-07-04 19:57:49 -04:00
migrate-entity-schema.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
migrate-source-archive.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
nightly-reweave.sh fix: lower reweave threshold 0.70→0.55, increase batch 50→200 2026-04-16 14:18:50 +01:00
normalize-submitted-by.py fix(attribution): canonicalize submitted_by at write time + historical normalizer 2026-05-13 02:56:50 +00:00
openrouter-extract-v2.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
prove_phase1b_local.py Prove phase 1b local e2e 2026-05-29 15:08:09 +02:00
reattribute-by-branch-prefix.py fix(attribution): classify submitted_by by branch prefix at PR discovery 2026-05-13 03:49:10 +00:00
reconcile-source-status.sh feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
reconcile-sources.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
replay_decision_engine_eval.py Add decision engine replay harness 2026-06-01 17:37:38 +02:00
reset-m3taversal-sourcer.py fix(tests): apply Ganymede review nits + add m3taversal reset script 2026-04-27 17:35:18 +01:00
scoring_digest.py feat: wire action-type CI into contributor profiles 2026-04-21 11:29:01 +01:00
tier0-gate.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00
vector-gc.py feat: reorganize repo with clear directory boundaries and agent ownership 2026-04-14 18:20:13 +01:00