Skip to content

feat: admit confirmed_online_support and declare the confirmation seam - #474

Merged
guangyu-reflexio merged 2 commits into
mainfrom
codex/offline-tuner-open-world-phase6
Sep 1, 2026
Merged

feat: admit confirmed_online_support and declare the confirmation seam#474
guangyu-reflexio merged 2 commits into
mainfrom
codex/offline-tuner-open-world-phase6

Conversation

@guangyu-reflexio

@guangyu-reflexio guangyu-reflexio commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Adds the open-source half of Phase 6 (passive confirmation): a ninth lifecycle terminal reason and the storage seam the enterprise confirm path implements.

Stacked on #473 (Phase 5). Review only the two commits above that base.

What this adds

  • LIFECYCLE_TERMINAL_REASONS gains confirmed_online_support — nine values, mirroring the tenant CHECK. Phase 5's note that Phase 6 would need no contract migration is true of the restore half and false of the confirm half: every one of the previous eight reasons describes why a successor was pulled, so state = 'confirmed' was unrepresentable.
  • confirm_user_playbook_provisional_publication declared on the UserPlaybookStoreMixin, beside restore_ and displace_, raising NotImplementedError on backends that do not support provisional confirmation.

Why the seam lives here rather than in the enterprise allowlist

_ENTERPRISE_ONLY_METHODS is for methods absent from the OSS ABC. This one is present on it, exactly like its two siblings — registering it in the allowlist would have failed test_storage_public_method_surface_matches.

Scope

Contract only. Nothing in this repository calls the new method, and the OSS backends inherit the NotImplementedError. The enterprise counterpart carries the RPC, the day-14 boundary, and the memo intake.

Rollout note for whoever composes this later

The reason-set widening must be fully deployed — all tasks on the new image — before the confirm path is wired, not merely merged. During a rollout the first new task widens the SQL CHECK while old-image tasks still hold the eight-value set, and an old task reading back a confirmed lifecycle would raise lifecycle terminal result reason is not enumerated. Unreachable today, since nothing can commit a confirmation.

Summary by CodeRabbit

  • New Features
    • Added support for confirming provisional playbook publications after online support validation.
    • Confirmation now records session evidence and coverage metrics.
    • Added validation to ensure submitted evidence totals are consistent.
    • Added a new terminal lifecycle status reason for confirmed online support.

@coderabbitai

coderabbitai Bot commented Aug 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Essentials

Run ID: 278fbb16-11c7-4e56-8a80-031e14cc3f7a

📥 Commits

Reviewing files that changed from the base of the PR and between 21de50b and 110db92.

📒 Files selected for processing (3)
  • reflexio/server/services/playbook/publication.py
  • reflexio/server/services/storage/storage_base/playbook/_user.py
  • tests/server/services/playbook/test_publication_models.py

Included review availability: 1 review is currently available. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour.


📝 Walkthrough

Walkthrough

The lifecycle terminal-reason contract now accepts confirmed_online_support. New protocol and storage operations confirm provisional publications with fencing, successor fingerprint, and evidence-count parameters.

Changes

Provisional publication confirmation

Layer / File(s) Summary
Terminal reason contract
reflexio/server/services/playbook/publication.py, tests/server/services/playbook/test_publication_models.py
Adds confirmed_online_support to the accepted terminal reasons. Tests cover valid confirmed results and reject unenumerated reasons.
Confirmation operation
reflexio/server/services/playbook/publication.py, reflexio/server/services/storage/storage_base/playbook/_user.py
Adds confirmation operations that retain the successor, validate lifecycle fencing and successor fingerprints, accept global and target coverage metrics, and record confirmed_online_support. Unsupported storage backends raise NotImplementedError.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to 110db

This PR adds a lifecycle reason and a declared storage seam without changing current runtime behavior; no actionable merge-blocking risk remains beyond normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 87.50% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 3 files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the two main changes: adding confirmed_online_support and declaring the confirmation interface seam.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/offline-tuner-open-world-phase6

Comment @coderabbitai help to get the list of available commands.

confirm_user_playbook_provisional_publication joins restore and displace on
UserPlaybookLifecycleTerminationStore and on the base storage playbook mixin.

Declared on the base rather than left as an enterprise-only extra: the three
are one termination triple over the same lifecycle row, and a backend
satisfying two thirds of the Protocol would be a surface every reader has to
special-case. There is no reason parameter -- confirmed_online_support is the
only reason this transition can record -- and the six evidence counts are
re-checked by the RPC inside its own transaction rather than validated twice.
@guangyu-reflexio
guangyu-reflexio force-pushed the codex/offline-tuner-open-world-phase6 branch from a461288 to 110db92 Compare August 31, 2026 23:40
@guangyu-reflexio
guangyu-reflexio changed the base branch from codex/offline-tuner-open-world-phase5 to main August 31, 2026 23:40
@guangyu-reflexio
guangyu-reflexio merged commit 560fcc8 into main Sep 1, 2026
5 checks passed
guangyu-reflexio added a commit that referenced this pull request Sep 1, 2026
…th (#475)

The open-source half of Phase 7 (the §21 clean break): contracts the
replay literals out of the public type surface and fixes the SQLite
allowlist rebuild so a *removal* actually takes effect.

Stacked on #474 (Phase 6). Review only the commits
above that base.

## The defect this fixes, which is the interesting part

Both SQLite allowlist rebuilds trigger on a **positive** substring
predicate:

```python
if all(check in table_sql for check in required_checks) and (
    "'offline_tuner_open_world'" in table_sql
):
    return
```

That is correct for *adding* a literal and silently wrong for *removing*
one. Drop a literal from the target tuple and an existing database —
whose `table_sql` still contains every remaining required string —
satisfies `all(...)` and returns early. **The rebuild never runs and the
old permissive CHECK survives forever.**

A migration that reports success while changing nothing. The removal
direction needs a negative predicate: rebuild if any *retired* literal
is still present.

Proven by contrast rather than asserted:

| `_base.py` triggers | result |
| --- | --- |
| negative predicate (shipped) | 4 passed |
| reverted to positive-only | 2 failed — `assert 'offline_tuner_replay'
not in 'CREATE TABL…'` |

## Remediation, because the rebuild is a table copy

A row carrying a retired value fails the copy, so the copy remediates:
`offline_tuner_replay` → `offline_tuner_legacy` (accurate — those jobs
*were* offline-tuner jobs, and that literal stays admissible), retired
`stage`/`terminal_outcome` values nulled (both columns nullable), and
`replay_manifest` artifact rows deleted (the column is NOT NULL and part
of a UNIQUE key, so there is nothing to relabel it to).

This is local-development SQLite, not tenant Postgres. No production row
is touched. Verified end to end: a legacy database carrying a replay job
and a `replay_manifest` artifact migrates rather than failing, the job
returns relabelled with `stage`/`terminal_outcome` NULL, the `candidate`
artifact survives, and the rebuild is idempotent.

## Type surface

`optimizer_kind`, `stage`, `terminal_outcome` and `artifact_kind` unions
lose their replay members. Four kinds survive.

**Backward compatibility, stated precisely:** this is a **read** break,
not a write break. An older image reads a retired-literal row fine — its
own `Literal` still admits it. The *new* image raises `ValidationError`
at model construction. Tenant Postgres still stores such rows until the
enterprise contract migration lands, so during that bake a new task
reading an old replay row raises. That is the clean break by design; the
enterprise side removed the path that would act on such a row.

## Scope

The OSS package remains importable and self-consistent standing alone —
full non-e2e tier: **6,379 passed, 13 skipped, 0 failed**, run from the
package's own venv.


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Breaking Changes**
* Retired replay-specific optimizer types, job stages, terminal
outcomes, and artifacts are no longer supported.
* Publication claims and legacy publication requests now support GEPA
only; open-world optimization remains supported for decision proofs.

* **Bug Fixes**
* Database constraint validation now rebuilds incomplete schemas to
preserve support for all valid optimizer values and stages.

* **Tests**
* Expanded coverage for outcome reachability, publication validation,
migrations, storage compatibility, and rejected replay transitions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant