Skip to content

feat(adapters): PR-39 workspace-primitives adapters slice#99

Merged
khaliqgant merged 2 commits into
mainfrom
pr39-adapters-slice
May 18, 2026
Merged

feat(adapters): PR-39 workspace-primitives adapters slice#99
khaliqgant merged 2 commits into
mainfrom
pr39-adapters-slice

Conversation

@khaliqgant
Copy link
Copy Markdown
Member

Summary

The relayfile-adapters-owned slice of the PR-39 workspace-primitives gap spec. Companion to relayfile#162 (relayfile slice) and AgentWorkforce/cloud#697 (cloud slice). Generated by a Ricky single-workflow run (26 steps, 0 failed) in an isolated worktree off origin/main; verified green before commit.

Delivered

  • Work Item B: removed the adapter-owned provider-specific digest() handler expectation from adapter docs + the digest/layout contract; the contract check now asserts no per-provider handler is required (generic-over-events rendering, per the canonicalized Work Item A decision).
  • Work Item C: by-edited/<date>/ alias emission wired into the per-provider path mappers (notion last_edited_time, linear updatedAt, github updated_at/merged_at/closed_at, jira/confluence updated), with layout-manifest support.
  • Work Item D: .schema.json / .create.example.json discovery is the adapter source of truth beside every writable resource.
  • Work Item E: provider LAYOUT.md content reflects real alias indexes + writeback resources; __-in-identifier sanitation covered.

Verification

  • npm run test:digest-contracts → 11 category + 11 regression contracts, "adapter metadata/layout contracts do not require provider digest handlers" — exit 0
  • npm run test:writeback-discovery → 73 writeback discovery endpoints, 0 fail — exit 0
  • npm test → 73/73 turbo tasks successful (e.g. github adapter 249 tests / 0 fail) — exit 0

Reviewer notes — included/excluded decisions

  • vitest.config.mjs is included (flagged): unlike cloud#697's quarantine, this is honest infra — the adapters repo's 231 suites are node --test, and a bare root npx vitest run would walk up to a workspace config and spuriously fail all of them ("No test suite found"). This scopes vitest to the one real Vitest suite (core round-trip) with passWithNoTests. It does not exclude any failing test. Calling it out because any new root test config deserves a look.
  • Excluded by-edited/YYYY-MM-DD/_gate-target.ts: a workflow-declared-target placeholder. The real by-edited emission lives in the per-provider path mappers committed here; that file is unreferenced root dead code.
  • Excluded scripts/generated-workflow-artifacts.test.mjs (asserts ricky's .workflow-artifacts/ scratch), workflows/generated/, .workflow-artifacts/, .trajectories/ trail churn.

Scope

Adapters slice only. relayfile#162 + cloud#697 are the companion slices; this completes the 3-repo PR-39 plan.

🤖 Generated with Claude Code

relayfile-adapters-owned slice of the PR-39 gap spec. Companion to
relayfile#162 + cloud#697. Generated by a Ricky single-workflow run
(26 steps, 0 failed) in an isolated worktree; verified green before
commit.

- Work Item B: removed the adapter-owned provider-specific digest()
  handler expectation from adapter docs + the digest/layout contract;
  contract check now asserts no per-provider handler is required.
- Work Item C: by-edited/<date>/ alias emission wired into the
  per-provider path mappers (notion last_edited_time, linear updatedAt,
  github updated_at/merged_at/closed_at, jira/confluence updated) with
  layout-manifest support.
- Work Item D: .schema.json / .create.example.json discovery source of
  truth verified beside every writable resource (73 endpoints).
- Work Item E: provider LAYOUT.md content reflects real alias indexes +
  writeback resources; __-in-identifier sanitation covered.

Verification: npm run test:digest-contracts (11+11 contracts) exit 0;
npm run test:writeback-discovery (73 endpoints, 0 fail) exit 0;
npm test (73/73 turbo tasks) exit 0.

Intentionally excluded:
- vitest.config.mjs IS included: it scopes root `npx vitest run` to the
  one real Vitest suite so the 231 node:test suites aren't mis-collected
  and spuriously failed. Honest infra, not a test quarantine — flagged
  for reviewer awareness.
- by-edited/YYYY-MM-DD/_gate-target.ts: a workflow-declared-target
  placeholder; the real by-edited emission lives in the per-provider
  path mappers committed here. Unreferenced root dead code — left out.
- scripts/generated-workflow-artifacts.test.mjs (asserts ricky's
  .workflow-artifacts scratch), workflows/generated/, .workflow-artifacts/,
  .trajectories/ trail churn.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c17376d5-91f5-4e34-a0d5-68a7786b5303

📥 Commits

Reviewing files that changed from the base of the PR and between a8369db and a5f0f9e.

📒 Files selected for processing (22)
  • .trajectories/index.json
  • packages/github/src/__tests__/emit-auxiliary-files.test.ts
  • packages/github/src/__tests__/path-mapper.test.ts
  • packages/github/src/emit-auxiliary-files.ts
  • packages/github/src/issues/issue-mapper.ts
  • packages/github/src/layout-prompt.ts
  • packages/github/src/path-mapper.ts
  • packages/gitlab/discovery/gitlab/.adapter.md
  • packages/gitlab/discovery/gitlab/projects/{projectPath}/issues/{issueIid}__{slug}/comments/.schema.json
  • packages/gitlab/discovery/gitlab/projects/{projectPath}/merge_requests/{mergeRequestIid}__{slug}/discussions/.schema.json
  • packages/jira/src/__tests__/emit-auxiliary-files.test.ts
  • packages/jira/src/__tests__/path-mapper.test.ts
  • packages/jira/src/layout.ts
  • packages/jira/src/path-mapper.ts
  • packages/linear/src/__tests__/emit-auxiliary-files.test.ts
  • packages/linear/src/emit-auxiliary-files.ts
  • packages/linear/src/layout-prompt.ts
  • packages/notion/src/layout-prompt.ts
  • scripts/digest-layout-contracts.mjs
  • scripts/verify-writeback-discovery.mjs
  • scripts/writeback-discovery-normalizer.test.mjs
  • vitest.config.mjs

📝 Walkthrough

Walkthrough

This PR implements the Workspace Primitive Skills PR-39 adapters slice by eliminating adapter-owned digest handler contracts from documentation and verification scripts; adding "by-edited" date-indexed alias paths to five providers (Confluence, GitHub, Jira, Linear, Notion) via new path builders and reconciliation logic; expanding reserved writeback filename patterns; and systematically documenting editor scratch file ignores across all adapters while refining GitLab schemas.

Changes

Digest Contract Refactoring

Layer / File(s) Summary
Contract documentation and spec updates
.claude/rules/relayfile-integration-digests.md, AGENTS.md, docs/digest-layout-contract.md, docs/workspace-primitives-pr39-adapters-spec.md
Rewrites Relayfile digest integration rules to shift responsibility toward generic upstream rendering; removes requirements that adapters export/own digest handlers, perform deterministic bullet sorting, or conduct per-provider digest tests; adds workspace-primitives PR-39 spec defining concrete adapter work items.
Contract verification script refactoring
scripts/digest-layout-contracts.mjs
Removes provider digest-handler verification loop and supporting helpers; adds self-check that scans script source for stale provider digest requirement strings; updates required documentation "needles" and removes GitHub executable regression contract for digest handlers.

By-Edited Alias Implementation Across Providers

Layer / File(s) Summary
Confluence by-edited implementation
packages/confluence/src/path-mapper.ts, packages/confluence/src/emit-auxiliary-files.ts, packages/confluence/src/layout.ts, packages/confluence/src/layout-prompt.ts, packages/confluence/src/__tests__/emit-auxiliary-files.test.ts, packages/confluence/src/__tests__/path-mapper.test.ts, packages/confluence/src/__tests__/layout-prompt.test.ts, packages/confluence/src/__tests__/layout.test.ts
Adds confluencePageByEditedPath path builder; extends page write planning to compute editedDate from page timestamps and include edited-date alias in path reconciliation; updates layout manifest and prompt with new alias segment and writeback discovery documentation; expands test coverage for path generation and alias reconciliation.
GitHub by-edited implementation
packages/github/src/path-mapper.ts, packages/github/src/emit-auxiliary-files.ts, packages/github/src/issues/issue-mapper.ts, packages/github/src/layout.ts, packages/github/src/layout-prompt.ts, packages/github/src/__tests__/emit-auxiliary-files.test.ts, packages/github/src/__tests__/path-mapper.test.ts, packages/github/src/__tests__/layout-prompt.test.ts, packages/github/discovery/github/.adapter.md
Adds githubByEditedAliasPath path builder; extends GitHubPullRequestEmitRecord and GitHubIssueEmitRecord with lifecycle timestamps; refactors emit-auxiliary-files.ts to compute editedDate from lifecycle fields (merged_at/closed_at/updated_at) and emit/reconcile edited-date aliases; refactors issue-mapper.ts to use static import instead of dynamic loader; updates manifest and layout prompt; expands tests.
Jira by-edited implementation
packages/jira/src/path-mapper.ts, packages/jira/src/emit-auxiliary-files.ts, packages/jira/src/layout.ts, packages/jira/src/layout-prompt.ts, packages/jira/src/__tests__/emit-auxiliary-files.test.ts, packages/jira/src/__tests__/path-mapper.test.ts, packages/jira/src/__tests__/layout-prompt.test.ts, packages/jira/discovery/jira/.adapter.md
Adds jiraIssueByEditedPath path builder; extends emitJiraAuxiliaryFiles to compute editedDate from issue updated timestamps and emit/reconcile alias; updates manifest to include by-edited segment and adds writebackResources mapping for projects; updates layout prompt with alias and writeback discovery documentation; expands test coverage.
Linear by-edited implementation
packages/linear/src/path-mapper.ts, packages/linear/src/emit-auxiliary-files.ts, packages/linear/src/layout.ts, packages/linear/src/layout-prompt.ts, packages/linear/src/__tests__/emit-auxiliary-files.test.ts, packages/linear/src/__tests__/path-mapper.test.ts, packages/linear/src/__tests__/layout-prompt.test.ts, packages/linear/discovery/linear/.adapter.md
Adds linearIssueByEditedPath path builder; extends issue auxiliary-file logic to derive editedDate from updatedAt with fallbacks and emit/reconcile alias; updates manifest and layout prompt; expands tests for path round-tripping and delete reconciliation.
Notion by-edited implementation
packages/notion/src/path-mapper.ts, packages/notion/src/emit-auxiliary-files.ts, packages/notion/src/layout.ts, packages/notion/src/layout-prompt.ts, packages/notion/src/__tests__/emit-auxiliary-files.test.ts, packages/notion/src/__tests__/path-mapper.test.ts, packages/notion/src/__tests__/layout-prompt.test.ts, packages/notion/discovery/notion/.adapter.md
Adds notionByEditedAliasPath path builder with parent scope support; extends page auxiliary-file emitter to compute editedDate from lastEditedTime and emit/reconcile alias; updates manifest and layout prompt with alias documentation and writeback discovery paths; expands test coverage for path generation and reconciliation.

Writeback Discovery and Filename Ignore Patterns

Layer / File(s) Summary
Core reserved filename logic expansion
packages/core/src/runtime/file-native-router.ts, packages/core/src/runtime/file-native-router.test.ts
Expands isReservedWritebackFilename to treat additional temp/partial filename patterns (.tmp, .partial, partial, *.tmp, *.partial) as reserved; adds comprehensive test coverage verifying classifyWrite returns null for temporary and partial writeback filenames.
GitLab schema and adapter documentation refinements
packages/gitlab/discovery/gitlab/.adapter.md, packages/gitlab/discovery/gitlab/projects/{projectPath}/issues/{issueIid}__{slug}/comments/.schema.json, packages/gitlab/discovery/gitlab/projects/{projectPath}/merge_requests/{mergeRequestIid}__{slug}/discussions/.schema.json, packages/gitlab/discovery/gitlab/projects/{projectPath}/issues/{issueIid}__{slug}/comments/.create.example.json, packages/gitlab/discovery/gitlab/projects/{projectPath}/merge_requests/{mergeRequestIid}__{slug}/discussions/.create.example.json
Updates issue note and merge request discussion schemas to include new Relayfile identity fields, enforce strict constraints, and align to canonical shapes; refines adapter documentation for PATCH-based edits, create-draft behavior with rewrite semantics, and explicit ignore rules; updates example placeholder text.
Adapter .adapter.md ignore documentation across all providers
packages/{asana,azure-blob,box,clickup,confluence,dropbox,gcs,github,gmail,google-calendar,google-drive,hubspot,intercom,jira,linear,notion,onedrive,pipedrive,postgres,redis,s3,salesforce,sharepoint,slack,teams,zendesk}/discovery/*/.adapter.md
Updates documentation in all adapter .adapter.md files to explicitly define which editor scratch/temporary filename patterns (partial.json, .tmp.json, .partial.json, *.tmp.json, *.partial.json) are ignored and never treated as create drafts.
Writeback discovery script updates
scripts/generate-writeback-discovery.mjs, scripts/verify-writeback-discovery.mjs, scripts/writeback-discovery-normalizer.mjs, scripts/writeback-discovery-normalizer.test.mjs
Updates generate-writeback-discovery.mjs to render an "Ignore" row in the Operations table; extends verify-writeback-discovery.mjs to validate documented ignore patterns; refines writeback-discovery-normalizer.mjs to recognize GitLab merge request discussions and issue comments path patterns; adds corresponding test coverage.
Test fixtures, snapshots, and configuration
packages/core/fixtures/round-trip/github-pulls/expected.snapshot.jsonl, vitest.config.mjs, .trajectories/index.json
Updates GitHub pulls snapshot fixture metadata path from metadata.json to meta.json; adds Vitest configuration to scope test discovery to core round-trip harness and exclude node_modules/dist; updates trajectory tracking index with new completed entries.

🎯 3 (Moderate) | ⏱️ ~20 minutes


🐰 With eager whiskers and a twitch of delight,
The digest refactor's done—no handlers in sight!
By-edited paths now track changes through time,
While scratch files are banished—a clean, orderly climb!


Possibly related PRs

  • AgentWorkforce/relayfile-adapters#93: Adds per-provider src/digest.ts implementations and public digest exports that directly target the same digest-handler contract surface this PR removes from requirements.
  • AgentWorkforce/relayfile-adapters#41: Extends the same writeback-discovery toolchain this PR updates (scripts/generate-writeback-discovery.mjs and scripts/verify-writeback-discovery.mjs) to enforce ignore-filename documentation and validation.
  • AgentWorkforce/relayfile-adapters#85: Modifies the same per-provider emit<Provider>AuxiliaryFiles implementations (Confluence, GitHub, Jira, Notion, Linear) that this PR extends to output by-edited alias files, creating code-level overlap in write planning flows.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pr39-adapters-slice

Copy link
Copy Markdown

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

Devin Review found 2 potential issues.

View 6 additional findings in Devin Review.

Open in Devin Review

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔴 Linear planIssueDelete omits editedDate, leaking stale by-edited aliases on tombstone deletes

When a Linear issue is deleted via a tombstone, planIssueDelete reads the prior state (which now includes editedDate via extractPriorIssueState) but does not pass it through to issuePathsFor. The write path (planIssueWrite at packages/linear/src/emit-auxiliary-files.ts:310) and its reconciliation branch (line 341) both include editedDate, so updates correctly clean up stale by-edited aliases. However, the delete path at lines 375–383 individually lists every prior field except editedDate. This means issuePathsFor won't generate the linearIssueByEditedPath(...) entry, and the by-edited alias file will survive the delete as a ghost file. Compare with Jira (packages/jira/src/emit-auxiliary-files.ts:358: issuePathsFor({ id, ...(prior ?? {}) })) and Confluence (packages/confluence/src/emit-auxiliary-files.ts:271: pagePathsFor({ id, ...(prior ?? {}) })) which both use object spread and automatically include editedDate.

(Refers to lines 375-383)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Comment on lines +13 to +17
"position": {
"type": "object",
"description": "Optional GitLab position object for diff discussions.",
"additionalProperties": true
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 GitLab issue note schema incorrectly includes position field meant only for MR discussions

The position field was added to the GitLab issue note comment schema (packages/gitlab/discovery/gitlab/projects/{projectPath}/issues/{issueIid}__{slug}/comments/.schema.json:13-16) and documented in .adapter.md line 59 as an optional field. However, the GitLab API's POST /projects/:id/issues/:iid/notes endpoint does not support a position parameter — that field is specific to merge request discussions (diff-level inline comments). With the schema now using additionalProperties: false, the position field will pass writeback validation, but when the adapter forwards it to GitLab's issue note API it will either be silently ignored or cause an error. The description text even says "Optional GitLab position object for diff discussions" which is self-contradictory on an issue note schema. The .adapter.md also mirrors this incorrect addition.

Prompt for agents
The position field was incorrectly added to the GitLab issue note schema. It should be removed from both the .schema.json file at packages/gitlab/discovery/gitlab/projects/{projectPath}/issues/{issueIid}__{slug}/comments/.schema.json (remove the position property from properties) and from the .adapter.md file at packages/gitlab/discovery/gitlab/.adapter.md (remove the position line from the issue note optional fields and fields list). The position field is correct in the merge request discussions schema and should remain there.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/linear/src/emit-auxiliary-files.ts (1)

377-385: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Include prior editedDate in tombstone reconciliation paths.

Delete planning reconstructs prior issue aliases but omits editedDate, so previously emitted by-edited aliases are left stale after tombstones.

Proposed fix
   const paths = issuePathsFor({
     id,
     identifier: prior?.identifier,
     title: prior?.title,
     stateName: prior?.stateName,
     assigneeId: prior?.assigneeId,
     creatorId: prior?.creatorId,
     priority: prior?.priority,
+    editedDate: prior?.editedDate,
   });
🤖 Prompt for 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.

In `@packages/linear/src/emit-auxiliary-files.ts` around lines 377 - 385, The
issuePathsFor call that builds tombstone reconciliation paths omits the prior
issue's editedDate, leaving previously emitted by-edited aliases stale; update
the object passed to issuePathsFor (the invocation assigning to paths) to
include editedDate: prior?.editedDate so the tombstone/path generation considers
the prior edited timestamp (reference symbols: issuePathsFor, prior, paths).
🧹 Nitpick comments (4)
scripts/verify-writeback-discovery.mjs (1)

58-60: ⚡ Quick win

Avoid duplicate adapter-level failures by moving this check outside the endpoint loop.

This check is adapter-wide but runs once per endpoint, so one missing doc line can produce many duplicate failures.

Suggested diff
-    if (!adapterMd.includes('*.tmp.json') || !adapterMd.includes('*.partial.json')) {
-      failures.push(`${adapter.slug}: .adapter.md must document ignored temporary/partial writeback filenames`);
-    }
   }
+
+  if (!adapterMd.includes('*.tmp.json') || !adapterMd.includes('*.partial.json')) {
+    failures.push(`${adapter.slug}: .adapter.md must document ignored temporary/partial writeback filenames`);
+  }
 }
🤖 Prompt for 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.

In `@scripts/verify-writeback-discovery.mjs` around lines 58 - 60, The
adapter-level check that inspects adapterMd for '*.tmp.json' and
'*.partial.json' is currently inside the endpoint loop and pushes failures per
endpoint; move that check out of the endpoint loop so it runs once per adapter:
locate the condition using adapterMd.includes('*.tmp.json') ||
adapterMd.includes('*.partial.json') and the failures.push(`${adapter.slug}:
.adapter.md must document ignored temporary/partial writeback filenames`) and
execute it once after adapterMd is loaded (or before iterating endpoints) rather
than inside the loop that iterates endpoints, ensuring duplicates are not
emitted.
vitest.config.mjs (1)

18-18: ⚡ Quick win

Consider removing passWithNoTests: true for more robust test discovery feedback.

This config deliberately scopes Vitest to only the round-trip harness while other 231 tests run under Node's built-in runner. While passWithNoTests: true is intentional here to avoid failures when Vitest finds no matching tests, it masks potential breakage if the include glob ever fails. Verification confirms the current glob works (1 test file matched), but removing this flag would provide stronger signal if test discovery breaks in the future.

🤖 Prompt for 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.

In `@vitest.config.mjs` at line 18, The config currently sets passWithNoTests:
true which can mask broken test discovery; remove that option (or set
passWithNoTests: false) from the Vitest configuration so the runner fails if the
include glob finds no tests, and then verify the include glob used in the config
still matches the intended round‑trip harness (run the vitest discovery
locally/CI to confirm at least one file is matched); alternatively, if you need
a safety net, comment the setting with a brief note linking it to the single
harness so future changes reconsider it.
packages/github/src/__tests__/emit-auxiliary-files.test.ts (1)

321-349: ⚡ Quick win

Add explicit by-edited assertions for issue alias emission.

The suite validates by-edited for PRs, but not for issues. Adding the issue-side assertion here will catch regressions in the issues alias branch earlier.

Suggested test addition
   assert.ok(writtenPaths.includes(githubByPriorityAliasPath('acme', 'widgets', 'issues', 'P0 Critical', 7)));
+  assert.ok(writtenPaths.includes(githubByEditedAliasPath('acme', 'widgets', 'issues', '2026-05-12', 7)));
   assert.ok(writtenPaths.includes(indexPath));
As per coding guidelines "Each path-mapper helper needs round-trip tests (compose -> parse -> equality); each alias subtree needs a collision test; each `LAYOUT.md` emitter needs a non-empty content test".
🤖 Prompt for 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.

In `@packages/github/src/__tests__/emit-auxiliary-files.test.ts` around lines 321
- 349, Add an assertion to this issue test to verify the "by-edited" alias is
emitted: when calling emitGitHubAuxiliaryFiles with the issue that has
updated_at '2026-05-12T00:00:00Z', assert that client.writes includes the path
produced by githubByEditedAliasPath('acme', 'widgets', 'issues', '<updated_at>',
7) (use the issue's updated_at value), mirroring the PR test pattern; update the
test block around emitGitHubAuxiliaryFiles / writtenPaths to include this new
assert so the issues alias branch is covered.
packages/linear/src/__tests__/emit-auxiliary-files.test.ts (1)

326-336: ⚡ Quick win

Add a tombstone regression for by-edited alias cleanup.

Nice coverage for rename reconciliation. Please add one delete-path test where prior payload includes updatedAt and assert the prior linearIssueByEditedPath(...) is deleted on tombstone.

🤖 Prompt for 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.

In `@packages/linear/src/__tests__/emit-auxiliary-files.test.ts` around lines 326
- 336, Add a regression test that simulates a tombstone delete when the prior
payload contains an updatedAt so the old by-edited alias is cleaned up: in the
existing test use the prior payload with updatedAt set (e.g., date
'2026-05-11'), call the tombstone/delete flow and then assert that deletedPaths
includes linearIssueByEditedPath('2026-05-11', 'issue-123'); also keep the
existing assertions that writtenPaths includes
linearByTitleAliasPath(ISSUES_SCOPE, 'New Title', 'issue-123'),
linearIssuePath('issue-123', 'AGE-8'), and linearIssueByEditedPath('2026-05-12',
'issue-123') to verify new aliases were created while the prior by-edited alias
was removed (helpers to locate: linearIssueByEditedPath, linearByTitleAliasPath,
linearIssuePath, and client.writes/deletedPaths).
🤖 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 `@packages/github/src/emit-auxiliary-files.ts`:
- Around line 472-473: The by-edited path is inconsistent: writes use
editedDateSegment(readLifecycleEditedAt(record)) but the index fallback/recovery
code derives dates from row.updated, causing mismatches and leftover by-edited
files; update the index-based delete/recovery logic to obtain the edited
timestamp via readLifecycleEditedAt(...) (the same source used when writing)
instead of using row.updated, and apply this change wherever similar logic
appears (refer to editedDateSegment, readLifecycleEditedAt, and the index
fallback/tombstone recovery blocks around the other occurrences).

In
`@packages/gitlab/discovery/gitlab/projects/`{projectPath}/issues/{issueIid}__{slug}/comments/.schema.json:
- Around line 13-17: Remove the unsupported "position" property from the
issue-note schema so POST /projects/:id/issues/:issue_iid/notes will no longer
accept diff discussion metadata; locate the JSON schema that defines "position"
(the "position" object entry) and delete that property (and any tests or schema
references that expect it) so validation matches the GitLab API for issue notes.

In `@packages/jira/src/__tests__/path-mapper.test.ts`:
- Around line 121-135: Add a unit that asserts the new alias subtree does not
collide with canonical or sibling alias namespaces: create a collision test
which composes a path with jiraIssueByEditedPath('2026-05-12', issueId) and then
assert it is different from the canonical/sibling paths (e.g.
jiraIssuePath(issueId) and any other alias composer like
jiraIssueByCreatedPath(date, issueId) if present) and/or that
extractJiraIdFromPathSegment applied to the leaf resolves only the intended id;
reference jiraIssueByEditedPath, extractJiraIdFromPathSegment and JIRA_PATH_ROOT
to locate the code under test.

In `@packages/jira/src/layout-prompt.ts`:
- Around line 50-57: The docs under "Writeback Discovery" list writable
discovery resources for jira/projects but the layout manifest
(packages/jira/src/layout.ts) lacks a corresponding writebackResources entry;
either add a writebackResources entry for "jira/projects" in the layout manifest
(update the writebackResources array/object in packages/jira/src/layout.ts to
include the projects resource with the proper schema/create example references)
or remove the "projects" bullet from packages/jira/src/layout-prompt.ts so the
documentation matches the manifest.

In `@packages/linear/src/layout-prompt.ts`:
- Line 10: Update the documentation line for the edited-date lookup
(`/linear/issues/by-edited/YYYY-MM-DD/<issue-uuid>.json`) to reflect the actual
timestamp precedence used at emission instead of claiming it's based only on
`updatedAt`; inspect the emitter code that writes the `/linear/issues/by-edited`
entries (search for the emit site or function that references that path) and
replace the sentence with an explicit ordered list of timestamps used as
fallbacks (e.g. which field is primary, then the secondary, etc.), state the
exact fields (e.g. `updatedAt`, `createdAt`, `closedAt` or whichever the code
uses) and note the date format (YYYY-MM-DD) for the bucket so consumers see the
real precedence and format.

In `@packages/notion/src/layout-prompt.ts`:
- Line 37: Update the by-edited alias examples in
packages/notion/src/layout-prompt.ts to use the dehyphenated UUID identifier
(idSuffix) that the system actually emits instead of the 8-character <short_id>
currently documented; locate the template strings or examples around the
by-edited alias (references in the file where the path shows
"by-edited/YYYY-MM-DD/<short_id>.json") and replace those example placeholders
with the dehyphenated UUID form (the idSuffix used when emitting filenames) so
agents are pointed to the real filenames.

In `@scripts/writeback-discovery-normalizer.test.mjs`:
- Around line 169-183: The test dereferences discussionEndpoint.resource and
commentEndpoint.resource without asserting the endpoints exist; add explicit
existence checks using assert.ok(discussionEndpoint) and
assert.ok(commentEndpoint) immediately after locating them via
normalized.endpoints.find(...) (before any access to .resource or
.resource.pathPatternSource) so a missing endpoint fails with a clear assertion
message rather than a TypeError.

---

Outside diff comments:
In `@packages/linear/src/emit-auxiliary-files.ts`:
- Around line 377-385: The issuePathsFor call that builds tombstone
reconciliation paths omits the prior issue's editedDate, leaving previously
emitted by-edited aliases stale; update the object passed to issuePathsFor (the
invocation assigning to paths) to include editedDate: prior?.editedDate so the
tombstone/path generation considers the prior edited timestamp (reference
symbols: issuePathsFor, prior, paths).

---

Nitpick comments:
In `@packages/github/src/__tests__/emit-auxiliary-files.test.ts`:
- Around line 321-349: Add an assertion to this issue test to verify the
"by-edited" alias is emitted: when calling emitGitHubAuxiliaryFiles with the
issue that has updated_at '2026-05-12T00:00:00Z', assert that client.writes
includes the path produced by githubByEditedAliasPath('acme', 'widgets',
'issues', '<updated_at>', 7) (use the issue's updated_at value), mirroring the
PR test pattern; update the test block around emitGitHubAuxiliaryFiles /
writtenPaths to include this new assert so the issues alias branch is covered.

In `@packages/linear/src/__tests__/emit-auxiliary-files.test.ts`:
- Around line 326-336: Add a regression test that simulates a tombstone delete
when the prior payload contains an updatedAt so the old by-edited alias is
cleaned up: in the existing test use the prior payload with updatedAt set (e.g.,
date '2026-05-11'), call the tombstone/delete flow and then assert that
deletedPaths includes linearIssueByEditedPath('2026-05-11', 'issue-123'); also
keep the existing assertions that writtenPaths includes
linearByTitleAliasPath(ISSUES_SCOPE, 'New Title', 'issue-123'),
linearIssuePath('issue-123', 'AGE-8'), and linearIssueByEditedPath('2026-05-12',
'issue-123') to verify new aliases were created while the prior by-edited alias
was removed (helpers to locate: linearIssueByEditedPath, linearByTitleAliasPath,
linearIssuePath, and client.writes/deletedPaths).

In `@scripts/verify-writeback-discovery.mjs`:
- Around line 58-60: The adapter-level check that inspects adapterMd for
'*.tmp.json' and '*.partial.json' is currently inside the endpoint loop and
pushes failures per endpoint; move that check out of the endpoint loop so it
runs once per adapter: locate the condition using
adapterMd.includes('*.tmp.json') || adapterMd.includes('*.partial.json') and the
failures.push(`${adapter.slug}: .adapter.md must document ignored
temporary/partial writeback filenames`) and execute it once after adapterMd is
loaded (or before iterating endpoints) rather than inside the loop that iterates
endpoints, ensuring duplicates are not emitted.

In `@vitest.config.mjs`:
- Line 18: The config currently sets passWithNoTests: true which can mask broken
test discovery; remove that option (or set passWithNoTests: false) from the
Vitest configuration so the runner fails if the include glob finds no tests, and
then verify the include glob used in the config still matches the intended
round‑trip harness (run the vitest discovery locally/CI to confirm at least one
file is matched); alternatively, if you need a safety net, comment the setting
with a brief note linking it to the single harness so future changes reconsider
it.
🪄 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: CHILL

Plan: Pro Plus

Run ID: eda99559-5862-4b33-a729-952690ecaa84

📥 Commits

Reviewing files that changed from the base of the PR and between 5022400 and a8369db.

📒 Files selected for processing (86)
  • .claude/rules/relayfile-integration-digests.md
  • AGENTS.md
  • docs/digest-layout-contract.md
  • docs/workspace-primitives-pr39-adapters-spec.md
  • package.json
  • packages/asana/discovery/asana/.adapter.md
  • packages/azure-blob/discovery/azure-blob/.adapter.md
  • packages/box/discovery/box/.adapter.md
  • packages/clickup/discovery/clickup/.adapter.md
  • packages/confluence/discovery/confluence/.adapter.md
  • packages/confluence/src/__tests__/emit-auxiliary-files.test.ts
  • packages/confluence/src/__tests__/layout-prompt.test.ts
  • packages/confluence/src/__tests__/path-mapper.test.ts
  • packages/confluence/src/emit-auxiliary-files.ts
  • packages/confluence/src/layout-prompt.ts
  • packages/confluence/src/layout.test.ts
  • packages/confluence/src/layout.ts
  • packages/confluence/src/path-mapper.ts
  • packages/core/fixtures/round-trip/github-pulls/expected.snapshot.jsonl
  • packages/core/src/runtime/file-native-router.test.ts
  • packages/core/src/runtime/file-native-router.ts
  • packages/dropbox/discovery/dropbox/.adapter.md
  • packages/gcs/discovery/gcs/.adapter.md
  • packages/github/discovery/github/.adapter.md
  • packages/github/src/__tests__/emit-auxiliary-files.test.ts
  • packages/github/src/__tests__/layout-prompt.test.ts
  • packages/github/src/__tests__/path-mapper.test.ts
  • packages/github/src/emit-auxiliary-files.ts
  • packages/github/src/issues/issue-mapper.ts
  • packages/github/src/layout-prompt.ts
  • packages/github/src/layout.test.ts
  • packages/github/src/layout.ts
  • packages/github/src/path-mapper.ts
  • packages/gitlab/discovery/gitlab/.adapter.md
  • packages/gitlab/discovery/gitlab/projects/{projectPath}/issues/{issueIid}__{slug}/comments/.create.example.json
  • packages/gitlab/discovery/gitlab/projects/{projectPath}/issues/{issueIid}__{slug}/comments/.schema.json
  • packages/gitlab/discovery/gitlab/projects/{projectPath}/merge_requests/{mergeRequestIid}__{slug}/discussions/.create.example.json
  • packages/gitlab/discovery/gitlab/projects/{projectPath}/merge_requests/{mergeRequestIid}__{slug}/discussions/.schema.json
  • packages/gmail/discovery/gmail/.adapter.md
  • packages/google-calendar/discovery/google-calendar/.adapter.md
  • packages/google-drive/discovery/google-drive/.adapter.md
  • packages/hubspot/discovery/hubspot/.adapter.md
  • packages/intercom/discovery/intercom/.adapter.md
  • packages/jira/discovery/jira/.adapter.md
  • packages/jira/src/__tests__/emit-auxiliary-files.test.ts
  • packages/jira/src/__tests__/layout-prompt.test.ts
  • packages/jira/src/__tests__/path-mapper.test.ts
  • packages/jira/src/emit-auxiliary-files.ts
  • packages/jira/src/layout-prompt.ts
  • packages/jira/src/layout.test.ts
  • packages/jira/src/layout.ts
  • packages/jira/src/path-mapper.ts
  • packages/linear/discovery/linear/.adapter.md
  • packages/linear/src/__tests__/emit-auxiliary-files.test.ts
  • packages/linear/src/__tests__/layout-prompt.test.ts
  • packages/linear/src/__tests__/path-mapper.test.ts
  • packages/linear/src/emit-auxiliary-files.ts
  • packages/linear/src/layout-prompt.ts
  • packages/linear/src/layout.test.ts
  • packages/linear/src/layout.ts
  • packages/linear/src/path-mapper.ts
  • packages/notion/discovery/notion/.adapter.md
  • packages/notion/src/__tests__/emit-auxiliary-files.test.ts
  • packages/notion/src/__tests__/layout-prompt.test.ts
  • packages/notion/src/__tests__/path-mapper.test.ts
  • packages/notion/src/emit-auxiliary-files.ts
  • packages/notion/src/layout-prompt.ts
  • packages/notion/src/layout.test.ts
  • packages/notion/src/layout.ts
  • packages/notion/src/path-mapper.ts
  • packages/onedrive/discovery/onedrive/.adapter.md
  • packages/pipedrive/discovery/pipedrive/.adapter.md
  • packages/postgres/discovery/postgres/.adapter.md
  • packages/redis/discovery/redis/.adapter.md
  • packages/s3/discovery/s3/.adapter.md
  • packages/salesforce/discovery/salesforce/.adapter.md
  • packages/sharepoint/discovery/sharepoint/.adapter.md
  • packages/slack/discovery/slack/.adapter.md
  • packages/teams/discovery/teams/.adapter.md
  • packages/zendesk/discovery/zendesk/.adapter.md
  • scripts/digest-layout-contracts.mjs
  • scripts/generate-writeback-discovery.mjs
  • scripts/verify-writeback-discovery.mjs
  • scripts/writeback-discovery-normalizer.mjs
  • scripts/writeback-discovery-normalizer.test.mjs
  • vitest.config.mjs

Comment thread packages/github/src/emit-auxiliary-files.ts
Comment thread packages/jira/src/__tests__/path-mapper.test.ts
Comment thread packages/jira/src/layout-prompt.ts
Comment thread packages/linear/src/layout-prompt.ts Outdated
Comment thread packages/notion/src/layout-prompt.ts Outdated
Comment thread scripts/writeback-discovery-normalizer.test.mjs
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

7 issues found across 86 files

Tip: instead of fixing issues one by one fix them all with cubic
Partial review: This PR has more than 50 files, so cubic reviewed the highest-priority files first. During the trial, paid plans get a higher file limit.
You can try an ultrareview to bypass the file limit, comment @cubic-dev-ai ultrareview. Learn more.
Re-trigger cubic

Comment thread package.json Outdated
Comment thread packages/gitlab/discovery/gitlab/.adapter.md Outdated
Comment thread packages/gitlab/discovery/gitlab/.adapter.md
Comment thread packages/linear/src/emit-auxiliary-files.ts
@khaliqgant khaliqgant merged commit 21e86f5 into main May 18, 2026
2 of 3 checks passed
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