feat: add Relay agent foundation and workflow recenter#25
feat: add Relay agent foundation and workflow recenter#25flyingrobots merged 18 commits intomainfrom
Conversation
|
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 16 minutes and 9 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the 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 have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds a JSONL-first agent CLI and protocol, many machine-facing agent commands for recipient/vault inspection and mutation, workflow/planning docs (WORKFLOW, legends, backlog, design, invariants), CLI wiring and credential/passphrase validation changes, and extensive integration/unit tests for agent protocol and vault flows. Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client/CLI
participant Agent as Agent CLI Handler
participant CAS as CAS Service
participant Vault as Vault/Manifest
Client->>Agent: runAgentCli(argv, {stdout,stderr,stdin})
activate Agent
Agent->>Agent: parseArgs / parseRequest (flags | `@file` | -)
Agent->>Agent: createAgentSession(command)
Agent->>Client: write start (stdout, seq=1)
Agent->>CAS: resolveTarget (--slug or --oid)
CAS->>Vault: readManifest / readEnvelope
Vault-->>CAS: manifest/envelope
CAS-->>Agent: manifest
Agent->>CAS: perform action (inspect/store/restore/rotate/recipient/vault)
CAS->>Vault: read/update/create trees, rewrap entries as needed
Vault-->>CAS: treeOid / commitOid / result
CAS-->>Agent: result payload
Agent->>Client: write result (stdout, seq=2)
Agent->>Client: write end (stdout, seq=3)
deactivate Agent
sequenceDiagram
participant Client as Client/CLI
participant Agent as Agent CLI Handler
participant CAS as CAS Service
participant Vault as Encrypted Vault
Client->>Agent: runAgentCli(..., --request / --old-passphrase / --new-passphrase)
activate Agent
Agent->>Agent: parse passphrase sources (inline | `@file` | -), validate exclusivity
Agent->>Agent: createAgentSession()
Agent->>Client: write start (seq=1)
alt Missing credentials or cannot decrypt
Agent->>Client: write needs-input (stderr, seq=2)
Agent->>Client: write end (stdout, seq=3)
Agent-->>Client: exitCode = AGENT_EXIT_CODES.INVALID_INPUT (2)
else Valid passphrases
Agent->>CAS: rotateVaultPassphrase(oldPass,newPass)
CAS->>Vault: unwrap/rewrap entries, commit
Vault-->>CAS: commitOid, kdfAlgorithm, rotated/skipped lists
CAS-->>Agent: result {commitOid, rotated, skipped}
Agent->>Client: write result (seq=2)
Agent->>Client: write end (seq=3)
Agent-->>Client: exitCode = AGENT_EXIT_CODES.SUCCESS (0)
end
deactivate Agent
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@bin/git-cas.js`:
- Around line 703-708: The checks for oldPassphrase and newPassphrase only
reject undefined/null but allow whitespace-only values; update the validation to
treat blank/whitespace-only strings as missing by trimming and verifying length
(e.g., if (!oldPassphrase || !oldPassphrase.trim()) and similarly for
newPassphrase) before throwing the existing Error messages so whitespace-only
passphrases are rejected consistently with earlier validation for passphrases
like oldPassphrase and newPassphrase.
- Around line 282-288: The current conflict check in the runAction callback
incorrectly uses hasPassphraseSource(opts) which treats ambient env vars (like
GIT_CAS_PASSPHRASE) as an explicit mode and blocks --recipient; change the
condition that throws when both recipient and a passphrase source are present to
only consider CLI-provided passphrase flags (e.g. check opts.vaultPassphrase ||
opts.vaultPassphraseFile or whatever CLI option properties represent
--vault-passphrase/--vault-passphrase-file) rather than
hasPassphraseSource(opts), or alternatively update hasPassphraseSource to
distinguish explicit CLI flags from environment variables so that opts.recipient
and opts.keyFile are only considered conflicting with an explicitly-provided
passphrase flag.
In `@CONTRIBUTING.md`:
- Around line 227-233: Replace the `pnpm run lint` guidance with the canonical
ESLint invocation used by the gate: instruct contributors to run `npx eslint .`
(ensuring it targets the code globs `**/*.{js,ts,jsx,tsx}`) and state that
ESLint must pass with zero errors; update the Local testing policy entry that
currently references `pnpm run lint` to this canonical command and requirement.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: c340d27b-1936-43b5-8eb1-4dec792b8d35
📒 Files selected for processing (32)
CHANGELOG.mdCONTRIBUTING.mdROADMAP.mdSTATUS.mdWORKFLOW.mdbin/actions.jsbin/agent/cli.jsbin/agent/protocol.jsbin/git-cas.jsdocs/BACKLOG/README.mddocs/BACKLOG/RL-001-agent-recipient-list.mddocs/BACKLOG/RL-002-agent-recipient-mutations.mddocs/BACKLOG/RL-003-agent-rotate.mddocs/BACKLOG/RL-004-agent-vault-rotate.mddocs/BACKLOG/RL-005-agent-vault-lifecycle.mddocs/design/0001-m18-relay-agent-cli.mddocs/design/0002-m18-relay-write-flows.mddocs/design/0003-m18-relay-tree-creation.mddocs/design/README.mddocs/design/RL-001-agent-recipient-list.mddocs/design/RL-002-agent-recipient-mutations.mddocs/design/RL-003-agent-rotate.mddocs/design/RL-004-agent-vault-rotate.mddocs/design/RL-005-agent-vault-lifecycle.mddocs/invariants/I-001-determinism-trust-and-explicit-surfaces.mddocs/invariants/README.mddocs/legends/README.mddocs/legends/RL-relay.mdtest/cycles/README.mdtest/integration/agent-cli.test.jstest/integration/vault.test.jstest/unit/cli/agent-protocol.test.js
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@bin/agent/cli.js`:
- Around line 818-823: Update the JSDoc for parseVaultRotateInput to match the
actual parameter names and types: change the first `@param` from "input" to "args"
and set its type to string[] (or the correct type used in the function), keep
the second `@param` as stdin with type NodeJS.ReadStream, and ensure the `@returns`
annotation matches the function's returned type; reference the function name
parseVaultRotateInput when making these edits.
- Around line 439-474: Update the JSDoc for readAgentPassphraseFile to document
the second options parameter: add a `@param` {Object} options description (or
`@param` {{stdin?: import('stream').Readable, onWarning?: function}} options) that
lists stdin (a Readable stream used when filePath === '-') and onWarning
(optional callback invoked with a warning object {code, message, filePath,
recommendation}); keep the existing `@param` {string} filePath and `@returns`
{Promise<string>} intact so the signature matches the actual function async
function readAgentPassphraseFile(filePath, { stdin, onWarning } = {}).
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2ef990fb-7a5f-4ce0-9f08-2408c02d40d0
📒 Files selected for processing (2)
bin/agent/cli.jstest/integration/agent-cli.test.js
|
@coderabbitai review please 🥕 |
|
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@bin/agent/cli.js`:
- Around line 371-395: parseAgentInput currently merges the parsed JSON request
payload from readRequestPayload directly into values, allowing improperly-typed
fields to bypass parseArgs validation; fix it by validating and coercing the
request object before merging: after calling readRequestPayload(request, stdin)
use the existing parseArgs/REQUEST_OPTION schema or explicit type checks to
ensure each expected option (e.g., boolean flags like "tree" and "force" and
string path fields) has the correct type, coerce string booleans
("true"/"false") to actual booleans, reject or normalize non-string path values,
and only then spread the sanitized request into values; keep requestSource as
parsed.values.request but do not merge raw request without this validation.
In `@bin/git-cas.js`:
- Around line 117-126: The helper hasExplicitPassphraseSource currently treats
empty strings as absent; change validation to detect presence of the flags
themselves (not truthiness) and treat an explicit empty string as provided so
CLI rejects conflicting inputs—update hasExplicitPassphraseSource to check for
keys in opts (e.g., Object.prototype.hasOwnProperty.call(opts,
'vaultPassphrase') or 'vaultPassphraseFile') and ensure the store/restore
command paths (the handlers that inspect opts for key-file, vaultPassphrase,
vaultPassphraseFile) validate and throw an error when both --key-file and any
vault passphrase flag are present; apply the same presence-based check in all
locations mentioned (hasExplicitPassphraseSource and the store/restore option
checks).
- Around line 521-539: The command currently allows specifying --algorithm
(opts.algorithm) but then silently proceeds with an unencrypted init when
resolvePassphrase(...) returns no passphrase; fix by refusing to proceed if an
algorithm was explicitly provided but no passphrase was obtained: after
computing passphrase = await resolvePassphrase(opts, { confirm: true }), if
(!passphrase && opts.algorithm) throw a user-facing error (or exit non-zero)
explaining that --algorithm requires a passphrase (use --vault-passphrase,
--vault-passphrase-file, or run interactively), and ensure initOpts.kdfOptions
is only set when passphrase is present (keep createCas and initOpts logic intact
otherwise).
In `@CONTRIBUTING.md`:
- Around line 49-50: Update the contributor docs to reflect that the "git cas
agent" command is shipped (not future): change phrasing in the bullets that
currently read "keep every human CLI command machine-readable through `--json`"
and "keep the future `git cas agent` surface JSONL-first and non-interactive" so
they state that "git cas agent" is available and its surface is JSONL-first and
non-interactive; update any other occurrences (e.g., the second block
referencing `git cas agent`) to remove future/planned language and use
present-tense wording indicating the command is implemented and follows the
JSON/JSONL non-interactive convention.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: b7fc2969-583d-49a2-a81f-df0e7b4074ed
📒 Files selected for processing (6)
CHANGELOG.mdCONTRIBUTING.mdbin/agent/cli.jsbin/git-cas.jstest/integration/agent-cli.test.jstest/integration/vault-cli.test.js
|
@coderabbitai review please 🥕 |
|
✅ Actions performedReview triggered.
|
Summary
This PR recenters
git-casaround the new legends/cycles workflow and lands the first substantial Relay agent surface on top of the existing CAS/vault core.It includes:
git-cas agententrypoint and JSONL protocolstore,restore, andtreevault init,vault remove)Review Order
WORKFLOW.md,CONTRIBUTING.md,ROADMAP.md,STATUS.mdbin/agent/protocol.js,bin/agent/cli.js,bin/git-cas.jstest/unit/cli/agent-protocol.test.js,test/integration/agent-cli.test.jsdocs/design/and backlog/legend/invariant docstest/integration/vault.test.jsNotes
This is intentionally the point where the branch stops growing and goes to review. The diff is already large enough that stacking more Relay work onto it would make review quality worse.
Verification
npx eslint .npm testdocker compose run --build --rm test-node npx vitest run test/integrationdocker compose run --build --rm test-bun bunx vitest run test/unitdocker compose run --build --rm test-bun bunx vitest run test/integrationdocker compose run --build --rm test-deno deno run -A npm:vitest run test/unitdocker compose run --build --rm test-deno deno run -A npm:vitest run test/integrationSummary by CodeRabbit
New Features
Documentation
Tests
Bug Fixes