Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/traceos-itself/observations/2026-09.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -323,3 +323,5 @@
{"assertion": "assert.reconcile.unverifiable-is-not-verified", "reference": "traceos/engine.py#Git", "observed_at": "2026-09-11T18:26:51.128266Z", "observed_ref": "03c9e6937f7b43525007da01fe2bb234d8c41712", "observed_blob": "a870a87f68df6f8f3608f43fe3e353e63c56e170", "observed_norm": "8d3e91f52e26d5b2f015b02c910bef33b0ea54e0", "supports": "supports", "observer": "agent", "kind": "implementation", "observed_symbol": "ab57e29fc8ce1e431dc098f762decf18e309ef3e"}
{"assertion": "assert.understand.observes-before-asserting", "reference": "skills/understanding-system/SKILL.md#Record Evidence references, then observe", "observed_at": "2026-09-11T18:26:51.264951Z", "observed_ref": "03c9e6937f7b43525007da01fe2bb234d8c41712", "observed_blob": "7d4ed02c376c5ef0facae5ec50e75069e92355a2", "observed_norm": "cae3a5732f59f4ca4c57d9c39a483e748566b39d", "supports": "supports", "observer": "agent", "kind": "documentation", "observed_symbol": "9062a1bf06b12d7e23b7cdd9b7774c4de38d04a0"}
{"assertion": "assert.understand.observes-before-asserting", "reference": "traceos/engine.py#observe", "observed_at": "2026-09-11T18:26:51.398497Z", "observed_ref": "03c9e6937f7b43525007da01fe2bb234d8c41712", "observed_blob": "a870a87f68df6f8f3608f43fe3e353e63c56e170", "observed_norm": "8d3e91f52e26d5b2f015b02c910bef33b0ea54e0", "supports": "supports", "observer": "agent", "kind": "implementation", "observed_symbol": "d4a3dae251d0a995e6decdb6ce84fd030ec7f3cd"}
{"assertion": "assert.render.no-second-implementation", "reference": "traceos/explore.py#build", "observed_at": "2026-09-11T18:32:03.938884Z", "observed_ref": "4c34ce50d7b9682d0a9f9f669bae32da51c7925c", "observed_blob": "1574df8387a10f539acf564db1d2bba1815e0fd1", "observed_norm": "268333d35517dc625b97afe48071c6c420e6c7cf", "supports": "supports", "observer": "agent", "kind": "implementation", "observed_symbol": "6efad87df1b56fd5471729be3f974b6e22e5d7d8"}
{"assertion": "assert.render.no-second-implementation", "reference": "tests/run_tests.py#tool_explore", "observed_at": "2026-09-11T18:32:04.072064Z", "observed_ref": "4c34ce50d7b9682d0a9f9f669bae32da51c7925c", "observed_blob": "a606ebde9c7623449f35cf98c6cfce3aa0252d17", "observed_norm": "dfce6a969090055d37d4a2d9ff0e571705741370", "supports": "supports", "observer": "agent", "kind": "test", "observed_symbol": "f058ed9593e81cf743f1153c09d6b227eca935e3"}
28 changes: 28 additions & 0 deletions tests/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,34 @@ def tool_explore():
page = E.build(EXAMPLE, None, repo_files, contexts)
model = T.Model(EXAMPLE)

# INV-027 / INV-028 in the one artifact a reader looks at first. Three outcome
# states must be distinguishable, not two: a checked outcome, a check nobody has
# run, and no check at all.
itself = E.build(ROOT / "examples" / "traceos-itself", ROOT, None, [{}])
check(
"TOOL explore",
"a Flow's Intents are rendered, labelled as provenance not truth",
"provenance, never truth" in itself and "intent.a-view-is-not-a-source" in itself,
)
check(
"TOOL explore",
"an outcome shows the check that verifies it",
'class="conf confirmed">' in itself or "checked</span>" in itself,
)
check(
"TOOL explore",
"a Flow with no Intent says so rather than rendering an empty list",
"no Intent declares why this Flow exists" in itself,
)
# The third state, which traceos-itself no longer has: an outcome nobody checks.
# Asserting only against a model where every outcome is checked is a test that
# cannot fail for the case it is named after.
check(
"TOOL explore",
"an outcome with no declared check is drawn differently, not omitted",
"no check declared" in page,
)

embedded = json.loads(re.search(r"const IMPACT = (\{.*?\});\n", page, re.S).group(1))
drifted = [
loc for loc, result in embedded.items() if T.impact(model, [loc]) != result
Expand Down
48 changes: 47 additions & 1 deletion traceos/explore.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,15 +236,56 @@ def conf_of(aid: str) -> str:
for fid, flow in ordered:
trig = flow.get("trigger", {})
trig_text = trig.get("ref") or trig.get("semantic") or trig.get("actor") or ""

def outcome_check(outcome: dict) -> str:
"""INV-027 rendered as three states, never two.

A declared check, a declared check nobody has run, and no check at all are
different situations, and an explorer that drew them the same way would be
the silent boundary INV-025 forbids - in the one place a reader looks first.
"""
verified_by = outcome.get("verified_by")
if not verified_by:
return '<span class="pill nocheck">no check declared</span>'
conf = conf_of(verified_by) if verified_by in model.assertions else None
if conf is None:
return (
f'<span class="pill refuted">check missing: {e(verified_by)}</span>'
)
latest = T.latest_observation(model, verified_by)
if latest is None:
return (
f'<span class="pill nocheck">never checked</span> '
f'<span class="mono dim">{e(verified_by)}</span>'
)
if latest.get("supports") == "refutes":
return (
f'<span class="pill refuted">REFUTED</span> '
f'<span class="mono dim">{e(verified_by)}</span>'
)
return (
f'<span class="conf {conf}">{CONF_GLYPH[conf]} checked</span> '
f'<span class="mono dim">{e(verified_by)}</span>'
)

outcomes = "".join(
f'<li><span class="mono">{e(o["id"])}</span> → '
+ ", ".join(
f"<code>{e(s['subject'])}={e(str(s['value']))}</code>"
for s in o.get("states") or []
)
+ f"<br>{outcome_check(o)}"
+ "</li>"
for o in flow.get("outcomes") or []
)

intents = "".join(
f'<li><span class="mono dim">{e(iid)}</span><br>'
f"{e((model.intents.get(iid) or {}).get('statement', '(not declared)'))}"
f'<br><span class="pill rec">{e(((model.intents.get(iid) or {}).get("record") or {}).get("locator", "no record"))}</span>'
"</li>"
for iid in flow.get("realizes") or []
)
assertions = "".join(
f'<li><span class="conf {conf_of(a["id"])}">'
f"{CONF_GLYPH[conf_of(a['id'])]} {conf_of(a['id'])}</span> "
Expand All @@ -270,7 +311,9 @@ def conf_of(aid: str) -> str:
</header>
<div class="graph">{flow_svg(model, fid)}</div>
<div class="cols">
<div><h4>Outcomes <span class="dim">declared, bound to states</span></h4>
<div><h4>Why <span class="dim">provenance, never truth (INV-028)</span></h4>
<ul>{intents or '<li class="dim">no Intent declares why this Flow exists</li>'}</ul></div>
<div><h4>Outcomes <span class="dim">and what checks them (INV-027)</span></h4>
<ul>{outcomes or '<li class="dim">none declared</li>'}</ul></div>
<div><h4>Assertions</h4><ul>{assertions or '<li class="dim">none</li>'}</ul></div>
</div>
Expand Down Expand Up @@ -454,6 +497,9 @@ def conf_of(aid: str) -> str:
border:1px solid var(--line); color:var(--muted); white-space:nowrap }}
.pill.current, .pill.ok, .pill.confirmed {{ color:var(--ok); border-color:var(--ok) }}
.pill.likely, .pill.warn, .pill.cov {{ color:var(--warn); border-color:var(--warn) }}
.pill.refuted {{ color:var(--err); border-color:var(--err); font-weight:600 }}
.pill.nocheck {{ color:var(--muted); border-style:dashed }}
.pill.rec {{ color:var(--muted); font-size:10px }}
.pill.uncertain, .pill.bad, .pill.error, .pill.err {{ color:var(--err);
border-color:var(--err) }}
.graph {{ overflow-x:auto; padding:6px 0 10px; border-bottom:1px solid var(--line);
Expand Down