Skip to content

refactor: hex-audit PRs + code review fixes#46

Merged
flyingrobots merged 21 commits intomainfrom
pr-combo
Mar 8, 2026
Merged

refactor: hex-audit PRs + code review fixes#46
flyingrobots merged 21 commits intomainfrom
pr-combo

Conversation

@flyingrobots
Copy link
Copy Markdown
Owner

@flyingrobots flyingrobots commented Mar 8, 2026

Summary

  • Six hex-audit PRs merged (refactor(test): extract shared test helpers (D1–D4) #40refactor(arch): fix domain boundary violations (H1, H2) #45): shared test helpers (D1–D4), shared view helpers (D5–D11), shared command patterns (D12–D13), SecretAdapter→SecretPort (H3), RoadmapPort ISP split (S6), domain boundary fixes (H1, H2)
  • Code review fixes addressing 10 of 19 issues from pedantic review, plus 1 discovered during self-review:
    • Added 38 new tests: view-helpers.test.ts (22) and validators.test.ts (16)
    • Removed dead exports stripPrefix/indexBy from view-helpers
    • Added Number.isFinite guard to sliceDate (prevents RangeError on NaN/Infinity)
    • @deprecated tag on SecretAdapter re-export alias
    • Renamed secretAdaptersecretPort param in AnthropicLlmAdapter
    • import type for RoadmapPort in WarpRoadmapAdapter
    • Moved RoadmapPort split CHANGELOG entry from Added → Changed
    • Storage-neutral JSDoc in KeyringStoragePort (no "file"/"path" leaking into port)
    • Fixed mockGraphPort returning Map instead of Record (git-warp v13 API)

Stats

  • 49 files changed, +1123 / −734
  • 709 tests passing (38 new)
  • Zero lint warnings, zero type errors

Test plan

  • npm run build — zero errors
  • npm run lint — clean
  • npm run test:local — 709/709 pass
  • Self-review: 0 issues remaining

Summary by CodeRabbit

Release Notes

  • New Features

    • Added centralized validation helpers for CLI commands
    • Introduced reusable test infrastructure and mock utilities
    • Added view utility functions for grouping and date formatting
  • Refactoring

    • Migrated internal architecture to port-based design for better abstraction
    • Relocated test parsing logic to infrastructure layer
    • Consolidated duplicate code patterns across CLI commands
  • Tests

    • Expanded test coverage for validators and view utilities
    • Refactored test suite to use shared helper modules

Create test/helpers/ with shared utilities previously duplicated
across views.test.ts, DashboardApp.test.ts and integration.test.ts:

- snapshot.ts: makeSnapshot() builder + entity factories
- keys.ts: makeKey() / makeResize() keyboard input helpers
- ansi.ts: strip() ANSI escape-code removal
- ports.ts: mock port factories for GraphContext, IntakePort,
  GraphPort, SubmissionPort

All 671 tests pass. Zero logic changes.
Add sliceDate(), groupBy(), indexBy(), stripPrefix() to the existing
view-helpers.ts module. Replace manual Map-building loops and
toISOString().slice(0,10) patterns across:

- src/tui/render-status.ts (4 sliceDate, 4 groupBy)
- src/tui/bijou/views/lineage-view.ts (1 sliceDate, 1 groupBy)
- src/tui/bijou/views/submissions-view.ts (1 sliceDate, 2 groupBy)
- src/tui/bijou/views/dashboard-view.ts (1 groupBy)
- src/tui/bijou/views/roadmap-view.ts (2 groupBy)

All 671 tests pass. Zero logic changes.
Add assertNodeExists() to validators.ts and use it across 5 CLI
command files, replacing 15 inline hasNode() + throw NOT_FOUND checks:

- coordination.ts (1 instance)
- dashboard.ts (2 instances)
- link.ts (3 instances)
- suggestions.ts (2 instances)
- traceability.ts (7 instances)

Also simplify assertCampaignPrefix (link.ts) and
assertDecomposeFrom/To (traceability.ts) to delegate to
assertPrefixOneOf instead of re-implementing the logic.

All 671 tests pass. Zero logic changes.
Create src/ports/SecretPort.ts with the SecretPort interface,
extracted from VaultSecretAdapter.ts (infrastructure layer).

- VaultSecretAdapter & InMemorySecretAdapter now implement SecretPort
- AnthropicLlmAdapter imports SecretPort from ports, not infra
- Backward-compatible type alias exported from VaultSecretAdapter.ts
- analyze.ts CLI command (imports VaultSecretAdapter class) unchanged

Fixes hexagonal architecture violation: interfaces belong in ports,
not in infrastructure adapters.

All 671 tests pass.
Apply Interface Segregation Principle — split monolithic RoadmapPort
into three focused sub-interfaces:

- RoadmapQueryPort: getQuests, getQuest, getOutgoingEdges
- RoadmapMutationPort: upsertQuest, addEdge
- RoadmapSyncPort: sync

RoadmapPort is retained as the composite (extends all three) for
backward compatibility and for the WarpRoadmapAdapter implementation.

Domain services now depend on the narrowest port they need:
- SovereigntyService, IntakeService → RoadmapQueryPort
- TriageService → RoadmapQueryPort & RoadmapMutationPort
- CoordinatorService → RoadmapPort (needs all three)

Test mocks trimmed to match their narrowed interfaces.

All 671 tests pass. Zero logic changes.
H1 — GuildSealService: Extract filesystem and crypto RNG operations to
KeyringStoragePort + FsKeyringAdapter. GuildSealService now depends
solely on the port interface; no node:fs, node:path, or node:crypto
imports remain in src/domain/.

H2 — TestFileParser: Move TypeScript Compiler API logic from
src/domain/services/analysis/TestFileParser.ts to
TsCompilerTestParserAdapter in the infrastructure layer, behind a
TestParserPort interface. Original domain file replaced with a
deprecation tombstone.

All 671 tests pass. Zero node:* imports in src/domain/.
- Add 22 tests for sliceDate, groupBy, formatAge, statusVariant
- Add Number.isFinite guard to sliceDate (prevents RangeError on NaN/Infinity)
- Remove stripPrefix and indexBy (zero consumers)
Cover assertNodeExists, assertPrefix, assertMinLength,
assertPrefixOneOf, and parseHours with 16 unit tests.
…r param (PR4 #13#14)

- Mark re-exported SecretAdapter type alias as @deprecated
- Rename secretAdapter → secretPort in AnthropicLlmAdapter to match port naming
…16)

- Use `import type` for RoadmapPort in WarpRoadmapAdapter (type-only import)
- Move RoadmapPort split entry from Added to Changed in CHANGELOG
Replace filesystem-specific terms (file, path, rename) with
storage-agnostic phrasing in the port interface documentation.
getNodeProps() returns Record<string, unknown> in v13, not Map.
The mock was returning new Map() which would break any future test
that accesses properties via bracket notation.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 8, 2026

Warning

Rate limit exceeded

@flyingrobots has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 32 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, 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 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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b64bae5b-95ef-46b1-a553-dd91af6331a5

📥 Commits

Reviewing files that changed from the base of the PR and between 1887f32 and b999159.

📒 Files selected for processing (5)
  • src/domain/services/GuildSealService.ts
  • src/domain/services/analysis/types.ts
  • src/infrastructure/adapters/TsCompilerTestParserAdapter.ts
  • test/helpers/ports.ts
  • test/helpers/snapshot.ts
📝 Walkthrough

Walkthrough

This PR introduces port-based architecture patterns by creating new abstractions (KeyringStoragePort, SecretPort, TestParserPort) and refactoring existing services to depend on these ports. It splits RoadmapPort into query/mutation/sync variants, migrates GuildSealService to use a filesystem keyring adapter, and consolidates repeated test infrastructure into shared helpers.

Changes

Cohort / File(s) Summary
Port abstractions
src/ports/KeyringStoragePort.ts, src/ports/SecretPort.ts, src/ports/TestParserPort.ts, src/ports/RoadmapPort.ts
New port interfaces for keyring storage and secret management; RoadmapPort split into RoadmapQueryPort, RoadmapMutationPort, and RoadmapSyncPort with extended getOutgoingEdges method.
GuildSealService refactor
src/domain/services/GuildSealService.ts
Migrated from filesystem path injection to KeyringStoragePort; replaced direct fs operations with port methods (loadKeyring, saveKeyring, private key management); removed legacy KeyringEntryJson structure.
Keyring adapter & secret adapter updates
src/infrastructure/adapters/FsKeyringAdapter.ts, src/infrastructure/adapters/VaultSecretAdapter.ts, src/infrastructure/adapters/AnthropicLlmAdapter.ts
New FsKeyringAdapter implements KeyringStoragePort with filesystem keyring/key storage; VaultSecretAdapter refactored to implement SecretPort; AnthropicLlmAdapter switched to SecretPort dependency.
Test parser relocation
src/domain/services/analysis/TestFileParser.ts, src/infrastructure/adapters/TsCompilerTestParserAdapter.ts
Domain TestFileParser replaced with tombstone; new TsCompilerTestParserAdapter in infrastructure implements TestParserPort with TS compiler AST traversal.
Service port type updates
src/domain/services/CoordinatorService.ts, src/domain/services/IntakeService.ts, src/domain/services/SovereigntyService.ts, src/domain/services/TriageService.ts
Services updated to use narrower RoadmapQueryPort and/or RoadmapMutationPort instead of monolithic RoadmapPort; RoadmapPort imports converted to type-only.
CLI command validator consolidation
src/cli/commands/coordination.ts, src/cli/commands/dashboard.ts, src/cli/commands/link.ts, src/cli/commands/suggestions.ts, src/cli/commands/traceability.ts, src/cli/validators.ts
New assertNodeExists validator helper replaces inline graph.hasNode() checks; assertPrefixOneOf centralizes prefix validation; multiple command handlers updated to use helpers.
GuildSealService CLI integration
src/cli/commands/artifact.ts, src/cli/commands/submission.ts
CLI commands updated to instantiate GuildSealService with FsKeyringAdapter dependency instead of raw trustDir path.
Test parser CLI integration
src/cli/commands/analyze.ts
Import path updated to use TsCompilerTestParserAdapter instead of domain TestFileParser.
TUI view refactoring
src/tui/bijou/views/dashboard-view.ts, src/tui/bijou/views/lineage-view.ts, src/tui/bijou/views/roadmap-view.ts, src/tui/bijou/views/submissions-view.ts, src/tui/render-status.ts, src/tui/view-helpers.ts
Manual grouping logic replaced with shared groupBy utility; date formatting centralized via sliceDate helper; new view helpers added.
Test infrastructure helpers
test/helpers/ansi.ts, test/helpers/keys.ts, test/helpers/ports.ts, test/helpers/snapshot.ts
New shared test helpers: ANSI stripping, keyboard/resize event factories, port mock factories, and snapshot/entity builders for consistent test setup.
TUI test refactoring
src/tui/bijou/__tests__/DashboardApp.test.ts, src/tui/bijou/__tests__/integration.test.ts, src/tui/bijou/__tests__/views.test.ts
Tests updated to use shared test helpers instead of inline implementations; mock construction centralized.
Service & port type tests
test/unit/CoordinatorService.test.ts, test/unit/CoordinatorService.POWERLEVEL.test.ts, test/unit/IntakeService.test.ts, test/unit/SovereigntyService.test.ts, test/unit/TriageService.test.ts
Tests updated with type-only imports of narrow RoadmapPort variants; mock surfaces reduced to match new port contracts.
GuildSealService tests
test/unit/GuildSealService.test.ts, test/unit/key-rotation.test.ts, test/unit/multibase.test.ts
Test setup updated to pass FsKeyringAdapter instance to GuildSealService instead of raw directory path.
Test parser tests & validators
test/unit/TestFileParser.test.ts, test/unit/validators.test.ts, test/unit/view-helpers.test.ts
TestFileParser test import updated to TsCompilerTestParserAdapter; new comprehensive unit tests for validators and view helpers.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 Ports now split, adapters weave,
Storage-backed keyrings we retrieve,
Test helpers grouped in one clean place,
Architecture blooms with grace,
Dependencies dance, injected with care—
Hexagons hexing everywhere!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.98% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: a refactor combining hex-audit PRs with code review fixes addressing architectural patterns and domain boundaries.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch pr-combo

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.

- Add missing opts param to filterSnapshot mock (matches GraphContext interface)
- Remove filesystem references from GuildSealService JSDoc (domain must not
  leak infrastructure details)
Use GraphContext['filterSnapshot'] type assertion instead of inline
parameter annotation to satisfy no-unused-vars while preserving
correct arity in the mock type.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (1)
src/infrastructure/adapters/FsKeyringAdapter.ts (1)

98-121: Consider adding debug logging for best-effort operations.

The empty catch blocks in removePrivateKey and restoreRetiredPrivateKey are intentionally best-effort, but silently swallowing errors can make debugging harder if key files get stuck in unexpected states.

If a logging port is available, consider emitting debug-level messages on failure. Otherwise, this is acceptable as-is for cleanup paths.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/infrastructure/adapters/FsKeyringAdapter.ts` around lines 98 - 121, The
empty catch blocks in removePrivateKey and restoreRetiredPrivateKey swallow
errors; change them to catch (err) and emit a debug-level message including err
so failures are visible during debugging: inside removePrivateKey and
restoreRetiredPrivateKey, capture the exception as err and call a logging sink
if present (e.g. this.logger?.debug?.(`removePrivateKey failed for ${agentId}:`,
err) or this.log?.debug), otherwise fall back to console.debug(`...`, err); keep
the operations best-effort (do not rethrow) and avoid changing retirePrivateKey
behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/domain/services/GuildSealService.ts`:
- Around line 89-106: Before registering the new public key, check the loaded
keyring (this.storage.loadKeyring()) for any existing active entry for the same
agentId and mark it inactive (or set active=false) so you don't create a second
active key; specifically, inside the try block before keyring.entries.set(...)
find entries where entry.agentId === agentId && entry.active === true and set
entry.active = false, then call this.storage.saveKeyring(keyring) (or save once
after making both the deactivation and the new entry) so
keyIdForAgent()/rotateKey() remain unambiguous; keep using
writePrivateKey(agentId, privateKeyHex) semantics and ensure the rollback in the
catch still removes the .sk if the keyring save fails.
- Around line 153-180: The sequence currently calls retirePrivateKey(agentId,
suffix) then writePrivateKeyOverwrite(agentId, privateKeyHex) before updating
and saving the keyring, which can leave the live .sk missing if the write fails;
move the writePrivateKeyOverwrite call into the try block so it runs after you
update keyring.entries and call this.storage.saveKeyring(keyring), and in the
catch ensure you both remove the new private key (this.storage.removePrivateKey)
and restore the retired one (this.storage.restoreRetiredPrivateKey) and also
revert any modified keyring.entries so the old key remains active (undo changes
to keyring.entries for currentKeyId and newKeyId) to maintain consistency
between the filesystem and the keyring.

In `@src/infrastructure/adapters/TsCompilerTestParserAdapter.ts`:
- Around line 90-92: The ImportRef currently conflates namespace imports with
default imports; update the ImportRef interface to add a namespaceImport?:
string field and in TsCompilerTestParserAdapter replace the
ts.isNamespaceImport(bindings) branch (where it currently sets defaultImport =
bindings.name.text) to set namespaceImport = bindings.name.text instead, leaving
defaultImport only for ts.isIdentifier/default import cases; also adjust any
places that construct or consume ImportRef to account for the new
namespaceImport field so downstream analysis uses namespaceImport when present.
- Around line 208-218: Called test-framework property-access methods (e.g.,
matchers/mocks) are being pushed into calledMethods; update the property-access
branch in TsCompilerTestParserAdapter where ts.isPropertyAccessExpression(expr)
is handled to first compute the full call name via getCallName(node or expr) and
skip pushing expr.name.text when isTestFrameworkCall(callName) returns true. In
short: replace the unconditional calledMethods.push(expr.name.text) with a guard
that calls getCallName(...) and only pushes when isTestFrameworkCall(...) is
false, keeping existing behavior for non-framework chains.
- Around line 39-45: The parser is hard-coding ts.ScriptKind.TSX when calling
ts.createSourceFile (in TsCompilerTestParserAdapter), which misparses plain .ts
files; change the call to derive the script kind from filePath (e.g., use
ts.getScriptKindFromFileName(filePath) or a small helper that maps extensions
.ts/.tsx/.js/.jsx to the correct ts.ScriptKind) and pass that value into
ts.createSourceFile (keep setParentNodes true and other args unchanged) so
sourceFile is created with the correct script kind for each test file.

In `@src/ports/KeyringStoragePort.ts`:
- Around line 17-65: The KeyringStoragePort must expose atomic mutation
semantics rather than a separate loadKeyring()/saveKeyring() pair: add a single
transactional API (eg. updateKeyring or runKeyringTransaction) that accepts a
mutator function which receives the current Keyring and returns a new Keyring
(or signals abort), and ensure the implementation performs the Keyring update
and any private-key lifecycle calls (retirePrivateKey, writePrivateKeyOverwrite,
restoreRetiredPrivateKey, writePrivateKey, removePrivateKey) atomically or rolls
back on failure; alternatively provide a CAS-style
saveKeyringIfUnchanged(oldKeyring, newKeyring) combined with a lock/lease
mechanism, and document that GuildSealService must use the new transactional
method instead of loadKeyring/saveKeyring to avoid lost updates and half-applied
rotations.

In `@test/helpers/snapshot.ts`:
- Line 37: Replace the time-dependent Date.now() defaults used for the asOf
property in the shared fixture definitions with a fixed, deterministic constant
(e.g., DEFAULT_AS_OF_TS) declared at the top of the file; update every
occurrence of asOf: Date.now() (the shared fixture builders in this file) to use
that constant and ensure tests that need a specific time explicitly
pass/override asOf. This keeps the shared fixtures deterministic across runs
while allowing targeted overrides where real timestamps are required.

---

Nitpick comments:
In `@src/infrastructure/adapters/FsKeyringAdapter.ts`:
- Around line 98-121: The empty catch blocks in removePrivateKey and
restoreRetiredPrivateKey swallow errors; change them to catch (err) and emit a
debug-level message including err so failures are visible during debugging:
inside removePrivateKey and restoreRetiredPrivateKey, capture the exception as
err and call a logging sink if present (e.g.
this.logger?.debug?.(`removePrivateKey failed for ${agentId}:`, err) or
this.log?.debug), otherwise fall back to console.debug(`...`, err); keep the
operations best-effort (do not rethrow) and avoid changing retirePrivateKey
behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 762cbca5-9fc0-47ae-a6ba-ff06053861e4

📥 Commits

Reviewing files that changed from the base of the PR and between 6d687cd and 1887f32.

📒 Files selected for processing (49)
  • CHANGELOG.md
  • src/cli/commands/analyze.ts
  • src/cli/commands/artifact.ts
  • src/cli/commands/coordination.ts
  • src/cli/commands/dashboard.ts
  • src/cli/commands/link.ts
  • src/cli/commands/submission.ts
  • src/cli/commands/suggestions.ts
  • src/cli/commands/traceability.ts
  • src/cli/validators.ts
  • src/domain/services/CoordinatorService.ts
  • src/domain/services/GuildSealService.ts
  • src/domain/services/IntakeService.ts
  • src/domain/services/SovereigntyService.ts
  • src/domain/services/TriageService.ts
  • src/domain/services/analysis/TestFileParser.ts
  • src/infrastructure/adapters/AnthropicLlmAdapter.ts
  • src/infrastructure/adapters/FsKeyringAdapter.ts
  • src/infrastructure/adapters/TsCompilerTestParserAdapter.ts
  • src/infrastructure/adapters/VaultSecretAdapter.ts
  • src/infrastructure/adapters/WarpRoadmapAdapter.ts
  • src/ports/KeyringStoragePort.ts
  • src/ports/RoadmapPort.ts
  • src/ports/SecretPort.ts
  • src/ports/TestParserPort.ts
  • src/tui/bijou/__tests__/DashboardApp.test.ts
  • src/tui/bijou/__tests__/integration.test.ts
  • src/tui/bijou/__tests__/views.test.ts
  • src/tui/bijou/views/dashboard-view.ts
  • src/tui/bijou/views/lineage-view.ts
  • src/tui/bijou/views/roadmap-view.ts
  • src/tui/bijou/views/submissions-view.ts
  • src/tui/render-status.ts
  • src/tui/view-helpers.ts
  • test/helpers/ansi.ts
  • test/helpers/keys.ts
  • test/helpers/ports.ts
  • test/helpers/snapshot.ts
  • test/unit/CoordinatorService.POWERLEVEL.test.ts
  • test/unit/CoordinatorService.test.ts
  • test/unit/GuildSealService.test.ts
  • test/unit/IntakeService.test.ts
  • test/unit/SovereigntyService.test.ts
  • test/unit/TestFileParser.test.ts
  • test/unit/TriageService.test.ts
  • test/unit/key-rotation.test.ts
  • test/unit/multibase.test.ts
  • test/unit/validators.test.ts
  • test/unit/view-helpers.test.ts

Comment thread src/domain/services/GuildSealService.ts
Comment thread src/domain/services/GuildSealService.ts Outdated
Comment thread src/infrastructure/adapters/TsCompilerTestParserAdapter.ts
Comment thread src/infrastructure/adapters/TsCompilerTestParserAdapter.ts
Comment thread src/infrastructure/adapters/TsCompilerTestParserAdapter.ts
Comment thread src/ports/KeyringStoragePort.ts
Comment thread test/helpers/snapshot.ts Outdated
- GuildSealService.generateKeypair: check keyring for existing active
  key before writing .sk file (prevents orphaned dual-active-key state)
- GuildSealService.rotateKey: move writePrivateKeyOverwrite inside
  try/catch so rollback covers write failures
- TsCompilerTestParserAdapter: derive ScriptKind from file extension
  instead of hard-coding TSX (fixes generic misparse in .ts files)
- TsCompilerTestParserAdapter: distinguish namespace imports from
  default imports via new ImportRef.namespaceImport field
- TsCompilerTestParserAdapter: filter test framework property-access
  chains (expect.toBe, vi.fn) from calledMethods to prevent score
  inflation in AST layer
- test/helpers/snapshot.ts: replace Date.now() with deterministic
  FIXED_TS constant (2024-01-01T00:00:00Z) in all entity builders
@flyingrobots
Copy link
Copy Markdown
Owner Author

All actionable CodeRabbit findings addressed in b999159:

Fixed (6 of 7):

  1. generateKeypair dual-active-key — now checks keyring for existing active entry before writing .sk
  2. rotateKey write outside rollbackwritePrivateKeyOverwrite moved inside try/catch
  3. ScriptKind.TSX hard-coded — now derives from file extension via scriptKindFromPath()
  4. Namespace import conflation — new ImportRef.namespaceImport field separates import * as ns from default imports
  5. collectCalls test framework noise — property-access chains on expect/vi/etc. now filtered from calledMethods
  6. Date.now() in test builders — replaced with deterministic FIXED_TS constant

Not actioned (1 of 7):

  • KeyringStoragePort transactional API — This is a single-process CLI tool, not a concurrent server. The loadKeyring()/saveKeyring() pattern is appropriate for the current architecture. Adding transactions/locks/CAS would over-engineer the port and introduce centralized-database vocabulary that contradicts the project's CRDT design principles (see CLAUDE.md: "NEVER describe git-warp using centralized-database vocabulary").

@flyingrobots
Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 8, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@flyingrobots flyingrobots merged commit d4c1c6d into main Mar 8, 2026
9 checks passed
@flyingrobots flyingrobots deleted the pr-combo branch March 8, 2026 16:42
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