From 04e658402ab2ff7ed0baf6faa3ca1e4117b74121 Mon Sep 17 00:00:00 2001 From: colombod Date: Tue, 30 Jun 2026 16:36:53 +0000 Subject: [PATCH 1/4] feat: context_intelligence base_path relocation (multiplexed-safe) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make a relocated context_intelligence base_path tell the truth end-to-end β€” what the hook writes is what every reader finds β€” and kill the confident false-positive where a reader latched onto Amplifier core's sessions//metadata.json (reported as a context_intelligence capture). Mechanism (multiplexed-safe by construction): - AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH is a read-only host/process INPUT. The bundle NEVER writes os.environ (zero assignments) β€” so concurrent sessions in one process cannot clobber each other. - A one-line in-bundle binding base_path: "${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:}" in behaviors/context-intelligence-logging.yaml carries relocation into the writer's config (config_resolver stays pure; fold-discipline gate green). - ONE shared canonicalizer (strip -> empty/relative -> default -> expanduser -> absolute-or-default, never cwd) applied identically by writer and readers. - ONE shared capture helper keyed on */sessions/*/context-intelligence/events.jsonl (fixed-shape; subsessions counted). The events.jsonl marker is the false-positive guard. discover.py and the workflow recipe agree on the same set. - discover.py returns DiskScanResult{root, root_exists, disk_only_ids, candidate_ids}; absent root is authoritative in the return (no silent zero). - Mandatory read-only consistency check in on_session_ready warns loudly if the env value and the resolved base_path disagree. Behaviorally proven in a Digital Twin (no skill pytest): relocation via the in-bundle binding, false-positive dead, reader convergence, multiplexed-safe invariant (zero env writes), and the consistency check firing β€” all PASS. Fold-gate 3/3; discover tests pass. Known residual: relocation granularity is per-process, not per-session (a host needing different roots per session in one process must use separate processes). Follow-ups (deferred, intentionally not in this PR): the base-path drift-guard lint, the broad doc-narrative sweep, and the uploader workspace-derivation edge. πŸ€– Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- agents/session-navigator.md | 71 ++++-- behaviors/context-intelligence-logging.yaml | 2 +- context_intelligence/__init__.py | 2 + context_intelligence/config.py | 121 ++++++++++ context_intelligence/reconstruct/__init__.py | 2 + context_intelligence/reconstruct/discover.py | 125 ++++++++-- .../__init__.py | 22 ++ .../config_resolver.py | 32 ++- recipes/workflow-pattern-analysis.yaml | 24 +- scripts/context-intelligence.py | 9 +- .../SKILL.md | 55 +++-- .../SKILL.md | 8 +- skills/workflow-pattern-analysis/SKILL.md | 5 +- tests/test_reconstruct_discover.py | 216 ++++++++++++++---- 14 files changed, 582 insertions(+), 112 deletions(-) diff --git a/agents/session-navigator.md b/agents/session-navigator.md index 19a4ba64..7cd5961c 100644 --- a/agents/session-navigator.md +++ b/agents/session-navigator.md @@ -8,7 +8,7 @@ meta: description: | MUST NOT be invoked directly by external callers. ALWAYS delegated to by graph-analyst when the graph server is unreachable or returns 0 sessions. - Local fallback agent for navigating session data via flat JSONL files using bash/jq/grep safe extraction patterns. Handles session discovery, event search, and session navigation across ~/.amplifier/projects/ when the context-intelligence graph server is unavailable. + Local fallback agent for navigating session data via flat JSONL files using bash/jq/grep safe extraction patterns. Handles session discovery, event search, and session navigation under the root resolved from `CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}"` when the context-intelligence graph server is unavailable. This agent is NOT called directly by external callers. It is only delegated to by graph-analyst when the graph server is unreachable or returns 0 sessions. External callers should use graph-analyst instead. @@ -17,7 +17,7 @@ meta: Context: Graph analyst delegating because server is unreachable user: [graph-analyst delegates] 'Find tool errors in session abc123 β€” graph server is unreachable. Workspace: my-project' - assistant: 'I will scope search to workspace my-project. I will look in ~/.amplifier/projects/my-project/sessions/ first, then filter by workspace field if needed. I will search for tool errors using safe jq extraction patterns.' + assistant: 'I will scope search to workspace my-project. I will first resolve CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}", then look in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/ first, then filter by workspace field if needed. I will search for tool errors using safe jq extraction patterns.' session-navigator receives workspace from graph-analyst and uses it to scope all directory lookups and field filters. External callers should never invoke session-navigator directly. @@ -113,13 +113,37 @@ You are `session-navigator` β€” the local JSONL fallback navigation agent for th **No server tools:** You do NOT have `graph_query` or `blob_read` tools. You operate entirely on local filesystem files using bash/jq/grep safe extraction patterns. Never attempt to use server tools β€” they are not available in your tool set. -**Storage path convention:** All session data lives at: +**Root resolution β€” MANDATORY FIRST STEP before any discovery:** + +Resolve the root once at the start of every context_intelligence session navigation operation: + +```bash +CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" +``` + +The on-disk layout is: ``` -~/.amplifier/projects/{project-slug}/sessions/{session_id}/context-intelligence/events.jsonl -~/.amplifier/projects/{project-slug}/sessions/{session_id}/context-intelligence/metadata.json +$CONTEXT_INTELLIGENCE_ROOT/{project-slug}/sessions/{session_id}/context-intelligence/events.jsonl +$CONTEXT_INTELLIGENCE_ROOT/{project-slug}/sessions/{session_id}/context-intelligence/metadata.json ``` +> **β›” MARKER RULE β€” the defect this fixes:** Every discovery glob MUST include the +> `context-intelligence/` path segment and MUST NOT stop at `sessions//`: +> +> ``` +> CORRECT: "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json +> WRONG: "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/metadata.json # catches Amplifier core's files +> ``` +> +> **Why:** Amplifier core writes `sessions//metadata.json` with NO `context-intelligence/` +> segment. Globbing one level too shallow latches onto core's files and produces a confident +> wrong count. + +> **β›” FAIL-LOUD RULE:** When zero captures are found, say exactly `"looked in , found 0"` β€” +> never report a confident count from a shallower glob, never silently fall back to a different +> path. + Every `events.jsonl` line and every `metadata.json` file contains a `workspace` field. The graph-analyst will pass the active workspace when it delegates to you. **Always scope your search to that workspace.** ### Workspace Scoping β€” Do This First @@ -129,15 +153,22 @@ When a workspace is provided by the caller, apply it immediately before any othe **Step 1 β€” Try directory-first lookup** (fast, covers the common case where workspace equals the project slug): ```bash -ls ~/.amplifier/projects/{WORKSPACE}/sessions/ 2>/dev/null +CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" +ls "$CONTEXT_INTELLIGENCE_ROOT"/{WORKSPACE}/sessions/ 2>/dev/null ``` -If this directory exists and contains sessions, work within it exclusively. +> **Guard:** A `sessions//` directory entry only counts as a context_intelligence capture +> when `sessions//context-intelligence/` also exists. `ls sessions/` may list directories +> from Amplifier core with no `context-intelligence/` subdir β€” do not count those as +> context_intelligence sessions. + +If this directory exists and contains sessions with `context-intelligence/` subdirs, work within it exclusively. **Step 2 β€” If that directory is empty or missing**, the workspace was set explicitly and differs from the project slug. Scan across all project directories and filter by the `workspace` field in `metadata.json`: ```bash -for f in ~/.amplifier/projects/*/sessions/*/context-intelligence/metadata.json; do +CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" +for f in "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json; do jq -r 'select(.workspace == "{WORKSPACE}") | input_filename' "$f" 2>/dev/null done ``` @@ -155,26 +186,32 @@ done Find sessions by ID, project slug, date, or agent name, always scoped to the provided workspace. ```bash +# Resolve root first (required before any snippet below) +CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" + # List sessions in a workspace (directory-first path) -for f in ~/.amplifier/projects/my-project/sessions/*/context-intelligence/metadata.json; do +for f in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/metadata.json; do jq -r '[.session_id, .workspace, .status, .started_at, .agent_name // "(root)"] | join("\t")' "$f" 2>/dev/null done | sort -t$'\t' -k4 # List sessions scoped by workspace field (cross-project scan) -for f in ~/.amplifier/projects/*/sessions/*/context-intelligence/metadata.json; do +for f in "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json; do jq -r 'select(.workspace == "my-project") | [.session_id, .status, .started_at, .agent_name // "(root)"] | join("\t")' "$f" 2>/dev/null done | sort -t$'\t' -k3 # Find a session by partial ID (within a workspace) -find ~/.amplifier/projects/my-project/sessions -maxdepth 1 -name "*PARTIAL_ID*" -type d +# NOTE: a sessions// directory only counts as a context_intelligence capture when +# sessions//context-intelligence/ also exists. Always confirm the subdir: +find "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions -maxdepth 1 -name "*PARTIAL_ID*" -type d \ + | while read -r d; do [ -d "$d/context-intelligence" ] && echo "$d"; done # Find sessions by agent name within a workspace -for f in ~/.amplifier/projects/my-project/sessions/*/context-intelligence/metadata.json; do +for f in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/metadata.json; do jq -r 'select(.agent_name == "TARGET_AGENT") | .session_id' "$f" 2>/dev/null done # Confirm the workspace of a specific session -jq -r '.workspace' ~/.amplifier/projects/my-project/sessions/SESSION_ID/context-intelligence/metadata.json +jq -r '.workspace' "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/SESSION_ID/context-intelligence/metadata.json ``` ### Event Search @@ -207,12 +244,15 @@ wc -l < events.jsonl Trace parent-child chains via `parent_id`, trace delegation trees via `delegate:agent_spawned`/`delegate:agent_completed`. ```bash +# Resolve root first (required before any snippet below) +CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" + # Check if session is root or child, and confirm its workspace jq -r '{parent_id, workspace, status}' metadata.json # Find child sessions within a workspace PARENT_ID="YOUR_SESSION_ID_HERE" -for f in ~/.amplifier/projects/my-project/sessions/*/context-intelligence/metadata.json; do +for f in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/metadata.json; do jq -r "select(.parent_id == \"$PARENT_ID\") | [.session_id, .agent_name // \"(root)\", .status, .workspace] | join(\"\t\")" "$f" 2>/dev/null done @@ -237,8 +277,9 @@ Since session-navigator is active when no server is configured, you must locate 2. Or read from bundle config YAML under `hook-context-intelligence.config`: `context_intelligence_server_url` and `context_intelligence_api_key` ```bash +CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" context-intelligence-upload \ - --path ~/.amplifier/projects/my-project \ + --path "$CONTEXT_INTELLIGENCE_ROOT"/my-project \ --server-url "https://your-server.example.com" \ --api-key "your-api-key" ``` diff --git a/behaviors/context-intelligence-logging.yaml b/behaviors/context-intelligence-logging.yaml index 58851f87..6f33812c 100644 --- a/behaviors/context-intelligence-logging.yaml +++ b/behaviors/context-intelligence-logging.yaml @@ -40,7 +40,7 @@ hooks: - delegate:agent_completed - delegate:agent_cancelled - delegate:error - # base_path: ~/.amplifier/projects (auto-resolved; uncomment to override) + base_path: "${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:}" # project_slug: (auto-resolved from working directory; uncomment to override) # exclude_events: [] (optional fnmatch patterns; uncomment and list events to suppress) # diff --git a/context_intelligence/__init__.py b/context_intelligence/__init__.py index 007f706e..993a42fd 100644 --- a/context_intelligence/__init__.py +++ b/context_intelligence/__init__.py @@ -25,6 +25,7 @@ resolve_config, ) from context_intelligence.reconstruct import ( + DiskScanResult, build_disk_only_metadata, discover_sessions, extract_events, @@ -45,6 +46,7 @@ "extract_transcript", "extract_metadata", "build_disk_only_metadata", + "DiskScanResult", "discover_sessions", "workspace_slug", "sessions_dir_for_project", diff --git a/context_intelligence/config.py b/context_intelligence/config.py index d53bdcb5..12fe9249 100644 --- a/context_intelligence/config.py +++ b/context_intelligence/config.py @@ -29,6 +29,10 @@ AMPLIFIER_DIR = Path.home() / ".amplifier" SETTINGS_PATH = AMPLIFIER_DIR / "settings.yaml" +#: The ONE canonical reader-side default root for context-intelligence captures. +#: All readers fall back to this when AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH is unset. +DEFAULT_BASE_PATH = Path.home() / ".amplifier" / "projects" + # --------------------------------------------------------------------------- # Shared env-var helpers (used by HookConfigResolver and ToolConfigResolver) @@ -50,6 +54,123 @@ def _env(suffix: str) -> str | None: return value if value else None +def canonicalize_base_path(raw: str | Path | None) -> Path: + """Canonicalise a raw base-path value to a **guaranteed absolute** :class:`Path`. + + Four rules applied in order (Β§D.2): + + 1. Convert to string and strip whitespace. ``None`` β†’ empty string. + 2. Empty string β†’ :data:`DEFAULT_BASE_PATH` (never anchored to CWD). + 3. Expand ``~`` via :meth:`~pathlib.Path.expanduser`. + 4. If the result is still relative β†’ warn and fall back to + :data:`DEFAULT_BASE_PATH`. Relative paths are invalid: each OS process + has its own CWD, so a relative root produces *different directories* for + different processes even when the string is byte-identical. + + No ``os.path.normpath`` or CWD-anchoring β€” pathlib already drops trailing + slashes; absoluteness, not normalisation, is the load-bearing property. + + Parameters + ---------- + raw: + A raw string, :class:`~pathlib.Path`, or ``None``. + + Returns + ------- + Path + An absolute :class:`~pathlib.Path`. Never relative, never empty. + """ + s = str(raw).strip() if raw is not None else "" + if not s: + return DEFAULT_BASE_PATH + p = Path(s).expanduser() + if not p.is_absolute(): + log.warning( + "base_path %r is not absolute; using default %s", + s, + DEFAULT_BASE_PATH, + ) + return DEFAULT_BASE_PATH + return p + + +def context_intelligence_base_path() -> Path: + """Reader-side root for context-intelligence captures. + + Reads ``AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH`` from the environment via + :func:`_env` (which returns ``None`` for both unset and empty) and passes the + result through :func:`canonicalize_base_path`, which guarantees an absolute + path and falls back to :data:`DEFAULT_BASE_PATH` for empty or relative values. + + Mirrors the shell idiom:: + + ${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-~/.amplifier/projects} + + This helper is **gate-safe**: it lives in ``config.py``, which already imports + ``os``. It does **not** touch ``config_resolver.py`` (fold-discipline gate). + """ + return canonicalize_base_path(_env("BASE_PATH")) + + +# --------------------------------------------------------------------------- +# Shared capture-path helpers (canonical capture definition β€” Β§D.1) +# --------------------------------------------------------------------------- + +#: Fixed-shape glob (relative to a ``sessions/`` directory) that matches +#: exactly the files the writer produces. One capture = +#: ``//context-intelligence/events.jsonl``. +#: +#: The ``events.jsonl`` **file** is the discriminator β€” a bare +#: ``context-intelligence/`` directory without the file is not a recoverable +#: capture and must not be counted. Amplifier core's +#: ``sessions//metadata.json`` has no ``context-intelligence/`` segment and +#: is excluded by construction. +CAPTURE_GLOB = "*/context-intelligence/events.jsonl" + + +def capture_paths_under_sessions_dir(sessions_dir: Path) -> list[Path]: + """Return all capture paths under a project ``sessions/`` directory. + + Uses the fixed-shape :data:`CAPTURE_GLOB` β€” **not** a recursive ``**`` + glob β€” so only the writer's real output layout is matched. + + Parameters + ---------- + sessions_dir: + The ``//sessions`` directory to scan. + + Returns + ------- + list[Path] + Sorted list of ``events.jsonl`` file paths, one per qualifying session + (including subsessions, which are flat siblings under ``sessions/``). + ``session_id`` for any path ``p`` is ``p.parent.parent.name``. + """ + return sorted(sessions_dir.glob(CAPTURE_GLOB)) + + +def capture_paths_under_base(base: Path) -> list[Path]: + """Return all capture paths under a base root across all projects. + + Scans ``/*/sessions/*/context-intelligence/events.jsonl`` β€” + the same fixed shape as :func:`capture_paths_under_sessions_dir` reached + from two levels higher. + + Parameters + ---------- + base: + The base root directory (e.g. ``~/.amplifier/projects``). + + Returns + ------- + list[Path] + Sorted list of ``events.jsonl`` file paths across all projects under + *base*. ``project_slug`` for any path ``p`` is ``p.parents[3].name``; + ``session_id`` is ``p.parent.parent.name``. + """ + return sorted(base.glob("*/sessions/" + CAPTURE_GLOB)) + + # --------------------------------------------------------------------------- # Shell-style placeholder expander (used by ToolConfigResolver) # --------------------------------------------------------------------------- diff --git a/context_intelligence/reconstruct/__init__.py b/context_intelligence/reconstruct/__init__.py index e396d32c..51ece5d8 100644 --- a/context_intelligence/reconstruct/__init__.py +++ b/context_intelligence/reconstruct/__init__.py @@ -33,6 +33,7 @@ from __future__ import annotations from context_intelligence.reconstruct.discover import ( + DiskScanResult, discover_sessions, sessions_dir_for_project, workspace_slug, @@ -49,6 +50,7 @@ "extract_transcript", "extract_metadata", "build_disk_only_metadata", + "DiskScanResult", "discover_sessions", "workspace_slug", "sessions_dir_for_project", diff --git a/context_intelligence/reconstruct/discover.py b/context_intelligence/reconstruct/discover.py index e0c73156..8337b062 100644 --- a/context_intelligence/reconstruct/discover.py +++ b/context_intelligence/reconstruct/discover.py @@ -3,7 +3,7 @@ Discovers sessions for a workspace by querying the context-intelligence graph and scanning the local filesystem for sessions not yet in the graph. -Level 2 β€” Network I/O (queries the CI graph server via CIClient). +Level 2 β€” Network I/O (queries the context-intelligence graph server via CIClient). Extracted from prototype scripts/ci-reconstruct-sessions.py (lines 104-111, 1051-1084). """ @@ -12,10 +12,14 @@ import logging import os +from dataclasses import dataclass, field from pathlib import Path from context_intelligence.client import CIClient -from context_intelligence.config import AMPLIFIER_DIR +from context_intelligence.config import ( + capture_paths_under_sessions_dir, + context_intelligence_base_path, +) log = logging.getLogger("context_intelligence.reconstruct.discover") @@ -51,9 +55,13 @@ def workspace_slug(project_dir: str) -> str: def sessions_dir_for_project(project_dir: str) -> Path: """Return the sessions directory for a project. - Builds the path: ``AMPLIFIER_DIR / 'projects' / slug / 'sessions'``, + Builds the path: ``context_intelligence_base_path() / slug / 'sessions'``, where *slug* is derived via :func:`workspace_slug`. + The base path honours ``AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH`` when + set (and guarantees an absolute result via the canonicalizer); falls back + to :data:`~context_intelligence.config.DEFAULT_BASE_PATH`. + Parameters ---------- project_dir: @@ -65,18 +73,70 @@ def sessions_dir_for_project(project_dir: str) -> Path: Path to the sessions directory for the project. """ slug = workspace_slug(project_dir) - return AMPLIFIER_DIR / "projects" / slug / "sessions" + return context_intelligence_base_path() / slug / "sessions" + + +@dataclass(frozen=True) +class DiskScanResult: + """Tagged result from a disk scan β€” prevents silent misreading of absent roots. + + The two distinct fail-loud states ride the **return value**, not only the + log, so callers must branch on :attr:`root_exists` rather than treating an + empty :attr:`disk_only_ids` as "success". + + Attributes + ---------- + root: + The ``sessions/`` directory that was (or was attempted to be) scanned. + root_exists: + ``True`` when ``root`` existed at scan time; ``False`` when the directory + was absent or was a typo'd / missing relocated root. A ``False`` value + means **the scan was impossible** β€” it is NOT equivalent to + "found zero captures". + disk_only_ids: + Session IDs present on disk (via the canonical + ``events.jsonl`` marker) but absent from the graph. + Computed as ``candidate_ids βˆ’ graph_ids``. + Empty list when ``root_exists`` is ``False``. + candidate_ids: + The full capture-candidate set β€” all session IDs that have an + ``events.jsonl`` file under ``root``, regardless of graph membership. + Subsessions (directories whose name begins with ``0000000000000000``) + ARE included; the ``events.jsonl`` marker is the sole discriminator. + Empty list when ``root_exists`` is ``False``. + """ + + root: Path + root_exists: bool + disk_only_ids: list[str] = field(default_factory=list) + candidate_ids: list[str] = field(default_factory=list) def discover_sessions( client: CIClient, workspace: str, sessions_dir: Path, -) -> tuple[list[dict], list[str]]: +) -> tuple[list[dict], DiskScanResult]: """Discover all sessions for a workspace from the graph and disk. Queries the context-intelligence graph for all sessions in *workspace*, - then scans *sessions_dir* for session directories not present in the graph. + then scans *sessions_dir* for captures (``events.jsonl`` files) not present + in the graph. + + The canonical capture definition (Β§D.1) is + ``//context-intelligence/events.jsonl`` β€” a + **fixed-shape** glob, **not** recursive. Subsessions (flat siblings whose + name begins with ``0000000000000000``) **are** included; they are real + captures that were silently dropped by the old ``0000…`` skip. + + Two distinct fail-loud states ride the **return value**: + + - ``root_exists=False`` β€” the sessions directory was absent or a typo'd + relocated root. ``disk_only_ids`` and ``candidate_ids`` are both empty. + This is **not** the same as "found zero captures" and the caller MUST + branch on it. + - ``root_exists=True, candidate_ids=[]`` β€” the directory exists but contains + no qualifying ``events.jsonl`` captures. Parameters ---------- @@ -89,15 +149,15 @@ def discover_sessions( Returns ------- - tuple[list[dict], list[str]] + tuple[list[dict], DiskScanResult] A 2-tuple of: - **graph_sessions** β€” list of row dicts from the graph query, each with keys ``s.node_id``, ``s.status``, ``s.started_at``, ``s.ended_at``, ordered by ``s.started_at``. - - **disk_only_ids** β€” list of session directory names found on disk - but absent from the graph (subsession directories starting with - ``0000000000000000`` are excluded). + - **scan** β€” :class:`DiskScanResult` with tagged disk-scan outcome. + Callers must branch on ``scan.root_exists`` before interpreting + ``scan.disk_only_ids``. """ rows = client.cypher( f'MATCH (s:Session) WHERE s.workspace = "{workspace}" ' @@ -106,21 +166,42 @@ def discover_sessions( workspace=workspace, ) - # Collect graph session IDs + # Collect graph session IDs. graph_ids: set[str] = set() for row in rows: sid = row.get("s.node_id", "") if sid: graph_ids.add(sid) - # Scan disk for session directories not in the graph - disk_only_ids: list[str] = [] - if sessions_dir.is_dir(): - for entry in sorted(sessions_dir.iterdir()): - if entry.is_dir() and entry.name not in graph_ids: - # Skip subsession directories (start with 0000000000000000) - if entry.name.startswith("0000000000000000"): - continue - disk_only_ids.append(entry.name) - - return rows, disk_only_ids + # --- Absent-root guard (Β§D.3 FIX 4) ------------------------------------ + if not sessions_dir.is_dir(): + log.warning( + "context_intelligence root does not exist: %s", + sessions_dir, + ) + return rows, DiskScanResult( + root=sessions_dir, + root_exists=False, + ) + + # --- Shared capture-candidate set (Β§D.1) -------------------------------- + # Fixed-shape glob keyed on events.jsonl β€” the writer's real output. + # Subsessions are flat siblings under sessions/ and ARE counted. + # The events.jsonl marker excludes bare dirs AND Amplifier-core's + # sessions//metadata.json (no context-intelligence/ segment). + capture_paths = capture_paths_under_sessions_dir(sessions_dir) + candidate_ids: list[str] = [p.parent.parent.name for p in capture_paths] + disk_only_ids: list[str] = [sid for sid in candidate_ids if sid not in graph_ids] + + if not candidate_ids: + log.warning( + "looked in %s, found 0 context_intelligence captures", + sessions_dir, + ) + + return rows, DiskScanResult( + root=sessions_dir, + root_exists=True, + disk_only_ids=disk_only_ids, + candidate_ids=candidate_ids, + ) diff --git a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/__init__.py b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/__init__.py index b71afe19..c12ace73 100644 --- a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/__init__.py +++ b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/__init__.py @@ -165,6 +165,28 @@ async def on_session_ready(coordinator: Any) -> None: unregister_fns = state["unregister_fns"] destinations: dict[str, Destination] = state["destinations"] + # --- Β§C.3 mandatory startup consistency check (always-fire, read-only) --- + # Compare the canonicalized writer root against the canonicalized env value. + # When they disagree the writer and readers target different roots β€” a silent + # split that this check makes LOUD. Never writes os.environ (multiplexed-safe). + import os # local import β€” only this path needs the process env + + from context_intelligence.config import canonicalize_base_path as _canon + + _ENV_VAR = "AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH" + _env_raw = os.environ.get(_ENV_VAR) + if _env_raw: + _env_root = _canon(_env_raw) + _writer_root = _canon(str(resolver.base_path)) + if _env_root != _writer_root: + log.warning( + "context-intelligence: BASE_PATH env (%s) and resolved base_path (%s) disagree" + " β€” readers and the writer will target different roots;" + ' bind base_path: "${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:}" in the hook config', + _env_root, + _writer_root, + ) + # --- Destination selection (C2: working_dir capability ONLY, fail-loud) --- active: dict[str, Destination] = {} match_key: str = "" diff --git a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py index 413031bd..93234cc3 100644 --- a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py +++ b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py @@ -239,7 +239,21 @@ def base_path(self) -> Path: """Resolved base path for project storage. Chain: config['base_path'] β†’ coordinator.config['base_path'] β†’ default. - Tilde is expanded. Result is cached after first access. + Result is cached after first access. + + Canonicalisation rules (Β§D.2 β€” identical to reader-side + ``canonicalize_base_path`` in ``context_intelligence.config``; inlined + here to keep zero hookβ†’reader-package coupling and the fold gate green): + + 1. Strip whitespace from the raw string. + 2. Empty string β†’ ``_DEFAULT_BASE_PATH`` (never anchored to CWD). + 3. Expand ``~`` via :meth:`~pathlib.Path.expanduser`. + 4. If the result is still relative β†’ warn, fall back to default. + + Both the writer (this property) and readers call the same four rules so + canonicalized paths are byte-identical regardless of which side resolves + them. The Β§D.2 contract test drives the real property and asserts + writer ≑ reader and always absolute. """ if self._base_path is None: raw = ( @@ -247,7 +261,21 @@ def base_path(self) -> Path: or self._coordinator_config_get("base_path") or _DEFAULT_BASE_PATH ) - self._base_path = Path(raw).expanduser() + # Β§D.2 canonicalizer (inline β€” no os, no import os, fold-gate safe) + s = str(raw).strip() + if not s: + self._base_path = Path(_DEFAULT_BASE_PATH).expanduser() + else: + p = Path(s).expanduser() + if not p.is_absolute(): + log.warning( + "base_path %r is not absolute; using default %s", + s, + _DEFAULT_BASE_PATH, + ) + self._base_path = Path(_DEFAULT_BASE_PATH).expanduser() + else: + self._base_path = p return self._base_path @property diff --git a/recipes/workflow-pattern-analysis.yaml b/recipes/workflow-pattern-analysis.yaml index aa08001d..d0b89e9a 100644 --- a/recipes/workflow-pattern-analysis.yaml +++ b/recipes/workflow-pattern-analysis.yaml @@ -96,15 +96,15 @@ stages: condition: "{{prescope}} != ''" command: | python3 -c " - import json, glob, os - paths = glob.glob( - os.path.expanduser('~/.amplifier/projects/**/context-intelligence/events.jsonl'), - recursive=True - ) + import json, os + from pathlib import Path + root = Path(os.environ.get('AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH') or os.path.expanduser('~/.amplifier/projects')) + _raw = sorted(root.glob('*/sessions/*/context-intelligence/events.jsonl')) workspace = '{{workspace}}' prescope = '{{prescope}}' if workspace: - paths = [p for p in paths if workspace in p] + _raw = [p for p in _raw if p.parents[3].name == workspace] + paths = [str(p) for p in _raw] candidates = [] total_scanned = len(paths) for p in paths: @@ -169,15 +169,15 @@ stages: condition: "{{graph_probe.graph_available}} != 'true'" command: | python3 -c " - import json, glob, os - paths = glob.glob( - os.path.expanduser('~/.amplifier/projects/**/context-intelligence/events.jsonl'), - recursive=True - ) + import json, os + from pathlib import Path + root = Path(os.environ.get('AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH') or os.path.expanduser('~/.amplifier/projects')) + _raw = sorted(root.glob('*/sessions/*/context-intelligence/events.jsonl')) workspace = '{{workspace}}' max_sessions = {{max_sessions}} if workspace: - paths = [p for p in paths if workspace in p] + _raw = [p for p in _raw if p.parents[3].name == workspace] + paths = [str(p) for p in _raw] session_ids_str = '{{session_ids}}' try: session_ids = json.loads(session_ids_str) diff --git a/scripts/context-intelligence.py b/scripts/context-intelligence.py index b297df68..eb00e09c 100644 --- a/scripts/context-intelligence.py +++ b/scripts/context-intelligence.py @@ -144,7 +144,14 @@ def cmd_reconstruct(args: argparse.Namespace) -> int: # ── Discover sessions ───────────────────────────────────────────────────── log.info("Discovering sessions for workspace %s ...", workspace) - sessions, disk_only_ids = _ci_discover.discover_sessions(client, workspace, sessions_dir) + sessions, scan = _ci_discover.discover_sessions(client, workspace, sessions_dir) + + # Absent root is a distinct failure β€” not "found zero" (Β§D.3) + if not scan.root_exists: + log.error("root not found: %s", scan.root) + return 1 + + disk_only_ids: list[str] = scan.disk_only_ids # Filter to a specific session if requested if args.session: diff --git a/skills/context-intelligence-session-navigation/SKILL.md b/skills/context-intelligence-session-navigation/SKILL.md index 15ebe2af..fa057dd6 100644 --- a/skills/context-intelligence-session-navigation/SKILL.md +++ b/skills/context-intelligence-session-navigation/SKILL.md @@ -16,26 +16,47 @@ For ready-to-use jq/grep recipes, see `context/safe-extraction-patterns.md`. ## Disk Layout +Resolve the root once before any discovery: + +```bash +CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" ``` -~/.amplifier/projects/{project-slug}/sessions/{session_id}/context-intelligence/ + +``` +$CONTEXT_INTELLIGENCE_ROOT/{project-slug}/sessions/{session_id}/context-intelligence/ β”œβ”€β”€ events.jsonl # one JSON object per line, append-only └── metadata.json # session metadata, written on start, updated on end ``` -- `~/.amplifier/projects/` β€” default base path (configurable via `config.base_path`) +- `$CONTEXT_INTELLIGENCE_ROOT` β€” resolved from the idiom `"${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}"` (unset β†’ legacy default; configurable via `config.base_path`) - `{project-slug}` β€” derived from the full working directory path (see Project Slug Algorithm below) - `{session_id}` β€” unique session identifier (UUID or UUID with agent suffix for child sessions) - `context-intelligence/` β€” subdirectory containing the session data files - `events.jsonl` β€” append-only log of every event the kernel emits during the session - `metadata.json` β€” compact session metadata for quick lookup without parsing the full event log -Example paths: +Example paths (with root resolved): ``` -~/.amplifier/projects/-home-user-myapp/sessions/55c8841a-1234-5678-9abc-def012345678/context-intelligence/events.jsonl -~/.amplifier/projects/-home-user-myapp/sessions/55c8841a-1234-5678-9abc-def012345678/context-intelligence/metadata.json +$CONTEXT_INTELLIGENCE_ROOT/-home-user-myapp/sessions/55c8841a-1234-5678-9abc-def012345678/context-intelligence/events.jsonl +$CONTEXT_INTELLIGENCE_ROOT/-home-user-myapp/sessions/55c8841a-1234-5678-9abc-def012345678/context-intelligence/metadata.json ``` +> **⚠ MARKER RULE β€” the defect this prevents:** Every discovery glob MUST include the +> `context-intelligence/` path segment and MUST NOT stop at `sessions//`: +> +> ``` +> CORRECT: "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json +> WRONG: "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/metadata.json # catches Amplifier core's files +> ``` +> +> **Why:** Amplifier core writes `sessions//metadata.json` with NO `context-intelligence/` +> segment. Globbing one level too shallow latches onto core's files and produces a confident +> wrong count. + +> **⚠ FAIL-LOUD RULE:** When zero captures are found, say exactly `"looked in , found 0"` β€” +> never report a confident count from a shallower glob, never silently fall back to a different path. + --- ## Record Format @@ -106,13 +127,13 @@ Example (child session with optional fields): | Concept | Purpose | Where used | |---------|---------|------------| -| `project_slug` | Directory name under `~/.amplifier/projects/` | On-disk path | +| `project_slug` | Directory name under `$CONTEXT_INTELLIGENCE_ROOT/` | On-disk path | | `workspace` | Field in every record | Querying and filtering | By **default** workspace equals `project_slug` (both derived from the working directory). They can differ when workspace is set explicitly via `settings.yaml` or env var β€” for example, workspace `"my-api"` while project_slug is `"-home-user-myapp"`. **Consequence for navigation:** -- **Directory-first lookup** β€” when workspace matches the project_slug, all sessions for that workspace live under `~/.amplifier/projects/{workspace}/sessions/`. This is fast and the common case. +- **Directory-first lookup** β€” when workspace matches the project_slug, all sessions for that workspace live under `$CONTEXT_INTELLIGENCE_ROOT/{workspace}/sessions/`. This is fast and the common case. - **Field-based filtering** β€” when workspace was set explicitly (overriding the slug default), scan across all project directories and filter records by `jq 'select(.workspace == "TARGET")'`. Always check both: attempt directory lookup first, then fall back to cross-project field scan. @@ -157,15 +178,21 @@ Session event files can contain lines with 100k+ tokens (e.g., `llm:response` wi ## Common Navigation Patterns +Resolve the root once before all discovery snippets in this section: + +```bash +CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" +``` + ### Resolve workspace to a project directory ```bash # If workspace == project_slug (common default), sessions are here: -ls ~/.amplifier/projects/{workspace}/sessions/ +ls "$CONTEXT_INTELLIGENCE_ROOT"/{workspace}/sessions/ # If workspace was set explicitly and differs from project_slug, # find all directories containing sessions tagged with this workspace: -grep -rl '"workspace":"{workspace}"' ~/.amplifier/projects/*/sessions/*/context-intelligence/metadata.json \ +grep -rl '"workspace":"{workspace}"' "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json \ | sed 's|/context-intelligence/metadata.json||' ``` @@ -173,12 +200,12 @@ grep -rl '"workspace":"{workspace}"' ~/.amplifier/projects/*/sessions/*/context- ```bash # Fast path: workspace matches directory name (default case) -for f in ~/.amplifier/projects/my-project/sessions/*/context-intelligence/metadata.json; do +for f in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/metadata.json; do jq -r '[.session_id, .status, .started_at, .agent_name // "(root)"] | join("\t")' "$f" 2>/dev/null done | sort -t$'\t' -k3 # Scoped path: workspace set explicitly β€” scan all projects, filter by field -for f in ~/.amplifier/projects/*/sessions/*/context-intelligence/metadata.json; do +for f in "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json; do jq -r 'select(.workspace == "my-project") | [.session_id, .status, .started_at, .agent_name // "(root)"] | join("\t")' "$f" 2>/dev/null done | sort -t$'\t' -k3 ``` @@ -195,7 +222,7 @@ head -1 events.jsonl | jq -r '.workspace' ```bash # Count events per workspace across all sessions in a project directory: -jq -r '.workspace' ~/.amplifier/projects/-home-user-myapp/sessions/*/context-intelligence/events.jsonl \ +jq -r '.workspace' "$CONTEXT_INTELLIGENCE_ROOT"/-home-user-myapp/sessions/*/context-intelligence/events.jsonl \ | sort | uniq -c | sort -rn ``` @@ -203,12 +230,12 @@ jq -r '.workspace' ~/.amplifier/projects/-home-user-myapp/sessions/*/context-int ```bash # Within a single project directory: -for f in ~/.amplifier/projects/my-project/sessions/*/context-intelligence/metadata.json; do +for f in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/metadata.json; do jq -r 'select(.status == "running") | .session_id' "$f" 2>/dev/null done # Cross-project, scoped to workspace: -for f in ~/.amplifier/projects/*/sessions/*/context-intelligence/metadata.json; do +for f in "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json; do jq -r 'select(.workspace == "my-project" and .status == "running") | .session_id' "$f" 2>/dev/null done ``` diff --git a/skills/context-intelligence-session-reconstruction/SKILL.md b/skills/context-intelligence-session-reconstruction/SKILL.md index 8ed3ecb4..4f6516f8 100644 --- a/skills/context-intelligence-session-reconstruction/SKILL.md +++ b/skills/context-intelligence-session-reconstruction/SKILL.md @@ -128,8 +128,9 @@ After reconstruction, verify the output files were written correctly: **Check line counts for events and transcript:** ```bash -wc -l ~/.amplifier/projects/{workspace}/sessions/{session-id}/context-intelligence/events.jsonl -wc -l ~/.amplifier/projects/{workspace}/sessions/{session-id}/context-intelligence/transcript.jsonl +CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" +wc -l "$CONTEXT_INTELLIGENCE_ROOT"/{workspace}/sessions/{session-id}/context-intelligence/events.jsonl +wc -l "$CONTEXT_INTELLIGENCE_ROOT"/{workspace}/sessions/{session-id}/context-intelligence/transcript.jsonl ``` A reconstructed `events.jsonl` should have at least a few lines (session start, prompts, tool calls). Zero lines indicates the session had no recoverable events. @@ -137,7 +138,8 @@ A reconstructed `events.jsonl` should have at least a few lines (session start, **Validate metadata JSON is well-formed:** ```bash -cat ~/.amplifier/projects/{workspace}/sessions/{session-id}/context-intelligence/metadata.json | python3 -m json.tool +CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" +cat "$CONTEXT_INTELLIGENCE_ROOT"/{workspace}/sessions/{session-id}/context-intelligence/metadata.json | python3 -m json.tool ``` This confirms the file is valid JSON. Check that `bundle`, `model`, and `session_id` fields are populated. diff --git a/skills/workflow-pattern-analysis/SKILL.md b/skills/workflow-pattern-analysis/SKILL.md index 17f6d11e..95d3521e 100644 --- a/skills/workflow-pattern-analysis/SKILL.md +++ b/skills/workflow-pattern-analysis/SKILL.md @@ -70,7 +70,7 @@ read_file("${SKILL_DIR}/cypher-patterns.md") β€” Cypher query templates Q1 Also load from the bundle context when querying the graph or scanning JSONL: ``` -@context-intelligence:context/graph-model-reference.md β€” CI graph schema +@context-intelligence:context/graph-model-reference.md β€” context-intelligence graph schema @context-intelligence:context/jsonl-event-schema.md β€” on-disk JSONL event schema @context-intelligence:context/safe-extraction-patterns.md β€” safe JSONL extraction patterns ``` @@ -129,7 +129,8 @@ Delegate to `context-intelligence:graph-analyst` to: - **Disk scan is the explicit alternative** when the user needs comprehensive coverage of ALL on-disk sessions regardless of graph indexing state. Disk scan entry: ```bash - find ~/.amplifier/projects -path "*/context-intelligence/metadata.json" 2>/dev/null + CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" + find "$CONTEXT_INTELLIGENCE_ROOT" -path "*/context-intelligence/metadata.json" 2>/dev/null ``` Filter to `format == "context-intelligence"` AND `version == "1.0.0"`. Follow `@context-intelligence:context/safe-extraction-patterns.md` β€” never load full diff --git a/tests/test_reconstruct_discover.py b/tests/test_reconstruct_discover.py index 22b13139..ded59555 100644 --- a/tests/test_reconstruct_discover.py +++ b/tests/test_reconstruct_discover.py @@ -1,14 +1,16 @@ """Tests for context_intelligence.reconstruct.discover (task-8). Covers: -- Module imports correctly (workspace_slug, sessions_dir_for_project, discover_sessions) -- workspace_slug() converts absolute path to slug (replacing / with -) -- sessions_dir_for_project() returns AMPLIFIER_DIR/'projects'/slug/'sessions' -- discover_sessions() queries graph for sessions in workspace -- discover_sessions() returns graph rows and disk-only session IDs -- discover_sessions() skips subsession directories starting with 0000000000000000 -- discover_sessions() skips graph sessions from disk-only list -- Imports: CIClient from client, AMPLIFIER_DIR from config +- Module imports correctly (workspace_slug, sessions_dir_for_project, discover_sessions, + DiskScanResult) +- workspace_slug() converts absolute path to slug (replacing / with -). +- sessions_dir_for_project() returns DEFAULT_BASE_PATH/slug/'sessions'. +- discover_sessions() queries graph for sessions in workspace. +- discover_sessions() returns graph rows and a DiskScanResult. +- discover_sessions() uses the events.jsonl marker as the sole capture discriminator. +- discover_sessions() INCLUDES subsession directories (0000…) β€” Β§D.1 subsession inclusion. +- discover_sessions() returns root_exists=False for absent roots β€” Β§D.3 absent-root guard. +- Imports: CIClient from client, AMPLIFIER_DIR from config. """ from __future__ import annotations @@ -18,6 +20,22 @@ from unittest.mock import MagicMock +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _make_capture(sessions_dir: Path, session_id: str) -> None: + """Create the canonical capture structure for *session_id* under *sessions_dir*. + + A qualifying capture requires: + ``sessions_dir//context-intelligence/events.jsonl`` + """ + cap_dir = sessions_dir / session_id / "context-intelligence" + cap_dir.mkdir(parents=True, exist_ok=True) + (cap_dir / "events.jsonl").write_text("") + + class TestImport: """Module must be importable with the required public API.""" @@ -33,9 +51,14 @@ def test_discover_sessions_import(self): """discover_sessions must be importable from context_intelligence.reconstruct.discover.""" from context_intelligence.reconstruct.discover import discover_sessions # noqa: F401 + def test_disk_scan_result_import(self): + """DiskScanResult must be importable from context_intelligence.reconstruct.discover.""" + from context_intelligence.reconstruct.discover import DiskScanResult # noqa: F401 + def test_acceptance_criteria_command(self): """Simulate the acceptance criteria import command.""" from context_intelligence.reconstruct.discover import ( + DiskScanResult, discover_sessions, sessions_dir_for_project, workspace_slug, @@ -44,6 +67,7 @@ def test_acceptance_criteria_command(self): assert workspace_slug is not None assert sessions_dir_for_project is not None assert discover_sessions is not None + assert DiskScanResult is not None def test_uses_ciclient_from_client(self): """CIClient must be importable from the client module (imported dependency).""" @@ -157,6 +181,15 @@ def test_returns_tuple(self): assert isinstance(result, tuple) assert len(result) == 2 + def test_second_element_is_disk_scan_result(self): + """Second element is a DiskScanResult, not a bare list.""" + from context_intelligence.reconstruct.discover import DiskScanResult, discover_sessions + + client = self._make_client([]) + with tempfile.TemporaryDirectory() as tmpdir: + _, scan = discover_sessions(client, "test-workspace", Path(tmpdir)) + assert isinstance(scan, DiskScanResult) + def test_returns_graph_rows(self): """First element is the list of rows returned by client.cypher().""" from context_intelligence.reconstruct.discover import discover_sessions @@ -171,7 +204,7 @@ def test_returns_graph_rows(self): ] client = self._make_client(fake_rows) with tempfile.TemporaryDirectory() as tmpdir: - graph_sessions, disk_only = discover_sessions(client, "test-workspace", Path(tmpdir)) + graph_sessions, scan = discover_sessions(client, "test-workspace", Path(tmpdir)) assert graph_sessions == fake_rows def test_calls_cypher_with_workspace(self): @@ -211,7 +244,7 @@ def test_cypher_query_ordered_by_started_at(self): assert "ORDER BY s.started_at" in query_arg def test_disk_only_includes_dirs_not_in_graph(self): - """Directories on disk not in graph_ids are returned as disk_only_ids.""" + """Directories with events.jsonl on disk but not in graph_ids appear in disk_only_ids.""" from context_intelligence.reconstruct.discover import discover_sessions fake_rows = [ @@ -225,62 +258,164 @@ def test_disk_only_includes_dirs_not_in_graph(self): client = self._make_client(fake_rows) with tempfile.TemporaryDirectory() as tmpdir: sessions_dir = Path(tmpdir) - # Create a session dir that is on disk but not in graph - (sessions_dir / "disk-only-session").mkdir() - # Create a session dir that is also in graph - (sessions_dir / "graph-session-1").mkdir() + # Create a capture that is on disk but not in graph + _make_capture(sessions_dir, "disk-only-session") + # Create a capture that is also in graph + _make_capture(sessions_dir, "graph-session-1") + + _, scan = discover_sessions(client, "test-workspace", sessions_dir) + + assert "disk-only-session" in scan.disk_only_ids + assert "graph-session-1" not in scan.disk_only_ids + + def test_candidate_ids_includes_graph_sessions(self): + """candidate_ids is the full set regardless of graph membership.""" + from context_intelligence.reconstruct.discover import discover_sessions + + fake_rows = [ + { + "s.node_id": "graph-sess", + "s.status": "completed", + "s.started_at": "2024-01-01", + "s.ended_at": "2024-01-02", + }, + ] + client = self._make_client(fake_rows) + with tempfile.TemporaryDirectory() as tmpdir: + sessions_dir = Path(tmpdir) + _make_capture(sessions_dir, "disk-only-session") + _make_capture(sessions_dir, "graph-sess") - _, disk_only = discover_sessions(client, "test-workspace", sessions_dir) + _, scan = discover_sessions(client, "test-workspace", sessions_dir) - assert "disk-only-session" in disk_only - assert "graph-session-1" not in disk_only + assert "disk-only-session" in scan.candidate_ids + assert "graph-sess" in scan.candidate_ids + assert len(scan.candidate_ids) == 2 + assert len(scan.disk_only_ids) == 1 - def test_disk_only_skips_subsession_dirs(self): - """Directories starting with 0000000000000000 are skipped (subsessions).""" + def test_disk_only_INCLUDES_subsession_dirs(self): + """Subsession directories (0000… prefix) ARE included β€” Β§D.1 subsession inclusion. + + The old 0000… skip silently dropped real captures; this test pins the + corrected behaviour: subsessions have captures and must be counted. + """ from context_intelligence.reconstruct.discover import discover_sessions client = self._make_client([]) with tempfile.TemporaryDirectory() as tmpdir: sessions_dir = Path(tmpdir) - # Subsession directory - should be skipped - (sessions_dir / "0000000000000000-abc123_some-agent").mkdir() - # Normal session directory - should be included - (sessions_dir / "real-session-abc").mkdir() + # Subsession capture β€” MUST be included + _make_capture(sessions_dir, "0000000000000000-abc123_some-agent") + # Normal root-session capture β€” also included + _make_capture(sessions_dir, "real-session-abc") - _, disk_only = discover_sessions(client, "test-workspace", sessions_dir) + _, scan = discover_sessions(client, "test-workspace", sessions_dir) - assert "0000000000000000-abc123_some-agent" not in disk_only - assert "real-session-abc" in disk_only + assert "0000000000000000-abc123_some-agent" in scan.disk_only_ids + assert "real-session-abc" in scan.disk_only_ids - def test_disk_only_empty_when_no_sessions_dir(self): - """When sessions_dir does not exist, disk_only_ids is empty.""" + def test_bare_dir_without_events_jsonl_excluded(self): + """A directory without context-intelligence/events.jsonl is NOT a capture.""" + from context_intelligence.reconstruct.discover import discover_sessions + + client = self._make_client([]) + with tempfile.TemporaryDirectory() as tmpdir: + sessions_dir = Path(tmpdir) + # Bare dir β€” no events.jsonl + (sessions_dir / "bare-dir").mkdir() + # Capture with correct marker + _make_capture(sessions_dir, "real-capture") + + _, scan = discover_sessions(client, "test-workspace", sessions_dir) + + assert "bare-dir" not in scan.disk_only_ids + assert "bare-dir" not in scan.candidate_ids + assert "real-capture" in scan.disk_only_ids + + def test_amplifier_core_bait_dir_excluded(self): + """Amplifier-core sessions//metadata.json (no context-intelligence/) are excluded.""" + from context_intelligence.reconstruct.discover import discover_sessions + + client = self._make_client([]) + with tempfile.TemporaryDirectory() as tmpdir: + sessions_dir = Path(tmpdir) + # Amplifier-core bait: has metadata.json but no context-intelligence/events.jsonl + bait_dir = sessions_dir / "core-session-bait" + bait_dir.mkdir() + (bait_dir / "metadata.json").write_text("{}") + # Capture with correct marker + _make_capture(sessions_dir, "real-capture") + + _, scan = discover_sessions(client, "test-workspace", sessions_dir) + + assert "core-session-bait" not in scan.candidate_ids + assert "real-capture" in scan.candidate_ids + + def test_absent_root_returns_root_exists_false(self): + """When sessions_dir does not exist, root_exists is False β€” Β§D.3 absent-root guard.""" from context_intelligence.reconstruct.discover import discover_sessions client = self._make_client([]) nonexistent = Path("/tmp/this-path-should-not-exist-8675309") - _, disk_only = discover_sessions(client, "test-workspace", nonexistent) - assert disk_only == [] + _, scan = discover_sessions(client, "test-workspace", nonexistent) + + assert scan.root_exists is False + assert scan.disk_only_ids == [] + assert scan.candidate_ids == [] + + def test_absent_root_is_distinct_from_found_zero(self): + """root_exists=False is distinct from root_exists=True with no captures.""" + from context_intelligence.reconstruct.discover import discover_sessions + + client = self._make_client([]) + + # Absent root + nonexistent = Path("/tmp/this-path-should-not-exist-8675309") + _, absent_scan = discover_sessions(client, "test-workspace", nonexistent) + + # Existing root but no captures + with tempfile.TemporaryDirectory() as tmpdir: + _, empty_scan = discover_sessions(client, "test-workspace", Path(tmpdir)) + + assert absent_scan.root_exists is False + assert empty_scan.root_exists is True + assert empty_scan.disk_only_ids == [] + + def test_found_zero_root_exists_true(self): + """An existing root with no captures: root_exists=True and empty lists.""" + from context_intelligence.reconstruct.discover import discover_sessions + + client = self._make_client([]) + with tempfile.TemporaryDirectory() as tmpdir: + _, scan = discover_sessions(client, "test-workspace", Path(tmpdir)) + + assert scan.root_exists is True + assert scan.disk_only_ids == [] + assert scan.candidate_ids == [] def test_disk_only_is_list_of_strings(self): - """disk_only_ids is a list of strings (directory names).""" + """disk_only_ids is a list of strings (session IDs).""" from context_intelligence.reconstruct.discover import discover_sessions client = self._make_client([]) with tempfile.TemporaryDirectory() as tmpdir: sessions_dir = Path(tmpdir) - (sessions_dir / "some-session").mkdir() - _, disk_only = discover_sessions(client, "test-workspace", sessions_dir) - assert isinstance(disk_only, list) - assert all(isinstance(s, str) for s in disk_only) + _make_capture(sessions_dir, "some-session") + _, scan = discover_sessions(client, "test-workspace", sessions_dir) + + assert isinstance(scan.disk_only_ids, list) + assert all(isinstance(s, str) for s in scan.disk_only_ids) def test_empty_sessions_dir(self): - """An empty sessions_dir returns no disk_only_ids.""" + """An empty sessions_dir returns empty lists (root_exists=True).""" from context_intelligence.reconstruct.discover import discover_sessions client = self._make_client([]) with tempfile.TemporaryDirectory() as tmpdir: - _, disk_only = discover_sessions(client, "test-workspace", Path(tmpdir)) - assert disk_only == [] + _, scan = discover_sessions(client, "test-workspace", Path(tmpdir)) + assert scan.root_exists is True + assert scan.disk_only_ids == [] + assert scan.candidate_ids == [] def test_files_in_sessions_dir_not_included(self): """Regular files (not directories) in sessions_dir are not included.""" @@ -290,5 +425,6 @@ def test_files_in_sessions_dir_not_included(self): with tempfile.TemporaryDirectory() as tmpdir: sessions_dir = Path(tmpdir) (sessions_dir / "not-a-session.txt").write_text("hello") - _, disk_only = discover_sessions(client, "test-workspace", sessions_dir) - assert disk_only == [] + _, scan = discover_sessions(client, "test-workspace", sessions_dir) + assert scan.disk_only_ids == [] + assert scan.candidate_ids == [] From 6424d60e1bad770618247dcf4fcd35a8396938cc Mon Sep 17 00:00:00 2001 From: colombod Date: Tue, 30 Jun 2026 19:57:28 +0000 Subject: [PATCH 2/4] fix(tests): sync test_cmd_reconstruct mocks to DiskScanResult contract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit discover_sessions now returns (rows, DiskScanResult); scripts/context-intelligence.py consumes scan.root_exists / scan.disk_only_ids. The cmd_reconstruct test mocks still returned the old (rows, list) shape, raising AttributeError: 'list' object has no attribute 'root_exists' β€” the real cause of the red root-test CI on PR #48. Updated all 14 mock sites to return a root_exists=True DiskScanResult, preserving disk-only ids in disk_only_ids/candidate_ids. tests/ now 729 passed, 0 failed. πŸ€– Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- tests/test_cmd_reconstruct.py | 142 ++++++++++++++++++++++++++++++---- 1 file changed, 128 insertions(+), 14 deletions(-) diff --git a/tests/test_cmd_reconstruct.py b/tests/test_cmd_reconstruct.py index 34733980..f98db4c5 100644 --- a/tests/test_cmd_reconstruct.py +++ b/tests/test_cmd_reconstruct.py @@ -25,6 +25,8 @@ from pathlib import Path from unittest.mock import MagicMock, patch +from context_intelligence.reconstruct.discover import DiskScanResult + REPO_ROOT = Path(__file__).parent.parent SCRIPTS_DIR = REPO_ROOT / "scripts" SCRIPT_PATH = SCRIPTS_DIR / "context-intelligence.py" @@ -102,7 +104,15 @@ def test_cmd_reconstruct_does_not_raise_not_implemented(self): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([], []), + return_value=( + [], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[], + candidate_ids=[], + ), + ), ), ): args = _make_args() @@ -136,7 +146,15 @@ def test_returns_zero_on_no_sessions(self): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([], []), + return_value=( + [], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[], + candidate_ids=[], + ), + ), ), ): args = _make_args() @@ -162,7 +180,15 @@ def test_returns_zero_on_successful_processing(self): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([mock_session], []), + return_value=( + [mock_session], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[], + candidate_ids=[], + ), + ), ), patch( "context_intelligence.reconstruct.events.extract_events", @@ -200,7 +226,15 @@ def test_returns_one_on_extract_errors(self): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([mock_session], []), + return_value=( + [mock_session], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[], + candidate_ids=[], + ), + ), ), patch( "context_intelligence.reconstruct.events.extract_events", @@ -249,7 +283,15 @@ def test_events_only_calls_extract_events_not_others(self): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([mock_session], []), + return_value=( + [mock_session], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[], + candidate_ids=[], + ), + ), ), patch( "context_intelligence.reconstruct.events.extract_events", @@ -292,7 +334,15 @@ def test_transcript_only_calls_extract_transcript_not_others(self): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([mock_session], []), + return_value=( + [mock_session], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[], + candidate_ids=[], + ), + ), ), patch( "context_intelligence.reconstruct.events.extract_events", @@ -335,7 +385,15 @@ def test_metadata_only_calls_extract_metadata_not_others(self): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([mock_session], []), + return_value=( + [mock_session], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[], + candidate_ids=[], + ), + ), ), patch( "context_intelligence.reconstruct.events.extract_events", @@ -378,7 +436,15 @@ def test_no_only_flags_calls_all_three(self): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([mock_session], []), + return_value=( + [mock_session], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[], + candidate_ids=[], + ), + ), ), patch( "context_intelligence.reconstruct.events.extract_events", @@ -435,7 +501,15 @@ def test_session_filter_limits_to_matching_sessions(self): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=(sessions, []), + return_value=( + sessions, + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[], + candidate_ids=[], + ), + ), ), patch( "context_intelligence.reconstruct.events.extract_events", @@ -500,7 +574,15 @@ def test_skips_events_jsonl_if_exists(self, tmp_path): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([mock_session], []), + return_value=( + [mock_session], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[], + candidate_ids=[], + ), + ), ), patch( "context_intelligence.reconstruct.discover.workspace_slug", @@ -555,7 +637,15 @@ def test_force_overwrites_existing_events_jsonl(self, tmp_path): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([mock_session], []), + return_value=( + [mock_session], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[], + candidate_ids=[], + ), + ), ), patch( "context_intelligence.reconstruct.discover.workspace_slug", @@ -615,7 +705,15 @@ def test_dry_run_does_not_write_files(self, tmp_path): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([mock_session], []), + return_value=( + [mock_session], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[], + candidate_ids=[], + ), + ), ), patch( "context_intelligence.reconstruct.discover.workspace_slug", @@ -679,7 +777,15 @@ def test_disk_only_sessions_call_build_disk_only_metadata(self, tmp_path): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([], [disk_only_id]), + return_value=( + [], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[disk_only_id], + candidate_ids=[disk_only_id], + ), + ), ), patch( "context_intelligence.reconstruct.discover.workspace_slug", @@ -716,7 +822,15 @@ def test_disk_only_sessions_skipped_when_metadata_only_false(self, tmp_path): patch("context_intelligence.config.resolve_config", return_value=("http://s", "key")), patch( "context_intelligence.reconstruct.discover.discover_sessions", - return_value=([], [disk_only_id]), + return_value=( + [], + DiskScanResult( + root=Path("/tmp/test-project/sessions"), + root_exists=True, + disk_only_ids=[disk_only_id], + candidate_ids=[disk_only_id], + ), + ), ), patch( "context_intelligence.reconstruct.discover.workspace_slug", From c455d04ac6cd1aff9aee68c5050f535dc041d55a Mon Sep 17 00:00:00 2001 From: colombod Date: Tue, 30 Jun 2026 22:50:39 +0000 Subject: [PATCH 3/4] fix(context-intelligence): harden base_path relocation per review + council MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses a code review and a six-lens council review of the base_path relocation work: - Consistency check now fires BIDIRECTIONALLY (also when env unset but the writer relocated via config.base_path, which env-only readers can't see); extracted as a pure, unit-tested helper `reader_writer_roots_disagree`. - Writer treats an unexpanded `${...}` base_path as silent default (no per- session noise); behavior YAML documents the host `${VAR:}`-expansion contract. - Operator-visible INFO confirmation of the active capture root when relocation is in effect (closes the "silent misconfiguration looks like success" gap); per-process limitation surfaced at the behavior-YAML touchpoint. - Unified bash readers (navigation skill, navigator agent, workflow skill) onto the canonical `events.jsonl` capture marker; fields read from sibling metadata.json β€” kills the events.jsonl/metadata.json reader split-brain. - Recipe workspace filter matches the `workspace` field (not just dir slug), with a bounded readline (1MB) and dict guard. - Removed dead `capture_paths_under_base`; cross-reference comments link the two by-design-duplicated canonicalizer copies. - New tests: tests/test_base_path_parity.py (writer≑reader parity + divergence cases) and an end-to-end consistency/confirmation suite run against the real amplifier_core runtime. Verification: python_check clean; 747 root tests pass; 5 end-to-end consistency tests pass under real amplifier_core. Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- agents/session-navigator.md | 28 ++++- behaviors/context-intelligence-logging.yaml | 23 ++++ context_intelligence/config.py | 62 ++++++---- .../__init__.py | 55 +++++++-- .../config_resolver.py | 24 +++- .../tests/test_base_path_consistency.py | 101 +++++++++++++++++ recipes/workflow-pattern-analysis.yaml | 34 +++++- .../SKILL.md | 23 +++- skills/workflow-pattern-analysis/SKILL.md | 7 +- tests/test_base_path_parity.py | 106 ++++++++++++++++++ 10 files changed, 410 insertions(+), 53 deletions(-) create mode 100644 modules/hook-context-intelligence/tests/test_base_path_consistency.py create mode 100644 tests/test_base_path_parity.py diff --git a/agents/session-navigator.md b/agents/session-navigator.md index 7cd5961c..7bc35ee0 100644 --- a/agents/session-navigator.md +++ b/agents/session-navigator.md @@ -132,13 +132,24 @@ $CONTEXT_INTELLIGENCE_ROOT/{project-slug}/sessions/{session_id}/context-intellig > `context-intelligence/` path segment and MUST NOT stop at `sessions//`: > > ``` -> CORRECT: "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json +> CORRECT: "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/events.jsonl > WRONG: "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/metadata.json # catches Amplifier core's files > ``` > > **Why:** Amplifier core writes `sessions//metadata.json` with NO `context-intelligence/` > segment. Globbing one level too shallow latches onto core's files and produces a confident > wrong count. +> +> **Canonical marker = `events.jsonl`.** The Python readers (`discover.py`, the workflow recipe) +> treat `context-intelligence/events.jsonl` as the single discriminator of a real capture. +> `metadata.json` is read here only for its fields; both files are written together, so either +> glob keeps the `context-intelligence/` segment and avoids the false-positive. For a strict +> capture count that matches the code, glob `events.jsonl`. + +> **β›” RELOCATION RULE:** The root comes ONLY from `AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH` +> (unset β†’ `$HOME/.amplifier/projects`). The hook's `config.base_path` moves the *writer* but +> NOT these readers β€” if a capture seems missing, confirm the writer was relocated via the env +> var, not `config.base_path` alone. > **β›” FAIL-LOUD RULE:** When zero captures are found, say exactly `"looked in , found 0"` β€” > never report a confident count from a shallower glob, never silently fall back to a different @@ -168,7 +179,8 @@ If this directory exists and contains sessions with `context-intelligence/` subd ```bash CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" -for f in "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json; do +for ev in "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/events.jsonl; do + f="${ev%/events.jsonl}/metadata.json" # canonical marker = events.jsonl; fields from sibling jq -r 'select(.workspace == "{WORKSPACE}") | input_filename' "$f" 2>/dev/null done ``` @@ -190,12 +202,14 @@ Find sessions by ID, project slug, date, or agent name, always scoped to the pro CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" # List sessions in a workspace (directory-first path) -for f in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/metadata.json; do +for ev in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/events.jsonl; do + f="${ev%/events.jsonl}/metadata.json" # canonical marker = events.jsonl; fields from sibling jq -r '[.session_id, .workspace, .status, .started_at, .agent_name // "(root)"] | join("\t")' "$f" 2>/dev/null done | sort -t$'\t' -k4 # List sessions scoped by workspace field (cross-project scan) -for f in "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json; do +for ev in "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/events.jsonl; do + f="${ev%/events.jsonl}/metadata.json" # canonical marker = events.jsonl; fields from sibling jq -r 'select(.workspace == "my-project") | [.session_id, .status, .started_at, .agent_name // "(root)"] | join("\t")' "$f" 2>/dev/null done | sort -t$'\t' -k3 @@ -206,7 +220,8 @@ find "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions -maxdepth 1 -name "*PARTIA | while read -r d; do [ -d "$d/context-intelligence" ] && echo "$d"; done # Find sessions by agent name within a workspace -for f in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/metadata.json; do +for ev in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/events.jsonl; do + f="${ev%/events.jsonl}/metadata.json" # canonical marker = events.jsonl; fields from sibling jq -r 'select(.agent_name == "TARGET_AGENT") | .session_id' "$f" 2>/dev/null done @@ -252,7 +267,8 @@ jq -r '{parent_id, workspace, status}' metadata.json # Find child sessions within a workspace PARENT_ID="YOUR_SESSION_ID_HERE" -for f in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/metadata.json; do +for ev in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/events.jsonl; do + f="${ev%/events.jsonl}/metadata.json" # canonical marker = events.jsonl; fields from sibling jq -r "select(.parent_id == \"$PARENT_ID\") | [.session_id, .agent_name // \"(root)\", .status, .workspace] | join(\"\t\")" "$f" 2>/dev/null done diff --git a/behaviors/context-intelligence-logging.yaml b/behaviors/context-intelligence-logging.yaml index 6f33812c..0fa45e78 100644 --- a/behaviors/context-intelligence-logging.yaml +++ b/behaviors/context-intelligence-logging.yaml @@ -40,6 +40,29 @@ hooks: - delegate:agent_completed - delegate:agent_cancelled - delegate:error + # base_path β€” relocation root for ALL captures. + # + # This binding is how relocation reaches the readers too: discover.py, the + # workflow recipe, and the navigation skills resolve their root ONLY from + # the AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH env var. Binding base_path to + # the same var keeps the writer and readers in lock-step. + # + # REQUIRES the host app to expand ${VAR:default} placeholders before mount + # (the hook does not self-expand β€” same contract as url/api_key above). The + # Amplifier app-cli does this. On a host that does NOT expand the ${VAR:} + # (colon-empty-default) form, the unexpanded literal falls back to the + # default SILENTLY, and the Β§C.3 consistency check in on_session_ready warns + # LOUD if the var was actually set β€” so a broken binding is never silent. + # + # ⚠ Do NOT relocate by hard-coding a path here instead of the env var: + # the writer would move but the env-only readers would not follow, and they + # would report "found 0". Always relocate via the env var. + # + # ⚠ Relocation granularity is PER-PROCESS, not per-session: every session in + # one process shares the one env value. A host that needs different roots per + # session must use separate processes. At session start the hook logs (INFO) + # the active capture root whenever relocation is in effect, so you can confirm + # it took effect. base_path: "${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:}" # project_slug: (auto-resolved from working directory; uncomment to override) # exclude_events: [] (optional fnmatch patterns; uncomment and list events to suppress) diff --git a/context_intelligence/config.py b/context_intelligence/config.py index 12fe9249..3efc4574 100644 --- a/context_intelligence/config.py +++ b/context_intelligence/config.py @@ -70,6 +70,12 @@ def canonicalize_base_path(raw: str | Path | None) -> Path: No ``os.path.normpath`` or CWD-anchoring β€” pathlib already drops trailing slashes; absoluteness, not normalisation, is the load-bearing property. + .. important:: **Duplicated by design.** The fold gate forbids the hook's + ``config_resolver.py`` from importing this package, so the SAME rules are + inlined in ``HookConfigResolver.base_path``. The two copies MUST stay + byte-equivalent; ``tests/test_base_path_parity.py`` pins writer ≑ reader. + If you edit one, edit the other and the parity test. + Parameters ---------- raw: @@ -112,6 +118,40 @@ def context_intelligence_base_path() -> Path: return canonicalize_base_path(_env("BASE_PATH")) +def reader_writer_roots_disagree( + env_raw: str | None, + writer_base_path: str | Path, +) -> tuple[bool, Path, Path]: + """Compare the reader root against the writer root (Β§C.3 consistency check). + + Pure, side-effect-free core of the startup consistency check in the hook's + ``on_session_ready``. Extracted here (rather than left inline) so the + divergence condition is **unit-testable** without importing the hook package + (which needs ``amplifier_core`` at import time). + + Both operands pass through the SAME :func:`canonicalize_base_path`, so the + comparison is symmetric: a relocated *writer* whose root the env-only readers + cannot see produces ``disagree=True``. + + Parameters + ---------- + env_raw: + The raw ``AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH`` value (``None`` when + unset/empty) β€” exactly what every reader resolves from. + writer_base_path: + The writer's resolved ``base_path`` (e.g. ``resolver.base_path``). + + Returns + ------- + tuple[bool, Path, Path] + ``(disagree, reader_root, writer_root)``. ``disagree`` is ``True`` when + the canonicalized roots differ β€” the caller should then warn LOUD. + """ + reader_root = canonicalize_base_path(env_raw) + writer_root = canonicalize_base_path(str(writer_base_path)) + return reader_root != writer_root, reader_root, writer_root + + # --------------------------------------------------------------------------- # Shared capture-path helpers (canonical capture definition β€” Β§D.1) # --------------------------------------------------------------------------- @@ -149,28 +189,6 @@ def capture_paths_under_sessions_dir(sessions_dir: Path) -> list[Path]: return sorted(sessions_dir.glob(CAPTURE_GLOB)) -def capture_paths_under_base(base: Path) -> list[Path]: - """Return all capture paths under a base root across all projects. - - Scans ``/*/sessions/*/context-intelligence/events.jsonl`` β€” - the same fixed shape as :func:`capture_paths_under_sessions_dir` reached - from two levels higher. - - Parameters - ---------- - base: - The base root directory (e.g. ``~/.amplifier/projects``). - - Returns - ------- - list[Path] - Sorted list of ``events.jsonl`` file paths across all projects under - *base*. ``project_slug`` for any path ``p`` is ``p.parents[3].name``; - ``session_id`` is ``p.parent.parent.name``. - """ - return sorted(base.glob("*/sessions/" + CAPTURE_GLOB)) - - # --------------------------------------------------------------------------- # Shell-style placeholder expander (used by ToolConfigResolver) # --------------------------------------------------------------------------- diff --git a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/__init__.py b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/__init__.py index c12ace73..f012079e 100644 --- a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/__init__.py +++ b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/__init__.py @@ -166,25 +166,56 @@ async def on_session_ready(coordinator: Any) -> None: destinations: dict[str, Destination] = state["destinations"] # --- Β§C.3 mandatory startup consistency check (always-fire, read-only) --- - # Compare the canonicalized writer root against the canonicalized env value. + # Compare what the READERS will compute (canonicalized env var, defaulting + # when unset) against what the WRITER resolved (canonicalized base_path). # When they disagree the writer and readers target different roots β€” a silent # split that this check makes LOUD. Never writes os.environ (multiplexed-safe). + # + # This fires in BOTH directions, covering the two ways relocation can break: + # 1. env SET, writer at a different root β€” binding did not expand, or a + # config override fought the env var. + # 2. env UNSET, writer NOT at default β€” someone relocated via + # config.base_path / settings.yaml, which the env-only readers CANNOT + # see (relocation is reader-visible ONLY via the env var). The earlier + # `if _env_raw:` guard missed this case entirely. import os # local import β€” only this path needs the process env - from context_intelligence.config import canonicalize_base_path as _canon + from context_intelligence.config import reader_writer_roots_disagree _ENV_VAR = "AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH" - _env_raw = os.environ.get(_ENV_VAR) - if _env_raw: - _env_root = _canon(_env_raw) - _writer_root = _canon(str(resolver.base_path)) - if _env_root != _writer_root: - log.warning( - "context-intelligence: BASE_PATH env (%s) and resolved base_path (%s) disagree" - " β€” readers and the writer will target different roots;" - ' bind base_path: "${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:}" in the hook config', - _env_root, + _env_raw = os.environ.get(_ENV_VAR) # may be None/empty β†’ readers fall to default + # Pure, unit-tested divergence core (see tests/test_base_path_parity.py). + _disagree, _reader_root, _writer_root = reader_writer_roots_disagree( + _env_raw, resolver.base_path + ) + if _disagree: + log.warning( + "context-intelligence: writer base_path (%s) and reader root (%s) disagree" + " β€” readers (discover, recipe, navigation skills) resolve the root ONLY from" + " %s, so captures written under %s will be invisible to them." + ' Relocate via the env var (or bind base_path: "${%s:}" in the hook config),' + " not via config.base_path alone.", + _writer_root, + _reader_root, + _ENV_VAR, + _writer_root, + _ENV_VAR, + ) + else: + # Positive confirmation at the operator's surface (default level is INFO). + # Fires ONLY when relocation is actually in effect, so the operator who + # relocated can SEE it took effect β€” closing the "success and silent + # misconfiguration look identical at the moment of action" gap. Stays + # silent in the default (non-relocated) case so it adds no noise. + from context_intelligence.config import DEFAULT_BASE_PATH + + if _writer_root != DEFAULT_BASE_PATH: + log.info( + "context-intelligence: capturing to %s" + " (readers resolve the same root from %s)." + " Relocation is per-process, not per-session.", _writer_root, + _ENV_VAR, ) # --- Destination selection (C2: working_dir capability ONLY, fail-loud) --- diff --git a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py index 93234cc3..4f6ed8e1 100644 --- a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py +++ b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py @@ -245,12 +245,23 @@ def base_path(self) -> Path: ``canonicalize_base_path`` in ``context_intelligence.config``; inlined here to keep zero hookβ†’reader-package coupling and the fold gate green): + 0. **Unexpanded-placeholder guard.** A value that still looks like a + shell placeholder (``${...}``) means the host app did NOT expand the + ``base_path: "${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:}"`` binding + (the hook relies on the app layer to expand ``${VAR}`` before mount, + exactly as it does for ``url`` / ``api_key`` / ``exclude_events``). + Rather than treat the literal ``${...}`` as a bogus relative path and + warn on every session, fall back to the default **silently**. The + env-reading readers still relocate via the variable directly, and the + Β§C.3 startup consistency check in ``on_session_ready`` fires LOUD if + the variable was actually set (i.e. real relocation was intended but + the binding did not expand). 1. Strip whitespace from the raw string. 2. Empty string β†’ ``_DEFAULT_BASE_PATH`` (never anchored to CWD). 3. Expand ``~`` via :meth:`~pathlib.Path.expanduser`. 4. If the result is still relative β†’ warn, fall back to default. - Both the writer (this property) and readers call the same four rules so + Both the writer (this property) and readers call the same rules so canonicalized paths are byte-identical regardless of which side resolves them. The Β§D.2 contract test drives the real property and asserts writer ≑ reader and always absolute. @@ -261,9 +272,16 @@ def base_path(self) -> Path: or self._coordinator_config_get("base_path") or _DEFAULT_BASE_PATH ) - # Β§D.2 canonicalizer (inline β€” no os, no import os, fold-gate safe) + # Β§D.2 canonicalizer (inline β€” no os, no import os, fold-gate safe). + # DUPLICATED BY DESIGN: the byte-equivalent reader copy is + # `canonicalize_base_path` in `context_intelligence.config`. The fold + # gate forbids importing that package here, so the two MUST be kept in + # sync by hand; `tests/test_base_path_parity.py` pins writer ≑ reader. + # Edit one β†’ edit the other and the parity test. s = str(raw).strip() - if not s: + if not s or s.startswith("${"): + # Empty, OR an unexpanded ${VAR} placeholder (host app did not + # expand the binding). Either way β†’ default, no noise. Β§D.2 rule 0. self._base_path = Path(_DEFAULT_BASE_PATH).expanduser() else: p = Path(s).expanduser() diff --git a/modules/hook-context-intelligence/tests/test_base_path_consistency.py b/modules/hook-context-intelligence/tests/test_base_path_consistency.py new file mode 100644 index 00000000..d8c8712c --- /dev/null +++ b/modules/hook-context-intelligence/tests/test_base_path_consistency.py @@ -0,0 +1,101 @@ +# pyright: reportMissingImports=false +# (pytest / amplifier_core are runtime/CI deps not visible to the static checker here.) +"""End-to-end proof of the Β§C.3 base_path consistency warning (Restless-Old-Brian gate). + +These tests drive the REAL ``on_session_ready`` against the REAL ``amplifier_core`` +runtime (not the resolver in isolation) and assert the loud divergence warning +actually fires β€” closing the gap that the writer/consistency branches were only +ever verified by hand/parity. + +NOTE: like the rest of this module's tests, these require ``amplifier_core`` to be +importable (it is in the Amplifier tool venv / CI, but NOT in the bundle's own +isolated ``.venv``). They are skipped automatically if the runtime is unavailable. +""" + +from __future__ import annotations + +import logging + +import pytest + +pytest.importorskip("amplifier_core", reason="amplifier_core runtime not installed in this venv") + +from tests.helpers import make_lifecycle_coordinator, mount_and_ready # noqa: E402 + +_ENV_VAR = "AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH" + + +def _messages(caplog) -> str: + return "\n".join(r.getMessage() for r in caplog.records) + + +class TestConsistencyWarningEndToEnd: + """Real on_session_ready, real runtime β€” watch the warning fire (or stay silent).""" + + async def test_warns_when_writer_relocated_but_env_unset(self, caplog, monkeypatch) -> None: + """Scenario A β€” the trap: relocate via config.base_path, env var UNSET. + + Readers resolve the root only from the env var (-> default), the writer + resolved /tmp/relocated-ci-A. on_session_ready MUST warn LOUD. + """ + monkeypatch.delenv(_ENV_VAR, raising=False) + coordinator = make_lifecycle_coordinator() + with caplog.at_level(logging.WARNING): + await mount_and_ready(coordinator, config={"base_path": "/tmp/relocated-ci-A"}) + msgs = _messages(caplog) + assert "disagree" in msgs, f"expected a divergence warning; got:\n{msgs}" + assert "/tmp/relocated-ci-A" in msgs + + async def test_silent_when_env_matches_writer(self, caplog, monkeypatch) -> None: + """Scenario C (positive control) β€” env set to the same root the writer uses β†’ NO warning.""" + monkeypatch.setenv(_ENV_VAR, "/tmp/relocated-ci-C") + coordinator = make_lifecycle_coordinator() + with caplog.at_level(logging.WARNING): + await mount_and_ready(coordinator, config={"base_path": "/tmp/relocated-ci-C"}) + assert "disagree" not in _messages(caplog) + + async def test_unexpanded_placeholder_is_silent_default(self, caplog, monkeypatch) -> None: + """Scenario B β€” host did NOT expand the ${VAR} binding, env unset. + + Writer falls back to default SILENTLY (no 'not absolute' noise) and, since + readers also default, there is NO divergence warning either. + """ + monkeypatch.delenv(_ENV_VAR, raising=False) + coordinator = make_lifecycle_coordinator() + with caplog.at_level(logging.WARNING): + await mount_and_ready( + coordinator, + config={"base_path": "${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:}"}, + ) + msgs = _messages(caplog) + assert "not absolute" not in msgs, f"unexpected noisy warning:\n{msgs}" + assert "disagree" not in msgs, f"unexpected divergence warning:\n{msgs}" + + +class TestPositiveConfirmation: + """Operator-visible (default INFO) confirmation of the active capture root.""" + + async def test_confirmation_when_relocated_and_consistent(self, caplog, monkeypatch) -> None: + """Relocation in effect + reader matches writer β†’ INFO 'capturing to ' fires. + + log_level=INFO mirrors the behavior YAML default (``...:INFO``), i.e. the + level a composed-bundle operator actually runs at. + """ + monkeypatch.setenv(_ENV_VAR, "/tmp/relocated-ci-confirm") + coordinator = make_lifecycle_coordinator() + with caplog.at_level(logging.INFO): + await mount_and_ready( + coordinator, + config={"base_path": "/tmp/relocated-ci-confirm", "log_level": "INFO"}, + ) + msgs = _messages(caplog) + assert "capturing to" in msgs, f"expected positive confirmation; got:\n{msgs}" + assert "/tmp/relocated-ci-confirm" in msgs + + async def test_no_confirmation_in_default_case(self, caplog, monkeypatch) -> None: + """No relocation (default root) β†’ stay silent even at INFO, no confirmation noise.""" + monkeypatch.delenv(_ENV_VAR, raising=False) + coordinator = make_lifecycle_coordinator() + with caplog.at_level(logging.INFO): + await mount_and_ready(coordinator, config={"log_level": "INFO"}) + assert "capturing to" not in _messages(caplog) diff --git a/recipes/workflow-pattern-analysis.yaml b/recipes/workflow-pattern-analysis.yaml index d0b89e9a..bde52092 100644 --- a/recipes/workflow-pattern-analysis.yaml +++ b/recipes/workflow-pattern-analysis.yaml @@ -102,8 +102,23 @@ stages: _raw = sorted(root.glob('*/sessions/*/context-intelligence/events.jsonl')) workspace = '{{workspace}}' prescope = '{{prescope}}' + def _ws_match(p, ws): + # Directory-first (fast): slug == workspace. Fall back to the + # workspace FIELD in events.jsonl when workspace was set explicitly + # and differs from the project slug (matches the navigation skills). + if p.parents[3].name == ws: + return True + try: + with open(p) as fh: + # Bound the read so a malformed newline-less file can't be slurped whole, + # but stay well above any real session:start line so a valid (long) first + # event is not truncated into invalid JSON and the session silently dropped. + obj = json.loads(fh.readline(1048576)) + return isinstance(obj, dict) and obj.get('workspace') == ws + except Exception: + return False if workspace: - _raw = [p for p in _raw if p.parents[3].name == workspace] + _raw = [p for p in _raw if _ws_match(p, workspace)] paths = [str(p) for p in _raw] candidates = [] total_scanned = len(paths) @@ -175,8 +190,23 @@ stages: _raw = sorted(root.glob('*/sessions/*/context-intelligence/events.jsonl')) workspace = '{{workspace}}' max_sessions = {{max_sessions}} + def _ws_match(p, ws): + # Directory-first (fast): slug == workspace. Fall back to the + # workspace FIELD in events.jsonl when workspace was set explicitly + # and differs from the project slug (matches the navigation skills). + if p.parents[3].name == ws: + return True + try: + with open(p) as fh: + # Bound the read so a malformed newline-less file can't be slurped whole, + # but stay well above any real session:start line so a valid (long) first + # event is not truncated into invalid JSON and the session silently dropped. + obj = json.loads(fh.readline(1048576)) + return isinstance(obj, dict) and obj.get('workspace') == ws + except Exception: + return False if workspace: - _raw = [p for p in _raw if p.parents[3].name == workspace] + _raw = [p for p in _raw if _ws_match(p, workspace)] paths = [str(p) for p in _raw] session_ids_str = '{{session_ids}}' try: diff --git a/skills/context-intelligence-session-navigation/SKILL.md b/skills/context-intelligence-session-navigation/SKILL.md index fa057dd6..0aa471ba 100644 --- a/skills/context-intelligence-session-navigation/SKILL.md +++ b/skills/context-intelligence-session-navigation/SKILL.md @@ -28,7 +28,7 @@ $CONTEXT_INTELLIGENCE_ROOT/{project-slug}/sessions/{session_id}/context-intellig └── metadata.json # session metadata, written on start, updated on end ``` -- `$CONTEXT_INTELLIGENCE_ROOT` β€” resolved from the idiom `"${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}"` (unset β†’ legacy default; configurable via `config.base_path`) +- `$CONTEXT_INTELLIGENCE_ROOT` β€” resolved from the idiom `"${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}"` (unset β†’ legacy default). **Relocation is reader-visible ONLY via this env var.** The hook's `config.base_path` moves where the *writer* stores captures, but readers (this skill, `discover.py`, the recipe) resolve the root solely from the env var β€” so always relocate via `AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH`, not `config.base_path` alone, or readers will look in the wrong place. - `{project-slug}` β€” derived from the full working directory path (see Project Slug Algorithm below) - `{session_id}` β€” unique session identifier (UUID or UUID with agent suffix for child sessions) - `context-intelligence/` β€” subdirectory containing the session data files @@ -46,13 +46,20 @@ $CONTEXT_INTELLIGENCE_ROOT/-home-user-myapp/sessions/55c8841a-1234-5678-9abc-def > `context-intelligence/` path segment and MUST NOT stop at `sessions//`: > > ``` -> CORRECT: "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json +> CORRECT: "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/events.jsonl > WRONG: "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/metadata.json # catches Amplifier core's files > ``` > > **Why:** Amplifier core writes `sessions//metadata.json` with NO `context-intelligence/` > segment. Globbing one level too shallow latches onto core's files and produces a confident > wrong count. +> +> **Canonical marker = `events.jsonl`.** The Python readers (`discover.py`, the workflow +> recipe) treat `context-intelligence/events.jsonl` as the single discriminator of a real +> capture. `metadata.json` is used here only to read fields (`workspace`, `status`, …); both +> files are written together, so either glob includes the `context-intelligence/` segment and +> avoids the false-positive. When you need a strict capture count that matches the code, +> glob `events.jsonl`, not `metadata.json`. > **⚠ FAIL-LOUD RULE:** When zero captures are found, say exactly `"looked in , found 0"` β€” > never report a confident count from a shallower glob, never silently fall back to a different path. @@ -200,12 +207,14 @@ grep -rl '"workspace":"{workspace}"' "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/c ```bash # Fast path: workspace matches directory name (default case) -for f in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/metadata.json; do +for ev in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/events.jsonl; do + f="${ev%/events.jsonl}/metadata.json" # canonical marker = events.jsonl; fields from sibling jq -r '[.session_id, .status, .started_at, .agent_name // "(root)"] | join("\t")' "$f" 2>/dev/null done | sort -t$'\t' -k3 # Scoped path: workspace set explicitly β€” scan all projects, filter by field -for f in "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json; do +for ev in "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/events.jsonl; do + f="${ev%/events.jsonl}/metadata.json" # canonical marker = events.jsonl; fields from sibling jq -r 'select(.workspace == "my-project") | [.session_id, .status, .started_at, .agent_name // "(root)"] | join("\t")' "$f" 2>/dev/null done | sort -t$'\t' -k3 ``` @@ -230,12 +239,14 @@ jq -r '.workspace' "$CONTEXT_INTELLIGENCE_ROOT"/-home-user-myapp/sessions/*/cont ```bash # Within a single project directory: -for f in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/metadata.json; do +for ev in "$CONTEXT_INTELLIGENCE_ROOT"/my-project/sessions/*/context-intelligence/events.jsonl; do + f="${ev%/events.jsonl}/metadata.json" # canonical marker = events.jsonl; fields from sibling jq -r 'select(.status == "running") | .session_id' "$f" 2>/dev/null done # Cross-project, scoped to workspace: -for f in "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/metadata.json; do +for ev in "$CONTEXT_INTELLIGENCE_ROOT"/*/sessions/*/context-intelligence/events.jsonl; do + f="${ev%/events.jsonl}/metadata.json" # canonical marker = events.jsonl; fields from sibling jq -r 'select(.workspace == "my-project" and .status == "running") | .session_id' "$f" 2>/dev/null done ``` diff --git a/skills/workflow-pattern-analysis/SKILL.md b/skills/workflow-pattern-analysis/SKILL.md index 95d3521e..d7ca08d7 100644 --- a/skills/workflow-pattern-analysis/SKILL.md +++ b/skills/workflow-pattern-analysis/SKILL.md @@ -130,9 +130,12 @@ Delegate to `context-intelligence:graph-analyst` to: ALL on-disk sessions regardless of graph indexing state. Disk scan entry: ```bash CONTEXT_INTELLIGENCE_ROOT="${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:-$HOME/.amplifier/projects}" - find "$CONTEXT_INTELLIGENCE_ROOT" -path "*/context-intelligence/metadata.json" 2>/dev/null + # Enumerate captures by the canonical marker (events.jsonl), matching the Python + # readers; read the sibling metadata.json for the format/version filter. + find "$CONTEXT_INTELLIGENCE_ROOT" -path "*/context-intelligence/events.jsonl" 2>/dev/null \ + | while read -r ev; do echo "${ev%/events.jsonl}/metadata.json"; done ``` - Filter to `format == "context-intelligence"` AND `version == "1.0.0"`. + Filter to `format == "context-intelligence"` AND `version == "1.0.0"` (from metadata.json). Follow `@context-intelligence:context/safe-extraction-patterns.md` β€” never load full `llm:request` lines. - Validate coverage: compare graph session count against disk count and inform the user diff --git a/tests/test_base_path_parity.py b/tests/test_base_path_parity.py new file mode 100644 index 00000000..d7c698fe --- /dev/null +++ b/tests/test_base_path_parity.py @@ -0,0 +1,106 @@ +# pyright: reportMissingImports=false +# (pytest is a test-only dep; the hook module is resolved at runtime via the +# sys.path insert below β€” neither is visible to the static type checker here.) +"""Parity + consistency-check tests for relocation base_path (Β§D.2 / Β§C.3). + +Two **duplicated-by-design** canonicalizers exist because the fold gate forbids the +hook's ``config_resolver`` from importing the reader package: + + - reader: ``context_intelligence.config.canonicalize_base_path`` + - writer: ``HookConfigResolver.base_path`` (byte-equivalent inline copy) + +These tests PIN ``writer ≑ reader`` so the hand-synced copies cannot drift silently, +and PIN the Β§C.3 divergence condition (``reader_writer_roots_disagree``) that the +hook's ``on_session_ready`` uses to decide whether to warn LOUD. Both were previously +only verified by hand; this freezes them in CI. +""" + +from __future__ import annotations + +import sys +from pathlib import Path + +import pytest + +# The writer-side canonicalizer lives in the hook module package, which is not on +# the default import path for the root test suite. Add it (the package __init__ is +# import-clean β€” handlers / amplifier_core are imported lazily inside functions). +REPO_ROOT = Path(__file__).parent.parent +HOOK_MODULE_DIR = REPO_ROOT / "modules" / "hook-context-intelligence" +if str(HOOK_MODULE_DIR) not in sys.path: + sys.path.insert(0, str(HOOK_MODULE_DIR)) + +from amplifier_module_hook_context_intelligence.config_resolver import ( # noqa: E402 + HookConfigResolver, +) + +from context_intelligence.config import ( # noqa: E402 + DEFAULT_BASE_PATH, + canonicalize_base_path, + reader_writer_roots_disagree, +) + + +def _writer_root(value: str) -> Path: + """Drive the REAL writer property with ``config['base_path'] = value``.""" + return HookConfigResolver(config={"base_path": value}, coordinator=None).base_path + + +# The input vector that was previously checked by hand β€” now pinned. +PARITY_INPUTS = [ + "${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:}", # unexpanded placeholder β†’ default + "/tmp/relocated", # absolute β†’ used as-is + "~/relocated", # tilde β†’ expanded + "relative/bad", # relative β†’ default + "", # empty β†’ default + " ", # whitespace β†’ default +] + + +class TestWriterReaderParity: + """writer ≑ reader for every input shape (the duplication's safety net).""" + + @pytest.mark.parametrize("value", PARITY_INPUTS) + def test_writer_equals_reader(self, value: str) -> None: + writer = _writer_root(value) + reader = canonicalize_base_path(value) + assert writer == reader, f"writer/reader drift on {value!r}: {writer} != {reader}" + + @pytest.mark.parametrize("value", PARITY_INPUTS) + def test_writer_always_absolute(self, value: str) -> None: + assert _writer_root(value).is_absolute() + + def test_unexpanded_placeholder_is_default_silently(self, caplog) -> None: + """A literal ``${...}`` (host did not expand) β†’ default, with NO noisy warning.""" + with caplog.at_level("WARNING"): + root = _writer_root("${AMPLIFIER_CONTEXT_INTELLIGENCE_BASE_PATH:}") + assert root == DEFAULT_BASE_PATH + assert not any("not absolute" in r.getMessage() for r in caplog.records) + + +class TestConsistencyDivergence: + """Pins the Β§C.3 condition consumed by on_session_ready.""" + + def test_agree_when_env_matches_writer(self) -> None: + disagree, reader, writer = reader_writer_roots_disagree( + "/tmp/relocated", Path("/tmp/relocated") + ) + assert disagree is False + assert reader == writer + + def test_agree_when_both_default(self) -> None: + # env unset (None) and writer at default β†’ consistent. + disagree, _reader, _writer = reader_writer_roots_disagree(None, DEFAULT_BASE_PATH) + assert disagree is False + + def test_disagree_when_writer_relocated_but_env_unset(self) -> None: + # The exact trap fix #1 exists to catch: relocation via config.base_path + # with the env var unset β€” env-only readers cannot see it. + disagree, reader, writer = reader_writer_roots_disagree(None, Path("/data/ci")) + assert disagree is True + assert reader == DEFAULT_BASE_PATH + assert writer == Path("/data/ci") + + def test_disagree_when_env_and_writer_differ(self) -> None: + disagree, _reader, _writer = reader_writer_roots_disagree("/a/one", Path("/b/two")) + assert disagree is True From e6b75c5045c3fc535fb17338658ffe48348d1f8b Mon Sep 17 00:00:00 2001 From: colombod Date: Wed, 1 Jul 2026 11:29:42 +0000 Subject: [PATCH 4/4] docs(context-intelligence): regenerate bundle.dot/png (clear stale source_hash) bundle.dot was stale after the base_path-relocation review + council changes. Regenerated with the structural bundle_repo_dot() generator (matching the committed convention, not LLM-enhanced) and re-rendered bundle.png; diff is the updated source_hash plus token-count deltas from the added doc/comment content. Clears the BUNDLE_DOT_STALE warning from the full validate-bundle-repo run. Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- bundle.dot | 8 ++++---- bundle.png | Bin 140748 -> 140455 bytes 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bundle.dot b/bundle.dot index 2fdb4366..b9ddc67d 100644 --- a/bundle.dot +++ b/bundle.dot @@ -8,7 +8,7 @@ digraph context_intelligence { nodesep=0.6 ranksep=0.7 bgcolor="white" - source_hash="ff1d6a9692415633ceafa3389694c17aa82f8f3d8296b1f7c440c9fb815ea5d2" + source_hash="18e3046d9999d7c21d8a948dbb2f0e83ae35c8b72a73e2e2793227571f9c088c" node [fontname="Helvetica", fontsize=11, style="filled,rounded"] edge [fontname="Helvetica", fontsize=9] @@ -23,8 +23,8 @@ digraph context_intelligence { beh_context_intelligence_analysis_behavior [label="context-intelligence-analysis-behavior\n1 tools\n~864 tok", shape=box, fillcolor="#e0f2f1", style="filled,rounded"] beh_context_intelligence_design_behavior [label="context-intelligence-design-behavior\n1 tools\n~331 tok", shape=box, fillcolor="#e0f2f1", style="filled,rounded"] - beh_context_intelligence_logging_behavior [label="context-intelligence-logging-behavior\n1 tools\n~1184 tok", shape=box, fillcolor="#e0f2f1", style="filled,rounded"] - beh_context_intelligence_navigation_behavior [label="context-intelligence-navigation-behavior\n2 tools\n~561 tok", shape=box, fillcolor="#e0f2f1", style="filled,rounded"] + beh_context_intelligence_logging_behavior [label="context-intelligence-logging-behavior\n1 tools\n~1661 tok", shape=box, fillcolor="#e0f2f1", style="filled,rounded"] + beh_context_intelligence_navigation_behavior [label="context-intelligence-navigation-behavior\n2 tools\n~617 tok", shape=box, fillcolor="#e0f2f1", style="filled,rounded"] beh_context_intelligence_behavior [label="context-intelligence-behavior\n~236 tok", shape=box, fillcolor="#e0f2f1", style="filled,rounded"] } @@ -37,7 +37,7 @@ digraph context_intelligence { agt_context_intelligence_design_facilitator [label="context-intelligence-design-facilitator\n~187 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] agt_context_intelligence_tool_designer [label="context-intelligence-tool-designer\n~198 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] agt_graph_analyst [label="graph-analyst\n~543 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] - agt_session_navigator [label="session-navigator\n~366 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] + agt_session_navigator [label="session-navigator\n~422 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] } subgraph cluster_modules { diff --git a/bundle.png b/bundle.png index 9723a87d6714b05794f5ff91fb0d6e80d8f4ed6a..64b0a5aaae90d02aaaca4012d580e057518e6170 100644 GIT binary patch delta 88825 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

h8{Ek|Pur-u3VZ*hOgZ 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 I@#5|O1H0R%Y5)KL delta 89109 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