Completes #16 (architecture review QRun-IO/qqq#1150, finding F12; agreed with the collaboration owner).
Follower fan-out.
AlertRouter adds the followers from core RecordFollowers.get(instance, ref, FollowEvent.ALERT) (QRun-IO/qqq#1164, in 4.1.0-RC.6) to any alert that concerns a record.
Followers are deduplicated with existing recipients by user and channel.
A follower must pass the same source-record permission and record-lock checks as other recipients.
The recipient's own preferences and suppression apply.
No provider registered means no change.
No dependency on qbit-collaboration, which implements the provider. Removes the STAND-IN(core=QRun-IO/qqq#1164, …) marker.
Guardrails: parent qbit-build-parent2.1.0 with qbit.guardrails.enforce=true and strict raw-route mode. All checks pass. The opt-in legacy Alertmanager alias is a documented advisory, and strict-mode tests check that it's rejected.
Reworded comments that only used the word "stand-in", e.g. the TEST channel's sample alert.
Tests
./mvnw -B verify on released RC.6: 94 tests, 0 failures, 0 checkstyle violations, JaCoCo gates pass. The new FollowerFanoutTest has 8 cases:
## Summary
Completes #16 (architecture review QRun-IO/qqq#1150, finding F12; agreed with the collaboration owner).
- **Follower fan-out.**
- `AlertRouter` adds the followers from core `RecordFollowers.get(instance, ref, FollowEvent.ALERT)` (QRun-IO/qqq#1164, in **4.1.0-RC.6**) to any alert that concerns a record.
- Followers are deduplicated with existing recipients by user and channel.
- A follower must pass the same **source-record permission and record-lock checks** as other recipients.
- The recipient's own preferences and suppression apply.
- No provider registered means no change.
- No dependency on qbit-collaboration, which implements the provider. Removes the `STAND-IN(core=QRun-IO/qqq#1164, …)` marker.
- **Guardrails:** parent `qbit-build-parent` **2.1.0** with `qbit.guardrails.enforce=true` and strict raw-route mode. All checks pass. The opt-in legacy Alertmanager alias is a documented advisory, and strict-mode tests check that it's rejected.
- Reworded comments that only used the word "stand-in", e.g. the TEST channel's sample alert.
## Tests
`./mvnw -B verify` on released RC.6: 94 tests, 0 failures, 0 checkstyle violations, JaCoCo gates pass. The new `FollowerFanoutTest` has 8 cases:
- followers notified;
- dedup;
- no read access means not notified;
- locked record;
- preferences respected;
- no provider;
- empty list;
- non-record alert.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Completes #16 (architecture review QRun-IO/qqq#1150, finding F12; agreed with the collaboration owner).
AlertRouteradds the followers from coreRecordFollowers.get(instance, ref, FollowEvent.ALERT)(QRun-IO/qqq#1164, in 4.1.0-RC.6) to any alert that concerns a record.STAND-IN(core=QRun-IO/qqq#1164, …)marker.qbit-build-parent2.1.0 withqbit.guardrails.enforce=trueand strict raw-route mode. All checks pass. The opt-in legacy Alertmanager alias is a documented advisory, and strict-mode tests check that it's rejected.Tests
./mvnw -B verifyon released RC.6: 94 tests, 0 failures, 0 checkstyle violations, JaCoCo gates pass. The newFollowerFanoutTesthas 8 cases:🤖 Generated with Claude Code