Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
5c0de35
feat: persist TEPP accepted receipts as transport evidence (v2.12.11)
seonghobae Aug 23, 2026
561376c
fix: keep TEPP receipt transactions usable
seonghobae Aug 23, 2026
49fae1b
docs: resolve TEPP receipt ADR number collision
seonghobae Aug 23, 2026
38ade89
chore: scope receipt SQL scanner suppression
seonghobae Aug 23, 2026
2b7fcea
fix: accept TEPP receipt state progression
seonghobae Aug 23, 2026
93ae489
fix: complete TEPP receipt replay contract
seonghobae Aug 23, 2026
1894b09
fix(ui): label TEPP status refresh accurately
seonghobae Aug 23, 2026
e40a9a1
test: cover TEPP receipt replay identity mismatches
seonghobae Aug 23, 2026
8d678bb
fix: preserve accepted TEPP run on retry outage
seonghobae Aug 23, 2026
9fe1932
fix: isolate optional analysis-run reads
seonghobae Aug 23, 2026
1e5430a
fix: align reviewed SQL suppression contract
seonghobae Aug 23, 2026
195ddf5
fix: preserve durable TEPP acceptance on recheck
seonghobae Aug 23, 2026
78287c0
test: use one TEPP start import style
seonghobae Aug 23, 2026
288125a
fix: allocate migration 0171 for TEPP receipts
seonghobae Aug 23, 2026
996c4fd
Merge remote-tracking branch 'origin/feat/oidc-return-remember-login-…
seonghobae Aug 23, 2026
1611ed4
fix: restack TEPP accepted receipts onto remembered OIDC login
seonghobae Aug 23, 2026
90fa91b
test(sql-review): bump expected suppression count to 39
seonghobae Aug 23, 2026
bc6d02e
merge feat/oidc-return-remember-login-v21219: rebase onto 2.12.20 base
seonghobae Aug 23, 2026
e30eada
merge feat/oidc-return-remember-login-v21219: rebase onto 2.12.21 base
seonghobae Aug 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -489,11 +489,13 @@ more than one), then open the Pending row to confirm the cutoff corpus.
`POST /api/analysis-runs/{id}/start` then commits Running plus a
durable outbox row, wakes Valkey, and delivers ThreadWeave on that
frozen bag (ADR 0021 / ADR 0023) or submits TEPP through
`tepp_client` (ADR 0022). It does not invent a TEPP score.
`tepp_client` (ADR 0022 / ADR 0162). It does not invent a TEPP score.
Request a lineage reconstruction from the home list, open the Pending
row, then start reconstruction. A Pending TEPP row starts a
measurement; a missing transport stays Failed /
`tepp_not_available`. Hover the Result digest
`tepp_not_available`. A live `accepted` envelope with a remote run id
persists as transport evidence and keeps the run Running — that
receipt is not a calibrated result. Hover the Result digest
prefix, then confirm the designed A-100 fork before treating the live
Event Lineage panel as that run's tree.
`make seed` also records a TEPP measurement run through
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.d/2.12.11-tepp-accepted-receipt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 2.12.11 TEPP accepted receipt

A live TEPP `accepted` / `queued` / `running` envelope with a remote
run id persists as transport evidence and leaves the local analysis
run Running. The receipt is not a measurement and does not invent a
theta. Empty accepted envelopes and missing transport stay Failed.
Completed envelopes still persist `analysis_run_tepp_result`. Login
no longer mounts Admin settings with an undefined token.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,24 @@ All notable changes to this project are documented here. Format follows
lineage run and Start still recovers the designed A-100 fork.
Never invent a theta.

## [2.12.11] - 2026-08-23

### Added

- A live TEPP `accepted` / `queued` / `running` envelope that carries a
remote run id is stored as transport evidence
(`analysis_run_tepp_accepted_receipt`). The local analysis run stays
Running. The receipt is not a calibrated measurement and does not
invent a theta. Empty accepted envelopes and a missing transport stay
Failed. Completed envelopes still persist `analysis_run_tepp_result`.
Completed-result polling remains blocked on TEPP#156.

### Fixed

- Unauthenticated login no longer mounts Admin settings with an
undefined access token, and login persists a validated OIDC return
URL before the redirect.

## [2.12.6] - 2026-08-20

### Added
Expand Down
84 changes: 67 additions & 17 deletions backend/app/analysis_run_ingestion.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,16 @@ async def fetch_outbox_deliveries(
entry ids stay off the payload -- they are not reader-facing evidence.
"""
try:
rows = await conn.fetch(
"""
select delivery_ordinal, delivery_status_code, occurred_at
from analysis_run_outbox_delivery
where analysis_run_id = $1::uuid
order by delivery_ordinal
""",
analysis_run_id,
)
async with conn.transaction():
rows = await conn.fetch(
"""
select delivery_ordinal, delivery_status_code, occurred_at
from analysis_run_outbox_delivery
where analysis_run_id = $1::uuid
order by delivery_ordinal
""",
analysis_run_id,
)
except asyncpg.UndefinedTableError:
return []
labels = await labels_for_codes(
Expand Down Expand Up @@ -289,6 +290,9 @@ async def _serialize_runs(
if not rows:
return []
count_rows = await _counts_by_run(conn, [str(row["analysis_run_id"]) for row in rows])
receipts = await fetch_tepp_accepted_receipts(
conn, [str(row["analysis_run_id"]) for row in rows]
)
Comment thread
seonghobae marked this conversation as resolved.
labels = await labels_for_codes(
conn,
[row["run_kind_code"] for row in rows]
Expand Down Expand Up @@ -334,6 +338,8 @@ async def _serialize_runs(
grouping_key = scope_grouping_key(row)
if grouping_key:
item["scope_grouping_key"] = grouping_key
if run_id in receipts:
item["tepp_accepted_receipt"] = receipts[run_id]
Comment thread
seonghobae marked this conversation as resolved.
payload.append(item)
return payload

Expand Down Expand Up @@ -427,6 +433,49 @@ def reconstructed_edge_is_visible(
return parent_visible and child_visible


async def fetch_tepp_accepted_receipt(
conn: asyncpg.Connection,
analysis_run_id: str,
) -> dict[str, Any] | None:
"""Transport receipt for one already-visible run, or None.

Missing table (migration 0171 not applied) is not a 500. The
receipt is not a measurement and never includes a theta.
"""
return (await fetch_tepp_accepted_receipts(conn, [analysis_run_id])).get(
analysis_run_id
)


async def fetch_tepp_accepted_receipts(
conn: asyncpg.Connection,
analysis_run_ids: list[str],
) -> dict[str, dict[str, Any]]:
"""Transport receipts for visible runs, isolated from optional-schema errors."""
if not analysis_run_ids:
return {}
try:
async with conn.transaction():
rows = await conn.fetch(
"""
select analysis_run_id, remote_run_id, accepted_status_code, received_at
from analysis_run_tepp_accepted_receipt
where analysis_run_id = any($1::uuid[])
""",
analysis_run_ids,
)
except asyncpg.UndefinedTableError:
return {}
Comment thread
seonghobae marked this conversation as resolved.
return {
str(row["analysis_run_id"]): {
"remote_run_id": str(row["remote_run_id"]),
"accepted_status_code": str(row["accepted_status_code"]),
"received_at": _iso(row["received_at"]),
}
for row in rows
}
Comment thread
seonghobae marked this conversation as resolved.
Comment thread
seonghobae marked this conversation as resolved.


async def fetch_reconstructed_edges(
conn: asyncpg.Connection,
analysis_run_id: str,
Expand All @@ -439,14 +488,15 @@ async def fetch_reconstructed_edges(
Titles follow the same public-or-affiliated rule as ``visible_posts``.
"""
try:
header = await conn.fetchrow(
"""
select result_sha256
from analysis_run_reconstruction
where analysis_run_id = $1
""",
analysis_run_id,
)
async with conn.transaction():
header = await conn.fetchrow(
"""
select result_sha256
from analysis_run_reconstruction
where analysis_run_id = $1
""",
analysis_run_id,
)
except asyncpg.UndefinedTableError:
return None, []
if header is None:
Expand Down
Loading