Skip to content

refactor(filesystem): simplify PIFS core surface#47

Merged
BukeLy merged 14 commits into
feat/pageindex-filesystemfrom
refactor/pifs-core-simplification
Jul 14, 2026
Merged

refactor(filesystem): simplify PIFS core surface#47
BukeLy merged 14 commits into
feat/pageindex-filesystemfrom
refactor/pifs-core-simplification

Conversation

@BukeLy

@BukeLy BukeLy commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Summary

Implements the locally approved PR VectifyAI#302 PIFS simplification contract. PIFS now has one public Python entry point, five agent commands, one summary projection, exact schema-v2 validation, and fail-closed workspace opening and migration behavior.

Goal

Keep the essential PIFS document workflow while removing pre-release compatibility surface and making the catalog, Summary Projection, and embedding cache safe to reopen and migrate as one workspace.

What Changed

  • Exposes only pageindex.PageIndexFileSystem as the supported Python entry point.
  • Retains only tree, browse, stat, cat, and grep in the shell executor.
  • Keeps browse query-required, summary-only, scope-aware, recursively flattenable, and paginated in fixed pages of ten.
  • Restores the retained canonical metadata scope grammar as alternating @field/value segments, including three-layer tree navigation, trailing-slash normalization, fixed 50-value pages, encoded slash/dot-only values, and actionable multi-axis locators; the pre-release @field=value form is rejected.
  • Uses canonical command identities and actionable locators without leaking persistence identifiers.
  • Makes setmeta derive its returned locator from the updated document rather than echoing the input target. File-ref targets and stale metadata-scope targets therefore return a fresh actionable physical path.
  • Uses the same collision-aware scoped locator mapping for tree and physical browse, preserving every ranked hit when multiple files share one membership display_name.
  • Keeps the catalog authoritative with exactly five schema-v2 tables; summary has three logical tables and the cache has one.
  • Validates exact v2 columns, PK/UNIQUE/FK constraints, required indexes, config keys, sqlite-vec declaration/dimension, canonical embedding identities, and vector blobs.
  • Preflights projection topology before any catalog or artifact creation.
  • Defines projection path presence once as path.exists() or path.is_symlink(); broken summary/cache symlinks therefore fail closed instead of being treated as an absent projection.
  • Requires the canonical root row folder_root / / in every existing catalog.
  • When a complete projection exists, requires exact bidirectional equality between active catalog refs (deleted_at IS NULL) and projected document refs; missing and orphan refs both fail closed.
  • Treats only a completely absent filesystem.sqlite as fresh. Existing zero-byte, non-SQLite, directory, legacy, pseudo-v2, or inconsistent catalog paths fail closed without mutation.
  • Keeps fresh/empty and deleted-only catalog listing available without importing sqlite-vec; an active catalog without a complete projection pair fails closed.
  • Makes Python register_file() / register_files() synchronously create or open the Summary Projection and persist ready. Failed registration restores all new-batch state and exact pre-call state for updated existing records across catalog rows/memberships/metadata, summary/vector rows, cache keys, owned text/raw artifacts, and PageIndex doc/meta artifacts; preparation itself is inside the same rollback boundary.
  • Preflights copies of every batch metadata payload for JSON serializability before PageIndex or artifact preparation, so a later invalid record triggers no earlier network work and generated summaries do not mutate caller-owned dictionaries.
  • Captures the exact default text/raw artifact baselines for each registration file_ref before preparation, including explicit raw paths that resolve to the canonical managed target; custom raw paths remain caller-owned and untouched.
  • Cleans partial fresh projection databases if projection schema creation aborts, so failed registration leaves a strictly reopenable workspace.
  • Consolidates summary population and retrieval in one SummaryProjection lifecycle.
  • Uses one OpenAI-compatible embedding identity: normalized base URL, trimmed model, and dimensions; credentials, timeout, and provider are not persisted in workspace data or identity.
  • Resolves the embedding API key as PIFS_EMBEDDING_API_KEY > user PIFS config embedding_api_key > OPENAI_API_KEY; pifs set workspace preserves the config key while command output and SQLite remain secret-free.
  • Makes PDF/Markdown add synchronous and atomic across owned artifacts, PageIndex output, catalog rows, summary rows, vectors, and newly introduced embedding-cache keys; reused cache rows survive rollback.
  • Keeps the real migration command and subprocess tests only in pifs-data/scripts.
  • The companion migration canonically rebuilds v2, validates actual vector dimensions and doc/vector row parity, rejects unknown legacy providers, losslessly preserves representable legacy metadata field/value rows without duplicating metadata JSON values, and applies the same strict checks during staging, post-replacement reopen, and already_migrated.
  • Migration failures after backup preserve all three original database hashes and clean staging/rollback files.

Command Surface

  • pifs add <source> <folder>: atomically import PDF or Markdown.
  • pifs tree <scope> [-L depth] [--page N]: inspect workspace structure.
  • pifs browse <scope> "<query>" [--page N] [--where JSON] [-R]: rank files by summary inside a scope.
  • pifs stat <file>: inspect one document.
  • pifs cat <file> --structure: inspect PageIndex structure.
  • pifs cat <file> --page N[-M]: read a bounded page range.
  • pifs grep <query> <file>: search evidence in one resolved document.
  • pifs ask / pifs chat: run the agent against the configured workspace.
  • pifs setmeta [--clear] <file> [JSON]: replace custom metadata and return the updated actionable locator.
  • pifs set ...: persist workspace and embedding connection settings; an optional config API key is preserved but never emitted or written into workspace databases.

Key Files

  • pageindex/filesystem/cli.py: add/setmeta/config/agent orchestration and command-facing output.
  • pageindex/filesystem/core.py: workspace lifecycle, registration artifact cleanup, post-update locators, scoped collision mapping, and summary-backed browse.
  • pageindex/filesystem/_projection_topology.py: shared path-presence semantics and lightweight summary/cache pair detection.
  • pageindex/filesystem/_workspace_consistency.py: read-only canonical-root and active projection-reference validation.
  • pageindex/filesystem/store.py: exact catalog v2 validation and absent-only fresh initialization.
  • pageindex/filesystem/semantic_projection.py: unified projection lifecycle, cache validation, topology ownership, and precise cache-key rollback.
  • pageindex/filesystem/semantic_index.py: exact summary/config/vec0 validation and retrieval.
  • pageindex/filesystem/_embedding_identity.py: canonical persisted identity rules.
  • pageindex/filesystem/_sqlite_schema.py: shared exact SQLite signatures.
  • pageindex/filesystem/commands.py: five-command contract and boundary identity mapping.
  • tests/test_pifs_simplification_acceptance.py: real temporary-workspace acceptance, actionable-locator, collision, logical-baseline rollback, and no-mutation coverage.
  • examples/pifs_demo.py: minimal supported walkthrough.

Verification

  • Locator-review setmeta red: file-ref setmeta produced 1 failed because the successful command returned path=null.
  • Locator-review browse red: tree returned two same.md~1/~2 files while physical browse returned zero documents (1 failed).
  • Locator-review green: file-ref setmeta, metadata-scope replace/clear, physical collision browse, canonical browse, and 12-result ranking/two-page pagination controls produced 8 passed.
  • Fourth-review broken-symlink red/green: focused real-workspace cases moved from 2 failed, 1 passed to 4 passed, including the truly absent catalog-only control.
  • Third-review workspace/migration fail-first coverage closes zero-byte, root/reference, actual-vector, pseudo-v2, provider, and rollback/hash-preservation gaps.
  • Registration-projection red: fresh registration created no projection, reopen stayed pending_index, and a second-record embedding failure returned success — 3 failed.
  • Projection-create red: a real SQLite path-limit failure left summary.sqlite without its cache — 1 failed.
  • Registration-projection green: fresh/reopen browse, existing-pair upsert, second-record batch rollback, partial-create cleanup/reopen, and both add atomic controls — 6 passed.
  • Registration-baseline red: fresh failure retained new folders, the year field, and one cache row; the preexisting-state control retained new batch-only catalog state — 2 failed.
  • Registration-baseline green: fresh and preexisting-state snapshots restore catalog folders/fields/values/files, summary docs/vec, cache keys, and owned artifacts exactly — 2 passed.
  • PageIndex-artifact red: second projection failure retained two PageIndex doc JSON files/meta keys; the old fake overwrote preexisting meta; second prepare-stage failure retained PageIndex docs and the first text artifact — 3 failed across the three fail-first slices.
  • PageIndex-artifact green: canonical meta/doc hashes return to baseline, unrelated preexisting structure remains available after strict reopen, and prepare-stage partial writes are removed — focused registration/add controls 8 passed.
  • Metadata-serialization red: invalid single and second-record metadata each left one owned text artifact — 2 failed, 75 deselected.
  • Metadata-serialization green: validation runs before PageIndex; both the single case and a batch whose second record is invalid make zero PageIndex calls, restore the complete logical baseline, and leave caller metadata unchanged.
  • Existing-artifact prepare red: an existing file_ref followed by an unresolvable record removed both preexisting owned text/raw artifacts — 1 failed.
  • Existing-artifact prepare green: exact catalog/projection/cache/PageIndex/text/raw baseline is restored; strict reopen plus stat, cat, grep, and PageIndex structure remain available; combined rollback controls — 11 passed, 67 deselected.
  • Independent P1/P2 TDD audit — 100/100 PASS, including forced partial-write restoration.
  • Fifth-review raw-policy red: an explicit canonical raw path sentinel was overwritten while the custom-path control remained intact — 1 failed, 1 passed.
  • Fifth-review raw-policy green: canonical and custom controls plus batch metadata preflight — 3 passed, 77 deselected; combined registration/add rollback controls — 13 passed, 67 deselected.
  • Fifth-review independent audit — 100/100 PASS, including a canonical-equivalent alias-path restoration probe.
  • Bidirectional-consistency runtime red: active catalog refs missing from a complete projection and active catalog-only workspaces were accepted — 2 failed, 4 passed, 80 deselected.
  • Bidirectional-consistency runtime green: matching, missing, deleted, orphan, catalog-only, and no-sqlite-vec controls — 7 passed, 80 deselected.
  • Companion migration red: staged legacy and pseudo-v2/already-migrated missing-summary cases both returned success — 2 failed, 23 deselected.
  • Companion migration green: both failure contracts plus strict happy reopen/tree/browse control — 3 passed, 22 deselected.
  • Final bidirectional-consistency independent audit — 100/100 PASS; focused PageIndex 10 passed, migration full 25 passed.
  • Sixth-round API-key red: config-only keys were ignored, config lost to pifs set workspace, and precedence was wrong — 3 failed, 3 passed; green precedence/config-preservation/secret-absence gate — 7 passed.
  • Restored Metadata Axis red against reviewed head: tree emitted /documents/@year=2024 instead of /documents/@year/2024; three-layer CLI/trailing-slash/50-value pagination and actionable locator gate — 8 passed.
  • Existing-record registration rollback red: later batch failure changed catalog metadata/summary/cache and left a replacement PageIndex pointer; green independent repro plus 17 registration/add rollback controls restore the exact logical baseline.
  • Runtime docs/vec red: missing, extra, source-type-mismatched, and malformed vector rows reopened; green runtime gate — 4 passed, with migration parity — 4 passed.
  • Failed-add cache red: a post-cache vector failure left one new cache row while the reused-key control passed; green fresh/reused controls — 2 passed.
  • Legacy metadata migration red: category=finance was silently dropped and an invalid legacy field migrated successfully — 2 failed; green preservation/fail-closed/already-migrated controls are included in the 32-test migration suite.
  • Dot-only metadata red: tree emitted /documents/@tag/. and /documents/@tag/..; green %2E/%2E%2E tree/browse/stat round trip — 1 passed; independent re-review 100/100 PASS.
  • env PYTHONPATH=. .../pytest -q — 172 passed.
  • Companion real SQLite/sqlite-vec subprocess suite — 32 passed.
  • python -m compileall -q pageindex tests.
  • Companion migration files updated locally: migration fb3f5edb9f0342d470e65924ede305e7aac330a534a1bdd01097aadb9abea577 (1341 lines), tests 1e02132b6f4aa5c3637a4a40fc7c47eeeb048d448c40df1b1adc7687cb2e114f (921 lines).
  • git diff --check and staged diff check.
  • Runtime rejection tests compare the complete workspace file set and hashes before/after.
  • Happy migration output reopens through the current strict PageIndexFileSystem, then succeeds through tree and cached browse.
  • All migration runs used temporary fixtures; no real workspace was touched.

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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

stable_path = self._stable_file_locator(
file_ref,
entry,
folder_path=folder_path,
)

P2 Badge Preserve browse hits for duplicate display names

When browsing a physical folder, this branch builds a plain /folder/display_name locator and then drops the candidate if that locator is ambiguous. If two files in the same folder have different titles but the same file_folders.metadata_json.display_name, tree already exposes /folder/name~1 and /folder/name~2, but browse /folder "..." catches the RuntimeError from _stable_file_locator and returns no documents for those hits. Use the scoped locator path here, as metadata scopes do, so summary results remain selectable.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

BukeLy added 2 commits July 14, 2026 15:31
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.
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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 121bef95e2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pageindex/filesystem/cli.py Outdated
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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 120b1ea5f7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pageindex/filesystem/cli.py Outdated
BukeLy added 2 commits July 14, 2026 16:39
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
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
@BukeLy

BukeLy commented Jul 14, 2026

Copy link
Copy Markdown
Owner Author

Also addressed the earlier review-summary feedback about duplicate physical display_name values in 81ee9ba: browse now reuses the same collision-aware scoped locator mapping as tree, preserving both ~1/~2 hits as actionable paths. Acceptance coverage verifies both browse results match tree locators and each succeeds with stat. Independent verification: focused locator suite 8 passed, full PageIndex suite 140 passed, companion migration suite 23 passed.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 81ee9baebf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pageindex/filesystem/core.py Outdated
BukeLy added 2 commits July 14, 2026 17:36
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.
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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eea969c1bb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pageindex/filesystem/core.py Outdated
Comment thread pageindex/filesystem/core.py Outdated
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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 867fd8f778

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pageindex/filesystem/core.py Outdated
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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 89c62087f2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pageindex/filesystem/_workspace_consistency.py
BukeLy added 2 commits July 14, 2026 18:52
Validate every batch metadata payload before PageIndex work begins. Reuse one canonical raw-artifact policy for both success-path writes and rollback baseline capture.
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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4a784f7bd8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pageindex/filesystem/_workspace_consistency.py
Comment thread pageindex/filesystem/cli.py Outdated
Comment thread pageindex/filesystem/commands.py Outdated
BukeLy added 2 commits July 14, 2026 19:48
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
Percent-encode dot-only metadata values so tree locators survive path normalization and remain actionable through tree, browse, and stat.

Refs #47
@BukeLy
BukeLy merged commit f4fb9d7 into feat/pageindex-filesystem Jul 14, 2026
@BukeLy
BukeLy deleted the refactor/pifs-core-simplification branch July 14, 2026 12:12
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.

1 participant