Skip to content

feat(server): add bounded thread content search

MacroscopeApp / Macroscope - Effect Service Conventions failed Aug 30, 2026 in 1m 28s

Effect Service Conventions: 1 issue found

apps/server/src/orchestration/Services/ProjectionSnapshotQuery.ts — the new service failure ProjectionThreadContentSearchInputError extends the built-in Error with a hand-written _tag and stores an unstructured message as its only data. Service failures must be declared with Schema.TaggedErrorClass and structured attributes, deriving message from those attributes (matching apps/server/src/orchestration/Errors.ts and apps/server/src/persistence/Errors.ts). Structured fields identifying the violated bound would also replace the single fixed sentence produced at the construction site in Layers/ProjectionSnapshotQuery.ts.

Details

Note

Your check run agent prompt is: .macroscope/check-run-agents/effect-service-conventions.md
More information about how Check Run Agents work can be found in our Help Center.

Files reviewed:

  • apps/server/src/orchestration/Services/ProjectionSnapshotQuery.ts
  • apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.ts
  • apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.search.test.ts

Checked and found acceptable:

  • Effect module imports use subpath namespaces (effect/Effect, effect/Layer, effect/Schema, effect/unstable/sql/*) in both the implementation and the new test; no consolidated named imports from "effect".
  • No ManagedRuntime.make, runPromise, or runPromiseExit introduced; no service-instance parameters or hidden module-global dependencies. Layer.succeed usages in the new test are legitimate test doubles for RepositoryIdentityResolver and ProjectFaviconResolver.
  • The existing ProjectionSnapshotQueryShape / Services + Layers split is pre-existing structure that this PR only extends; consolidating it would be unrelated repository-wide cleanup and was not flagged.
  • The added test covers new backend behavior (bounded content search, pagination, archived/deleted filtering, literal and non-ASCII queries, legacy RPC unchanged), which is required rather than test bloat for a mechanical refactor.

🔍 Agent activity — 8 tool calls

💭 I'm checking whether the pre-existing ProjectionSnapshotQueryShape interface violates the convention of defining interfaces inline in Context.Service, but since it's retained rather than introduced by this PR, I should only flag genuinely new violations within the changed scope. Looking closer, ProjectionThreadContentSearchInputError extending Error with a readonly _tag clearly violates the requirement to define service failures via Schema.TaggedErrorClass with structured attributes rather than an unstructured message — and since this is newly introduced, it's a strong finding. I want to check how other errors are defined in that Services file to confirm the expected pattern, and verify whether the new searchThreadContent method follows the existing shape's conventions.

1. browse_code — apps/server/src/orchestration/Services/ProjectionSnapshotQuery.ts

2. git_tools — TaggedErrorClass

💭 This confirms the new error class breaks convention—it should use Schema.TaggedErrorClass with structured attributes and a derived message rather than a manual _tag and plain string. I want to check persistence/Errors.ts to see how ProjectionRepositoryError is styled, so I can suggest a concrete fix.

3. browse_code — apps/server/src/orchestration/Errors.ts

4. git_tools — class|message

💭 I'm noting that the new error class should be a TaggedErrorClass with structured attributes rather than just an unstructured message string—it needs stable, serializable context like the field, value, or limit that failed. Now I'm checking the test file's imports and layer setup to see how it composes with the rest of the module. I'm weighing whether the file's continued use of the Shape["method"] pattern for referencing the service interface counts as a violation worth flagging, but since this PR is only consuming/extending an existing service rather than refactoring its structure, I'm leaning toward not treating that as a new issue introduced by the change. Merging Services/Layers here would be unrelated cleanup, so I'm skipping it and moving on to check the Layers file's changed regions for other problems like error mapping or validation alternatives, planning to look at the searchThreadContent implementation and its imports next.

5. git_tools — ^import|^} from

6. git_tools — extends Error {

💭 There's another instance of extends Error in threadHistoryPaging.ts that looks like existing precedent, so I want to check that file first.

7. browse_code — apps/server/src/orchestration-v2/threadHistoryPaging.ts

💭 Even though there's older code precedent, the current instructions take priority here, and the convention is clear: service failures should use TaggedErrorClass with structured attributes, deriving the message rather than storing it as unstructured text. This new failure violates that, so I'll flag it with an inline comment, noting also that the message is passed as unstructured text at the failure site. I want a structured field indicating which bound was violated, suggesting attributes like field and limit/value. Checking the rest of the new implementation, everything else looks fine — Effect.fn usage, escapeLikePattern, no ManagedRuntime concerns, and the test's use of Layer.succeed for test doubles is acceptable. There's no redundant discriminator or duplicate error tags, and the "don't copy cause.message into detail" rule doesn't apply here. Now I'm pinpointing where in the diff to place the inline comment — lines 74-76 of the new ProjectionSnapshotQuery.ts file. Since making it a proper inline suggestion would require adding a Schema import that isn't currently present in that file, I'll need to use a unified diff instead of a self-contained suggestion. Since fixing this properly touches multiple hunks (the import addition plus the class change) and also requires updating the construction site in the Layers file where a plain message string is passed, this doesn't cleanly qualify as a single-hunk fix. I'll skip the formal diff and instead offer a short illustrative code snippet to convey the intended shape, while noting that the call site will also need updating. For the review comment, I'll consolidate my notes into one comment on the failure site, mentioning both the convention issue and that the message should carry structured context about which bound was violated, then confirm the test's use of _tag is fine with a TaggedErrorClass approach. I'll flag this as a clear convention violation that should fail the check, targeting the review comment at lines 74-76 on the new file's right side, then post it.

8. modify_pr — Effect service conventions review: one finding on the new service failure type.


Agent Credits: 55 credits

Token usage: 12 uncached input · 202,124 cache-read input · 46,736 cache-write input · 5,108 output
Agent Credits may also include non-token charges from external tools such as web research.