oc_chat
Loading...
Searching...
No Matches
oc_chat.registry.queue_backend Namespace Reference

Classes

class  LaneIsNotASlotError
class  MissingRegistryArgumentError
class  UnknownPlanRowError
class  UnsupportedItemKindError
class  RegistryQueueBackend

Functions

str|None _bucket_of (QueueState state, str item_id)
int _pending_index (QueueState state, str item_id)
int _checked_index (int|None position, int upper)

Variables

str ENQUEUE_REASON = "initial enqueue"
str DEQUEUE_REASON_DEFAULT = "operator_dequeue"
dict _OP_BY_TYPE
str _COMMAND_PREFIX = "work_queue"
 _INSTANCE_RE = re.compile(r"instance=(?P<instance>\S+)")

Detailed Description

The registry backend: the queue's operations over the registry's own.

Purpose
-------
Plan 258 P3. The queue has one operation set and two backends. This is
the one oc_chat plugs in, and it lives on the REGISTRY side on purpose:
signing, audit and checkpoints already live here, so the queue inherits
them instead of growing a second copy. It implements the same
:class:`~oc_chat.core.work_queue.QueueBackend` protocol over the four
typed operations that ``registry/domain.py`` already exposes --
``queue_enqueue``, ``queue_move``, ``queue_dequeue``, ``queue_complete``
-- and writes nothing else: every mutation is one operation-log row with
``related_plan_id`` set, and the registry's own projection updates the
``plans`` table.

The import direction is registry -> dispatch, which is the permitted
one and the one ``registry/mirror_observer.py`` already takes. Nothing
in the dispatch layer imports this module.

**The vocabulary mismatch, named rather than papered over.** The
registry's operations are slot-shaped and reason-closed; the contract's
are lane-shaped and reason-free. Three things do not fit, and each is
handled in the open:

``lane`` does not map onto ``slot``
    MEASURED against a temporary registry, not assumed: ``plans``
    declares ``assigned_slot TEXT REFERENCES agents(slot)`` and
    ``PRAGMA foreign_keys`` is on, so a free-text slot is refused with
    ``sqlite3.IntegrityError: FOREIGN KEY constraint failed``. The
    adapter therefore takes ONE registered slot at construction and
    refuses a work item whose ``lane`` names anything else, by name.
    No roster was invented to make the mapping work.

``instance`` and the contract's own reason have no column
    The queue payloads are fixed and adding a field is a registry
    change this plan does not make. They ride in ``command``, the
    operation log's free-text provenance column, in a deterministic
    form this module also parses back.

``complete`` needs a round and a merge commit
    ``queue_complete`` requires ``round_no`` and ``merge_commit_sha``.
    They are taken as keyword arguments -- which the file backend
    accepts and ignores -- rather than smuggled through ``reason``,
    because a round number and a sha packed into free text would be a
    parser in disguise.

Responsibilities
----------------
- :class:`RegistryQueueBackend` -- the six contract operations.
- :data:`ENQUEUE_REASON` / :data:`DEQUEUE_REASON_DEFAULT` -- the two
  closed-set members this adapter maps onto, pinned as constants so the
  witness can assert them.
- :class:`LaneIsNotASlotError`, :class:`MissingRegistryArgumentError`,
  :class:`UnknownPlanRowError`, :class:`UnsupportedItemKindError` --
  the adapter's own named refusals, all under the contract's
  :class:`~oc_chat.core.work_queue.QueueBackendError`.

Diagnostics
-----------
Domain: OC_CHAT.MAIN
Levels:
    L2 - lifecycle events (an operation emitted)
    L3 - semantic details (a mapping, a refusal)
    L4 - deep tracing (module load)

Contracts
---------
- This module MUTATES only through ``registry.domain``: no SQL write,
  no direct table update. Its reads are SELECTs through
  ``registry.readers`` and one connection for the ``plans`` projection.
- ``status()`` takes the pending ORDER from the ``plans`` table's
  ``assigned_slot`` / ``queue_position`` projection -- that projection
  is what the registry maintains -- and the PHASE of each item from its
  latest queue operation in the log, because the projection models
  pending and not-pending and cannot by itself tell "in progress" from
  "completed" from "never queued".
- ``kind`` other than ``"plan"`` is refused BY NAME: ``related_plan_id``
  is plan-shaped, which the design note ยง5 names as the seam a second
  kind will find.
- Nothing here is edited in ``registry/domain.py``,
  ``registry/backends/**`` or ``registry/cli/**``; this adapter is the
  only registry-side file plan 258 adds.

Dependencies
------------
- oc_diagnostics (structured debug logging via _dbg)
- oc_orchestrator.work_queue (the contract; moved there by plan 271)
- oc_chat.registry.api (the Registry facade)
- oc_chat.registry.domain (the four typed queue operations)
- oc_chat.registry.readers (the queue history reader)

Function Documentation

◆ _bucket_of()

str | None oc_chat.registry.queue_backend._bucket_of ( QueueState state,
str item_id )
protected
Which bucket holds *item_id*, in words, or ``None``.

Definition at line 497 of file queue_backend.py.

Here is the caller graph for this function:

◆ _checked_index()

int oc_chat.registry.queue_backend._checked_index ( int | None position,
int upper )
protected
*position* as a 1-based index in ``1..upper``, or the end.

Definition at line 519 of file queue_backend.py.

Here is the caller graph for this function:

◆ _pending_index()

int oc_chat.registry.queue_backend._pending_index ( QueueState state,
str item_id )
protected
The 1-based position of *item_id* in pending, or a named refusal.

Definition at line 509 of file queue_backend.py.

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ _COMMAND_PREFIX

str oc_chat.registry.queue_backend._COMMAND_PREFIX = "work_queue"
protected

Definition at line 157 of file queue_backend.py.

◆ _INSTANCE_RE

oc_chat.registry.queue_backend._INSTANCE_RE = re.compile(r"instance=(?P<instance>\S+)")
protected

Definition at line 158 of file queue_backend.py.

◆ _OP_BY_TYPE

dict oc_chat.registry.queue_backend._OP_BY_TYPE
protected
Initial value:
1= {
2 "queue.enqueue": OP_ENQUEUE,
3 "queue.move": OP_MOVE,
4 "queue.dequeue": OP_DEQUEUE,
5 "queue.complete": OP_COMPLETE,
6}

Definition at line 150 of file queue_backend.py.

◆ DEQUEUE_REASON_DEFAULT

str oc_chat.registry.queue_backend.DEQUEUE_REASON_DEFAULT = "operator_dequeue"

Definition at line 145 of file queue_backend.py.

◆ ENQUEUE_REASON

str oc_chat.registry.queue_backend.ENQUEUE_REASON = "initial enqueue"

Definition at line 136 of file queue_backend.py.