2dfa96939e
The first environment shipped through .claude/workflows/new-environment.js: specification, three adversarial reviews (all 'fixable', none fatal), the Python environment, the TypeScript port, captured rollouts, and the demo page. Eleven agents, no errors. The proof that the platform scales is one line long. Alert Triage has a completely different shape from Word Five — JSON actions, priced lookups, an analyst screen instead of a grid — and the only change under src/components/demo/ is a comment edit, because the isolation lint refused the word "wordle" there. Zero shell code changed. 415 contract checks now pass against two demos, up from 206 against one. The environment is honest by construction. Every alert is synthetic, generated from the seed, and the banner saying so sits inside the board surface. Two of the eleven scenario templates are hidden-suspicious: generated by the same code as their benign twin with the signal overlaid only in lookup data, so the free screen is identically distributed and a screen-only policy STRUCTURALLY cannot tell them apart. The probe ladder measures it: `fast` catches 0.0 of hidden seeds. That is the counterweight made real rather than asserted. Twelve policies, thirteen ladder assertions, a genuine three-way trade: fast 0.846 wins hours (0.85), misses every hidden case targeted 0.894 wins the shipped total thorough 0.820 wins evidence (1.00), spends 2.9 hours None dominates. 92 Python tests, 35 TypeScript tests, 65 fixtures replaying at delta 0, and conformance gated on world + scorer + protocol so the browser shows the same alert for ?seed= that Python generated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019mt6sHQHEnEYrJZvoMCJSB
49 lines
1.7 KiB
Python
49 lines
1.7 KiB
Python
"""The pinned parse rules — the ones two runtimes disagree on."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from alert_triage.protocol import extract_candidate, parse_reply
|
|
|
|
FENCE = "```"
|
|
|
|
|
|
def test_fence_wins_over_an_earlier_bare_brace() -> None:
|
|
text = 'first {not it} then ' + FENCE + 'json\n{"action":"lookup","what":"documents"}\n' + FENCE
|
|
assert extract_candidate(text) == '{"action":"lookup","what":"documents"}\n'
|
|
obj, reason = parse_reply(text)
|
|
assert obj == {"action": "lookup", "what": "documents"} and reason is None
|
|
|
|
|
|
def test_first_balanced_span_is_string_aware() -> None:
|
|
text = 'ok {"note":"a } inside \\" quotes","action":"close"} trailing {"x":1}'
|
|
obj, _ = parse_reply(text)
|
|
assert obj == {"note": 'a } inside " quotes', "action": "close"}
|
|
|
|
|
|
def test_invalid_first_span_is_rejected_without_further_scanning() -> None:
|
|
obj, reason = parse_reply('{"a":1,} {"action":"lookup","what":"documents"}')
|
|
assert obj is None and reason
|
|
|
|
|
|
def test_non_object_json_is_rejected() -> None:
|
|
assert parse_reply("[1,2]")[0] is None
|
|
assert parse_reply(FENCE + "json\n[{\"action\":\"lookup\"}]\n" + FENCE)[0] is None
|
|
assert parse_reply("42")[0] is None
|
|
|
|
|
|
def test_nan_and_infinity_are_rejected_like_json_parse_does() -> None:
|
|
assert parse_reply('{"x":NaN}')[0] is None
|
|
assert parse_reply('{"x":Infinity}')[0] is None
|
|
|
|
|
|
def test_unbalanced_or_absent_braces() -> None:
|
|
assert parse_reply('{"action":"lookup"')[0] is None
|
|
assert parse_reply("no braces at all")[0] is None
|
|
assert parse_reply("")[0] is None
|
|
assert parse_reply(None)[0] is None
|
|
|
|
|
|
def test_nested_object_is_the_outer_one() -> None:
|
|
obj, _ = parse_reply('{"outer":{"action":"lookup"}}')
|
|
assert obj == {"outer": {"action": "lookup"}}
|