Merge remote-tracking branch 'origin/main' into copilot/feat-reconcile-unmanaged-position-durable-lifecycl

# Conflicts:
#	.proofline/criteria/ac-0029.md
#	.proofline/identities.json
#	tests/adapters/persistence/test_migration_and_drift.py

Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-09-13 02:53:22 +00:00
committed by GitHub
co-authored by genichin
40 changed files with 1254 additions and 276 deletions
@@ -1,6 +1,6 @@
-- BAT-050 / REQ-102: reconcile-warning durable store (dcy-034).
-- PK: slot_id (TEXT, UUID string). pause_store 동형 설계.
-- ON CONFLICT DO UPDATE: 동일 slot_id 재삽입 시 최신 값으로 갱신.
-- Initial schema; migration 028 upgrades PK to (slot_id, case_code)
-- so B/C causes can coexist for the same slot.
CREATE TABLE IF NOT EXISTS slot_reconcile_warning (
slot_id TEXT PRIMARY KEY,
portfolio_id TEXT NOT NULL,
@@ -0,0 +1,30 @@
-- REQ-123 / issue #83:
-- Preserve simultaneous warning causes by keying warnings per (slot_id, case_code).
-- NOTE: historical overwritten causes cannot be reconstructed from the prior
-- slot_id-only schema; this migration enables forward preservation only.
UPDATE slot_reconcile_warning
SET case_code = 'B'
WHERE case_code IS NULL OR case_code = '';
ALTER TABLE slot_reconcile_warning
ALTER COLUMN case_code SET NOT NULL;
DELETE FROM slot_reconcile_warning w
USING (
SELECT ctid, ROW_NUMBER() OVER (
PARTITION BY slot_id, case_code
ORDER BY updated_at DESC, created_at DESC, ctid DESC
) AS rn
FROM slot_reconcile_warning
) ranked
WHERE w.ctid = ranked.ctid
AND ranked.rn > 1;
ALTER TABLE slot_reconcile_warning
DROP CONSTRAINT IF EXISTS slot_reconcile_warning_pkey;
ALTER TABLE slot_reconcile_warning
ADD CONSTRAINT slot_reconcile_warning_pkey PRIMARY KEY (slot_id, case_code);
CREATE INDEX IF NOT EXISTS idx_slot_reconcile_warning_slot_id
ON slot_reconcile_warning (slot_id);
@@ -0,0 +1,23 @@
-- GitHub #84: persist outbox owner instance and add claim/lease fields so
-- shared-DB daemon writers only deliver their own rows and can safely recover
-- abandoned work after lease expiry. Existing rows remain fail-closed when the
-- owner instance cannot be inferred.
ALTER TABLE ledger_outbox ADD COLUMN IF NOT EXISTS instance_key TEXT;
ALTER TABLE ledger_outbox ADD COLUMN IF NOT EXISTS claim_owner TEXT;
ALTER TABLE ledger_outbox ADD COLUMN IF NOT EXISTS claim_expires_at TIMESTAMPTZ;
UPDATE ledger_outbox
SET instance_key='__unowned__'
WHERE instance_key IS NULL;
ALTER TABLE ledger_outbox ALTER COLUMN instance_key SET DEFAULT '__unowned__';
ALTER TABLE ledger_outbox ALTER COLUMN instance_key SET NOT NULL;
DROP INDEX IF EXISTS idx_ledger_outbox_instance_pending;
CREATE INDEX IF NOT EXISTS idx_ledger_outbox_instance_pending
ON ledger_outbox (instance_key, status, created_at, correlation_id)
WHERE status = 'pending';
CREATE INDEX IF NOT EXISTS idx_ledger_outbox_instance_claim_expires
ON ledger_outbox (instance_key, claim_expires_at)
WHERE status = 'pending';