Skip to content

feat: P0 live window — hot intents, honest index status, aicx continuity - #46

Open
div0-space wants to merge 8 commits into
mainfrom
feat/live-window-hot-path
Open

feat: P0 live window — hot intents, honest index status, aicx continuity#46
div0-space wants to merge 8 commits into
mainfrom
feat/live-window-hot-path

Conversation

@div0-space

Copy link
Copy Markdown
Contributor

Co to jest

P0 z operatorskiego specu "Live window": intents/search w oknie ≤48h nie mogą zależeć od wczorajszego indeksu. Pusty wynik przy stale index to bug, nie „brak intencji".

Cuty w tym PR

Cut 1 — live window w intents (P0.1–2)

  • catalog::live_delta(home, user_home, cutoff): sesje na dysku, których cenzus (sessions.jsonl) jeszcze nie zna, + najświeższy live mtime. Cache 30 s (5 lane'ów packa i MCP współdzielą jeden skan).
  • collect_intent_files: w trybie live stęchła data z rebuildu nie wycina wiersza, którego żywy mtime jest w oknie (decyduje jeden stat); sesje unadmitted parsowane ad-hoc tym samym readerem katalogowym.
  • ClaimHonesty::live_open() (open_session/live_unverified): rekordy live renderują się w osobnej sekcji ## Live Session Intent (unverified, open) — nigdy nie mieszają się z closed timeline.
  • CLI: --live / --no-live (okna ≤48h skanują automatycznie); nagłówek raportu:
    live_sessions: 12
    index_lag_hours: 37.5
    mode: hybrid_live
    
  • JSON/MCP: completeness.live_sessions + warning.

Cut 2 — uczciwość statusu + fail-closed (P0.4-status, P2.8)

  • index status liczy newest_session_updated_at / sessions_newer_than_chunks / chunking_lag_secs z fingerprintów cenzusu (zero-walk). <none>/0 przy widocznej aktywności agentów — koniec z tym kłamstwem.
  • Sesje nowsze niż build CURRENT → readiness StaleChunks.
  • Pusty intents przy cenzusie starszym niż window/2 i zerze sesji live → stale_context_engine error z hintem, nie cisza.

Cut 3 — continuity pack (P1.5–7)

  • aicx continuity show|write: deterministyczny pack NOW / PEERS / DECISIONS (closed) / TASKS / SOURCES / INDEX HEALTH per projekt+okno; --for-inject tnie do budżetu ~6k tokenów; embedder nigdy nie jest na tej ścieżce.
  • SessionCatalog::scan_hot_window(cutoff): walk+stat wszystkich kandydatów, bounded-header probe tylko dla plików w oknie. Pełny probe na realnych rootach = 5 min 14 s; hot scan = ~8 s cold, powtórki z cache.
  • Enrichment (czytanie treści wszystkich sesji dla cwd/title) poza gorącą ścieżką — atrybucja projektu ze ścieżki, wzbogacona prawda zostaje w cenzusie.

Akceptacja (na żywym domu)

Test Wynik
aicx intents -p Loctree/aicx -H 12 przy cenzusie 37,5 h starym niepusty, live_sessions: 12, mode: hybrid_live
aicx continuity show -p Loctree/aicx -H 12 widzi sesje 2 agentów (claude + grok) na żywo, 8,5 s
index status realny newest_session_updated, pending: 546, staleindex
-p vibecrafted (bare) error + kandydaci (fail-closed, istniało)
kill embedder cała ścieżka live/continuity lexical-only, embedder nieużywany

Świadomie poza tym PR (backlog)

  • P0.4 watch/daemon (aicx index watch, SLA lexical ≤60 s) + P3 vibecrafted wrapper.
  • P0.1-search: live merge w aicx search (intents ma live window; search dalej index-only).
  • P2.9: canonical store C6.
  • Alias map cwd git remote → bucket.
  • Jakość claimów (linie diffów jako „decisions") — osobna oś: ekstraktor, nie mechanika live-window.

🤖 Generated with Claude Code

…sessions newer than the census

- catalog::live_delta(): unadmitted sessions + newest live mtime, one
  source-root walk per 30s (TTL cache shared by pack lanes and MCP)
- collect_intent_files: in live mode a stale census date no longer drops
  a row whose live mtime is inside the window (one stat decides), and
  unadmitted sessions are parsed ad-hoc through the same catalog reader
- ClaimHonesty::live_open(): open_session/live_unverified frame; live
  records render in a separate '## Live Session Intent (unverified,
  open)' section, never blended into the closed timeline
- CLI: --live / --no-live on intents (windows ≤48h scan automatically);
  text surfaces print live_sessions / index_lag_hours / mode header —
  a hot query can no longer masquerade as a pure census read
- completeness JSON gains live_sessions (+warning) for MCP consumers
- tests: catalog delta drain, live admission both paths, markdown split

Authored-By: claude <agents@vetcoders.io>
session_id: 855f3ce6-6088-4480-a608-9d9c504d6dc6
timestamp: 2026_0728_1600_CEST
runtime: claude-code-interactive
…+ stale fail-closed intents

- index status (hybrid CURRENT + catalog_only paths) now derives
  newest_session_updated_at, sessions_newer_than_chunks and
  chunking_lag_secs from catalog source_mtime_ns fingerprints —
  zero-walk honesty; '<none>'/0 during visible agent activity was the
  P0 freshness lie
- readiness: sessions newer than the CURRENT build now report
  StaleChunks instead of hiding behind Ready/StaleIndex
- P2.8: empty intents from a census older than window/2 with zero
  live-admitted sessions now fails closed (stale_context_engine +
  rebuild hint) instead of masquerading as 'nothing happened'
- test: census fingerprints surface the newest in-scope mtime

Authored-By: claude <agents@vetcoders.io>
session_id: 855f3ce6-6088-4480-a608-9d9c504d6dc6
timestamp: 2026_0728_1625_CEST
runtime: claude-code-interactive
…sub-10s hot live scan

- new `aicx continuity show|write`: deterministic NOW / PEERS /
  DECISIONS (closed) / TASKS / SOURCES / INDEX HEALTH pack per project
  window; --for-inject bounds output to a ~6k-token prompt budget;
  embedder never on this path (P1.5-7)
- SessionCatalog::scan_hot_window(cutoff): walk+stat all candidates,
  open bounded headers ONLY for in-window files — the full probe pass
  measured 5m14s on real roots; the hot scan lands at ~8s cold and
  serves repeat queries from the 30s live-delta cache
- live_delta takes the window cutoff (cache keyed with 60s tolerance);
  enrichment (content re-reads for cwd/title) stays off the hot path —
  project attribution comes from path inference, census keeps the
  enriched truth at rebuild
- smoke on the real home: pack sees this session and parallel peers
  (claude + grok) live; INDEX HEALTH reports pending=546/staleindex
  honestly instead of '<none>'

Authored-By: claude <agents@vetcoders.io>
session_id: 855f3ce6-6088-4480-a608-9d9c504d6dc6
timestamp: 2026_0728_1640_CEST
runtime: claude-code-interactive
…e test

- the slim (no-default-features) lib test builds IntentsConfig directly;
  gate's loctree-consumer-check caught the missing field

Authored-By: claude <agents@vetcoders.io>
session_id: 855f3ce6-6088-4480-a608-9d9c504d6dc6
timestamp: 2026_0728_1655_CEST
runtime: claude-code-interactive
…ath through the operator allowlist

- Semgrep tainted-path (blocking) on the live-mtime probe: the census
  source_path is now resolved via SourceAllowlist::for_operator before
  the stat — same containment contract as read_catalog_signal_at

Authored-By: claude <agents@vetcoders.io>
session_id: 855f3ce6-6088-4480-a608-9d9c504d6dc6
timestamp: 2026_0728_1645_CEST
runtime: claude-code-interactive
Copilot AI review requested due to automatic review settings July 28, 2026 14:42
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements the “Live window” P0 behavior for intents (and supporting status surfaces) so hot-window queries (≤48h) don’t silently depend on a stale catalog/index, and adds a new embedder-free “continuity pack” CLI surface for multi-agent session resume.

Changes:

  • Add hot-window (“live”) intents mode: admit in-window sessions by live mtime (including unadmitted sessions), stamp them with an open/live honesty frame, and surface live_sessions/index lag in text + JSON/MCP stats.
  • Improve index status honesty by deriving newest-session timestamps and staleness signals from catalog fingerprints (zero-walk), including “StaleChunks” readiness.
  • Introduce aicx continuity show|write to render a deterministic markdown continuity pack (NOW/PEERS/DECISIONS/TASKS/SOURCES/INDEX HEALTH) built from live-window + census.

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/session_catalog.rs Adds coverage for hot-window scan probing behavior.
tests/project_filter_strict_surface.rs Updates test config to include the new live field.
src/wizard/screens/intents.rs Enables auto-live mode for wizard intents based on hours.
src/session_catalog.rs Introduces scan_hot_window and HotWindowScan to cheaply walk+stat and selectively probe fresh candidates.
src/overlay.rs Forces overlay joins to remain census-only (live: false).
src/oracle.rs Adds live/open-session honesty frame helpers (live_open, is_live_open).
src/mcp.rs Enables auto-live in MCP intents and updates stats struct init.
src/main/tests.rs Updates intents stats test fixtures for new live_sessions field and config live.
src/main.rs Adds --live/--no-live, live-window report header, fail-closed stale-engine error, and continuity subcommand wiring.
src/lib.rs Exposes new continuity module behind app feature and updates config fixtures.
src/intents/types.rs Adds live config flag, auto_live rule, and live_sessions in stats/completeness.
src/intents/tests.rs Adds tests for markdown separation of live vs closed and live-window admission behavior.
src/intents/display.rs Splits live/open claims into a separate markdown section.
src/intents.rs Implements live-window collection: mtime-based admission + unadmitted live-delta ingestion + live_sessions counting.
src/continuity.rs Adds continuity pack collection + deterministic rendering + inject budget truncation.
src/catalog.rs Adds cached live_delta discovery (unadmitted sessions + newest mtime) and associated tests.
src/api.rs Updates index status to use catalog fingerprints for newest session mtime, sessions-newer-than-chunks, lag, and readiness.
examples/loctree_consumer.rs Updates example config to include live: false.
crates/aicx-parser/src/sanitize.rs Registers continuity as a known CLI subcommand for sanitization.
crates/aicx-parser/src/chunker.rs Adds constants for the open/live honesty contract.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/intents/display.rs
Comment on lines 500 to 504
// Honesty frame for the whole surface: every record below is a historical
// claim bound to its session close, never runtime-verified by aicx.
out.push_str(&format!(
"_{}_\n\n",
ClaimHonesty::canonical().display_line()
Comment thread src/continuity.rs
min_confidence: None,
kind_filter: None,
frame_kind: None,
live: true,
Comment thread src/continuity.rs
Comment on lines +115 to +118
let cutoff_ns = cutoff
.timestamp_nanos_opt()
.map(|nanos| nanos as u64)
.unwrap_or(0);
Comment thread src/continuity.rs
Comment on lines +124 to +126
let mtime_ns = crate::catalog::live_source_fingerprint(Path::new(&entry.source_path))
.map(|(_, mtime)| mtime)
.or(entry.source_mtime_ns);
…se plane

- Add `aicx index --semantic` to embed extracts and publish dense.exact_mmap_v1.bin
- publish_source_hybrid_generation + current_dense_not_built for owner-host rebuilds
- index status surfaces lexical_status / dense_status / dense_recommendation
- Clarify stale_index as catalog-vs-lexical lag (not pending embed)
- Docs: COMMANDS, MULTI_MACHINE, README; regen completions
- Unit test hybrid publish; CLI parses --semantic

Authored-By: grok <agents@vetcoders.io>
session_id: 019fa004-a0dd-7603-a5d8-e069af9a9408
timestamp: 2026_0729_1900_CEST
runtime: interactive
…-frame

- Add Search screen (key 5): wraps aicx search lexical CURRENT with hits + Source panel
- / from any screen lands on Search; p/a/t filters; r re-runs
- Truthful backend line: index CURRENT (sync/host/gen) vs fallback FS (bounded, recency)
- Drift banner + repair path when CURRENT missing/stale — never silent empty
- Launch: wizard --view search [--query] [-p] [-a] without stdin prompts
- Unit tests for five-screen nav, slash routing, empty query, launch entry

Authored-By: grok <agents@vetcoders.io>
session_id: 825d9b4e-6810-4d13-9de8-dc5f3bc485d7
timestamp: 2026_0729_1901_CEST
runtime: headless
…first

Adds bounded hot admission, remote-backed project identity, clean no-session continuity, and catalog-backed wizard/dashboard surfaces.

Authored-By: codex <agents@vetcoders.io>
session_id: 019fb0d6-70b7-7993-b196-b1aee11b7e3f
timestamp: 2026_0730_0510_CEST
runtime: headless
Copilot AI review requested due to automatic review settings July 30, 2026 06:46

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 41 out of 41 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

src/intents/display.rs:505

  • When live records exist, the markdown header still prints the canonical honesty line (“every record below is a historical claim …”), which becomes false for the live/open section. Also, in the live case the “Closed Session Intent” section is missing its canonical honesty line, so readers can’t distinguish the contracts at a glance.
    let mut out = String::from("# Intent Timeline\n\n");
    // Honesty frame for the whole surface: every record below is a historical
    // claim bound to its session close, never runtime-verified by aicx.
    out.push_str(&format!(
        "_{}_\n\n",
        ClaimHonesty::canonical().display_line()
    ));

src/main.rs:2728

  • aicx wizard now hard-fails when run outside a git checkout with a readable origin (because current_checkout_project()? errors). This makes the TUI unusable in non-git directories unless the user always passes -p, which is a behavior change not implied by the command itself.
                run_catalog_refresh(168, false)?;
                if project.is_none() {
                    project = Some(current_checkout_project()?);
                }

src/wizard/app.rs:24

  • The wizard help text labels screen 1 as “sessions”, but the top bar title still renders it as “Corpus”. This inconsistency is user-visible and makes navigation/keymap harder to follow.
    pub fn title(self) -> &'static str {
        match self {
            Self::Corpus => "Corpus",
            Self::Doctor => "Doctor",
            Self::Intents => "Intents",
            Self::Rebuild => "Refresh",
            Self::Search => "Search",

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants