Skip to content

docs: document Teams, and correct what the Team work changed - #283

Open
logicflakes wants to merge 3 commits into
mainfrom
2026-08-12-docs-teams-and-notification-sync
Open

docs: document Teams, and correct what the Team work changed#283
logicflakes wants to merge 3 commits into
mainfrom
2026-08-12-docs-teams-and-notification-sync

Conversation

@logicflakes

Copy link
Copy Markdown
Contributor

The notification and ownership pages were written before Teams became a
first-class entity. They referenced teams as something the reader was assumed
to already know, pointed at a tab that no longer hosts assignment rules, and
described durability by a rule that has since changed.

New page: Teams

configure/teams.md -- what a team is (accountability, not access), what it
holds, why you would contain a user group instead of listing people, and what
archiving one actually does. That last part is the one worth writing down:
archiving a team silently stops delivery on every route targeting it and
degrades ownership of every component it owns, and nothing fails anywhere while
that happens.

Corrected, each checked against the code rather than carried over

  • Assignment rules live under Organization Settings -> Teams now, not User
    Groups (they moved with fix(ui): restore userGroupPermissionsDirty, and move assignment rules to Teams #281).
  • Durability is measured against the team's roster -- members plus everyone
    contributed by contained user groups -- or a contained SSO-backed group. The
    old text said "two direct members", which now understates a team of one that
    contains a ten-person group.
  • The component Settings panel no longer reports a durability status, so the
    page no longer says it does; it points at the ownership report, which is where
    a fleet-level question belongs.
  • The owner picker offers active teams only but still shows an already-stored
    archived owner, labelled. Documented because the alternative reading of an
    empty picker is "this component has no owner".

Added -- existing behaviour, undocumented, easy to get wrong

  • A minimum severity on a subscription whose event types carry no severity does
    not narrow it, it silences it completely. Verified against
    extractEventSeverity and severityGateMatches.
  • A dedup window of 0 means "deliver everything", and dedup cannot be
    demonstrated with the Test button, because synthetic events skip it by design.
    Testing twice always produces two deliveries, which reads exactly like dedup
    being broken.
  • A test that reports no delivery has a third explanation beyond filter and gate
    whenever a route resolves through a team or an owner.

One claim I set out to document and found to be false

The UI hint and the perspectiveGateMatches javadoc both say perspectives make
release and approval events "match nothing", because only vulnerability events
carry affectedReleases. They do carry them: ReleaseChangeHookImpl (created /
lifecycle / bom-diff) and ApprovalEventNotifierImpl (requested / resolved)
both stamp buildAffectedReleases, and that helper copies the component's
perspectives onto each entry. A perspective-scoped route matches those event
types fine -- what it needs is a component that belongs to the perspective.

The page now says that. The stale UI hint is fixed in #282; the identical
javadoc claim lives in rearm-saas and is on the board
(t20260812-121545-31450).

Validation

npm run docs:build clean, with VitePress dead-link checking on (no
ignoreDeadLinks), so every new cross-reference and anchor resolves. Added
lines are plain ASCII.

ReARM Agent (claude2) and others added 3 commits August 12, 2026 12:29
The notification and ownership pages were written before Teams became a
first-class entity, so they referenced teams as something the reader was
assumed to already know, pointed at a tab that no longer hosts assignment
rules, and described durability by a rule that has since changed.

NEW PAGE: configure/teams.md. What a team is (accountability, not access), what
it holds, why you would contain a user group instead of listing people, and
what archiving one actually does -- which is the part worth writing down,
because archiving silently stops delivery on every route targeting the team and
degrades ownership of every component it owns, with nothing failing anywhere.

CORRECTED, each verified against the code rather than carried over:

- Assignment rules now live under Organization Settings -> Teams, not User
  Groups (they moved with #281).
- Durability is measured against the team's ROSTER -- members plus everyone
  contributed by contained user groups -- or a contained SSO-backed group. The
  old text said "two direct members", which now understates a team of one that
  contains a ten-person group.
- The component Settings panel no longer reports a durability status, so the
  page no longer says it does. It points at the ownership report, which is
  where a fleet-level question belongs.
- The owner picker offers active teams only but still shows an already-stored
  archived owner, labelled -- documented because the alternative reading of an
  empty picker is "this component has no owner".

ADDED, all behaviour that existed but was undocumented and is easy to get wrong:

- A minimum severity on a subscription whose event types carry no severity does
  not narrow it, it silences it completely. Verified against extractEventSeverity
  and severityGateMatches.
- Dedup window 0 means "deliver everything", and dedup CANNOT be demonstrated
  with the Test button because synthetic events skip it by design -- testing
  twice always produces two deliveries, which reads exactly like a bug.
- A test that reports no delivery has a third explanation beyond filter and
  gate whenever a route resolves through a team or an owner.

One claim I set out to document and found to be FALSE, so it is now documented
the other way round: the UI hint and the perspectiveGateMatches javadoc both
say perspectives make "release and approval events match nothing" because only
vulnerability events carry affectedReleases. They do carry them --
ReleaseChangeHookImpl and ApprovalEventNotifierImpl both stamp
buildAffectedReleases, complete with the component's perspectives, on every
release, BOM-diff and approval event. A perspective-scoped route matches those
event types fine; what it needs is a component that belongs to the perspective.
The stale UI hint is a separate fix, noted on the board task that asked whether
perspectives should be hidden the way the severity control was -- the answer is
no, keep it and fix the wording.

Docs site builds clean with dead-link checking on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ReARM-Agent: a7dbfd07-7512-451d-8883-2e047dff3a50
ReARM-Agentic-Session: 3b26cb26-2a38-4ed6-811b-d008781071f1
The conventions pass confirmed the perspectives reversal against the producers
independently, and caught that three sentences described UI that only exists on
the unmerged #282.

- Dropped the claim that the component Settings panel does not report
  durability. That is true on #282 and false on main today, and a docs page
  cannot be right about both. The section now says where the fleet-level answer
  lives without describing a panel mid-change.
- Dropped "an archived owner stays visible, labelled" from the ownership page
  for the same reason -- on main it renders a raw uuid. Replaced with what is
  true either way and matters more: the owner stays on record, reports DEGRADED,
  and stops receiving owner-routed notifications.
- The name-collision advice told readers to infer an archived team from a
  refused name. They do not have to infer anything: requireNameAvailable says
  "An archived team named 'X' already exists. Restore it instead of creating a
  new one", and archived teams are listed on the tab rather than hidden behind a
  toggle the way inactive user groups are.
- "Set a team to inactive" named no control. The action is Archive; INACTIVE is
  the status it produces.
- Replaced an invented rationale for name-and-description-only creation with the
  real one from CreateTeamDto: everything else arrives through the update path,
  so each reference is validated by one code path instead of two that can drift.
- "Every event type" overreached -- VEX_STATE_CHANGED has no producer and stamps
  nothing. Narrowed to the three families that do.
- Untangled the Pro list, which named teams twice.

Also linked slack.md's route-target aside at the new page, and normalised the
route picker's team label to "(archived)" in #282 so the docs can name one word
for one state.

Docs build clean with dead-link checking on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ReARM-Agent: a7dbfd07-7512-451d-8883-2e047dff3a50
ReARM-Agentic-Session: 3b26cb26-2a38-4ed6-811b-d008781071f1
Two claims that were still ahead of, or beside, what the code does.

- The CE note said routes and components "address channels directly instead".
  Half right and half meaningless: routes do, but components on CE do not
  address anything -- the mirror carries ComponentOwnershipService while having
  no Team at all, so describing CE's ownership model in one clause was going to
  be wrong whichever way it was phrased. It now says only what it can stand
  behind: routes on CE use channels and channel groups, both available on either
  edition.
- The archived-team bullet still promised an "(archived)" label on the owner
  picker, which is #282 behaviour, not main's. Replaced with the part that is
  true in both and is what the reader needs anyway: archiving stops the team
  being chosen again but does not detach it from what it already owns or serves.

Docs build clean with dead-link checking on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ReARM-Agent: a7dbfd07-7512-451d-8883-2e047dff3a50
ReARM-Agentic-Session: 3b26cb26-2a38-4ed6-811b-d008781071f1
@logicflakes

Copy link
Copy Markdown
Contributor Author

Two-layer review: run, findings fixed

Layer 2 (ReARM-conventions subagent) and Layer 1 both ran. Fixes are in
89da155e and d2251792.

Layer 2 independently confirmed the perspectives reversal against the
producers -- ReleaseChangeHookImpl for all three release events,
ApprovalEventNotifierImpl for both approval events, and
ReleaseNotificationSupport.buildAffectedReleases stamping the component's
perspectives onto each entry. It also checked every other claim on the page
against the named source: org-admin gating, the field table, roster semantics,
lead validation, name uniqueness, archiving consequences, durability, the
severity gate, dedup-0 and the synthetic bypass. Those stand.

The real finding was merge order. Three sentences described UI that exists
only on #282, not on main:

  • "the Settings panel does not report durability" -- on main it still shows the
    status chip and reason line;
  • "an archived owner stays visible, labelled" -- on main the owner picker drops
    archived teams and renders a raw uuid;
  • the (archived) label itself -- the route-target picker said (deactivated).

All three are now written so they are true on main today and remain true after
#282, rather than betting on merge order. Where a fact genuinely could not be
stated both ways, the page says the thing that matters instead: an archived
owner stays on record, reports DEGRADED, and stops receiving owner-routed
notifications.

Layer 2 also caught four text-level errors worth naming, because each was me
writing plausible prose instead of reading the code: the name-collision advice
told readers to infer an archived team when requireNameAvailable names it
outright; "set a team to inactive" named no control (it is Archive); the
rationale for name-and-description-only creation was invented, where
CreateTeamDto's javadoc gives the real one; and "every event type" overreached
past VEX_STATE_CHANGED, which has no producer.

Layer 1 found two more of the same kind: a CE note that described CE's ownership
model in a clause that could not be right (the mirror has
ComponentOwnershipService but no Team), and the last surviving
forward-looking label claim.

Out of scope, filed: the perspectiveGateMatches javadoc in rearm-saas
still carries the false claim this page corrects (t20260812-121545-31450). The
UI half is fixed in #282, along with normalising the route picker's team label to
(archived) so one state has one word across all three pickers.

Validation: npm run docs:build clean with VitePress dead-link checking on
(no ignoreDeadLinks), so every cross-reference and anchor resolves. Added lines
are plain ASCII.

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