Oracle Waves 2+3: capability catch-up + UI v3 bundle (v2.48.0-v2.49.0)#29
Merged
Conversation
…ot session cookie POST /api/apikey/generate|rotate|clear, /api/chat, /api/suggestions/approve and /api/config were reachable by any local process; rotate returned the fresh Discovery token, defeating the Bearer gates on /api/config and /api/discovery/*. New oracle/services/local_session.py issues a per-boot HttpOnly SameSite=Strict cookie on GET / to loopback clients only; a default-deny _local_write_guard requires session cookie OR Bearer on every mutating /api/* call outside /api/discovery/*. Session also un-breaks the dashboard Settings save (the UI never sent a Bearer token) and lets the dashboard reveal the Discovery key. Discovery stays Bearer-only.
discover() re-ran the hub fetch + per-project facts enrichment on every tool call (validate_project_path) and multiple times per graph request. Now cached for scanner_ttl_seconds (default 20s) under a lock; cache hits return deep copies (api_projects mutates the dicts), empty discoveries are never cached, and the dashboard Scan action forces a refresh.
…m-on-build Deletes the hand-rolled 3-slot LRU (the shared cache's own docstring names it as the predecessor it was lifted from). C3Bridge now holds a PRIVATE ProjectRuntimeCache (size 8, C3_RUNTIME_CACHE_SIZE-tunable) so cross-project search over >3 projects stops thrashing, while keeping its atexit shutdown semantics. New on_build hook on ProjectRuntimeCache (default None, existing callers untouched) fires once per newly built runtime; the Oracle uses it to warm embedding_index + vector_store in a daemon thread, mirroring the MCP server's lifespan warm, so the first c3_search stops paying chromadb init on the request thread. Read-only enforcement and validate_project_path are unchanged.
…llback
Chat previously described tools in the system prompt and regex-parsed
<tool_call> text blocks, patched with retry/trust heuristics. Now:
- OllamaBridge: show()/supports_tools() capability probe (cached; None =
unknown), set_tools_support() negative-cache poke, stream_chat(tools=)
yielding structured ("tool_call", {name, arguments}) events.
- ChatEngine: native tools array built from TOOL_SPECS (single source of
truth; api_max_tier caps external callers only); one shared _drain_stream
generator replaces three copies of the chunk-unpacking loop (main loop,
visible-retry, delegate sub-agent). Three-way mode: tools-capable models
run native (no stripper, no trust-answer heuristic, role:tool feeding,
no finalize nudge); incapable models keep the legacy text protocol
verbatim; unknown-capability models attempt native and demote mid-turn
on HTTP 400, negative-caching only when the server names tools as the
problem. Sub-agents pick their protocol from their own model.
- SSE event vocabulary, payload shapes, and persisted round_messages roles
unchanged — oracle.html needs no changes; history reloads re-inject
<tool_result> user messages in both modes.
- Hygiene: is_available() no longer reports a 5xx-failing server as up;
LLM disk cache gains TTL (llm_cache_ttl_sec, default 86400) and a
512-entry bound evicting oldest by mtime.
First-ever ChatEngine test coverage (18 tests) + bridge tests (14).
…/chat tools Deny-by-default allowlists: c3_project permits list/info/subprojects/search/ read/compress/status/memory/impact/edits/validate — register/unregister, sub_* mutations, edit/shell, and 'scan' (reveals unregistered .c3 projects, outside the discovered-project trust boundary) are excluded. The wrapper signature has no allow_write and no write-op params; the registry drops undeclared keys, so write verbs cannot reach handle_project from any transport. Every resolution passes resolve_project THEN validate_project_path (the resolver accepts any on-disk .c3 folder; Oracle re-checks membership). c3_artifacts blocks scan (mutates the manifest despite the handler's READ_ACTIONS listing) and restore; list/history/show/diff/status proxy through the validated runtime cache. MCP + OpenAPI pick both up from TOOL_SPECS automatically. Tests pin the allowlist enums, the allow_write drop, and _BLOCKED_MEMORY_ACTIONS == cli.tools.project._MEMORY_WRITE.
…y, scoped cross tools The Oracle treated every project as flat, ignoring the v2.44 parent/child model. Now: ProjectScanner carries registry parent_path (previously dropped) and _enrich adds is_subproject / parent_path (child-config back-link as fallback; broken links degrade to top-level) / subproject_rel_paths / count — /api/projects and the list_projects chat tool surface hierarchy for free. FederatedGraph gains a serve-time parent_child overlay applied on BOTH fresh builds and cache hits (hierarchy lives in .c3/config.json, which the facts-mtime cache key never sees; the overlay is never baked into the cache file, and no fact-level edges are added — they would pollute similarity clustering). c3_search_cross / c3_edits_cross gain an optional scope param: '' = all, 'top' = top-level only, or a project name/path = that project plus its direct sub-projects (resolved + validated).
ActivityReporter was fully built but only reachable on demand. The review loop now emits a cross-project digest when due: config-gated (digest_enabled default FALSE — current behavior preserved; digest_interval_seconds daily; digest_narrate opt-in since narration costs a cloud LLM call), config read live each cycle so toggling needs no restart, last_digest_at pre-stamped in review_state.json so an overlapping run_now can't double-digest, digests persisted to ~/.c3/oracle/activity_digests/<date>.json + latest.json with retention pruning (digest_retention_days), optional one-line JSONL notify sink (digest_notify_file), and the whole path try/except-wrapped so a digest failure never kills the review cycle. New GET /api/activity/digest/latest; Activity tab shows a last-scheduled-digest banner; Settings gains the toggle and interval (round-trips through the existing /api/config).
…ni/claude/auto) Oracle agents ran only on Ollama while core C3's delegate layer already had hardened Codex/Gemini/Claude CLI backends. Agents now carry a per-agent backend (default 'ollama' = unchanged nested tool loop); CLI backends route through cli.tools.delegate.handle_delegate against _OracleDelegateRuntime — a read-only shim of the target project's runtime that forces codex/gemini memory bridges OFF (they write facts into the target), notifications None (no NotificationStore writes), and codex_default_sandbox='read-only', while passing everything else through. CLI backends need a concrete project (subprocess cwd + the TARGET's own delegate config; Oracle never force-enables a backend): explicit project_path arg → conversation's focused project (via thread-local conv state) → instructive error; never silently picked. delegate_task spec/defs gain optional project_path; agent modal gains a backend select; delegate progress notes stream to the UI through the existing agent event sink.
…v2.49.0) (#28) * feat(oracle): UI v3 — split the 4,181-line oracle.html monolith into a concat bundle oracle.html was the pre-refactor hub.html pattern: one file, ~780 lines of CSS + ~400 lines of markup + a 2,967-line inline script. Following the hub v2 concat architecture: new oracle_ui.html shell (CSS + markup + __C3_ORACLE_SCRIPTS__ token) + 18 oracle/ui/ modules split at section banners (core, busy, theme_tabs, crossgraph, header, projects, insights, activity, suggestions, settings, agents, chat/{markdown,conversations, stream_renderer,toolbar,input,send}, app.js LAST — the init IIFE). _ORACLE_JS_FILES + _build_oracle_html() concatenate server-side with per-file markers; / serves the cached bundle, /legacy serves the frozen monolith for one release (both issue the dashboard session cookie). Extraction is VERBATIM: a splitter script cut exact line ranges with a tiling assertion (no gaps/overlaps), and a multiset diff proved the bundle differs from the original script by only the intentional ORACLE_BUILD_TIME bump. Whole-bundle esbuild parse clean. Deliberate deviation from the Wave-3 plan: no React/babel runtime — the logic is 100%% vanilla imperative and the transferable hub pattern is the file structure + build pipeline, not the framework; wrapping unowned vanilla code in React would add a CDN/transpile failure surface for zero owned UI. Also: pyproject package-data globs for oracle/ui + oracle/ui/chat (the '*' top-level-only gotcha), and a new 'c3 oracle serve|start' subcommand (lazy import, mirrors cmd_hub) so the server no longer requires the python entry point. New tests/test_oracle_ui_bundle.py; wheel inspection confirms all 18 modules + shell + legacy ship. * docs(oracle): oracle-guide caught up a full product generation; CHANGELOG v2.49.0 The guide documented the original memory/insight Oracle but none of what it became: architecture.md gains Chat subsystem (tool loop, native-vs-text protocol, full SSE event vocabulary), C3Bridge, Federated graph, and Security model sections, all 17 services listed, stale line counts fixed, Web UI section rewritten for the 8-tab concat bundle. api-reference.md adds the /api/apikey, /api/chat, /api/graph/federated, /api/insights/cross and /api/activity/digest/latest families plus the v2.47.0 write-gate auth note and fixed /api/health payload. configuration.md now covers all 30 DEFAULTS keys incl. the agents roster shape with the backend field. README leads with c3 oracle serve. discovery-api.md lists c3_project/c3_artifacts, the scope param, and delegate_task's project_path. changelog.md gains v1.3.0 (C3 v2.47.0-v2.48.0), v1.4.0 (C3 v2.49.0), and an honest 'previously undocumented' block for the v2.32-v2.38 era features. AGENTS.md tree updated; root CHANGELOG gains the v2.49.0 Wave 3 entry.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Completes the stacked chain: #26 (Wave 1) squash-merged to main, but #27/#28 merged into their stacked bases (oracle-wave-1 / oracle-wave-2) and never cascaded. This branch tip contains Waves 2+3 exactly as reviewed in #27 and #28 (wave-1 content is identical to what #26 already landed).
See #27 and #28 for the full summaries: c3_project/c3_artifacts read-tier tools, sub-project awareness, scheduled digest, multi-backend agents, UI v3 concat bundle + /legacy, c3 oracle serve, oracle-guide refresh. Full suite at branch tip: 1015 passed / 1 skipped.