Skip to content

Feat: add qw warpspace locate - #27

Merged
flyingrobots merged 6 commits into
mainfrom
feature/qw-warpspace-locate
Jun 15, 2026
Merged

Feat: add qw warpspace locate#27
flyingrobots merged 6 commits into
mainfrom
feature/qw-warpspace-locate

Conversation

@flyingrobots

Copy link
Copy Markdown
Owner

Summary

  • add the first TACHYON resolver module for WARPspace path location
  • add qw warpspace locate with --lock, --root, --cwd, --basis, and --json
  • return typed warp.locator.v1 data, rendered warp:// and warp@<basis>:// locators, and runtime projection metadata marked hashScope: excluded
  • reject undeclared sibling paths and symlink escapes
  • document the new command in the Warp README, WARPspace docs, and changelog

Validation

  • node --test apps/warp/test/*.test.mjs -> 25/25 pass
  • git diff --check -> pass
  • git diff --cached --check -> pass before commit
  • npx --yes markdownlint-cli2 CHANGELOG.md apps/warp/README.md docs/warpspaces/README.md -> pass
  • node apps/warp/bin/warp.mjs warpspace --help -> pass
  • node apps/warp/bin/warp.mjs warpspace locate --help -> pass

Jim smoke test

From /Users/james/git/jim:

node continuum/apps/warp/bin/warp.mjs warpspace locate ../echo/package.json   --lock warpspace.lock.json   --root "/Users/james/git/jim/continuum"   --cwd "/Users/james/git/jim/continuum/jedit"   --basis basis:jim-local   --json

Resolved to warp://jim/repo/echo/package.json and warp@basis:jim-local://jim/repo/echo/package.json with the runtime projection outside hash scope.

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@flyingrobots, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 57 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 46ce6ea0-3b60-4ec7-aacb-742a12e7de7b

📥 Commits

Reviewing files that changed from the base of the PR and between 6921816 and 362193d.

📒 Files selected for processing (2)
  • apps/warp/src/locator.mjs
  • apps/warp/test/warp-warpspace.test.mjs

Walkthrough

Adds the qw warpspace locate subcommand. A new locateWarpspacePath function in locator.mjs reads a warpspace.lock.json, validates root containment and symlink safety, selects the best-matching repo by longest-prefix, and returns a typed warp:// locator with runtime projection metadata. cli.mjs routes and parses the command; tests and documentation are updated accordingly.

Changes

warpspace locate command

Layer / File(s) Summary
locateWarpspacePath implementation and helpers
apps/warp/src/locator.mjs
New file implementing lock file reading/validation, root-containment assertion, symlink-escape detection via deepestExistingAncestor + realpath, repo selection by longest-prefix match, warp:// locator URL rendering with URI-encoded segments, and path/encoding/error utilities (normalizeRelativePath, encodeWarpSegment, requiredText, userFacingError, pathExists).
CLI routing, arg parsing, and error handling
apps/warp/src/cli.mjs
Adds command === 'locate' dispatch inside runWarpspace; adds parseWarpspaceLocateArgs parsing --lock, --root, --cwd, --basis, --json; extends writeJsonCommandError with a fallbackCode param (defaulting EINSTALL); emits warp.warpspace.locate.error.v1 / EWARP_LOCATE_FAILED on failure; adds renderWarpspaceLocateUsage() and updates renderWarpspaceUsage().
Integration tests
apps/warp/test/warp-warpspace.test.mjs
Three new test blocks: typed-locator normalization across host/container roots, rejection of undeclared sibling paths and symlink escapes with domain error codes, and malformed-lock --json path emitting correct error kind and fallback code. Adds writeLocateLock fixture helper.
Documentation
CHANGELOG.md, apps/warp/README.md, docs/warpspaces/README.md
Documents the qw warpspace locate command across changelog, warp README (command list, TACHYON locator flow description, example invocation), and warpspaces README (inputs and hash-scope exclusion).

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant CLI as cli.mjs / runWarpspace
  participant Locator as locator.mjs / locateWarpspacePath
  participant FS as Filesystem

  User->>CLI: qw warpspace locate <path> --lock --root --basis --json
  CLI->>CLI: parseWarpspaceLocateArgs → options, positionals
  CLI->>Locator: locateWarpspacePath({ inputPath, lockPath, root, cwd, basis })
  Locator->>FS: readFile(lockPath) → JSON
  Locator->>Locator: assertUnderRoot(inputPath, root)
  Locator->>FS: realpath(deepestExistingAncestor)
  Locator->>Locator: assertNoSymlinkEscape via realpath
  Locator->>Locator: findRepoMatch(repos, inputPath) → longest prefix repo
  Locator->>Locator: renderWarpLocator(basis, warpspace, segments)
  Locator-->>CLI: { locator, basisLocator, typedLocator, runtimeProjection }
  CLI-->>User: JSON output or plain locator string
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • flyingrobots/continuum#20: Extends the same warpspace subcommand dispatch, help-text rendering, and writeJsonCommandError error-handling infrastructure in apps/warp/src/cli.mjs that this PR builds upon.

Poem

🛸 A path walks in, uncertain of its name,
The lock is read, the repos staked their claim,
No symlink shall escape the realpath's eye,
A warp:// locator forms — typed, encoded, spry.
The hash scope shuts its door on runtime noise,
And TACHYON resolves with pedantic poise. 🔒

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main feature addition: introducing the qw warpspace locate command, which is the primary change across the changeset.
Description check ✅ Passed The description comprehensively relates to the changeset, detailing the feature implementation, flags, return values, security measures, documentation updates, and extensive validation performed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@flyingrobots

Copy link
Copy Markdown
Owner Author

Self-Code Review Findings

@codex please confirm these findings before remediation.

Scope: reviewed git diff origin/main...HEAD at eb95f94 after clean worktree preflight and git fetch origin.

Severity File / Lines Infraction Evidence Agent mitigation prompt
P1 High apps/warp/src/locator.mjs:131-134, test gap at apps/warp/test/warp-warpspace.test.mjs:753-768 Symlink escape detection only runs when the final target path exists, so paths through a symlinked parent can be canonicalized if the leaf does not exist yet. assertNoSymlinkEscape returns early when pathExists(runtimePath) is false. A local probe with echo/outside -> ../../outside accepted outside/new.txt and emitted warp://jim/repo/echo/outside/new.txt, even though writes/opens would traverse outside the WARPspace. Existing coverage only checks outside/secret.txt, where the leaf exists. Add a regression for locating a non-existent file under a symlinked directory that points outside the WARPspace. Fix symlink escape checking by resolving the deepest existing ancestor, verifying that physical ancestor remains under the physical root, then validating the remaining lexical suffix without allowing symlink traversal to escape.
P3 Medium apps/warp/src/cli.mjs:323-324, apps/warp/src/cli.mjs:366-372 qw warpspace locate --json can emit an install-specific fallback error code for locate failures. For a malformed lock file, output is kind: "warp.warpspace.locate.error.v1" but error.code: "EINSTALL". That is an install-domain code leaking into a locate-domain machine contract. Make JSON command errors accept a command-specific fallback code, or wrap locate failures with a locate-domain code before serialization. Add a regression for malformed lock JSON under qw warpspace locate --jsonasserting a locate-specific error code, notEINSTALL.

Mechanical checks run after review:

  • git status --porcelain before review: clean
  • git fetch origin: completed
  • node --test apps/warp/test/*.test.mjs -> 25/25 pass
  • git diff --check origin/main...HEAD -> clean
  • git diff --name-only origin/main...HEAD -- "*.md" | xargs npx --yes markdownlint-cli2 -> clean

No Markdown style violations were found in the changed Markdown files.

@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

code: error?.code ?? 'EINSTALL',

P3 Badge Use a locate-domain fallback JSON error code

When qw warpspace locate --json hits an uncoded error, such as malformed warpspace.lock.json throwing from JSON.parse, this shared serializer emits kind: "warp.warpspace.locate.error.v1" but falls back to code: "EINSTALL". JSON callers that dispatch on machine-readable locate errors now receive an install-domain code for a locate failure; pass a command-specific fallback code or wrap locate failures before serialization.

ℹ️ 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 apps/warp/src/locator.mjs Outdated
Comment thread apps/warp/src/locator.mjs
Comment thread apps/warp/src/locator.mjs
Comment thread apps/warp/src/locator.mjs Outdated
@flyingrobots

Copy link
Copy Markdown
Owner Author

Self-Review Resolution

Resolved both findings from issuecomment-4707667997 in commit 6921816.

Severity Finding Commit Outcome
P1 Symlinked parent could escape WARPspace when final leaf did not exist 6921816 qw warpspace locate now resolves the deepest existing ancestor and verifies that physical ancestor stays under the physical WARPspace root. Added regression coverage for a new/missing leaf under an escaping symlinked directory.
P3 locate --json could emit install-domain fallback code EINSTALL 6921816 JSON error serialization now supports command-specific fallback codes; locate failures use EWARP_LOCATE_FAILED. Added malformed-lock regression coverage.

Validation after remediation:

  • node --test apps/warp/test/warp-warpspace.test.mjs -> 21/21 pass
  • node --test apps/warp/test/*.test.mjs -> 26/26 pass
  • git diff --check -> clean
  • changed Markdown lint -> no changed Markdown in remediation commit; previous changed Markdown check was clean

Current PR head: 69218167f2f60b512061b809f230dc3582cc26b1.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/warp/src/locator.mjs`:
- Around line 131-138: The pathExists() function is using stat() which follows
symlinks to their targets, causing dangling symlinks to be skipped during the
upward directory walk in deepestExistingAncestor(). This breaks symlink-escape
validation by validating the wrong ancestor path. Change pathExists() to use
lstat() instead of stat() so it detects symlinks themselves rather than their
nonexistent targets. Additionally, add error handling in assertNoSymlinkEscape()
to catch and handle the case where realpath() fails when encountering a dangling
symlink after the path fix.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 417655e6-6079-432c-bfeb-c8c9f9178f07

📥 Commits

Reviewing files that changed from the base of the PR and between 8856950 and 6921816.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • apps/warp/README.md
  • apps/warp/src/cli.mjs
  • apps/warp/src/locator.mjs
  • apps/warp/test/warp-warpspace.test.mjs
  • docs/warpspaces/README.md
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

**: # AGENTS.md

Role

Continuum is the coordination spine for the active stack. It does not own a
runtime implementation, a substrate, or a parallel ontology. It owns shared
truth across Echo, git-warp, warp-ttd, and Wesley.

Git Safety

  • Never amend commits.
  • Never rebase.
  • Never force git operations.
  • Stage only the files written in the current turn.
  • Commit each completed slice in the same turn.

Process

  • Read METHOD.md before changing structure.
  • Keep active work in docs/design/.
  • Keep concrete work in docs/method/backlog/.
  • Keep retros in docs/method/retro/.
  • Update docs/BEARING.md and docs/VISION.md
    only at cycle boundaries.

Doctrine

  • Continuum owns coordination truth, not substrate truth.
  • Shared nouns need one authored home and explicit publication boundaries.
  • Cross-repo witness and compatibility truth beats hand-wavy alignment claims.
  • No shadow schemas, no shadow vocabularies, no shadow ownership.

Files:

  • docs/warpspaces/README.md
  • apps/warp/README.md
  • CHANGELOG.md
  • apps/warp/src/cli.mjs
  • apps/warp/src/locator.mjs
  • apps/warp/test/warp-warpspace.test.mjs
🔇 Additional comments (6)
CHANGELOG.md (1)

11-13: LGTM!

apps/warp/README.md (1)

35-35: LGTM!

Also applies to: 57-59, 87-87

docs/warpspaces/README.md (1)

20-23: LGTM!

apps/warp/src/locator.mjs (1)

1-130: LGTM!

Also applies to: 139-145, 150-191, 200-203

apps/warp/src/cli.mjs (1)

2-2: LGTM!

Also applies to: 297-329, 366-372, 510-544, 599-600, 620-622

apps/warp/test/warp-warpspace.test.mjs (1)

6-6: LGTM!

Also applies to: 661-816, 1109-1149

Comment thread apps/warp/src/locator.mjs Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jun 15, 2026
@flyingrobots

Copy link
Copy Markdown
Owner Author

Activity Summary

@codex review loop completed for feature/qw-warpspace-locate.

# Severity Source File Commit Outcome
1 P1 PR apps/warp/src/locator.mjs 6921816 Already fixed non-existent leaves under symlinked ancestors; thread resolved.
2 P1 PR apps/warp/src/locator.mjs 3bf1fc1 Rejected dangling symlink ancestors by detecting ancestors with lstat() and handling failed realpath().
3 P1 PR apps/warp/src/locator.mjs cc1237a Rejected symlinks that leave the matched repo while remaining inside the WARPspace root.
4 P2 PR apps/warp/src/locator.mjs 0986603 Allowed valid repo-relative names beginning with .. without treating them as parent traversal.
5 P2 PR apps/warp/src/locator.mjs 362193d Rejected locate lock inputs whose kind is not warpspace.constellation-lock.v1.

Validation:

Gate Result
node --test apps/warp/test/*.test.mjs PASS, 28/28
git diff --check origin/main...HEAD PASS
npx --yes markdownlint-cli2 CHANGELOG.md apps/warp/README.md docs/warpspaces/README.md PASS, 0 errors
Review threads PASS, 0 unresolved

No additional self-discovered issues remain after the PR-thread queue was resolved.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

@flyingrobots
flyingrobots merged commit 94e77de into main Jun 15, 2026
1 check passed
@flyingrobots
flyingrobots deleted the feature/qw-warpspace-locate branch June 15, 2026 13:07
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