Repository navigation
fix(detection): augment plain source on candidate lifecycle - #267
asteier2026 wants to merge 31 commits into
Conversation
[Medium impact] This PR appears safe to merge; no new actionable issue was found. SummaryAugmentation now reads canonical plain source text without detector tags or a seed-entity list.
The earlier overlap concern is no longer outstanding. asteier2026 accepted the old behavior because augmentation was expected to return minimal spans; the current stack supersedes that behavior with shared longest-first selection. Reviews (6) · Last reviewed commit: "fix(detection): augment plain source on ..." · Reviewed by Greptile |
cbf4e98 to
36d76a3
Compare
| """ | ||
| non_augmenter = [item for item in entities if item.source != "augmenter"] | ||
| augmenter = [item for item in entities if item.source == "augmenter"] |
There was a problem hiding this comment.
Broader sensitive spans discarded
When the augmenter identifies a broader sensitive value that overlaps a narrower detector span, this filter discards the entire augmenter entity instead of preserving its non-overlapping sensitive portion. For example, if the augmenter finds a full street address containing a detector-identified city, only the city reaches validation and replacement. The rest of the address can remain unanonymized.
How this was verified: Only entities retained by resolve_overlaps() are passed into validation and replacement, and no later stage reconstructs the discarded span or its residual intervals.
There was a problem hiding this comment.
This is by design. If gliner finds Seattle and augment finds "near downtown Seattle", it's better to hold on to the validated gliner entity "Seattle" and throw out the rest. I think it's too messy to try and weed out parts of the augment span that should still be an entity. Augment is supposed to find minimal spans. If "Seattle, Washington" shows up, we want augment to tag "Seattle" and "Washington" individually.
There was a problem hiding this comment.
That makes sense. Given the augmenter’s minimal-span contract, dropping an overlapping augmenter result is intentional: the validated GLiNER span is preserved, while the augmenter is expected to emit separate minimal entities such as Seattle and Washington rather than a broader span containing Seattle. I’m withdrawing this concern.
There was a problem hiding this comment.
Updating this older thread to reflect the current stack: #267 has been restacked at 16e9d0d onto #305 head 399ede8. The original seed-overlap rejection patch is no longer part of #267. It changes augmentation input/prompt only; independently grounded/admitted suggestions and detector observations flow through #305's shared eligibility, exact-identity coalescing, and final reconciliation.
Consequently, an eligible broader span is not discarded merely because it overlaps a narrower detector span: greedy longest-first selection prefers the broader supplied span in a containment conflict. Same-bound ties use acceptance/source policy. Partial overlaps still select one supplied span, not a synthetic union or residual intervals; this is not a maximum-total-coverage guarantee. Discriminating containment, later-start/longer, greedy-tradeoff, and excluded-fallback tests live in #305. The restacked #267 passed 1,841 tests, make check, and strict docs build. This supersedes the earlier seed-precedence explanation in this thread.
36d76a3 to
a6f683a
Compare
|
@asteier2026 — handoff for bringing this onto #305, including the local experiment results. What we actually changed locally We tested a prompt-only adaptation of this PR's The adaptation:
We did not apply this PR's overlap-resolver change. #305 replaces that older path with occurrence-specific admitted candidates and shared final reconciliation. That part needs reassessment against #305, rather than carrying the old How we tested it We replayed augmentation only, retaining each original run's exact validated seed candidates. No new detector or validator calls were made. Luna and Nemotron 3.5 Super VL used NVIDIA Inference; Gemma 4 26B A4B used OpenRouter. Sampling and the 32,768-token output limit were unchanged.
A target checked in three repeats contributes three checks; these are not counts of unique records. All 34 Luna/Super replay attempts returned. Gemma returned 48/51 after retrying only failed attempts on another provider; three responses still failed output-format validation. No invalid final source spans were found among returned replays. The Gemma control regression was an organization mention omitted in all three repeats, not an accepted finding discarded during reconciliation. This needs investigation before claiming the prompt is an across-the-board improvement. Average augmentation time, including retries, was approximately 19 → 28 seconds for Luna and 19 → 32 seconds for Super. We should not make a causal Gemma speed claim because its replay overlapped other endpoint traffic and failed attempts were recovered on another provider. Limits: this was a small, selected failure-enriched cohort. We reused saved current-prompt outputs, rather than rerunning both prompts in a fresh counterbalanced comparison. The Gemma recovery also changed providers. These results show recovery of selected missed mentions, not population precision/recall or proof that all additional predictions are correct. Suggested port
The same results are recorded in the implementation-review comment on #305. This prompt change remains separate from #305 and from the regex work in #265. |
a6f683a to
abb6d88
Compare
This comment has been minimized.
This comment has been minimized.
abb6d88 to
16e9d0d
Compare
|
Restacked onto the current #305 head, 399ede8. New #267 head: 16e9d0d; base remains lipikaramaswamy/feature/detection-semantics. Only the original #267 commit was replayed. Range-diff shows the same intended patch (only a surrounding test-helper context changed), so this retains canonical plain-text augmentation, removal of seed/do-not-repeat instructions, and the existing grounding/admission/reconciliation contracts. It also inherits #305 fixes, async-only plugins, test cleanup, documentation, and the bounded grounding optimization. Original author/sign-off preserved; the old tip abb6d88 is retained locally for recovery. Validation: all 1,841 tests passed; make check and strict make docs-build passed. No provider-backed inference or new quality benchmark was run; the earlier reported experiment remains historical evidence with its existing caveats. |
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Bind each validator response to an immutable request inventory and use the same observation-based path for synchronous and asynchronous dispatch. Keep connected overlap groups together. Treat max_entities_per_call as a batching target: send an oversized group alone and log only its size and the configured target. Tag only observations assigned to the current request. Neighboring detections remain plain text in its source excerpt, rather than receiving the detector label tags used by the old excerpt builder. Prompt skeleton offsets index the untagged excerpt, while the authoritative inventory keeps canonical offsets. Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Validator drops are no longer re-applied after augmentation. Each decision governs only its original observation, so an independently admitted augmenter match of a dropped GLiNER span can now survive finalization, subject to label eligibility and overlap resolution. This user-visible change can increase recall or reduce precision; its frequency and benchmark impact are unmeasured. Track validator-drop rediscovery in the plan and compare main and this branch on the same dataset, reporting overall precision and recall and the affected entities' count and precision. Carry this disclosure into the PR description when the implementation is pushed. Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Ground augmenter suggestions to exact contextual source occurrences. Preserve successfully grounded items and retry only unsuccessful suggestions once, including their original fields and failure categories without identifiers. Assign observation IDs after combining successful attempts. Grounding failures no longer fail the whole record: drop remaining ungroundable suggestions while retaining admitted GLiNER candidates and successful augmentation. Record partial outcomes and attempt-local failure indexes and categories without values. Transport and schema failures retain FailedRecord behavior. Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Publish final entities and tagged text from reconciled occurrence-specific candidates, rather than reinterpreting merged entity values. Remove: - Global case-insensitive value propagation via expand_entity_occurrences. - Automatic splitting of full_name into first, middle, and last name entities. - Legacy value-only augmentation matching via apply_augmented_entities, its route-local resolve_overlaps policy, and helpers used only by those paths. - Fallback branches that read legacy entity payloads when required candidate columns are absent. - Redundant label filtering in merge/finalize and its config and dispatch parameters; admission already enforces label eligibility. - Unused _seed_tagged_text, _merged_tagged_text, and _validated_seed_entities row columns, including constants and side-effect declarations. Repeated values and standalone name parts now require occurrence-specific detector or grounded augmenter observations. Missing required candidate columns fail explicitly instead of silently taking a legacy path. Keep final tagged output, request-specific validator excerpts, and _seed_validation_candidates for measurement. Separate the validator excerpt template variable from stored column constants. Replace obsolete helper tests with candidate-lifecycle, output-contract, and non-propagation coverage. Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Wrap detector source text in a JSON-encoded object before DataDesigner renders the prompt. Its automatic JSON decoding unwraps the object without reformatting the original source string, keeping detector offsets aligned with canonical text. Drop the temporary wrapper from workflow output. Cover synchronous and asynchronous prompt generation, formatted JSON objects and arrays, scalar JSON, Unicode, escaping, whitespace, literal Jinja syntax, and canonical-offset parsing with synthetic regression tests. Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Use 128-word windows with 32-word overlap in the bundled GLiNER2 server and preserve configured window settings in the detection workflow. Reuse the source-safe native-word chunking implementation from main. Keep overlapping alternatives through native inference and document merging so validation can judge cleaner nested spans. Translate five checkpoint-native inference labels and restore requested labels without narrowing the entity scope or changing the 0.3 threshold. Include source-offset, window, overlap, and label-mapping tests, deployment guidance, and the targeted benchmark rationale. Augmentation grounding remains unchanged. Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: lipikaramaswamy <lramaswamy@nvidia.com>
Signed-off-by: asteier2026 <asteier@nvidia.com>
16e9d0d to
1c3e181
Compare
Summary
Stacked on #305 (
lipikaramaswamy/feature/detection-semantics, current parent399ede83). Depends on #305; retarget tomainafter that PR lands.The augmenter now receives canonical plain source text (
COL_TEXT), without engine tags, seed-entity lists, or instructions to avoid existing detections. Both label-mode examples use plain text and retainvalue,label,context_before,context_after, andreason.Preserves #305's exact-source grounding, bounded grounding retries, label scope, date policy, independent seed admission, and shared candidate reconciliation. Removes augmentation's obsolete tagged-input dependencies and tag-stripping guidance, including the correction prompt. The old #267
resolve_overlaps()patch is intentionally not ported: duplicate and conflicting discoveries follow #305's existing policy. No every-occurrence instruction or native schema enforcement is added. Public API is unchanged.Plan and experiment details: plans/267/plain-text-augmentation.md. Tracks #262; separate from the regex work in #265.
Reported replay evidence
These are supplied experiment results from a prompt-only adaptation onto
97c0ae80, not new measurements on this head. Augmentation-only replays retained original validated seeds, sampling, and the 32,768-token output limit; no fresh detector or validator calls were made.Checks include repeats, not unique-record counts. All 34 Luna/Super attempts returned. Gemma returned 48/51 after failed-attempt recovery on another provider; three still failed output-format validation. Returned replays had no invalid final source spans. The Gemma regression was an organization mention omitted in all three repeats, not a finding discarded by reconciliation.
Average augmentation time including retries rose approximately 19 → 28 seconds for Luna and 19 → 32 seconds for Super. Gemma timing is confounded by concurrent endpoint traffic and provider changes.
This small selected failure-enriched cohort reused saved baselines and is not a fresh counterbalanced comparison. It does not establish population precision/recall, correctness of every additional prediction, or a general quality/performance improvement. A fresh paired provider-backed comparison and investigation of the exact Gemma control remain outstanding; no broad improvement claim is made.
Validation
TMPDIR=/tmpand a short pytest base directory to avoid unrelated macOS temporary-path failures.make checkpassed in an isolated dev/docs environment (the local notebook extras expose existing unused-ignore warnings in refactor(detection): establish deterministic entity candidate lifecycle #305). Strictmake docs-buildpassed.PR stack
Merge/review order: #305 → #267 → #335.
main.After a parent is squash-merged, restack the remaining child commits onto the updated parent/
mainand retarget their PRs as appropriate. These links describe dependency order, not approval or CI status.