Skip to content

Resolve text approvals against the oldest pending approval - #2008

Merged
Aaronontheweb merged 2 commits into
devfrom
fix/approval-text-match-order
Aug 19, 2026
Merged

Resolve text approvals against the oldest pending approval#2008
Aaronontheweb merged 2 commits into
devfrom
fix/approval-text-match-order

Conversation

@Aaronontheweb

@Aaronontheweb Aaronontheweb commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

What

PR 7 of the code-reduction stack (on top of #2007). Implements the maintainer decision on the match-order divergence that the binding-engine consolidation (#2005) surfaced and documented: a text approval reply resolves the OLDEST pending approval (first in, first resolved), on every channel.

  • Discord and Mattermost previously resolved the NEWEST pending approval — that was drift; Slack's oldest-first behavior is canonical.
  • Since no caller passes an order anymore, the ApprovalMatchOrder enum and parameter are removed entirely; PendingApprovalLookup.Resolve hard-codes oldest-first with a remark recording the decision. The requester check is structurally unchanged.
  • New cross-channel contract test Text_approval_response_resolves_earliest_pending_approval: two pending approvals, first text reply resolves the earliest, second reply resolves the remaining one (also proving removal). Runs per channel; fails under the old Newest behavior. No existing test pinned the old behavior.
  • Parity spec updated in both the main spec and the change delta: match order is now a SHALL-be-identical guarantee, not a per-channel hook.

Verification

  • Approval + contract suites: 805 passed / 0 failed (807 on the restacked tip); full Netclaw.Actors.Tests: 3,443 / 0 / 1 pre-existing skip
  • slopwatch 0 issues, headers clean, zero build warnings

Stack

Base: refactor/remove-vestigial (#2007). Note: the whole stack was rebased onto current dev in the same push.

@Aaronontheweb Aaronontheweb added bug Something isn't working channels Discord, Slack, and other channels. labels Aug 19, 2026
@Aaronontheweb
Aaronontheweb force-pushed the fix/approval-text-match-order branch from 728b8f6 to 1dc7d73 Compare August 19, 2026 02:52
@Aaronontheweb
Aaronontheweb force-pushed the fix/approval-text-match-order branch from 1dc7d73 to 728b8f6 Compare August 19, 2026 03:39
@Aaronontheweb
Aaronontheweb marked this pull request as ready for review August 19, 2026 06:23
@Aaronontheweb
Aaronontheweb force-pushed the fix/approval-text-match-order branch from 728b8f6 to 6e40b93 Compare August 19, 2026 12:26
@Aaronontheweb Aaronontheweb changed the title Resolve text approvals against the earliest pending approval Resolve text approvals against the oldest pending approval Aug 19, 2026

@Aaronontheweb Aaronontheweb left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

All text channels now process text-based approvals oldest-> newest by default.

@Aaronontheweb Aaronontheweb left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

LGTM

// millisecond suffix collided when two fires for one reminder landed in
// the same millisecond and threw InvalidActorNameException. The actor is
// single-threaded, so a plain counter is collision-free for its lifetime.
private long _executionSequence;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

LGTM

Base automatically changed from refactor/remove-vestigial to dev August 19, 2026 16:41
Discord and Mattermost resolved the most recent pending approval. Slack
resolved the earliest one. The consolidation found the difference. The
maintainer decided that one order applies to every channel: the earliest
pending approval wins.

Changes:

- PendingApprovalLookup selects the earliest match. It no longer takes a
  match order. The requester check keeps its structure.
- ApprovalResponseFlow drops the matchOrder dependency.
- The three binding actors drop the matchOrder argument.
- The ApprovalMatchOrder enum is removed. No caller needs it.
- A new cross-channel contract test proves that a text reply resolves the
  earliest of two pending approvals on Slack, Discord, and Mattermost.
- The channel-binding-parity spec records the maintainer decision.
Two fires for one reminder inside the same millisecond produced the
same child actor name and threw InvalidActorNameException — observed
as a macOS CI failure in the retry test. The actor is single-threaded,
so a monotonic counter is collision-free for its lifetime. The start
time stays tracked in the active-execution table where it belongs.
@Aaronontheweb
Aaronontheweb force-pushed the fix/approval-text-match-order branch from 30ff5d2 to 250afee Compare August 19, 2026 16:41
@Aaronontheweb
Aaronontheweb merged commit cdd970d into dev Aug 19, 2026
23 checks passed
@Aaronontheweb
Aaronontheweb deleted the fix/approval-text-match-order branch August 19, 2026 18:06
@Aaronontheweb Aaronontheweb added the security Security-related changes label Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working channels Discord, Slack, and other channels. security Security-related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant