ouroboros/tests/test_polyglot_inventory.py
Ouroboros fa424eb46f release: Ouroboros v6.33.0 — Capability-Evidence context modes, multi-project + LLM-first named projects, WS11 UI/UX
Context window is no longer a static per-model table: every window claim is sourced,
route-fingerprinted Capability Evidence (provider /models metadata, local n_ctx, or an
owner acknowledgement) with a status (confirmed/asserted/unprobeable/failed), persisted
atomically. Max context mode is fail-closed — it requires >=1M confirmed/asserted evidence
for the active route. Changing the model while Max is on stays friction-free: the change
succeeds and context auto-downgrades to Low with a plain notice when the new route can't be
confirmed >=1M, but a genuine no-connection during the probe is an error (the model is not
saved), and a transient provider outage never erases a prior confirmed record.

Multi-project: the agent can now CREATE a NAMED project from chat in one LLM-first call
(promote_chat_to_task project_name/title; non-ASCII names get a deterministic hash id while
the display name is preserved). A main-chat task converts to a project in one click,
auto-named from its title/objective (no prompt, no extra LLM call); project-chat follow-up
tasks bind to their project so the main chat shows no stray "turn into project" button and
instead a calm pointer that opens the project panel; a converted card becomes a calm indigo
project identity (no red "error" look); per-project unread dots sort active projects to the
top (server-stored last-viewed); the project status/sleep-wake lifecycle was removed.

UI: oval (pill) composer with centered controls; per-thread chat scroll restored on tab/
panel switch instead of jumping to the top.

Also: real deadline_at finalization + advisory pacing, polyglot tree-sitter code intelligence
for non-Python symbols (query_code op=digest; Python stays on stdlib ast), reflection
faculty-atrophy doctrine, BIBLE P1 (Capability Evidence) + P8 (faculty atrophy) clauses, and
assorted WS9 tool fixes.

New surface: POST /api/owner/capability-ack, ouroboros/capability_evidence.py,
data/state/capability_evidence.json.

Reviewed by triad (gpt-5.5/gemini-3.5-flash/opus-4.8) + scope (gpt-5.5) + claudexor (gpt-5.5)
+ an independent adversarial multi-agent audit, against the original plans and the owner's raw
message transcript; all confirmed defects fixed, remaining findings evidence-rejected or tracked.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 09:21:57 +03:00

99 lines
3.9 KiB
Python

"""Polyglot structural extraction (v6.33.0 WS3).
One generic tree-sitter path covers every language without a bespoke extractor
(Go/Rust/Java/Ruby/C/...). Python stays on the canonical stdlib ast. When
tree-sitter is unavailable the file is marked structural_unavailable VISIBLY,
never silently regex-guessed.
"""
from __future__ import annotations
import pathlib
import ouroboros.code_intelligence as ci
from ouroboros.code_intelligence import _file_fact
def _fact(tmp_path: pathlib.Path, name: str, body: str):
p = tmp_path / name
p.write_text(body, encoding="utf-8")
return _file_fact(tmp_path, p)
def test_go_symbols_and_calls(tmp_path):
ff = _fact(tmp_path, "srv.go",
"package main\nfunc Add(a int) int { return helper(a) }\n"
"type Server struct{}\nfunc (s *Server) Start() { Add(1) }\n")
assert ff.language == "go"
kinds = {(s.kind, s.name) for s in ff.symbols}
assert ("function", "Add") in kinds
assert ("type", "Server") in kinds
assert ("method", "Start") in kinds
assert "helper" in {c.name for c in ff.call_sites}
assert ff.disposition == "indexed"
def test_rust_symbols(tmp_path):
ff = _fact(tmp_path, "lib.rs",
"fn main() {}\nstruct P { x: i32 }\nimpl P { fn new() -> Self { todo!() } }\ntrait T { fn go(&self); }\n")
kinds = {(s.kind, s.name) for s in ff.symbols}
assert ("function", "main") in kinds
assert ("struct", "P") in kinds
assert ("trait", "T") in kinds
def test_java_symbols(tmp_path):
ff = _fact(tmp_path, "App.java", "class Foo {\n int bar() { return baz(); }\n}\ninterface Baz { void go(); }\n")
kinds = {(s.kind, s.name) for s in ff.symbols}
assert ("class", "Foo") in kinds
assert ("method", "bar") in kinds
assert ("interface", "Baz") in kinds
def test_javascript_uses_treesitter_and_keeps_imports(tmp_path):
ff = _fact(tmp_path, "app.js",
"import {x} from './m';\nfunction hello(){ return world(); }\nclass Widget {}\n")
kinds = {(s.kind, s.name) for s in ff.symbols}
assert ("function", "hello") in kinds
assert ("class", "Widget") in kinds
assert "world" in {c.name for c in ff.call_sites}
assert "./m" in ff.imports # extract_js_imports still feeds JS imports
def test_python_stays_on_ast(tmp_path):
ff = _fact(tmp_path, "m.py", "async def go():\n pass\nCONST = 1\n")
by_name = {s.name: s.kind for s in ff.symbols}
# async_function kind is an ast-only distinction tree-sitter would not produce.
assert by_name.get("go") == "async_function"
assert by_name.get("CONST") == "constant"
def test_visible_fallback_when_treesitter_unavailable(tmp_path, monkeypatch):
monkeypatch.setattr(ci, "_ts_parser", lambda grammar: None)
ff = _fact(tmp_path, "srv.go", "package main\nfunc Add() {}\n")
assert ff.disposition == "structural_unavailable:go"
assert ff.symbols == [] # NOT a silent regex guess
def test_non_code_file_indexed_not_unavailable(tmp_path):
ff = _fact(tmp_path, "notes.md", "# title\n")
assert ff.disposition == "indexed"
def test_member_call_extracts_callee_not_receiver(tmp_path):
"""Regression (adversarial r1): a member/method call must record the FINAL
identifier (the callee), not the receiver/namespace — obj.doThing() -> doThing,
fmt.Sprintf() -> Sprintf — matching the Python ast path and the former JS regex."""
go = _fact(tmp_path, "m.go",
"package main\nimport \"fmt\"\nfunc F() { fmt.Sprintf(\"x\") }\n")
go_calls = {c.name for c in go.call_sites}
assert "Sprintf" in go_calls, go_calls
assert "fmt" not in go_calls, go_calls
js = _fact(tmp_path, "m.js",
"function f(obj){ obj.doThing(); console.log('x'); }\n")
js_calls = {c.name for c in js.call_sites}
assert "doThing" in js_calls, js_calls
assert "log" in js_calls, js_calls
assert "console" not in js_calls and "obj" not in js_calls, js_calls