Skip to content

feat(filesystem): add PageIndex FileSystem and PIFS CLI#302

Open
BukeLy wants to merge 100 commits into
VectifyAI:mainfrom
BukeLy:feat/pageindex-filesystem
Open

feat(filesystem): add PageIndex FileSystem and PIFS CLI#302
BukeLy wants to merge 100 commits into
VectifyAI:mainfrom
BukeLy:feat/pageindex-filesystem

Conversation

@BukeLy

@BukeLy BukeLy commented May 26, 2026

Copy link
Copy Markdown
Member

Summary

This PR adds PageIndex FileSystem (PIFS): a filesystem-like interaction system for agents working inside a PageIndex workspace, plus a pifs CLI and an ask / chat loop built on the same command surface.

The core purpose is to help an agent quickly locate the right file in a workspace, then combine that filesystem context with PageIndex structure, metadata, and projection indexes to retrieve precise file evidence.

Goal

PIFS gives agents a stable filesystem-like interface to PageIndex workspaces:

  • inspect workspace shape with familiar folder commands;
  • locate relevant files inside an explicit path scope;
  • use PageIndex-backed structure, metadata, and semantic projections for precise evidence retrieval;
  • keep reads bounded, auditable, and tied to concrete virtual file paths.

browse is part of the file-location step. It ranks file candidates within a folder scope when folder names and exact filters are not enough. Evidence still comes from bounded cat, grep, and PageIndex structural reads.

What Changed

  • Added the PIFS core model: virtual folders, registered files, metadata status, PageIndex/projection status, path resolution, and SQLite persistence.
  • Added pifs, a shell-style CLI for workspace navigation, file discovery, metadata filtering, source reads, imports, and agent execution.
  • Added PageIndex-backed registration for PDF, Markdown, and text files, including structural reads, generated metadata, and summary projection indexing.
  • Added pifs add for atomic local imports into workspace-owned artifacts.
  • Added pifs ask and pifs chat, where the agent uses the same read-only filesystem commands available to users.
  • Added PIFS Semantic Folder as an explicit build step for flat or weakly organized corpora: pifs semantic-folder build [source_scope] materializes a generated <source_scope>/semantic tree from canonicalized domain / topic metadata.
  • Added command guardrails for bounded reads, lexical grep -R, path ambiguity, projection dimension mismatches, atomic import cleanup, and semantic-folder rebuild safety.
  • Expanded regression coverage across storage, command parsing/rendering, registration, add rollback, browse behavior, structural reads, metadata generation, semantic indexes, and semantic-folder materialization.

Command Surface

  • Global flags: --workspace, --env-file, --json
  • Workspace defaults: pifs set workspace <path>
  • Navigation and inspection: pifs ls, pifs tree, pifs find, pifs stat
  • File discovery: pifs browse [-R] <folder> "<query>" [--space summary|entity|relation] [--where JSON] [--page N]
  • Evidence reads: pifs cat <path> --structure|--page|--range|--all, pifs grep [-R] <pattern> <path>
  • Imports and generated views: pifs add <physical_path> <virtual_path>, pifs semantic-folder build [source_scope]
  • Agent loop: pifs ask "<question>", pifs chat

The agent command surface intentionally exposes only read/navigation commands: ls, tree, find, browse, grep, cat, and stat. It can use an existing semantic folder like any other tree, but it cannot build one.

Key Files

  • pageindex/filesystem/core.py: high-level PIFS API, registration flow, metadata generation, projection wiring, semantic-folder build orchestration, and browse behavior.
  • pageindex/filesystem/store.py: SQLite workspace catalog for folders, files, metadata, generated memberships, and PageIndex/projection state.
  • pageindex/filesystem/commands.py: command parser, executor, shell rendering, capabilities, and guardrail messages.
  • pageindex/filesystem/agent.py: ask / chat policy and streaming loop over the PIFS command surface.
  • pageindex/filesystem/semantic_folder.py: Semantic Folder planner contract, OpenAI planner, plan schema, and validation rules.
  • pageindex/filesystem/semantic_projection.py and semantic_index.py: summary projection indexing and vector search adapter used by browse.
  • pageindex/filesystem/metadata.py and metadata_generation.py: metadata schema, policy, status, and generated metadata helpers.
  • pageindex/filesystem/cli.py and pifs: CLI entrypoints.
  • examples/pifs_demo.py: local end-to-end demo over example documents.

Verification

  • uv run pytest tests/test_filesystem_store.py tests/test_import_surface.py tests/test_metadata_generation.py tests/test_pageindex_filesystem_scope.py tests/test_pageindex_structural_read.py tests/test_pifs_add_command.py tests/test_pifs_agent_stream.py tests/test_pifs_cli.py tests/test_pifs_find_maxdepth.py tests/test_pifs_like_escape.py tests/test_pifs_path_resolution.py tests/test_pifs_register_side_effects.py tests/test_pifs_semantic_folder.py tests/test_semantic_index.py
  • Manual PIFS CLI/chat demo coverage on the example workspace during development.
  • Manual Semantic Folder smoke on SEC filings: /SEC_Filings_LTM/semantic built as topic/domain with 82 files, 82 memberships, and 0 skipped files.
  • Manual Semantic Folder smoke on 33capital: /33capital/semantic built as topic/domain with 18 files, 18 memberships, and 0 skipped files.

@BukeLy BukeLy force-pushed the feat/pageindex-filesystem branch from 274af6c to d7d3cb8 Compare May 26, 2026 18:08
BukeLy added 29 commits May 27, 2026 02:12
Remove the synchronous=OFF pragma from PIFS catalog inserts so SQLite remains the durable source of truth.
Route default semantic search to the summary projection when summary is the only populated semantic channel.
Only use the fresh event loop fallback for missing running-loop detection, so RuntimeError from a threaded agent run is not retried.
BukeLy added 7 commits May 31, 2026 23:57
Return nested PageIndex structure JSON from cat --structure and keep content reads page-based only. Remove the cat --node command surface, related limits, prompts, and structure-text fallback.
* feat(filesystem): add pifs semantic folder build

* fix(filesystem): preserve semantic folder command paths

* fix(filesystem): retry semantic folder planning

* fix(filesystem): balance semantic folder planner guidance

@KylinMountain KylinMountain left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Automated deep-review summary (recall-oriented)

Machine-assisted review (multi-agent finder + adversarial verification passes) of the PIFS change, optimized for recall of real defects. Each inline finding was independently verified against the PR-head code. Severity tags: High = breaks normal usage / crashes / silent wrong results; Med = real bug with a narrower trigger.

Positioning question first (see the requirements.txt comment)

PIFS introduces sqlite-vec + an OpenAI embedding pipeline, and pifs browse performs vector similarity search, which sits in tension with the README's "Vectorless / No Vector DB" positioning (L14 / L16 / L65 / L67). Flagging for an explicit product + docs decision, not as a code bug.

Highest-impact correctness issues (inlined below)

  • Malformed command (find /docs --where) → uncaught IndexError crashes the agent turn / CLI.
  • Read-only commands (ls/cat/find...) require an embedding key once content is indexed.
  • Stopword-only query (--name "the") silently returns [].
  • One ambiguous title aborts the whole browse.
  • Metadata filters: numeric $eq int/float mismatch, $gt/$lt excludes text-stored numerics, large-int float precision loss — three distinct holes in the same area.

Investigated but NOT flagged (verified safe)

SQLiteSession thread / shared-history concerns (SDK uses check_same_thread=False + per-instance in-memory DB); decode_vector dimension (index-level search/upsert already validate); __init__.py only swallows ModuleNotFoundError for the 4 optional deps with a re-raise guard; add_file readiness guards not reused on register (intentional deferred-metadata design); the folder-vs-file depth -1 asymmetry (actually correct — a file is one tree level below its folder).

Lower-severity (not inlined, for completeness)

cat --range past EOF → nonsensical start>end empty result; the pagination "next" command can point past document EOF; SQLiteVecSemanticIndex.reset() uses auto-committing executescript with no rollback (recoverable — rebuildable index); with self.connect() commits but never closes the connection (bounded by CPython GC); entity/relation channels are declared & plumbed but never populated (dormant — hidden from capabilities & rejected up front, only over-advertised in static help). The default-model change to gpt-5.4 looks intentional (retrieve_model was already gpt-5.4).

There are also several cleanup/DRY opportunities (OpenAI-client construction duplicated 3x; normalize_path / JSON-coercion / textwrap.shorten reimplemented; MetadataGenerator lazy-init copy-pasted 3x; per-file LLM/embedding calls that could batch) — happy to file separately if useful.

Generated with assistance; treat as input, not gospel — verify before acting.

Comment thread pageindex/filesystem/commands.py Outdated
Comment thread pageindex/filesystem/cli.py Outdated
Comment thread pageindex/filesystem/store.py Outdated
Comment thread pageindex/filesystem/core.py Outdated
Comment thread pageindex/filesystem/store.py
Comment thread pageindex/filesystem/store.py Outdated
Comment thread pageindex/filesystem/semantic_projection.py Outdated
Comment thread pageindex/filesystem/store.py
Comment thread pageindex/filesystem/semantic_projection.py
Comment thread requirements.txt
BukeLy added 6 commits June 2, 2026 12:57
* cleanup(pifs): align bashlike command surface

* fix(pifs): finish core alignment cleanup

* chore(pifs): keep alignment docs local

* cleanup(pifs): simplify summary projection surface

* chore(pifs): keep local uv files out of repo

* fix(pifs): return cli error status for failed commands
* refactor(pifs): simplify metadata handling

* fix(pifs): keep summary out of metadata search
* feat(filesystem): add metadata scope paths

Add one shared PIFS query-scope resolver for physical folders plus @field/value metadata suffixes. Wire tree, browse, and stat through it with metadata axis discovery, value pagination, semantic scope errors, and agent guidance updates.

* fix(filesystem): preserve scoped child paths

Keep metadata-filtered tree child paths copyable by reattaching the active metadata suffix to emitted folder nodes, and resolve query scope before folder validation in browse_semantic_files.

* fix(filesystem): recurse metadata scope in core browse

Make browse_semantic_files treat metadata-scoped paths as recursive even when recursive=False, matching the command wrapper, and cover the descendant case in the direct core test.

* fix(filesystem): prefer in-scope browse membership

Make browse_semantic_files choose the physical membership under query_scope.folder_path for metadata-scoped direct calls, and cover the dual-membership regression in the scope-path tests.
@BukeLy BukeLy force-pushed the feat/pageindex-filesystem branch from 027382c to 9a57804 Compare June 28, 2026 06:19
BukeLy added 8 commits June 28, 2026 14:21
Read PIFS embedding model, dimensions, provider, and timeout from the persisted PIFS config when constructing CLI workspaces. Also print ask final output when streaming tool events.
* fix(pifs): load embedding runtime config

Read embedding base URL and API key from PIFS config and pass them directly through the filesystem to the embedding client, avoiding PIFS_* shell exports or env bridging.

* fix(pifs): require direct embedding config

* fix(pifs): keep config file override
BukeLy added 3 commits July 4, 2026 22:54
* fix(filesystem): round-trip scope-qualified file locators

* chore(filesystem): keep local docs out of PR

* fix(filesystem): stabilize scoped file locator lookup

* fix(filesystem): encode scoped file locator leaves

* fix(filesystem): avoid scoped locator suffix collisions
* refactor(filesystem): simplify PIFS core surface

Align the CLI, public Python API, SQLite schemas, and summary projection with the locally approved PR VectifyAI#302 simplification spec. Add fail-first behavior coverage and real migration compatibility fixtures.

* fix(filesystem): enforce exact PIFS schema validation

Fail closed on pseudo-v2 catalog and projection databases, validate projection topology before any workspace mutation, and keep migration subprocess coverage outside the PageIndex test suite.

* fix(filesystem): close PIFS migration validation gaps

Require an exact catalog whenever projection databases exist, validate canonical vec0 and persisted embedding identities, and align the external migration's staged and idempotent checks with the runtime schema contract.

* fix(filesystem): validate workspace consistency

Fail closed before mutating an existing catalog and reject projection rows that do not reference active catalog files. Validate the canonical root and cross-database references at workspace open.

Refs #47

* fix(filesystem): reject broken projection symlinks

Treat existing symlink entries as projection paths even when their targets are missing. Share the same presence rule between core preflight and topology validation so damaged projections fail closed without workspace mutation.

Refs #47

* fix(filesystem): preserve actionable file locators

Derive setmeta output from the updated document instead of echoing its input target. Reuse the tree scope collision mapping for physical browse and stable locators so duplicate display names remain ranked and resolvable.

Refs #47

* fix(filesystem): complete projections for registrations

Open or create the Summary Projection for Python registrations, require ready status before returning, and roll back fresh batches when projection completion fails. Clean partial fresh projection databases when schema creation aborts.

* fix(filesystem): restore registration rollback baseline

Track only folders, metadata fields, and embedding cache keys introduced by a failed registration batch, then remove them without disturbing preexisting workspace state. Generalize Summary Projection lifecycle readiness messages for add and registration.

* fix(filesystem): restore PageIndex registration artifacts

Capture PageIndex document IDs before registration preparation and remove only IDs introduced by a failed batch. Prepare records inside the rollback boundary so PageIndex after-write failures also restore the logical workspace baseline.

* fix(filesystem): preserve registration rollback state

Validate copied caller metadata before PageIndex and artifact preparation. Capture exact registration-owned artifact baselines so prepare-stage failures restore existing bytes and remove only newly created paths.

* fix(filesystem): preflight registration mutations

Validate every batch metadata payload before PageIndex work begins. Reuse one canonical raw-artifact policy for both success-path writes and rollback baseline capture.

* fix(filesystem): require complete workspace projection

Validate active catalog and Summary Projection references in both directions. Existing catalogs with active files now fail closed when the projection pair is absent, while fresh and deleted-only catalog listing remains lazy.

* fix(filesystem): close PIFS consistency gaps

Restore the canonical metadata-axis paths, load embedding credentials from the configured precedence, and validate projection rows on open. Make add and registration failures restore catalog, projection, cache, PageIndex, and owned artifact state exactly, including updates to existing records.

Refs #47

* fix(filesystem): encode metadata dot segments

Percent-encode dot-only metadata values so tree locators survive path normalization and remain actionable through tree, browse, and stat.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants