Skip to content

refactor: unify assertion and run status vocabularies - #3657

Merged
Sinity merged 3 commits into
masterfrom
feature/refactor/t46-vocabulary-hygiene
Aug 3, 2026
Merged

refactor: unify assertion and run status vocabularies#3657
Sinity merged 3 commits into
masterfrom
feature/refactor/t46-vocabulary-hygiene

Conversation

@Sinity

@Sinity Sinity commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Summary

This PR wires the missing CAVEAT assertion capture route and consolidates run-lifecycle status handling across operation surfaces, maintenance planning, and disposable ops ledgers. It preserves public capture and embedding display values while making the internal lifecycle boundary typed.

Problem

The assertion audit found CAVEAT present in candidate readers and allowlists but absent from the production capture map. The same audit initially suggested RUN_STATE was dead, but focused production tests proved the transform-candidate pipeline still emits and promotes that historical value. Run and attempt lifecycle states were independently declared in ops DDL, maintenance planning, and operation acknowledgements, with interrupted and cancelled representing the same non-error stop in adjacent subsystems.

Solution

  • Add CAVEAT to the shared candidate capture map and the existing terminal note choices. Keep HIGHLIGHT and PROMPT_EVAL, which were already wired by prior master work. Keep RUN_STATE, LESSON, BLOCKER, and HANDOFF where production writers or readers still prove their meaning. Retain the former BackfillStatus import as an alias while making the planner model use canonical OperationStatus.
  • Move canonical OperationStatus into core.enums, add interrupted, generate both ops-tier lifecycle checks from one subset, and re-export the existing operations import path.
  • Replace the embed writer's implicit status fallback with an explicit typed mapping from public complete and stopped values to completed and interrupted. Map interrupted operations to blocked readiness and preserve the legacy monolith reader's historical statuses.

Acceptance matrix

Bead Acceptance criterion Result Evidence
polylogue-jwqj CAVEAT has a production writer and remains judgeable Satisfied Real note --kind caveat capture test writes a candidate returned by the candidate-review reader
polylogue-jwqj Dead enum values are removed only when production evidence proves no writer or reader Satisfied with corrected evidence HIGHLIGHT and PROMPT_EVAL were already wired on master; RUN_STATE is retained because transform candidates produce it and promotion consumes it
polylogue-jwqj Public vocabulary and historical interpretation stay stable Satisfied No stored assertion value is migrated or deleted; existing lifecycle claim kinds remain covered
polylogue-oj4oo Run lifecycle states share one typed vocabulary and generated ops checks Satisfied Canonical OperationStatus, one lifecycle subset, and both ops DDL checks are exercised by real writer/readback tests
polylogue-oj4oo Public embed values retain their display vocabulary while write translation becomes typed Satisfied complete and stopped remain payload values; stopped persists as interrupted through _record_archive_backfill_run
polylogue-oj4oo Maintenance and readiness consume the canonical status Satisfied Planner model, compatibility import, operation contract, and blocked-readiness tests use the canonical enum

Verification

  • python -m devtools test tests/unit/cli/test_note.py tests/unit/storage/test_archive_tiers_assertions.py tests/unit/operations/test_operation_contract.py tests/unit/core/test_readiness_capability.py tests/unit/cli/test_embed_status_fast.py tests/unit/sources/test_live_watcher_catchup_order.py tests/unit/daemon/test_live_ingest_attempt_progress.py tests/unit/maintenance/test_planner_contract.py -> 196 passed.
  • python -m devtools verify --quick -> exit 0; format, lint, mypy, render, layering, policy, and schema promotion steps passed.
  • python -m devtools render openapi and python -m devtools render cli-output-schemas -> synchronized; no generated file diff was required.
  • python -m devtools render all --check -> all checked surfaces synchronized.
  • python -m devtools verify --seed-testmon --skip-slow reached the seeded broad suite and exposed unrelated baseline failures in tests/unit/daemon/test_daemon_bulk_rebuild_responsiveness.py::test_small_writer_actors_stay_responsive_during_bulk_rebuild_drain and both tests/unit/sources/test_live_watcher_locking.py::test_real_watcher_writer_routes_cannot_pin_process_exit cases. The run was stopped after these failures were established; the affected focused suite remained green.

Ref polylogue-jwqj
Ref polylogue-oj4oo

Summary by CodeRabbit

  • New Features

    • Added support for caveat and prompt_eval note types.
    • Added an interrupted operation status for stopped or halted processes.
    • Interrupted operations now appear as blocked in readiness indicators.
  • Bug Fixes

    • Stopped archive backfills are consistently recorded as interrupted.
    • Invalid operation statuses are handled safely instead of being misclassified.
  • Tests

    • Added coverage for note types, interrupted operations, status persistence, and readiness behavior.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Sinity, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 42 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f06e4595-6aa5-4b3f-9283-9d812b3a169d

📥 Commits

Reviewing files that changed from the base of the PR and between b88deb1 and aa7a1b8.

📒 Files selected for processing (15)
  • polylogue/api/archive.py
  • polylogue/cli/commands/embed.py
  • polylogue/cli/commands/note.py
  • polylogue/core/enums.py
  • polylogue/maintenance/planner.py
  • polylogue/operations/operation_status.py
  • polylogue/readiness/capability.py
  • polylogue/storage/sqlite/archive_tiers/bootstrap.py
  • polylogue/storage/sqlite/archive_tiers/ops.py
  • polylogue/storage/sqlite/archive_tiers/ops_write.py
  • tests/unit/cli/test_embed_status_fast.py
  • tests/unit/cli/test_note.py
  • tests/unit/core/test_readiness_capability.py
  • tests/unit/operations/test_operation_contract.py
  • tests/unit/storage/test_archive_tiers_ops_write.py
📝 Walkthrough

Walkthrough

The PR centralizes OperationStatus, adds the interrupted lifecycle state, validates archive backfill status persistence, updates OPS database constraints and writes, maps interrupted operations to blocked readiness, and adds caveat and prompt_eval CLI vocabulary.

Changes

Operation status lifecycle

Layer / File(s) Summary
Canonical status contract
polylogue/core/enums.py, polylogue/operations/operation_status.py, polylogue/maintenance/planner.py, tests/unit/operations/test_operation_contract.py
Defines and exports the shared OperationStatus enum. Preserves compatibility imports and updates planner deserialization and contract tests.
Status persistence and backfill translation
polylogue/storage/sqlite/archive_tiers/ops.py, polylogue/storage/sqlite/archive_tiers/ops_write.py, polylogue/cli/commands/embed.py, tests/unit/cli/test_embed_status_fast.py
Uses canonical lifecycle checks and normalizes enum values for OPS writes. Maps complete to COMPLETED and stopped to INTERRUPTED; unsupported statuses raise ValueError.
Vocabulary and readiness updates
polylogue/api/archive.py, polylogue/cli/commands/note.py, polylogue/readiness/capability.py, tests/unit/cli/test_note.py, tests/unit/core/test_readiness_capability.py
Adds caveat and prompt_eval choices. Maps interrupted operations to blocked readiness.

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

Sequence Diagram(s)

sequenceDiagram
  participant embed_command
  participant _record_archive_backfill_run
  participant ops_write
  participant OPS_database
  embed_command->>_record_archive_backfill_run: pass CLI backfill status
  _record_archive_backfill_run->>_record_archive_backfill_run: map complete or stopped to OperationStatus
  _record_archive_backfill_run->>ops_write: persist normalized status
  ops_write->>OPS_database: write embedding catchup run
  OPS_database-->>_record_archive_backfill_run: store completed or interrupted status
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: consolidating assertion and run status vocabularies.
Description check ✅ Passed The description covers the required summary, problem, solution, verification, acceptance criteria, and known broader-suite failures.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/refactor/t46-vocabulary-hygiene

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@Sinity
Sinity force-pushed the feature/refactor/t46-vocabulary-hygiene branch 3 times, most recently from 71e995e to b88deb1 Compare August 3, 2026 17:52

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@polylogue/storage/sqlite/archive_tiers/ops.py`:
- Around line 7-12: Update the OPS schema convergence logic around
OPS_SCHEMA_VERSION and _OPS_RUN_STATUS_CHECK to repair existing ops.db files,
not only newly created tables. Add idempotent helpers that drop and recreate the
status CHECK constraints for ingest_attempts and embedding_catchup_runs using
OPERATION_LIFECYCLE_STATUSES, ensuring interrupted is accepted, and invoke them
during bootstrap after OPS_DDL.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e79e3766-8d95-4b58-b4d2-80676efe29b2

📥 Commits

Reviewing files that changed from the base of the PR and between 8eb5ed3 and b88deb1.

📒 Files selected for processing (13)
  • polylogue/api/archive.py
  • polylogue/cli/commands/embed.py
  • polylogue/cli/commands/note.py
  • polylogue/core/enums.py
  • polylogue/maintenance/planner.py
  • polylogue/operations/operation_status.py
  • polylogue/readiness/capability.py
  • polylogue/storage/sqlite/archive_tiers/ops.py
  • polylogue/storage/sqlite/archive_tiers/ops_write.py
  • tests/unit/cli/test_embed_status_fast.py
  • tests/unit/cli/test_note.py
  • tests/unit/core/test_readiness_capability.py
  • tests/unit/operations/test_operation_contract.py

Comment thread polylogue/storage/sqlite/archive_tiers/ops.py
Sinity and others added 3 commits August 3, 2026 20:08
Problem: CAVEAT was accepted by the assertion candidate allowlists and readers but omitted from the capture-kind map, so terminal and agent capture could not produce it.\n\nWhat changed: add CAVEAT to the shared capture map and the existing terminal note choices. Preserve RUN_STATE after focused tests proved the transform-candidate producer and promotion reader still use its historical value.\n\nCompatibility/migration: no stored vocabulary changed. Existing HIGHLIGHT, PROMPT_EVAL, BLOCKER, HANDOFF, LESSON, and RUN_STATE semantics remain intact.\n\nRef polylogue-jwqj
Problem: ingest attempts, embedding catch-up, maintenance planning, and operation acknowledgements carried duplicated lifecycle vocabularies, including interrupted versus cancelled for the same non-error stop. The embed writer translated public values with an untyped fallback.\n\nWhat changed: make OperationStatus the canonical low-level enum, add interrupted, generate both ops-tier lifecycle checks from one subset, type status boundaries, map the public complete/stopped payload explicitly, and replace the planner-local enum with a compatibility alias to the canonical type. Interrupted operations now project to blocked readiness.\n\nCompatibility/migration: public complete/stopped payload values remain unchanged. The ops tier is disposable, so its bootstrap DDL uses interrupted consistently; the legacy monolith reader still interprets historical rows unchanged. Existing imports of BackfillStatus resolve to the canonical OperationStatus.\n\nRef polylogue-oj4oo
Problem: same-version OPS bootstrap replays CREATE TABLE IF NOT EXISTS, which leaves an existing embedding_catchup_runs CHECK admitting cancelled but rejecting the new interrupted lifecycle status.

What changed: reuse the canonical OPS table DDL in a row-preserving status-check convergence helper. Rebuild only stale ingest_attempts or embedding_catchup_runs tables, normalize legacy cancelled embedding rows to interrupted, and recreate the ingest indexes. Bootstrap invokes the helper after additive column convergence.

Compatibility/migration: OPS remains disposable and schema version 1. Existing rows are copied transactionally; cancelled embedding rows retain their non-error stop meaning as interrupted.

Verification: devtools test tests/unit/storage/test_archive_tiers_ops_write.py tests/unit/storage/test_schema_drift_samples.py (25 passed). devtools verify --quick passed all checks except the inherited stale layering baseline entry for polylogue/mcp/server_prompts.py, unchanged from origin/master.

Co-Authored-By: Claude <noreply@anthropic.com>
@Sinity
Sinity force-pushed the feature/refactor/t46-vocabulary-hygiene branch from b88deb1 to aa7a1b8 Compare August 3, 2026 18:09
@Sinity

Sinity commented Aug 3, 2026

Copy link
Copy Markdown
Owner Author

Verified against the OPS bootstrap and lifecycle paths: same-version opens re-run OPS_DDL, but SQLite leaves existing table CHECK constraints unchanged. An existing embedding_catchup_runs table with the former cancelled constraint rejected interrupted writes; OPS_SCHEMA_VERSION remains 1 under the disposable-tier convergence regime.

Added idempotent OPS writer convergence invoked after additive column setup. It rebuilds only stale ingest_attempts or embedding_catchup_runs tables in the caller transaction, copies existing rows, normalizes legacy cancelled embedding rows to canonical interrupted, and recreates the ingest indexes. Added a real existing-database regression covering pre-repair rejection, repeated bootstrap, row preservation, and interrupted writes on both tables.

Verification: devtools test tests/unit/storage/test_archive_tiers_ops_write.py tests/unit/storage/test_schema_drift_samples.py -> 25 passed; rebased pre-push devtools verify --quick -> all 21 steps passed.

@Sinity
Sinity merged commit 0a39fe0 into master Aug 3, 2026
3 checks passed
@Sinity
Sinity deleted the feature/refactor/t46-vocabulary-hygiene branch August 3, 2026 18:46
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