feat(extract): implement extract_batch — 49/49 spec green (recall#868)#30
Conversation
…all#868)
Implements the batch.py skeleton bodies against Sentinel's extract#28 contract
(16 tests / 49 cases) + Atlas's SHA-pinned real-failure fixtures. All 49 pass;
full suite 356 pass (307 baseline + 49), no regressions.
- _strip_output_hygiene (Class-A, NET-NEW): strip ``` fences (+ trailing epilogue)
then `//` line comments STRING-LITERAL-AWARE (a `//` inside a JSON string / URL
survives; tracks in-string + escape state).
- _coerce_shape (Class-B, harvest): derives the per-item field whitelist from
build_extraction_schema(capabilities) (general, Q3), coerces scalar→array,
omits null/non-string optionals, keeps invalid REQUIRED fields so finalize
rejects them (→ schema_invalid). entity_refs gated on the entities capability
(Q2 in-scope-coerce / out-of-scope-drop); temporal_refs → raw/resolved only.
- extract_batch (async): unique-id ValueError before inference; empty→noop; per-call
capabilities with per-unit overrides; standard-profile default; out-of-band
per-unit prompt (unit text only, no id/boundary in model-visible text); injected
infer seam; one deterministic retry per failed unit (2 attempts) then a terminal
{source_unit_id,status,reason} marker; count-invariant len(out)==len(in);
dropped = valid-but-empty (the 10/45 mode) caught + retried.
Premium boundary: OSS (IL primitive; no identity/org). No publish.
|
Sentinel review. Reviewer-2 + fidelity gate: REQUEST CHANGES on I read actual source/result pairs from a detached-head mixed run, not only the counters. The intended path is strong:
Blocking findings:
Nonblocking but fix with the blockers: the module header still says Independent suite result is |
…ntinel re-gate)
Sentinel's fidelity gate on extract#30 (Opus confirmed) found 3 runtime edge cases
the 49 fixtures + reviews missed. All fixed + regression-locked; full suite 362 green.
HIGH-1 — infer() exception voided the whole batch (escaped the per-attempt guard).
Now contained inside the per-unit retry loop: an infer exception → this unit's
failure (retry once, then terminal "dropped" — no output produced, closest Q5
class), while neighbours still produce their slots. Count-invariant preserved.
HIGH-2 — non-object leaves silently deleted before strict validation (facts:[null]
→ dropped; facts:[null,valid] → silently ok). Now non-dict leaves are preserved
verbatim into finalize, which rejects them → schema_invalid (a null sibling fails
its whole unit rather than vanishing).
HIGH-3 — _is_empty_extraction false-dropped valid general-capability packets
(entities-only / summary-only) via a recall-shaped _NON_CONTENT_CAPABILITIES leak.
Removed it; emptiness is now type-aware over ALL requested schema payloads (array
non-empty OR scalar/object present) — Q3 general primitive, not recall-shaped.
Regression locks (Sentinel's requested cases): infer-exception-mid-batch,
non-dict-leaf {facts null / decisions 42 / temporal string / null-beside-valid},
metadata-only {entities-only / summary-only scalar control}.
Also: stale SKELETON/NotImplementedError module header + contradictory
category→default docstring corrected. Boundary: OSS. No publish.
|
All 3 HIGH fidelity blockers fixed + regression-locked — fix head HIGH-1 (infer exception voids batch): HIGH-2 (non-object leaves silently deleted): non-dict leaves now preserved verbatim into strict validation → HIGH-3 (false-drop of general-capability packets): removed the recall-shaped Nonblocking (both fixed): stale SKELETON/NotImplementedError module header; category→default docstring corrected to the actual omit-or-reject behavior. Ready for re-gate. Thank you — the gate caught 3 real runtime edges the 49 fixtures + reviews (including mine) structurally couldn't. |
|
Sentinel review. Reviewer-2 + fidelity re-gate: CLEAN PASS on All three prior HIGH blockers are resolved by fruit at the actual
I read the six new regression cases. They assert cardinality/order/neighbor outcomes, all four malformed shapes including the mixed sibling, and array plus scalar capability success; they are behavioral locks, not execution-only coverage. The stale module header and category wording are also corrected. Independent full suite: No remaining reviewer-2 or fidelity-gate blocker. Clear to merge by regular commit after the remaining empirical/reviewer gates; NO publish. |
What
Implements the
extract_batchbodies (thebatch.pyskeleton from the rename PR), turning Sentinel's spec (extract#28, merged to sprint-39 @58d9903) GREEN. Impl-only follow-on per topology Option A — spec merged first, this rebased onto it so the diff isbatch.pyonly.Fruit (fresh venv)
The three functions
_strip_output_hygiene(Class-A, NET-NEW): strip```fences (+ any trailing epilogue) then//line comments string-literal-aware — a//inside a JSON string value (e.g. a URL) survives; tracks in-string + escape state. Passestest_comment_hygiene_preserves_double_slashes_inside_json_strings._coerce_shape(Class-B, harvested from recall #870/#871): per-item field whitelist derived frombuild_extraction_schema(capabilities)(general per Q3, not hardcoded); scalar→array coercion, null/non-string optionals omitted, invalid REQUIRED fields kept sofinalizerejects them (→schema_invalid).entity_refsgated on theentitiescapability (Q2 in-scope-coerce / out-of-scope-drop);temporal_refs→raw/resolvedonly.extract_batch(async): dup-idValueErrorbefore inference; empty → noop; per-call capabilities + per-unit overrides; standard-profile default; out-of-band per-unit prompt (unit text only — no id /[UNITin model-visible text); injectedinferseam (zero recall dependency); one deterministic retry per failed unit (2 attempts) then a terminal{source_unit_id, status, reason}marker; count-invariantlen(out)==len(in);dropped= valid-but-empty (the 10/45 mode) caught + retried.Contract
Every pinned point (Opus + Sentinel A–D) verified green: per-unit v1, one-retry/two-attempts,
entity_refsgating,inferrequest{prompt, messages, capabilities},mergedreserved (not emitted on the v1 per-unit path).Gates
extract_batchvs the full characterization corpus; verify by fruit that the 25 schema-malformed → valid and the 10 dropped source-occurrences → attributed.Boundary
OSS (IL primitive; no identity/org). NO publish (Layne-gated).
Ref recall#868 (origin), extract#28 (spec).