mirror of
https://github.com/razzant/ouroboros.git
synced 2026-10-03 04:07:04 +00:00
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>
99 lines
3.9 KiB
Python
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
|