Report independent interpretation citation errors in one repair
This commit is contained in:
1 parent
a9b49bbb13
commit
c4225ebf04
10 files changed
+3746
-6
No files matched your search
@@ -0,0 +1,13 @@
|
||||
# BUG-000021: independent citation diagnostics
|
||||
|
||||
Date: 2026-10-24. Input: operator-supplied `BUG-000021-Fallakte.zip`, analysis revision 1, review reason `MODEL_VALIDATION_EXHAUSTED`. No cloud calls were executed for this investigation or patch.
|
||||
|
||||
The interpretation-only fallback omitted the identity evidence for Furien in `/relevant_entities/1` and independently cited a report in `/described_behavior/0`, where local-description facts are required. The existing statement collector diagnosed only the first issue. The next response correctly repaired the requested entity citation, but final validation rejected the previously undisclosed description citation.
|
||||
|
||||
The collector now reports both independent paths. Interpretation-only fallback rejections persist their diagnostics just like joint and statement-repair outputs. Feedback uses the saved diagnostics. Historical rejections without this diagnostic field retain the legacy collector, and statement-patch validation accepts the exact legacy or current deterministic issue list, preserving request and parent-call binding. No source rule or final validation was relaxed.
|
||||
|
||||
The curated rejection fixture is `tests/fixtures/llm_rejections/20261024/bug21-independent-citation-errors/`. It includes a rejected interpretation, source-validation context and analysis, not a full package or run dump. The independent usage report is `docs/test-results/token-usage/bug21-first-field-review-20261024.json`.
|
||||
|
||||
Validation: 92 passed, 1 skipped across joint-v2, early correction and entity-resolution tests; one subsequently added frozen-feedback regression passed separately. The unchanged operator package also passes `correction.validate_review`, including replay of its rejected calls. An additional joint-planning pipeline test fails at `BLOCKED` instead of `OUTPUT_READY`; the same test fails on the pre-patch HEAD source extracted to a temporary directory. The other 26 tests in that correction/joint-planning run pass; one is skipped.
|
||||
|
||||
The case detail page now distinguishes failed analysis from successful handoff. Recovery of an already exhausted revision uses the existing case-return contract with `review_feedback`, not a fabricated failed patch and not an in-place alteration of rejected responses. This starts a new analysis revision with the original archives and full history retained. It does not grant extra attempts to the exhausted revision. This operator recovery has not yet been executed on the VPS, and a new revision may repeat planning work. There was no hypothesis investigation budget initialized in this field run.
|
||||
@@ -0,0 +1,215 @@
|
||||
{
|
||||
"case_id": "BUG-000021",
|
||||
"snapshot": "review-after-entity-origin-fix",
|
||||
"result": "FAILED_TO_ANALYZE",
|
||||
"reason": "MODEL_VALIDATION_EXHAUSTED",
|
||||
"recorded_at": "2026-10-24",
|
||||
"scope": "Six saved model calls; no new model calls executed.",
|
||||
"calls": [
|
||||
{
|
||||
"ref": "llm/operations/6c0a36f93bea41b87241a30769bd92bb6dc387869b46d3a013ec595cfc7e9548/round-0001.json",
|
||||
"status": "SUCCESS",
|
||||
"code": null,
|
||||
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
|
||||
"request_hash": "022e6abbf1925482838f81b0a3a8b1994afe54835adc0510707b4a3ea00a88be",
|
||||
"phase": "INTERPRETING_CASE",
|
||||
"usage_classification": "regular",
|
||||
"metadata": {
|
||||
"attempts": [],
|
||||
"cache_created_tokens": 0,
|
||||
"cache_status": "below_minimum",
|
||||
"cached_input_tokens": null,
|
||||
"cost_currency": "USD",
|
||||
"elapsed_seconds": 71.552436,
|
||||
"estimated_cache_storage_cost": 0.0,
|
||||
"estimated_cached_input_cost": null,
|
||||
"estimated_cost": null,
|
||||
"estimated_input_cost": null,
|
||||
"estimated_output_cost": 0.00036,
|
||||
"input_tokens": 15626,
|
||||
"model": "gemini-3.8-flash",
|
||||
"output_tokens": 96,
|
||||
"prompt_version": "entity_resolution_plan_v4",
|
||||
"provider": "gemini-native",
|
||||
"reasoning_tokens": null,
|
||||
"uncached_input_tokens": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"ref": "llm/operations/88adb8b462df2c473b421f617b086dd65351532f28e81a7a1052e1f24da87dea/round-0001.json",
|
||||
"status": "SUCCESS",
|
||||
"code": null,
|
||||
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
|
||||
"request_hash": "aae23ca176952a643fb9a5f5546e2f003eb0af9ce1fe1b3c6e3d4d4a852ad33f",
|
||||
"phase": "INTERPRETING_CASE",
|
||||
"usage_classification": "regular",
|
||||
"metadata": {
|
||||
"attempts": [],
|
||||
"cache_created_tokens": 0,
|
||||
"cache_status": "below_minimum",
|
||||
"cached_input_tokens": null,
|
||||
"cost_currency": "USD",
|
||||
"elapsed_seconds": 4.446479,
|
||||
"estimated_cache_storage_cost": 0.0,
|
||||
"estimated_cached_input_cost": null,
|
||||
"estimated_cost": null,
|
||||
"estimated_input_cost": null,
|
||||
"estimated_output_cost": 0.00103875,
|
||||
"input_tokens": 18384,
|
||||
"model": "gemini-3.8-flash",
|
||||
"output_tokens": 277,
|
||||
"prompt_version": "entity_resolution_assessment_v4",
|
||||
"provider": "gemini-native",
|
||||
"reasoning_tokens": null,
|
||||
"uncached_input_tokens": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"ref": "llm/operations/e6f77de4396a9e8dc19665d9f8d2544febad7983aa8797141760c691a4d2a805/round-0001.json",
|
||||
"status": "SUCCESS",
|
||||
"code": null,
|
||||
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
|
||||
"request_hash": "3715adca8b12d9e2b10dedc65c07ff801e659bda71db5042fc6e63b0e9420e8b",
|
||||
"phase": "INTERPRETING_CASE",
|
||||
"usage_classification": "correction",
|
||||
"metadata": {
|
||||
"attempts": [],
|
||||
"cache_created_tokens": 0,
|
||||
"cache_status": "below_minimum",
|
||||
"cached_input_tokens": 16341,
|
||||
"cost_currency": "USD",
|
||||
"elapsed_seconds": 4.580154,
|
||||
"estimated_cache_storage_cost": 0.0,
|
||||
"estimated_cached_input_cost": 0.001225575,
|
||||
"estimated_cost": 0.004089074999999999,
|
||||
"estimated_input_cost": 0.00160725,
|
||||
"estimated_output_cost": 0.00125625,
|
||||
"input_tokens": 18484,
|
||||
"model": "gemini-3.8-flash",
|
||||
"output_tokens": 335,
|
||||
"prompt_version": "entity_resolution_assessment_v4",
|
||||
"provider": "gemini-native",
|
||||
"reasoning_tokens": null,
|
||||
"uncached_input_tokens": 2143
|
||||
}
|
||||
},
|
||||
{
|
||||
"ref": "llm/operations/572afccbd4034d9c5485045cb4bb28b61fdd40e48dc8a3fab67cfc17e997cd65/round-0001.json",
|
||||
"status": "ERROR",
|
||||
"code": "LLM_RESPONSE",
|
||||
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
|
||||
"request_hash": "33b5c731797a37d26f4d7ac5f560573bbe576db6a51fe099f2952ecfa818c33f",
|
||||
"phase": "INTERPRETING_CASE",
|
||||
"usage_classification": "correction",
|
||||
"metadata": {
|
||||
"attempts": [],
|
||||
"cache_created_tokens": 0,
|
||||
"cache_status": "below_minimum",
|
||||
"cached_input_tokens": null,
|
||||
"cost_currency": "USD",
|
||||
"elapsed_seconds": 26.257507,
|
||||
"estimated_cache_storage_cost": 0.0,
|
||||
"estimated_cached_input_cost": null,
|
||||
"estimated_cost": null,
|
||||
"estimated_input_cost": null,
|
||||
"estimated_output_cost": 0.01366875,
|
||||
"input_tokens": 11100,
|
||||
"model": "gemini-3.8-flash",
|
||||
"output_tokens": 3645,
|
||||
"prompt_version": "case_plan_v2",
|
||||
"provider": "gemini-native",
|
||||
"reasoning_tokens": 783,
|
||||
"uncached_input_tokens": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"ref": "llm/operations/cdf9fddd5dccf7c6859f2f4c5aa65e46778d6d44e446cf579fa6b6f462b9b85c/round-0001.json",
|
||||
"status": "SUCCESS",
|
||||
"code": null,
|
||||
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
|
||||
"request_hash": "6038fe06c92ae2093575231052b86d9c9336db7c1be6db290d38788247acac54",
|
||||
"phase": "INTERPRETING_CASE",
|
||||
"usage_classification": "correction",
|
||||
"metadata": {
|
||||
"attempts": [],
|
||||
"cache_created_tokens": 0,
|
||||
"cache_status": "below_minimum",
|
||||
"cached_input_tokens": null,
|
||||
"cost_currency": "USD",
|
||||
"elapsed_seconds": 36.071492,
|
||||
"estimated_cache_storage_cost": 0.0,
|
||||
"estimated_cached_input_cost": null,
|
||||
"estimated_cost": null,
|
||||
"estimated_input_cost": null,
|
||||
"estimated_output_cost": 0.02161875,
|
||||
"input_tokens": 10867,
|
||||
"model": "gemini-3.8-flash",
|
||||
"output_tokens": 5765,
|
||||
"prompt_version": "case_plan_interpretation_repair_v1",
|
||||
"provider": "gemini-native",
|
||||
"reasoning_tokens": 4138,
|
||||
"uncached_input_tokens": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"ref": "llm/operations/2cd36795173fe6d547ff571814187ce1b12b3a7ec6accd4ebd98869d46bad248/round-0001.json",
|
||||
"status": "SUCCESS",
|
||||
"code": null,
|
||||
"config_hash": "692c8bac07efc915a44a89ac8aab1b4caa3e125d8619745f13c2ee570cb9e054",
|
||||
"request_hash": "6ca3f5d95072a753690196dd2bb30d8df60d75c6d3fc41c64f4e736dfb64ab18",
|
||||
"phase": "INTERPRETING_CASE",
|
||||
"usage_classification": "correction",
|
||||
"metadata": {
|
||||
"attempts": [],
|
||||
"cache_created_tokens": 0,
|
||||
"cache_status": "below_minimum",
|
||||
"cached_input_tokens": null,
|
||||
"cost_currency": "USD",
|
||||
"elapsed_seconds": 24.407819,
|
||||
"estimated_cache_storage_cost": 0.0,
|
||||
"estimated_cached_input_cost": null,
|
||||
"estimated_cost": null,
|
||||
"estimated_input_cost": null,
|
||||
"estimated_output_cost": 0.01227,
|
||||
"input_tokens": 4163,
|
||||
"model": "gemini-3.8-flash",
|
||||
"output_tokens": 3272,
|
||||
"prompt_version": "case_plan_statement_repair_v2",
|
||||
"provider": "gemini-native",
|
||||
"reasoning_tokens": 3064,
|
||||
"uncached_input_tokens": null
|
||||
}
|
||||
}
|
||||
],
|
||||
"pricing": {
|
||||
"currency": "USD",
|
||||
"source": "saved per-call metadata; local example rates match output 3.75/million, input .75/million, cache .075/million",
|
||||
"captured_at": "2026-10-24",
|
||||
"storage": "saved estimate 0; no additional estimate"
|
||||
},
|
||||
"totals": {
|
||||
"input_tokens": 78624,
|
||||
"output_tokens_including_reasoning": 13390,
|
||||
"reasoning_tokens": "unknown for entity resolution calls; included in output_tokens elsewhere"
|
||||
},
|
||||
"account_balance_eur": "unknown",
|
||||
"clean_accounting_note": "First case_plan_v2 call mislabeled correction; count as regular. Entity assessment second attempt and two interpretation repair calls are corrections.",
|
||||
"limitations": [
|
||||
"Cache token counts missing for five calls; exact total USD estimate unknown.",
|
||||
"Reasoning must not be added again to output_tokens."
|
||||
],
|
||||
"total_balance": {
|
||||
"input_tokens": 78624,
|
||||
"output_tokens_including_reasoning": 13390,
|
||||
"model_seconds": 167.315887,
|
||||
"estimated_usd": "unknown (missing cache accounting)",
|
||||
"per_call_output_cost_usd": 0.05021250000000001
|
||||
},
|
||||
"clean_balance": {
|
||||
"input_tokens": 45110,
|
||||
"output_tokens_including_reasoning": 4018,
|
||||
"model_seconds": 102.256422,
|
||||
"estimated_usd": "unknown (missing cache accounting)",
|
||||
"per_call_output_cost_usd": 0.015067500000000001
|
||||
}
|
||||
}
|
||||
@@ -271,7 +271,9 @@ def feedback(reader, phase, failure):
|
||||
instruction += " Return only hypotheses with interpretation_ids from the accepted interpretation_sources. The rejected joint transport used interpretation_paths; do not copy that field or regenerate interpretation."
|
||||
if phase=="interpretation" and context.get("joint_generation",{}).get("version")==2:
|
||||
from .joint_v2 import issues as statement_issues
|
||||
local=statement_issues(payload,context)
|
||||
# Frozen diagnostics preserve replay of requests produced before the
|
||||
# comprehensive collector was introduced. New errors store the full list.
|
||||
local=error.get('validation_issues',statement_issues(payload,context,comprehensive=False))
|
||||
return {"code":error["code"],"issues":local,"instruction":"Replace only the listed statements. Do not attribute inferred beliefs to the tester. Review every hypothesis for direct AND implicit dependency on changed statements; missing references do not prove independence."}
|
||||
return {"code":error["code"],"issues":issues[:32],"instruction":instruction}
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ class CaseInterpreter:
|
||||
|
||||
def _reject(self, reader, common, attempt_id, code):
|
||||
document = {**common, "format": "viano-case-interpretation-error", "code": code}
|
||||
if common['prompt_version'] in {'case_plan_v2','case_plan_statement_repair_v2'}:
|
||||
if common['prompt_version'] in {'case_plan_v2','case_plan_statement_repair_v2','case_plan_interpretation_repair_v1'}:
|
||||
from .joint_v2 import issues
|
||||
context=read_json(reader,common['context_ref'],'case-interpretation-context',self.limits.max_context_bytes)
|
||||
call=read_json(reader,common['llm_result_ref'],'llm-call',self.gateway.config.max_request_bytes+self.gateway.config.max_response_bytes+16384)
|
||||
|
||||
@@ -162,7 +162,7 @@ def validate_premises(raw, interpretation, context):
|
||||
except (KeyError,IndexError,ValueError,TypeError):raise HypothesisError("HYPOTHESIS_SOURCE_UNKNOWN") from None
|
||||
|
||||
|
||||
def issues(payload, context):
|
||||
def issues(payload, context, *, comprehensive=True):
|
||||
from .contracts import output_schema, entity_citation_issues
|
||||
result={}
|
||||
if not isinstance(payload,dict):return []
|
||||
@@ -208,6 +208,17 @@ def issues(payload, context):
|
||||
except (TypeError,KeyError,AttributeError):entity_issues=[]
|
||||
for issue in entity_issues:
|
||||
parts=issue["field"].split('/')[:2];add('/'+'/'.join(parts),issue["code"],constraint=issue.get("constraint"),allowed_source_ids=issue.get("allowed_source_ids",[]))
|
||||
if comprehensive:
|
||||
from .quality import quality_context, description_sources
|
||||
if quality_context(context):
|
||||
allowed=description_sources(context)
|
||||
for i,statement in enumerate(payload.get('described_behavior',[])):
|
||||
if isinstance(statement,dict) and isinstance(statement.get('source_ids'),list):
|
||||
bad=[sid for sid in statement['source_ids'] if sid not in allowed]
|
||||
if bad:
|
||||
add(f'/described_behavior/{i}', 'INTERPRETATION_DESCRIPTION_SOURCES',
|
||||
invalid_source_ids=bad, allowed_source_ids=sorted(allowed),
|
||||
constraint='cite_local_description')
|
||||
# Overlapping edits are replaced by the enclosing field; order cannot change their meaning.
|
||||
for path in list(result):
|
||||
if any(path.startswith(parent+'/') for parent in result if parent!=path):del result[path]
|
||||
@@ -220,7 +231,9 @@ def repair_request(request,reader,failure,feedback):
|
||||
source=failure[2];
|
||||
try:original=interpretation_payload(source,context,reader)
|
||||
except InterpretationError:return None
|
||||
problems=issues(original,context)
|
||||
problems=feedback.get('issues',issues(original,context))
|
||||
if problems not in (issues(original,context),issues(original,context,comprehensive=False)):
|
||||
raise InterpretationError('INTERPRETATION_PATCH_BINDING')
|
||||
if not problems:return None
|
||||
try:raw = candidate(reader,source,context,strict=False)
|
||||
except (HypothesisError,InterpretationError):raw=None
|
||||
@@ -311,8 +324,9 @@ def project(reader,call,context,depth=0):
|
||||
from .joint_planning import interpretation_payload
|
||||
previous,body=parent(reader,call,context,depth)
|
||||
original=interpretation_payload(previous,context,reader,depth+1)
|
||||
expected=issues(original,context)
|
||||
if expected!=body["issues"]:raise InterpretationError("INTERPRETATION_PATCH_BINDING")
|
||||
expected=body['issues']
|
||||
if expected not in (issues(original,context),issues(original,context,comprehensive=False)):
|
||||
raise InterpretationError("INTERPRETATION_PATCH_BINDING")
|
||||
document=call["outcome"].get("document",{})
|
||||
if not isinstance(document,dict) or set(document)-{'patches','reviews'}:
|
||||
raise InterpretationError('INTERPRETATION_PATCH_SCOPE')
|
||||
|
||||
@@ -108,6 +108,9 @@ def hypotheses_view(reader, docs):
|
||||
|
||||
|
||||
def next_actions(state, reason, worker):
|
||||
if state == 'FAILED_TO_ANALYZE':
|
||||
return [{'kind':'download','text':'Die Analyse wurde ohne erfolgreich validierten Abschluss beendet. Fallakte und Fehlerdiagnostik zur Prüfung herunterladen.'},
|
||||
{'kind':'return','text':'Nach Fehlerbehebung oder ergänzender Prüfung die unveränderte Akte mit einer Review-Rückmeldung zurückgeben. Ein gescheiterter Patch muss dafür nicht behauptet werden.'}]
|
||||
if state in FINISHED:
|
||||
return [{'kind':'download','text':'Die Analyse ist abgeschlossen. Aufträge und Fallakte an die nächste Instanz übergeben.'},
|
||||
{'kind':'return','text':'Nach gescheitertem Patch oder neuen Beobachtungen die unveränderte Akte mit Rückmeldung übergeben.'}]
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
# BUG-000021: independent citation errors
|
||||
|
||||
Source: first VPS field run, 2026-10-24. This curated fixture contains one rejected interpretation and its citation-validation context, not a complete run archive.
|
||||
|
||||
The Furien identity in /relevant_entities/1 omits its identity evidence (N0002 or F0020). Independently, /described_behavior/0 cites B0002, a report, although that field only permits local-description facts. The original collector reported only the entity problem. The model repaired that problem and then exhausted the correction allowance on the previously undisclosed description error.
|
||||
|
||||
Regression: report both paths together, leave the input unchanged, retain strict final validation, and replay legacy repair requests with their frozen narrower issue list. No hypothesis or causal conclusion is validated by this fixture.
|
||||
Vendored
+156
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"behavior_gap": null,
|
||||
"confirmed_technical_facts": [
|
||||
{
|
||||
"source_ids": [
|
||||
"F0001",
|
||||
"F0002",
|
||||
"F0003",
|
||||
"F0004",
|
||||
"F0005",
|
||||
"F0006",
|
||||
"F0007",
|
||||
"F0008",
|
||||
"F0009",
|
||||
"F0010",
|
||||
"F0011"
|
||||
],
|
||||
"text": "Reproduction reproduced the reported state at position (187.7, 1782.16, 89.9472) on map 1, zone 405, area 2404 with orientation 4.70689 with diagnostic focus quest ID 28548."
|
||||
},
|
||||
{
|
||||
"source_ids": [
|
||||
"F0014",
|
||||
"F0015",
|
||||
"F0016"
|
||||
],
|
||||
"text": "Quest ID 28548 has LogTitle 'Warchief's Command: Desolace!' in quest_template with LogDescription 'Report to Furien at Tethris Aran in Desolace.'"
|
||||
},
|
||||
{
|
||||
"source_ids": [
|
||||
"F0017",
|
||||
"F0018"
|
||||
],
|
||||
"text": "creature_queststarter query filtered for quest 28548 returned zero rows."
|
||||
},
|
||||
{
|
||||
"source_ids": [
|
||||
"F0020"
|
||||
],
|
||||
"text": "Lookup in creature_template for 'Furien' returned entry 35286 ('Furien') as well as related entries 35287, 35288, 35316, and 51554."
|
||||
}
|
||||
],
|
||||
"contradictions": [],
|
||||
"described_behavior": [
|
||||
{
|
||||
"basis": "local_description",
|
||||
"source_ids": [
|
||||
"B0002",
|
||||
"F0015"
|
||||
],
|
||||
"text": "Quest 28548 instructs players to report to Furien at Tethris Aran in Desolace to turn in the quest.",
|
||||
"verification": "not_independently_verified"
|
||||
}
|
||||
],
|
||||
"expected_behavior": [],
|
||||
"failure_stage": {
|
||||
"source_ids": [
|
||||
"F0001",
|
||||
"O0004"
|
||||
],
|
||||
"text": "Quest turn-in and NPC interaction stage at Tethris Aran in Desolace"
|
||||
},
|
||||
"first_known_divergence": null,
|
||||
"interpretation_summary": {
|
||||
"source_ids": [
|
||||
"B0002",
|
||||
"F0001",
|
||||
"F0015",
|
||||
"O0001"
|
||||
],
|
||||
"text": "Reproduction and reports indicate that NPC Furien is missing at Tethris Aran in Desolace, where quest 28548 ('Warchief's Command: Desolace!') directs the player to report."
|
||||
},
|
||||
"investigation_direction": [
|
||||
{
|
||||
"source_ids": [
|
||||
"F0012",
|
||||
"F0020"
|
||||
],
|
||||
"text": "Investigate creature spawn entries in the creature table for creature_template entry 35286 ('Furien') at Tethris Aran in Desolace."
|
||||
},
|
||||
{
|
||||
"source_ids": [
|
||||
"F0014",
|
||||
"F0017"
|
||||
],
|
||||
"text": "Examine quest ending and turn-in relations for quest 28548 to determine the configured quest ender creature."
|
||||
}
|
||||
],
|
||||
"observed_behavior": [
|
||||
{
|
||||
"source_ids": [
|
||||
"B0002",
|
||||
"O0001",
|
||||
"O0004"
|
||||
],
|
||||
"text": "NPC Furien is not present at Tethris Aran at the marked turn-in location for the quest."
|
||||
},
|
||||
{
|
||||
"source_ids": [
|
||||
"O0002"
|
||||
],
|
||||
"text": "The tester confirms during reproduction that the NPC is missing, noting a similar lack of spawn observed on an earlier Warchief's Command quest."
|
||||
},
|
||||
{
|
||||
"source_ids": [
|
||||
"O0003"
|
||||
],
|
||||
"text": "The player is located at the marked map coordinates, identified in-game as Tethris Aran."
|
||||
}
|
||||
],
|
||||
"provisional_behavior_gap": {
|
||||
"basis": "local_description",
|
||||
"source_ids": [
|
||||
"B0002",
|
||||
"F0015",
|
||||
"O0001"
|
||||
],
|
||||
"status": "provisional",
|
||||
"text": "Quest text specifies reporting to Furien at Tethris Aran, but Furien is missing at that location."
|
||||
},
|
||||
"relevant_entities": [
|
||||
{
|
||||
"entity_id": "N0001",
|
||||
"reason": "Diagnostic focus quest referenced in bug reports and reproduction records.",
|
||||
"source_ids": [
|
||||
"B0002",
|
||||
"F0011",
|
||||
"F0016"
|
||||
]
|
||||
},
|
||||
{
|
||||
"entity_id": "N0002",
|
||||
"reason": "Quest 28548 ('Warchief's Command: Desolace!') specifically instructs the player in LogDescription and QuestDescription (F0015) to report to 'Furien' at Tethris Aran in Desolace. Bug reports B0002 and observation O0001 report NPC Furien missing at that location. Candidate K0001 (entry 35286, 'Furien') exactly matches the NPC name and target role, unlike subordinate entities (K0002 Mount, K0003/K0004 Dragonhawk, K0005 Assistant).",
|
||||
"source_ids": [
|
||||
"B0002",
|
||||
"F0015",
|
||||
"O0001"
|
||||
]
|
||||
}
|
||||
],
|
||||
"tester_assumptions": [],
|
||||
"unknowns": [
|
||||
{
|
||||
"source_ids": [
|
||||
"Q0001"
|
||||
],
|
||||
"text": "Expected behavior specification is missing from archived case records."
|
||||
},
|
||||
{
|
||||
"source_ids": [
|
||||
"D0006",
|
||||
"F0021"
|
||||
],
|
||||
"text": "Exact German localization for Furien in creature_template_locale is unresolved due to truncated lookup results."
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+3282
File diff suppressed because it is too large.
Load diff
@@ -111,6 +111,54 @@ def test_rejected_corpus_produces_local_issues_without_modifying_original():
|
||||
assert data==before
|
||||
|
||||
|
||||
def test_bug21_reports_independent_description_and_identity_errors_together():
|
||||
from pathlib import Path
|
||||
from viano_bug_analysis.analysis.joint_v2 import issues
|
||||
from viano_bug_analysis.analysis.contracts import validate_interpretation
|
||||
from viano_bug_analysis.analysis.errors import InterpretationError
|
||||
root=Path('tests/fixtures/llm_rejections/20261024/bug21-independent-citation-errors')
|
||||
context=json.loads((root/'validation-context.json').read_text(encoding='utf-8'))
|
||||
original=json.loads((root/'parsed-answer.json').read_text(encoding='utf-8'))
|
||||
before=copy.deepcopy(original)
|
||||
found=issues(original,context)
|
||||
assert {'/relevant_entities/1','/described_behavior/0'} <= {i['path'] for i in found}
|
||||
assert '/described_behavior/0' not in {i['path'] for i in issues(original,context,comprehensive=False)}
|
||||
fixed=copy.deepcopy(original)
|
||||
fixed['relevant_entities'][1]['source_ids'].append('N0002')
|
||||
with pytest.raises(InterpretationError):validate_interpretation(fixed,context)
|
||||
fixed['described_behavior'][0]['source_ids'].remove('B0002')
|
||||
validate_interpretation(fixed,context)
|
||||
assert original==before
|
||||
|
||||
|
||||
def test_failed_analysis_does_not_claim_successful_handoff():
|
||||
from viano_bug_analysis.api.cases import next_actions
|
||||
failed=next_actions('FAILED_TO_ANALYZE','MODEL_VALIDATION_EXHAUSTED',{})
|
||||
assert 'ohne erfolgreich validierten Abschluss' in failed[0]['text']
|
||||
assert 'Review-Rückmeldung' in failed[1]['text']
|
||||
finished=next_actions('OUTPUT_READY',None,{})
|
||||
assert 'Aufträge und Fallakte' in finished[0]['text']
|
||||
|
||||
|
||||
def test_new_feedback_uses_frozen_comprehensive_diagnostics_and_legacy_replays(monkeypatch):
|
||||
from pathlib import Path
|
||||
from viano_bug_analysis.analysis import correction,joint_planning,joint_v2
|
||||
root=Path('tests/fixtures/llm_rejections/20261024/bug21-independent-citation-errors')
|
||||
context=json.loads((root/'validation-context.json').read_text(encoding='utf-8'))
|
||||
payload_=json.loads((root/'parsed-answer.json').read_text(encoding='utf-8'))
|
||||
monkeypatch.setattr(correction,'read_json',lambda *a,**kw:context)
|
||||
monkeypatch.setattr(joint_planning,'interpretation_payload',lambda *a,**kw:payload_)
|
||||
call={'outcome':{'document':payload_},'prompt_version':'case_plan_interpretation_repair_v1'}
|
||||
error={'context_ref':'context','code':'INTERPRETATION_ENTITY_PROVENANCE',
|
||||
'prompt_version':'case_plan_interpretation_repair_v1'}
|
||||
legacy=correction.feedback(None,'interpretation',('error',error,call))
|
||||
assert legacy['issues']==joint_v2.issues(payload_,context,comprehensive=False)
|
||||
frozen=joint_v2.issues(payload_,context)
|
||||
current=correction.feedback(None,'interpretation',('error',{**error,'validation_issues':frozen},call))
|
||||
assert current['issues']==frozen
|
||||
assert {'/relevant_entities/1','/described_behavior/0'} <= {i['path'] for i in current['issues']}
|
||||
|
||||
|
||||
def test_direct_dependency_can_be_explicitly_replaced(built_case):
|
||||
def bad(d):
|
||||
d['interpretation']['observed_behavior'][0]['source_ids']=['F0001']
|
||||
|
||||
Reference in new issue
Block a user