Repository navigation
L08 — Bounded Decision Worker module gate #9
Description
Outcome
Optional local-first typed decision observations for explanation, routing, and proposals, built on the jev-ultrafast loop: indexed state → one request choosing an operation and its target → a deterministic consumer that alone touches Core.
Module owner
proposed Decision module. Adapters in other surfaces consume this module contract; they do not create alternate PDF or provenance authority.
North Star architecture
Reference pinned at browser-use/jev-ultrafast@1231850a (README.md, docs/design.md, jev_ultrafast/model.py, jev_ultrafast/agent.py). L08 adopts its architecture. It does not adopt the provider, the browser task, or the Python code. Every sub-issue implements one row of this translation.
| jev-ultrafast | L08 equivalent | Owner |
|---|---|---|
| One atomic snapshot → indexed element table; code-owned node identity, never CDP IDs | One DecisionState snapshot of an exact Core receipt/revision → indexed candidate table (findings, admitted operations, eligible Medic routes, enumerated parameter values). Indices are code-owned and map to Core identities |
#61 |
Dynamic action space: only supported operations and compatible targets are offered; DONE/BLOCKED are always offered |
Dynamic question space: only operations deterministic eligibility already admits; each target head lists only compatible candidates; ABSTAIN and NO_ACTION are always offered |
#61, #62 |
| One request: an operation head plus speculative per-operation target heads; only the selected operation's head is consumed | One provider round trip per decision; unused heads are retained in the receipt and can never produce an observation | #61, #63 |
validate_choice: the choice is an offered ID, probabilities cover exactly the offered IDs, sum ≈ 1, the choice is the argmax, all values finite |
The same validation at the parse boundary. Any failure means no actionable observation | #61, #64 |
A text LLM runs only for TYPE_TEXT: strict {"text": …}, null when the value is missing, cached only for identical input |
Free text only for declared text slots: strict single-key JSON that cites indices, null when unsupported, digest-keyed cache |
#261 |
| Model output never becomes selectors, coordinates, or code | Model output never becomes Core IDs, paths, parameters, or plan fields except by selecting an offered index | #64 |
| Freshness fingerprint rechecked before execution; stale → re-observe and choose again; guards are scoped to semantic state, not every DOM mutation | Revision/receipt/policy/candidate-set digest rechecked before handoff; stale → discard and re-snapshot; unrelated state changes do not invalidate | #66 |
| A decision is consumed once; mutations are never retried; the executed action is logged before the next observation | An observation is consumed once by the L04 or Medic adapter; proposals are never auto-resubmitted; the receipt is written before any follow-up decision | #66, #67 |
Budgets: 60 actions, 120 decisions, 250 candidates (truncated candidates are unselectable), 3 no-progress steps → BLOCKED |
Per-task budgets for decisions, candidates, latency, and tokens; truncated candidates are unselectable; no progress → abstain with a reason | #64, #65 |
DONE is not proof; the outcome is verified independently |
An observation is never PASS, approval, or a verdict. Core revalidation and human approval decide | #66 |
| No screenshots in the loop; visible text only; page text is untrusted data | Minimized structured state; no artwork bytes; PDF text is quoted data, never instructions | #64 |
| Inspector: numbered elements, operation and target probabilities, a "Choose next" pause before execution | Decision inspector and trace for Editor and PdfTool: the table, every head's distribution, the selected head, reason codes, and a pause before handoff | #67 |
| Matched alternating runs; per-run source hashes, request counts, token counts; all failures retained | Held-out rules-vs-model packets and target-hardware latency receipts with the same discipline | #63, #65, #67 |
| About six small files; the loop fits on one screen | One snapshot builder, one question builder, one validator, one consumer, one provider port. Keep the loop small enough to read | all |
Not imported: the hosted TypeSafe endpoint as the default provider (it conflicts with local-first operation and the egress ban), browser control, a Python runtime as a product dependency, and jev-* model labels as admission evidence. A hosted Jev-style provider may serve only as an opt-in research comparator on rights-cleared or synthetic inputs under #64 egress approval. Loop evaluates its own tasks; see the R4 ledger.
Entry dependencies
Exit gate
No-provider path works through the same question/answer contract. Exact-context, response-validation, single-head-consumption, freshness, calibration, abstention, adversarial, privacy, target-hardware, and two-client tests pass per admitted task.
Native sub-issues
Order: #61 → (#62, #64, #261) → #63 → #65 → #66 → #67.
- L08-01 — Define indexed decision state and one-request question contract #61 — L08-01 Define indexed decision state and one-request question contract
- L08-02 — Build deterministic no-provider policy over the same action space #62 — L08-02 Build deterministic no-provider policy over the same action space
- L08-03 — Select and pin providers behind the one-request port #63 — L08-03 Select and pin providers behind the one-request port
- L08-04 — Contain private state, hostile documents, and model output #64 — L08-04 Contain private state, hostile documents, and model output
- L08-05 — Calibrate task and stratum abstention #65 — L08-05 Calibrate task and stratum abstention
- L08-06 — Consume observations once through Medic routing and plan-assist adapters #66 — L08-06 Consume observations once through Medic routing and plan-assist adapters
- L08-07 — Qualify two clients, decision receipts, and the inspector #67 — L08-07 Qualify two clients, decision receipts, and the inspector
- L08-08 — Gate free-text slots behind a single-key text helper #261 — L08-08 Gate free-text slots behind a single-key text helper
Evidence and scope rules
Pin the starting SHA. Distinguish implementation, runtime proof, independent proof, and release admission. Use the repository's mapped tests, architecture proof lanes, check-change gate, and a scoped changelog fragment for PRs. Do not import legacy status as completion. Resolve overlaps by verifying current code first and updating an existing outcome branch if one exists. Where an issue departs from the North Star table, record the reason in its handoff.
Sources
Approved master roadmap · Legacy/research intake · jev-ultrafast design.
Generated by Claude Code
Activity