feat: client-agnostic backend — workspace-relative source_uri (client + infra)#189
Open
feat: client-agnostic backend — workspace-relative source_uri (client + infra)#189
Conversation
NEEDS HEAVY REVIEW: "needs heavy review as didnt verify this change for
additional bug for all of this, this could be completely wrong"
Client half of the client/backend separation. The backend no longer needs
host filesystem access; this side makes the client emit workspace-relative
paths as the canonical source_uri so no absolute host paths ever leave the
client process.
Client:
- core-ingestion/src/types.ts, ix-cli/src/client/types.ts:
PatchSource gains an optional workspaceId field. Documented that source.uri
is now a workspace-relative POSIX path, not an absolute host path.
- ix-cli/src/cli/commands/ingest.ts:
Compute workspaceRoot + workspaceId (SHA-256 of workspaceRoot abs path)
once per run. Convert absolute paths to workspace-relative before
dispatching to parseFile, buildGlobalResolutionIndex, and the parse pool,
so every deterministic node/patch/edge/chunk ID hashes relative paths.
Keep absolute paths only for local fs reads. Tag every built patch's
source with workspaceId. loadExistingHashes now queries the backend with
relative paths and maps the response back onto absolute keys.
On ingest startup, compare backend /v1/health schema_version against
CLIENT_EXPECTED_SCHEMA_VERSION=2 and force full re-ingest on mismatch
(node IDs change when the graph format flips from absolute to relative).
- ix-cli/src/cli/config.ts:
New absoluteFromSourceUri helper — joins a workspace-relative source_uri
against the active workspace root so commands that need to open files off
disk (ix read) can still do so.
- ix-cli/src/cli/format.ts:
relativePath now treats already-relative input as a no-op.
- ix-cli/src/cli/commands/read.ts:
Resolves sourceUri via absoluteFromSourceUri before any fs.* call so the
graph's workspace-relative paths still map to real files.
Infra:
- docker-compose.standalone.yml:
Removed the HOME bind mount (source: ${IX_HOST_MOUNT_ROOT:-$HOME},
target: $HOME, read_only: true) from the memory-layer service. The backend
is now client-agnostic and never reads host files. Closes the privacy hole
where the entire user HOME directory was bind-mounted into the backend
container.
- scripts/backend.sh, scripts/dev/shutdown.sh, scripts/install/install.sh:
Removed the IX_HOST_MOUNT_ROOT / IX_CONTAINER_MOUNT_ROOT exports that fed
that bind mount. dc() helpers remain so Windows/MINGW compose dispatch
still works.
Requires the matching ix-memory-layer change (StalenessDetector rewrite +
schema_version bump) on feat/client-agnostic-backend.
Every modified file carries a "NEEDS HEAVY REVIEW" banner. This change has
NOT been verified end-to-end and may be completely wrong — reviewers should
treat every line as suspect until validated against a real ingest + ix read
round-trip with the client-agnostic backend image.
This was referenced Apr 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Client + infra half of the client/backend separation. Removes the HOME bind mount entirely and switches the client to emit workspace-relative paths as the canonical
source_uriso no absolute host paths ever cross the wire.What changed
Client (ingestion pipeline)
core-ingestion/src/types.ts,ix-cli/src/client/types.ts—PatchSourcegainsworkspaceId?: string;source.uriis now documented as a workspace-relative POSIX path.HealthResponsegainsschema_version?: number.ix-cli/src/cli/commands/ingest.ts:workspaceRoot+workspaceId(SHA-256 of workspaceRoot abs path) once per run.parseFile,buildGlobalResolutionIndex, and the parse pool, so every deterministic node/patch/edge/chunk ID hashes relative paths.sourcewithworkspaceId.loadExistingHashesnow queries the backend with relative paths and maps the response back onto absolute keys./v1/healthschema_versionagainstCLIENT_EXPECTED_SCHEMA_VERSION = 2and forces a clean re-ingest on mismatch (node IDs change when the graph format flips from absolute to relative).ix-cli/src/cli/config.ts— newabsoluteFromSourceUrihelper that joins a workspace-relativesource_uriagainst the active workspace root for commands that still need to open files off disk.ix-cli/src/cli/format.ts—relativePathis a no-op for already-relative input.ix-cli/src/cli/commands/read.ts— resolvessourceUriviaabsoluteFromSourceUribefore anyfs.*call so the graph's relative paths still map to real files.Infra
docker-compose.standalone.yml— removed the HOME bind mount from thememory-layerservice. Closes the privacy hole where the entire user HOME directory was bind-mounted (read-only) into the backend container.scripts/backend.sh,scripts/dev/shutdown.sh,scripts/install/install.sh— removedIX_HOST_MOUNT_ROOT/IX_CONTAINER_MOUNT_ROOTexports.dc()wrappers preserved for Windows/MINGW compose dispatch.Must land with
ix-infrastructure/ix-memory-layerPR onfeat/client-agnostic-backend→dev:StalenessDetectorto pure graph comparison (nojava.nio.file)./v1/healthschema_versionto 2.RoutesSpec/StalenessDetectorSpecaccordingly.Test plan
ix map --forceagainst a backend built from the paired backend branch. Confirm every patch'ssource.uriis workspace-relative andsource.workspaceIdis populated.ix read <symbol>andix read <file>— confirm files still resolve viaabsoluteFromSourceUri.docker compose -f docker-compose.standalone.yml upstarts cleanly with no HOME bind mount and memory-layer still serves/v1/health.opts.force.ix impact,ix overview,ix search).