---
id: IR-15
title: "synapse: invocation-time stderr warnings for deprecated surfaces (deferred from IR-6)"
status: Complete
type: implementation
blocked_by: [IR-6]
unlocks: []
severity: Low
target_repo: synapse
---

## Problem

IR-6 landed tree-rendering markers for deprecated activations and methods — a user running `synapse solar` sees `⚠` on any deprecated method. But at **invocation** time — when the user actually calls a deprecated method — there is no stderr notice. IR-6 deferred this per the retry guidance's minimum-viable scope.

Users who script against synapse (piping into other tools, CI jobs, etc.) may never see the `⚠` in tree rendering — they invoke directly. They deserve a visible deprecation warning at the moment of use, even if they didn't browse the tree first.

## Context

Synapse's invocation path: when the CLI resolves a method and invokes it via the Plexus RPC transport, the method's schema is known (the IR is built first). If the schema carries `methodDeprecation = Just (...)`, synapse can emit a warning to stderr before or after the method's output.

Relevant modules:
- Method dispatch in `Synapse/Monad.hs` (or `Synapse/Transport.hs`, check the actual dispatch site)
- IR consumed from `Synapse/IR/Builder.hs`

Similar treatment for activation-level deprecation: when a deprecated activation is addressed (any method on it), print the activation-level warning once per session.

## Required behavior

1. **Method-level invocation warning.** Before invoking a deprecated method, synapse prints to stderr:
   ```
   ⚠ <activation>.<method> is DEPRECATED since <since>, removed in <removed_in>: <message>
   ```
   Then proceeds with the invocation normally. Method output lands on stdout as usual.

2. **Activation-level invocation warning.** When a deprecated activation is first addressed in a session, synapse prints an activation-level notice to stderr once. Subsequent invocations on the same activation do not repeat the notice (per-session state).

3. **Parameter-level warnings.** Out of scope for this ticket. If a user passes a value for a deprecated parameter, a one-liner notice could fire — tracked as a further follow-up if wanted.

4. **Suppression flag.** `--no-deprecation-warnings` CLI flag suppresses all of the above (for script consumers who don't want noise).

## Risks

| Risk | Mitigation |
|---|---|
| stdout/stderr interleaving in pipe consumers. | Warning goes to stderr only. stdout is untouched. |
| Repetition noise if a deprecated method is called in a loop. | Per-session dedupe using the method's full path as the key. |
| Activation-level notice fires on EVERY call. | Per-session dedupe using the activation namespace as the key. |

## What must NOT change

- stdout format of method invocations.
- Exit codes.
- IR-6's tree rendering decorations.
- `--no-deprecation-warnings` default is OFF (warnings on by default).

## Acceptance criteria

1. `cabal build` and `cabal test` in synapse pass.
2. Invoking a deprecated method (fixture fixture schema or test backend) prints the expected `⚠ … DEPRECATED since … removed in … …` line to stderr before method output.
3. Invoking the same deprecated method twice in one session prints the warning on the first call only.
4. Invoking a non-deprecated method in a deprecated activation prints the activation-level warning once per session.
5. `--no-deprecation-warnings` suppresses all warnings; stdout behavior unchanged.
6. Exit codes unchanged from pre-ticket.

## Completion

PR against synapse. CI green. Status flipped to Complete in the same commit.
