|
oc_connect
|
Classes | |
| class | WorkerReportError |
| class | WorkerReportRelayError |
| class | WorkerReportEvent |
| class | WorkerReportStore |
| class | RelayOutcome |
| class | WorkerReportRelay |
Functions | |
| str | chunk_prefix (int index, int total) |
| tuple[str,...] | chunk_summary (str summary, *, int limit=TELEGRAM_MESSAGE_LIMIT) |
| str | render_chunk (str piece, int index, int total) |
| str | render_event (WorkerReportEvent event) |
| None | _atomic_write (Path path, str payload) |
Variables | |
| str | WORKER_REPORT_LANE = "worker-reports" |
| str | WORKER_REPORT_SOURCE = "worker" |
| str | WORKER_REPORT_SCHEMA_VERSION = "1.0" |
| int | TELEGRAM_MESSAGE_LIMIT = 4096 |
| int | MIN_CHUNK_LIMIT = 32 |
| WorkerReportStatus = Literal["awaiting_gate", "blocked"] | |
| str | WORKER_REPORT_BEGIN = "<<<BEGIN WORKER REPORT {event_id}>>>" |
| str | WORKER_REPORT_END = "<<<END WORKER REPORT {event_id}>>>" |
| str | NEUTRALISED_MARKER = "<< <" |
The worker-report lane: worker events at rest, and the verbatim relay.
Proposal V1 §5 (the ruled test case). A plan worker that reaches AWAITING GATE
or Blocked writes ONE event into ``comms/lanes/worker-reports/`` and stops
there: it holds no credential, knows nothing about connectors, and touches no
other lane. This module is the other half — the orchestrator-side reader and
the grant-checked, egress-filtered relay that puts the worker's own words on
the operator's phone.
**This module is the schema authority for the lane.** The writer lives in
``oc_chat/oc_chat/scripts/plan_status.py`` (a ``report`` action on the existing
worker channel) and deliberately does NOT import this package — that is what
keeps workers credential-free. The two sides therefore agree by a written
contract rather than by a shared import, and the contract is
:class:`WorkerReportEvent`::
{
"schema_version": "1.0",
"event_id": "<26-character ULID, time-first so lexical == arrival>",
"lane": "worker-reports",
"direction": "inbound",
"risk_class": "low",
"plan_id": "231-worker-report-lane",
"agent": "agent-007",
"status": "awaiting_gate" | "blocked",
"worktree": "<absolute worktree path>",
"report_path": "<absolute path of report.md in that worktree>",
"created_at_utc": "2026-09-01T12:00:00Z",
"summary": "<the worker's FULL closing summary, verbatim>",
"summary_sha256": "<sha256 of summary, utf-8>",
"relayed_at_utc": null,
"relay_chunk_count": null
}
File naming follows the §3 bus convention, ``<utc-stamp>_worker_<ulid>.json``.
Two properties are worth stating because they are easy to lose in a refactor:
* **The egress scan runs on the WHOLE summary, before any chunking.** Scanning
the rendered chunks instead would let a credential that straddles a chunk
boundary leave in two safe-looking halves. The relay therefore blocks on the
joined text and never enqueues anything for an event that failed the scan.
* **Chunk identity is derived from the event id**, so a relay interrupted after
chunk 3 of 5 resumes without re-sending chunks 1-3: the durable outbox
already holds them under the same idempotency keys and returns their existing
receipts instead of re-delivering.
Dependencies
------------
- oc_connect.audit (AuditStore, content_hash, timestamp, utc_now - audits relay outcomes, verifies summary_sha256 and stamps relayed_at_utc)
- oc_connect.delivery (OutboundSender - the grant-checked send path every relayed chunk crosses)
- oc_connect.egress (require_safe, EgressBlockedError - scans the whole summary before any chunking)
- oc_diagnostics (_dbg structured logger)
- option_c_connector_contracts (DeliveryReceipt, lane - chunk receipts and the lane's declared direction and risk ceiling)
- pydantic (BaseModel, ConfigDict, field_validator - the WorkerReportEvent schema)
|
protected |
| str oc_connect.worker_reports.chunk_prefix | ( | int | index, |
| int | total ) |
Return the ordering marker prepended to one chunk of a split summary.
Definition at line 173 of file worker_reports.py.
| tuple[str, ...] oc_connect.worker_reports.chunk_summary | ( | str | summary, |
| * | , | ||
| int | limit = TELEGRAM_MESSAGE_LIMIT ) |
Split *summary* into pieces that fit *limit* once numbered.
The split is a plain slice, never a word-boundary or whitespace-trimming
split: ``"".join(chunk_summary(text)) == text`` is the property the whole
verbatim guarantee rests on. A summary that already fits comes back as one
piece, and :func:`render_chunk` leaves that single piece unnumbered.
The chunk count and the marker width depend on each other, so the budget is
solved to a fixed point rather than guessed: every marker is rendered at the
widest form (``[{total}/{total}]``) so all pieces share one budget.
Definition at line 178 of file worker_reports.py.
| str oc_connect.worker_reports.render_chunk | ( | str | piece, |
| int | index, | ||
| int | total ) |
Return the message text for one chunk; a lone chunk is unnumbered.
Definition at line 218 of file worker_reports.py.
| str oc_connect.worker_reports.render_event | ( | WorkerReportEvent | event | ) |
Return the only representation in which a summary may be displayed. The body is fenced with the event's own id and any literal ``<<<`` inside it is neutralised, so a summary cannot forge its own closing fence. The rendered copy is the only thing that changes; the stored text does not.
Definition at line 225 of file worker_reports.py.
| int oc_connect.worker_reports.MIN_CHUNK_LIMIT = 32 |
Definition at line 90 of file worker_reports.py.
| str oc_connect.worker_reports.NEUTRALISED_MARKER = "<< <" |
Definition at line 103 of file worker_reports.py.
| int oc_connect.worker_reports.TELEGRAM_MESSAGE_LIMIT = 4096 |
Definition at line 87 of file worker_reports.py.
| str oc_connect.worker_reports.WORKER_REPORT_BEGIN = "<<<BEGIN WORKER REPORT {event_id}>>>" |
Definition at line 98 of file worker_reports.py.
| str oc_connect.worker_reports.WORKER_REPORT_END = "<<<END WORKER REPORT {event_id}>>>" |
Definition at line 99 of file worker_reports.py.
| str oc_connect.worker_reports.WORKER_REPORT_LANE = "worker-reports" |
Definition at line 78 of file worker_reports.py.
| str oc_connect.worker_reports.WORKER_REPORT_SCHEMA_VERSION = "1.0" |
Definition at line 83 of file worker_reports.py.
| str oc_connect.worker_reports.WORKER_REPORT_SOURCE = "worker" |
Definition at line 81 of file worker_reports.py.
| oc_connect.worker_reports.WorkerReportStatus = Literal["awaiting_gate", "blocked"] |
Definition at line 92 of file worker_reports.py.