Skip to content

Sync csa branch with main - #1273

Merged
sarthak shaha (Sarthak-Shaha) merged 11 commits into
mainfrom
automation/update_main
Oct 13, 2026
Merged

sarthak shaha (Sarthak-Shaha) merged 11 commits into
mainfrom
automation/update_main

Conversation

@silabs-matter-ci-bot

Copy link
Copy Markdown
Contributor

This PR syncs the csa branch with the main branch.

PR MUST BE MERGED WITH MERGE COMMIT - ADMIN MUST ENABLE THE OPTION

Mahesh (pimpalemahesh) and others added 11 commits October 12, 2026 02:32
* Add support for BRD4343C

* Update is_si917y_mcu block

* Update is_si917y_mcu block

* Update matter_support submodule
…Auto-merged by platform-bot) (#74464)

When the debug console is configured with non-blocking transfer via
SerialManager, log output is buffered in a ring buffer and flushed
asynchronously by a lower-priority SerialManager task. After
RunAllTests() returns, test_task exits and FreeRTOS enters
prvTaskExitError(), which spins at the task's high priority. This
starves the SerialManager task, preventing the final test results
(including "Done running all tests") from being flushed to UART,
causing the CI harness to time out.

Add an infinite loop after RunAllTests() to keep test_task alive,
matching the pattern already used in the FSL_OSA_MAIN_FUNC_ENABLE
path.
* [MFM] Regenerate Media File Management XML with Alchemy v1.7.7

Regenerate media-file-management-cluster.xml from current spec master.
Fixes #74557: SupportedMimeTypes read privilege is View per spec (was
Manage), which failed TC-ACE-2.1 / TC-ACE-2.4.

The regen also brings in other spec changes:
- ImageUri -> ImageURI (FileDescriptionStruct, AddFile, OfferFile)
- RequestSharedFiles.SupportedMimeTypes is no longer nullable
- GetSharedFileResponse.FileDescription is mandatory (still nullable)
- TotalStorage/AvailableStorage drop the default="0"

Update the MFM server, delegate, unit tests, tv-app, tv-casting-app and
Python test base for the renamed and re-typed fields.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Rename imageUri to imageURI in tv-casting Darwin bridge structs

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
…tch entries by value (#74429)

* fix(jfds): compare CommitFailed failureCode as an IM Status Code

statusEntry.failureCode holds an Interaction Model Status Code. The
RefreshNode triage for CommitFailed group, binding, node key set and ACL
entries converted it with CHIP_ERROR(uint8_t), which builds an
SdkPart::kCore error, and compared that against CHIP_IM_GLOBAL_STATUS(),
which builds an SdkPart::kIMGlobalStatus error. The two never compared
equal, so ConstraintError and ResourceExhausted entries were classified
as recoverable and retried instead of removed.

The triage now casts failureCode to Protocols::InteractionModel::Status
and compares it against the Status values, as RefreshNode specifies
(Matter Core R1.4.2, 11.24.7.11).

The group entry branch still skips the entry in both cases; only its
comparison changes here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(jfds): add value-identity matching for ACL and binding entries

The Access Control Acl attribute and the Binding attribute carry no
per-entry identity on the wire: the datastore's listID and statusEntry
are not written to the node, so an entry fetched from a node can only be
matched to a datastore entry by its value.

Add pure functions in chip::app::detail for that:

- AclEntryValueEquals compares privilege, authMode, subjects and
  targets. Subjects and targets are compared as multisets. A null list
  equals an empty one: AclStorage reports an empty subject or target
  list as null, while the datastore sends an empty non-null list.
- BindingEntryValueEquals compares endpointID and the binding target.
- ApplyAclEdit and ApplyBindingEdit return the list that results from
  applying one add, replace or DeletePending removal to a node's fetched
  list. Removal erases every equal entry and treats an absent entry as
  already removed. An ACL removal or replacement also erases the
  superseded value, if one is given.

The bodies of BindingMatches and ACLTargetMatches move into
detail::BindingTargetValueEquals and detail::AclTargetValueEquals; the
private members forward to them, so existing callers are unchanged.

Also add datastore::ACLEntryStruct::supersededValue and a private
EncodeAclEntryForSync, both unused until later changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): record failed syncs as CommitFailed

Every Delegate::SyncNode completion receives the result of the
operation, but the datastore's completions returned on error without
recording anything: a failed add stayed Pending and a failed removal
stayed DeletePending. When SyncNode failed to start, most callers
returned the error and left the entry unchanged.

Completions and start failures now record CommitFailed, with the IM
status of the error as FailureCode, as the specification describes for
each operation. Removal completions erase the entry only on success.

CommitFailed is the same state for a failed add and a failed removal,
and RefreshNode re-writes recoverable CommitFailed entries. Entries
being removed are therefore also marked internally: a pendingRemoval
flag on ACL entries, and sets keyed by entry identity for bindings,
endpoint groups and node key sets. RefreshNode leaves those ACL and
binding entries out of its full-list writes and erases them once the
write succeeds, and does not re-write node key sets being removed. Add
paths clear any removal mark left for their key, since list IDs and
group assignments can recur.

The Delegate interface now documents its contract: an accepted call
completes exactly once, argument spans are valid only during the call,
fetched vectors only during the callback, and delegates do not modify
the vectors they are given.

In the Linux jf-admin-app delegate:

- Connection failures, GroupKeyMap write and reconnect failures, KeySet
  read failures, AddGroup start failures and start failures of the
  write, invoke or read in OnDeviceConnectedFn now complete the
  operation with the error. A key set write for an unknown key set ID
  completes with CHIP_ERROR_NOT_FOUND. Previously these paths released
  the command without calling the completion.
- CallbackContext::Complete clears the stored callbacks after invoking
  them, so each operation completes once.
- The binding single-entry sync completes with the fetch error when the
  binding list cannot be read, instead of writing a list that holds
  only the new entry.
- OnWriteFailureResponse no longer writes CommitFailed and a truncated
  error code into the vector passed to SyncNode.
- When GetConnectedDevice fails, SyncNode and Fetch* release the
  in-flight command before returning the error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): tear down RefreshNode in one place

RefreshNode reset its state at about a dozen separate sites, and some
paths reset nothing: a RefreshNode call that failed synchronously, for
example for an unknown node, left mRefreshingNodeId set and every later
refresh returned CHIP_ERROR_INCORRECT_STATE. Errors from ContinueRefresh
inside callbacks were ignored.

FinishRefresh now ends a refresh and resets all of its state, including
the per-pass lists and indices. It is the only place that clears
mRefreshingNodeId. RefreshNode calls it when ContinueRefresh fails, and
every callback calls it when the next step fails.

A failed binding write, group entry write or key set write no longer
ends the refresh: the failure is recorded on the entries and the
remaining stages still run, including the ACL write. The node is marked
Committed only if every stage succeeded; otherwise it stays Pending.

On a successful binding write, every written Pending or CommitFailed
binding is now marked Committed with FailureCode 0. Previously the
completion copied the state of the written copy back, so a binding that
was being retried after CommitFailed stayed CommitFailed.

The binding and ACL completions key on the node ID captured when the
write was issued. On success they also erase entries being removed, and
the ACL completion clears supersededValue on the entries it commits. On
failure they record CommitFailed on the written entries and on entries
being removed, which keep their removal intent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): match refreshed ACL entries by value

The Access Control Acl attribute has no per-entry identity: the ACL
entries RefreshNode reads from a node carry no listID, so every fetched
entry had listID 0. The merge matched fetched entries to datastore
entries by listID, so it imported only the first fetched entry, and
treated datastore entries with other listIDs as absent from the node.

The merge now compares values with detail::AclEntryValueEquals. For
each fetched entry, in order:

- If it equals a datastore entry for the node, in any state, that entry
  is kept with its listID and state.
- If it equals the supersededValue of an entry for the node, it is not
  adopted. The node still holds the value from before a Pending update,
  and the refresh write replaces it.
- Otherwise it was added outside the datastore and is adopted as
  Committed with a new listID. RefreshNode says the remaining entries
  should be replaced by the entries on the node; this is a "should", and
  adopting a superseded value would undo the pending update.

Datastore entries the node does not hold are erased if they are
Committed or being removed (the removal has taken effect).

Fixes #74377.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): send the real entry when removing groups and key sets

RefreshNode's endpoint-group and key-set removal steps, and
RemoveNodeKeySetEntry, passed a zero-initialized entry to SyncNode. Its
state is Pending and its IDs are 0, so the Linux delegate sent
AddGroup(0) or KeySetWrite for key set 0 instead of RemoveGroup or
KeySetRemove. They now send a copy of the entry being removed, in the
DeletePending state.

The endpoint-group step now handles CommitFailed entries like the other
lists. Previously it skipped them whether or not the failure was
recoverable. Unrecoverable failures are erased; recoverable ones are
retried as an add, or as a removal for an entry being removed. It also
collects its work before issuing any SyncNode: a completion that ran
synchronously erased the entry the loop's iterator pointed at.

The key-set removal step now also covers entries whose earlier removal
failed, and RemoveNodeKeySetEntry records the removal intent, erases the
entry only on success, and records CommitFailed on failure.

The endpoint-group and binding fetch merges now erase entries the node
no longer holds if they are Committed or being removed, whatever their
state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): limit RefreshNode's binding merge to the fetched endpoint

RefreshNode fetches the Binding attribute one endpoint at a time and
then erased every Committed or DeletePending binding of the node that
was not in that endpoint's list, including bindings on other endpoints.
Because the root endpoint is always fetched, a refresh erased the node's
bindings on every other endpoint, or re-imported them with new list IDs.

The merge now only erases bindings on the endpoint whose list it
fetched, as the endpoint-group merge already does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): keep removing entries whose removal failed unrecoverably

RefreshNode must drop an entry whose CommitFailure is unrecoverable
(CONSTRAINT_ERROR or RESOURCE_EXHAUSTED). When that entry was being
removed, the node still holds it, and the next refresh's merge adopted
the node's copy as a new Committed entry, or added it back as a missing
entry for bindings and endpoint groups.

The refresh triage now drops such entries first, as specified, and
records a tombstone for the value of any dropped entry that was being
removed (for ACLs, also its superseded value). When a later refresh
finds a tombstoned value on the node, it adds the value back as
DeletePending with removal intent, and that refresh removes it. For
bindings and endpoint groups this is the "add any missing entries" step;
for ACLs and key sets the specification says the remaining entries
"should" be replaced by the node's, which this refines. A tombstone is
dropped when a refresh finds the node no longer holds its value, and
each tombstone list is capped at the size of the list it shadows.

Adding an entry equal to one that is being removed now cancels the
removal: AddACLToNode, AddBindingToEndpointForNode,
AddGroupIDToEndpointForNode and AddNodeKeySetEntry clear the removal
intent, mark the entry Pending and sync it as an add. Previously they
returned early and the removal went ahead. An add also drops any
tombstone for its value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): serialize read-modify-write syncs per node

A single-entry ACL or binding sync reads the node's whole Acl or Binding
list, edits it and writes it back. Two such syncs for the same node could
run at the same time, and the second write replaced the first. A sync
could also run while RefreshNode was writing the same list.

The datastore now runs at most one of these operations per node at a
time. AddACLToNode, RemoveACLFromNode, the ACL updates in UpdateGroup,
AddBindingToEndpointForNode and RemoveBindingFromEndpointForNode record
their change, then start the sync, or queue it behind the node's
operation in flight. A queued operation looks its entry up by node and
list ID when it starts: it syncs a removal if the entry is being removed,
an add of the current value if the entry is not Committed, and nothing
otherwise. A completion applies only if the entry is still being added
or removed as when its sync started, so an add that cancels an in-flight
removal is kept.

RefreshNode returns BUSY while the node has operations in flight or
queued, and holds the node until it finishes; operations requested in
the meantime run afterwards. The refresh no longer erases an entry whose
removal was requested while its write was in flight, since that write
still contained the entry.

The queue lives in the datastore rather than in the delegate so that it
applies to every delegate and can be unit tested. It is bounded at
kMaxACLs waiting operations per node; beyond that the operation returns
RESOURCE_EXHAUSTED. Like the rest of the datastore it uses std::map and
std::deque, which allocate on the heap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jf-admin-app): replace and remove ACL and binding entries by value

The Acl and Binding attributes have no per-entry identity: entries read
from a node carry no nodeID or listID. The Linux delegate's single-entry
syncs still matched on them. An ACL removal compared nodeID and listID
against the fetched entries, which are always 0, and an update appended
the new value next to the old one. A binding add appended the entry even
if the node already held it.

The single-entry ACL SyncNode overload now also takes the entry's
superseded value, and the datastore sends the full stored value for
removals instead of an entry carrying only nodeID and listID. The
delegate applies the edit with detail::ApplyAclEdit, and bindings with
detail::ApplyBindingEdit, then writes the resulting list:

- a removal removes every entry equal to the value, and to the
  superseded value if set;
- an update removes the superseded value and adds the new one;
- an add is skipped if an equal entry is present.

Removing a value the node does not hold, or several equal copies of it,
is not an error: identical entries are the same grant, and an absent
entry is already removed.

UpdateGroup records an ACL entry's previous value as supersededValue
before changing its privilege, keeping the oldest value across
back-to-back updates, and every commit clears it. When an update
succeeds after the entry was updated again, the sent value becomes the
superseded value for the next sync.

This changes the signature of the single-entry ACL overload of
JointFabricDatastore::Delegate::SyncNode; the three-argument form is
removed. Joint Fabric is provisional, and the jf-admin-app delegate is
the only implementation in the tree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(jfds): update RefreshNode comment in TC_JFDS_BindingSync

RefreshNode now keeps all of a node's ACL entries, so the comment no
longer says it keeps only part of them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): log RefreshNode stage failures

A failed group, key set or binding write during RefreshNode leaves the
node Pending, but only the binding write logged its error. The refresh
now logs every failed write with its error. A failed fetch of an
endpoint's groups or bindings, which also happens for endpoints without
the Groups or Binding cluster, is logged, and the merge for that
endpoint is skipped as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* test(jfds): pass MakeEndpointGroupEntry's failure code as uint8_t

DatastoreStatusEntryStruct's failureCode is a uint8_t. The helper took a
uint32_t, and Darwin builds, which enable -Wimplicit-int-conversion,
rejected the narrowing assignment.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): do not commit ACL updates made during RefreshNode's write

RefreshNode's ACL write holds the node's sync slot, so a permission
change made by UpdateGroup while it is in flight is queued behind it.
On success, the write's completion marked every Pending entry it had
written as Committed and cleared its superseded value, although the
write carried the value from before the change. The queued sync then
found a Committed entry and did nothing: the node kept the old
privilege while the datastore reported the new one as Committed.

The refresh now keeps owned copies of the values it writes. The
completion commits an entry only if its value still equals the written
one. Otherwise the written value becomes the entry's superseded value,
and the queued sync replaces it, as single-entry ACL syncs already do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): ignore group and key set removals cancelled by an add

Group and key set syncs are not serialized per node, so an add can
cancel a removal while the removal is in flight. The removal's
completion erased the entry by key alone, including the re-added entry,
whose own completion then found nothing to commit. The node held the
group while the datastore no longer listed it. A failed removal
likewise marked the re-added entry CommitFailed.

The removal completions in RemoveGroupIDFromEndpointForNode,
RemoveNodeKeySetEntry and RefreshNode's group and key set stages now
apply only to entries that are still being removed, as ACL and binding
completions already do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): match ACL entries by value in AddACLToNode

AddACLToNode looked for an existing entry with ACLMatches, which
compares subjects and targets in order, while the node's edits and
RefreshNode's merge compare them as multisets. Adding an entry that
differed only in subject or target order created a second datastore
entry that was the same entry on the node. Removing either one then
removed the node's only copy, and the next refresh dropped the other
from the datastore.

AddACLToNode now decodes the entry first and matches it with
detail::AclEntryValueEquals. ACLMatches, and ACLTargetMatches, which
only it used, are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* refactor(jfds): store removal intent on binding, group and key set entries

Removal intent for bindings, endpoint groups and node key sets lived in
three sets keyed by each entry's identity, beside the entries
themselves. Every erase and add had to clear the matching key, and
RemoveNode, which erases only the node record, left keys behind that
would mark a later entry with the same identity as being removed.

The entries are now stored as datastore::EndpointBindingEntryStruct,
datastore::EndpointGroupIDEntryStruct and datastore::NodeKeySetEntryStruct.
Each extends the generated cluster type with a pendingRemoval flag, as
datastore::ACLEntryStruct already does, so the intent is created and
destroyed with its entry. MarkRemovalRequested and HasRemovalIntent
become one template each, and ClearRemovalIntent is removed.

The flag is not on the wire: the EndpointGroupIDList,
EndpointBindingList and NodeKeySetList attribute reads encode the
generated base type, so they are unchanged.

This changes the return types of GetEndpointGroupIDList,
GetEndpointBindingList and GetNodeKeySetList. Their element types
derive from the generated types, so code that reads the entries keeps
working; code that inserts entries constructs the new types. Joint
Fabric is provisional, and the cluster server and the unit tests are
the only users in the tree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): queue group and key set syncs per node, and answer BUSY when full

Only single-entry ACL and binding syncs went through the per-node queue.
Group and key set syncs started at once, so an add and a removal of the
same group or key set could reach a node out of order.

Every single-entry sync outside RefreshNode now goes through
RunOrQueueNodeSync: AddGroupIDToEndpointForNode,
RemoveGroupIDFromEndpointForNode, UpdateGroup (endpoint groups, node key
sets and ACL entries) and UpdateKeySet. As for ACLs and bindings, each
queued operation looks its entry up when it starts, and bindings, groups
and key sets share one StartEntrySync. RefreshNode's own syncs do not
queue: the refresh already holds the node's slot. Queued entries stay
Pending until their sync runs.

A full queue now fails the command with BUSY instead of
RESOURCE_EXHAUSTED. The specification ties RESOURCE_EXHAUSTED to the
datastore's storage capacity, with duties to notify the user and offer a
purge, while BUSY is a temporary condition that commissioners retry.
Commands check the queue before changing any entry, so a rejected
command leaves the datastore unchanged and the retry repeats it.
Previously an ACL or binding add stored the entry first, and the retry
found it Pending, succeeded and queued nothing. UpdateGroup and
UpdateKeySet check every affected node before changing anything.

Behavior changes that follow the specification:

- AddGroupIDToEndpointForNode marks the node's key set entry Committed
  once the key set is written ("If this succeeds, update the new KeySet
  entry in the Datastore to Committed"); it was left Pending.
- UpdateKeySet stores the key set, then marks each node entry for it
  Pending and syncs the stored value, Committing it on success. It sent
  the command's value before storing it and left the entries' state
  unchanged.

The group sync in AddGroupIDToEndpointForNode is queued behind the key
set sync, and is not attempted if the key set failed to reach the node,
as before: the node would reject the group's key map with an
unrecoverable CONSTRAINT_ERROR, and RefreshNode would drop the entry.
RemoveNodeKeySetEntry, used by UpdateGroup when a group's key set
changes, now removes the old key set from every node in the group, not
only the first one found.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): discard syncs in flight when the joint fabric is removed

ClearAllRecords, which OnFabricRemoved runs for the anchor fabric,
emptied the per-node sync queues but left the refresh state and the
operations in flight alone. Their completions still ran afterwards. A
stale single-entry completion called FinishNodeSync for its node, which
started an operation queued after the removal while another was already
running, so two read-modify-write syncs could overlap. A refresh in
flight kept its node ID set, and RefreshNode returned INCORRECT_STATE
until the stale refresh called back, and its completion could then end
a later refresh.

ClearAllRecords now resets all refresh state along with the queues, and
increments a generation counter. Every refresh and queued-sync
completion captures the counter when its operation starts and returns
without touching the datastore if it has changed. Queued operations are
dropped without starting.

Nothing changes for clients: the specification has no requirements for
syncs in flight when the fabric is removed, and its CommitFailed and
retry rules apply only to entries that still exist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(jfds): share duplicated sync bookkeeping

- CancelRemoval replaces five copies of the block that re-adds an entry
  being removed.
- MarkRefreshWriteFailed replaces MarkRefreshBindingsSyncFailed and
  MarkRefreshAclsSyncFailed, which differed only in their lists.
- InRefreshWrite replaces four lambdas that looked an entry up in the
  active refresh's ACL or binding write.
- AclTombstoneMatches replaces the tombstone predicate written out in
  RefreshNode's ACL merge and in AddACLToNode.
- QueueNodeKeySetSyncs replaces three copies of the loop that queues key
  set syncs.

No behavior change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): propagate CAT changes to encoded ACL subjects

UpdateGroup selected ACL entries by comparing each subject with the raw
GroupID, whatever the entry's auth mode, and then set the privilege of
every selected entry to the group's permission. A CASE entry that grants
a group through its CASE Authenticated Tag holds the subject
kMinCASEAuthTag | (GroupCAT << 16) | GroupCATVersion, so it was never
selected, and changing GroupCAT or GroupCATVersion did not change the
ACL entries on the nodes. A CASE subject equal to the GroupID, which is
a node ID, was selected instead. A version-only change also overwrote
the privilege of every selected entry.

UpdateGroup now selects subjects by auth mode:

- in Group entries, subjects equal to the GroupID;
- in CASE entries, CAT subjects whose identifier is the group's previous
  GroupCAT, at any version, so an entry left at an older version is also
  updated.

When GroupCAT or GroupCATVersion changes, the selected CASE subjects are
rewritten to the new CAT and version. The privilege changes only when
GroupPermission changes. If an entry also names other subjects, it is
split: the original keeps the other subjects and its privilege, and a
new entry with a new list ID holds the group's subjects with the new
privilege. The original is replaced on the node before the new entry is
added. Each modified entry records its previous value, so the node's
entry is replaced rather than appended, and is synced through the
per-node queue.

A GroupCATVersion of 0 is rejected with CONSTRAINT_ERROR before anything
changes: it is not a valid CAT, and the field's range is 1 to 65535. A
permission change that would need more ACL entries than kMaxACLs is
rejected with RESOURCE_EXHAUSTED. The per-node queue check counts two
syncs for each entry that is split.

Matter Core R1.4.2 11.24.4.5 (Removing a Node from a Group) and
11.24.7.5 (UpdateGroup).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* test(jfds): read recorded ACL syncs through checked accessors

clang-tidy's bugprone-unchecked-optional-access flagged every
`delegate.lastAclSyncOwned->` and `delegate.lastAclSuperseded->` in
TestJointFabricDatastore, including those after an
ASSERT_TRUE(... .has_value()), and fails the Darwin build.

TrackingDelegate gains LastAclSync() and LastAclSuperseded(), which read
through value_or, and the tests use them. The has_value() assertions
stay, so a missing sync still fails the test directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): reject reserved and zero GroupCAT values

UpdateGroup checked the GroupCAT the group already had, but not the one
in the command. UpdateGroup(G, GroupCAT=0xFFFF) rewrote every CASE ACL
subject naming G's CAT to the Administrator CAT and synced the change
to the nodes. G then carried the Administrator CAT, so later
UpdateGroup and RemoveGroup commands on it failed. GroupCAT 0 and the
Anchor CAT were accepted the same way. A CAT change without a
GroupCATVersion keeps the stored version, which ForceAddGroup does not
check, so a stored version of 0 was written into the subjects as an
invalid CAT. AddGroup accepted GroupCAT 0 and any GroupCATVersion.

UpdateGroup and AddGroup now reject a GroupCAT of 0, the Anchor CAT or
the Administrator CAT with CONSTRAINT_ERROR before anything changes
(GroupCAT is 1 to 65534, and neither command may set a reserved CAT).
UpdateGroup also rejects a CAT change whose effective version is 0, and
AddGroup rejects a GroupCATVersion outside 1 to 65534. ForceAddGroup,
which JFAManager uses to create the Administrator and Anchor groups, is
unchanged.

Matter Core R1.4.2 11.24.7.4 (AddGroup) and 11.24.7.5 (UpdateGroup).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): leave ACL entries being removed out of UpdateGroup

UpdateGroup rewrote and split ACL entries without checking whether they
were being removed. With E = {CASE, Operate, [CAT(G,v1), 0x1111]} queued,
in flight or failed for removal (CommitFailed keeps the removal intent
while the node is offline), UpdateGroup(G, GroupPermission=Manage) split
E: E kept 0x1111 and its removal, and a new entry {CASE, Manage,
[CAT(G,v1)]} was added and synced as an add, so the node held an entry
naming G's CAT after E's removal. A refresh of an offline node did the
same. On
the non-split path, the rewrite overwrote DeletePending or CommitFailed
with Pending, so the attribute misreported the entry while its removal
was still pending.

aclChangeFor now returns no change for an entry with removal intent, so
the split pre-count, the BUSY pre-count and the mutation loop all leave
it untouched: its value, privilege, state and removal intent are kept,
and its removal goes ahead with the value the node holds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): record the value an ACL update left on a node being removed

Each ACL entry keeps one superseded value, the value the node is
believed to hold while an update is pending. When an update succeeded
after its entry had been marked for removal, the completion looked the
entry up as an add, found nothing, and did not record that the node now
held the value sent, although the write had erased the superseded value.

With E Committed on N with CAT(C,1), UpdateGroup(v2) sets E to v2 and
syncs it. While that sync is in flight, UpdateGroup(v3) sets E to v3,
keeping v1 as superseded, and RemoveACLFromNode(E) marks it for removal.
The v2 write succeeds, and the removal then sends v3 with superseded v1.
N holds only v2, so nothing is erased, E is dropped from the datastore,
and the next RefreshNode adopts v2 as a new Committed entry.

The completion now looks the entry up by key. If its value still equals
the value sent, the superseded value is cleared, since the node no
longer holds it, and the entry is marked Committed unless it is being
removed. Otherwise the value sent becomes the superseded value, which
the queued sync replaces or removes. The state and removal intent of an
entry being removed are left unchanged.

A write that the node applied but that was reported as failed, for
example because the response was lost, can still leave a value on the
node that the datastore does not record. Covering it needs a list of
superseded values through ApplyAclEdit and the Delegate, which is out
of scope here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): reject epoch keys that are not 16 bytes

AddKeySet and UpdateKeySet accepted a non-null epoch key of 0 to 15
bytes: the datastore only checked that a key fits its 16-byte storage,
and neither the cluster handler nor the decoder checks the length.
Nodes reject such a key in KeySetWrite with CONSTRAINT_ERROR, which is
recorded on every node's entry for the key set, and the next RefreshNode
drops those entries as unrecoverable. Nothing re-creates them, so a
corrected UpdateKeySet reached no node, and removing a node from the
group never sent it KeySetRemove.

An epoch key must now be null or exactly 16 bytes, the length the Group
Key Management cluster requires. Any other length fails AddKeySet and
UpdateKeySet with CONSTRAINT_ERROR before the key set is stored or
synced. Tests that used shorter keys, including the key set the test
delegate returns from FetchGroupKeySet, now use 16-byte keys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): do not replace a node's ACL when its entries cannot be adopted

RefreshNode adopts the ACL entries a node holds that the datastore does
not track. When the datastore's ACL list was full (kMaxACLs entries
across all nodes), the merge skipped such an entry with a log, and the
refresh then wrote the node's ACL list from the datastore anyway. The
write replaces the node's whole list, so it deleted the skipped
entries, and the refresh marked the node Committed. Adding back a tombstoned
value to be removed did not check the limit at all.

The merge now counts the fetched entries it cannot store, in both
paths. If there are any, the refresh ends with RESOURCE_EXHAUSTED
before the ACL write, logs the count once, and the node stays Pending.
The tombstones are kept, so a value that could not be added back is
removed by a later refresh instead of being adopted. Entries the node no
longer holds are still erased first, which frees room for the next
refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): keep the ACL value a node holds while its update is unapplied

RefreshNode's ACL merge skipped a fetched entry equal to some entry's
superseded value, the value the entry had before an update the node has
not applied. It did not mark that entry as seen or look at its state:

- When the node rejected the update for good (CONSTRAINT_ERROR, as for
  a Group-auth entry raised to Administer), the triage dropped the entry
  as an unrecoverable failure, and the ACL write left out both values,
  deleting the entry the node still held, and the refresh reported
  Committed.
- When the entry's removal had failed as well, the merge took the
  unseen entry's removal as done and erased it before the write. If the
  write then failed, nothing remembered the removal, and the next
  refresh adopted the old value as Committed.

Every entry whose superseded value the node holds is now seen, so its
removal is retried until the node no longer holds the value. An entry
whose update failed with an unrecoverable status, and that is not being
removed, goes back to the superseded value as Committed, keeping its
list ID, so the write keeps the node's entry. Pending updates and recoverable
failures are unchanged: the write replaces the old value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): sync each new entry alone when a refresh list write fails

RefreshNode writes a node's whole ACL list, and its binding list, in one
write, and the node answers with one status. MarkRefreshWriteFailed
recorded that status on every entry in the write that was not
Committed. An unrecoverable status (CONSTRAINT_ERROR or
RESOURCE_EXHAUSTED) makes the next refresh drop the entry, so one
invalid pending entry, or a list one entry over the node's per-fabric
capacity, dropped every pending entry, including those the node would
have accepted on their own. Entries being removed, which the write
leaves out, recorded the status too.

An unrecoverable write status is now recorded only when the write held
a single entry that was not Committed. With several, each records a
recoverable FAILURE, and a single-entry sync is queued for each. The
syncs start once the refresh releases the node and record the node's
own status for each entry. If the node's sync queue fills up, the
remaining entries stay recoverable and the next refresh retries them.
Entries being removed record FAILURE instead of an unrecoverable write
status and keep their removal intent. Recoverable statuses are recorded
as before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): record the ACL value a refresh wrote for an entry being removed

The earlier fix that records the value an ACL update left on a node
being removed covered single-entry syncs only. RefreshNode's ACL write
completion still updated only entries that were Pending or CommitFailed
when it ran, so an entry marked for removal while the write was in
flight kept a superseded value that the node no longer held.

E is Committed on N with CAT(C,1), and UpdateGroup(v2) times out on N,
leaving E CommitFailed with v2 and superseded v1. RefreshNode(N) fetches
v1 and writes N's ACL list with v2. While the write is in flight,
UpdateGroup(v3) sets E to v3, keeping v1 as superseded, and
RemoveACLFromNode(E) marks it for removal. The write succeeds, so N
holds v2, but E still had superseded v1. The queued removal then sent
v3 with superseded v1, erased nothing on N, and E was dropped from the
datastore; the next refresh adopted v2 as a new Committed entry.

The completion now handles every entry of the node that was in the
write as StartAclEntrySync does, whatever its state: if the entry still
has the written value, its superseded value is cleared and it is marked
Committed unless it is being removed; otherwise the written value
becomes its superseded value, which the queued sync replaces or removes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): keep a full ACL list from blocking refreshes and removals

The earlier fix that ends a refresh with RESOURCE_EXHAUSTED when a
fetched ACL entry cannot be adopted compared the whole ACL list with
kMaxACLs. That count included the node's own entries that the triage
before the ACL write drops, those whose sync failed for good. With the
list full, a node holding one entry the datastore does not track could
then never be refreshed again: every refresh ended before the triage
that would have made room. A tombstoned value that the node still held
also ended the refresh while the list was full, so a value whose removal
had been requested stayed on the node until room was freed elsewhere.

The merge now counts the room of the node's entries that the triage
drops as free: those with an unrecoverable failure, other than updates
whose old value the node still holds, which the merge restores. A
tombstoned value that cannot be added back as DeletePending for lack of
room no longer ends the refresh. Its tombstone is kept, and the ACL
write leaves the value out, which removes it from the node, since the
write replaces the node's whole list. The tombstone is dropped once the
node no longer holds the value, as before.

RefreshWithFullAclListKeepsTombstone expected a full list to end the
refresh without a write. It is now
RefreshWithFullAclListRemovesTombstonedValue, and expects a write
without the value, and the kept tombstone to remove the value again at
the next refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(jfds): queue a refresh's per-entry re-syncs by key

The earlier fix that syncs each new entry alone when a refresh list
write fails collected full copies of the entries to sync, including an
ACL entry's subject and target vectors and its superseded value, only to
read their keys when it queued the syncs.

MarkRefreshWriteFailed now collects the start function of each sync,
which captures only the entry's key, and hands it to the node's queue
as is. RunOrQueueEntrySync becomes EntrySyncStart, which returns that
function instead of queuing it. No behavior change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): reject an unknown key set security policy in AddKeySet

The earlier fix that rejects epoch keys that are not 16 bytes closed one
way for AddKeySet to store a key set that every node refuses. UpdateKeySet
also rejects a GroupKeySecurityPolicy of kUnknownEnumValue, but
AddKeySet stored such a key set. Nodes answer its KeySetWrite with
CONSTRAINT_ERROR, which is recorded on every node's entry for the key
set, and the next RefreshNode drops those entries as unrecoverable, so
nothing would write the key set to the nodes or remove it from them
again.

AddKeySet now rejects an unknown security policy with CONSTRAINT_ERROR
before the key set is stored, as UpdateKeySet does. The key set 0
placeholder that JFAManager adds for the IPK keeps the default policy,
TrustFirst, and is still accepted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): sync a key set updated while its write is in flight

A key-set entry's sync completion matched the entry by node, key set and
removal intent only, and committed it. With a CASE session to N,
UpdateKeySet(K, v1) marks (N,K) Pending and sends KeySetWrite(v1).
UpdateKeySet(K, v2) before N answers stores v2, marks (N,K) Pending
again and queues a second sync. The v1 completion then marked (N,K)
Committed, and the queued sync, which skips Committed entries, never
sent v2. N kept v1, and RefreshNode does not rewrite Committed
entries. RefreshNode's own key-set writes,
which the refresh does not wait for, matched on node and key set alone,
with the same result. A late failure of one of them could also mark an
entry whose newer write had already succeeded.

Key-set, endpoint-group and binding entries now carry a sync revision,
which is not on the wire. UpdateKeySet changes it on the entries it
marks for a new write, and so does UpdateGroup on the entries of a
renamed group; nothing changes it on binding entries, which carry it
because StartEntrySync is shared. A queued sync captures the revision
when it starts, and its success commits the entry only if the revision
is unchanged; otherwise the entry stays Pending for the queued sync.
RefreshNode's key-set writes apply their result, success or failure,
only to an entry that is still being added at the revision written.

A failed queued sync is still recorded when the revision has changed.
The queued sync of the new value runs anyway, since only Committed
entries are skipped, and StartEndpointGroupEntrySync relies on the
recorded failure to hold back a group add while the node lacks the
group's key set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): limit a refresh's key-set syncs to the refreshed node

RefreshNode's key-set stages handled every node's entries. They
collected all nodes' key-set removals once and sent each one later,
outside that node's sync queue and without reading the entry again. They
also rewrote other nodes' Pending and CommitFailed entries, and dropped
every node's entries with an unrecoverable failure. With (X,K) and (M,K)
both being removed, RefreshNode(N) could wait on the removal from an
offline X while AddGroupIDToEndpointForNode(M, ep, G), for a group G
using K, cancelled the removal of (M,K) and wrote K and G to M. The
refresh then sent the collected KeySetRemove(K) to M, which deleted K
and its GroupKeyMap entries, while (M,K) and the group stayed
Committed, and no refresh repaired it.

The key-set stages now handle only the refreshed node's entries. Other
nodes' entries are synced by their own refreshes and sync queues, which
keep a node's key-set writes and removals in order. Each collected
removal is read again before it is sent, and skipped if the entry is gone
or no longer being removed: an add that cancelled it is queued behind
the refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): don't commit a refreshed group entry changed during its sync

RefreshNode syncs the node's group entries that are Pending,
CommitFailed or being removed without waiting for the syncs, and each
completion matched its entry by node, endpoint, group and removal
intent only. UpdateGroup marks a group's endpoint entries for another
sync, and changes their sync revision, when the group is renamed. If
it did so during a refresh, its sync of the entry waited behind the
refresh, and a successful completion of the refresh's sync marked the
entry Committed, so the queued sync, which skips Committed entries,
never ran, and the new name never reached the node. A refresh sync that
failed after a later sync of the entry had succeeded also marked the
entry CommitFailed.

The refresh's group syncs now capture the entry's sync revision. Their
completions commit the entry, record a failure on it or erase it after
a removal only if it is still being added or removed as when the sync
started and its revision is unchanged. This extends the revision check
that "sync a key set updated while its write is in flight" added for
queued syncs and the refresh's key-set writes to the refresh's group
syncs. As in the key-set stage, a failure still marks the refresh
failed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): change the sync revision when a removal is cancelled

The earlier fix that gave key-set, endpoint-group and binding entries a
sync revision changed it only where UpdateKeySet and UpdateGroup mark an
entry for a new write. Both skip entries that are being removed, and
cancelling a removal left the revision as it was. An add in flight from
before the removal request therefore committed the entry once a re-add
cancelled the removal, although the stored value had changed in between,
and the queued syncs then skipped the Committed entry.

With a CASE session to N, AddGroupIDToEndpointForNode(N, 1, G), for a
group G using key set K stored as A, sends KeySetWrite(A).
RemoveGroupIDFromEndpointForNode(N, 1, G) marks (N,K) for removal, and
UpdateKeySet(K, B) skips it. A second AddGroupIDToEndpointForNode(N, 1,
G) cancels the removal, and the success of the write of A then marked
(N,K) Committed: N kept A while the datastore read Committed.

CancelRemoval now changes the sync revision of the entry types that
carry one, so an add in flight from before the removal request does not
commit the entry, and the queued sync writes the current value. When
nothing changed in between, the entry is written once more. ACL entries
have no sync revision: their syncs compare the value sent with the
entry's value, which UpdateGroup leaves unchanged while the entry is
being removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): classify transport timeouts and busy errors

A failed sync records the IM status of its error as the entry's
FailureCode. Errors that carry no IM status were all recorded as
FAILURE, including a transport timeout (CHIP_ERROR_TIMEOUT) and a busy
CASE session (CHIP_ERROR_BUSY). An ACL add sent to a node that does not
answer, for example, recorded CommitFailed with FAILURE.

CHIP_ERROR_TIMEOUT is now recorded as TIMEOUT and CHIP_ERROR_BUSY as
BUSY, for single-entry syncs and for a refresh's list writes. Other
errors are recorded as before. RefreshNode still retries entries with
either code: it drops only entries with CONSTRAINT_ERROR or
RESOURCE_EXHAUSTED.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): drop a key-set removal the node no longer needs

RefreshNode's key-set removal stage sent KeySetRemove for each of the
node's key-set entries being removed, without checking the key-set list
it had fetched from the node. If the node did not hold the key set, it
answered NOT_FOUND, which is recorded as recoverable: the entry stayed
CommitFailed with its removal intent, and every refresh sent the
removal again and left the node Pending. This happened when the key
set's write failed while the node was offline and its group was then
removed from the node's endpoint. The stage also considered only key
sets still in the datastore, so a removal of a key set that had since
been removed from the datastore, and that the node no longer held, was
never sent nor erased.

The stage now goes through the node's key-set entries being removed
directly, and erases an entry whose key set is not in the fetched list
without sending KeySetRemove. A removal of a key set the node holds is
sent as before. A failed fetch still ends the refresh before this
stage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(jfds): expect Committed in TC-JFDS-2.5 step 33

Step 33 read the node's NodeKeySetList entry for the key set that
AddGroupIDToEndpointForNode wrote in step 29, and expected it to be
Pending. The datastore marks the entry Committed once the key set is
written, as the specification requires ("If this succeeds, update the
new KeySet entry in the Datastore to Committed"). Step 30 already waits
for the group entry to be Committed, which follows the key set's write.

The step now expects Committed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(jfds): tighten tests that pass without the behavior they check

AddOfTombstonedAclValueDropsTombstone passed whether or not AddACLToNode
dropped the tombstone of the added value: the refresh matched the
node's value to the added entry, so the tombstone was never consulted.
The test now removes the added entry before the refresh, with the node
holding the value again. The refresh adopts the value only if the
tombstone is gone, and removes it otherwise.

ReAddedBindingIsNotTreatedAsRemoval checked that a removal intent left
in a set keyed by list ID did not apply to a re-added binding with the
same list ID. Removal intent is now stored on the entry and erased with
it, so the test checked nothing specific. It is removed;
AddCancelsPendingBindingRemoval checks that an add cancels a failed
binding removal and that RefreshNode then writes the binding.

The checks that an added or adopted ACL entry got a new list ID also
reject 0. FindAcl results are checked for nullptr before they are
dereferenced, and RunDeferred fails the test instead of reading past
the end of the deferred completions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(jfds): move the fabric removal comment to its test

The comment describing OnFabricRemovedWipesDatastoreOnlyForAnchorFabric
sat above RefreshDropsUnrecoverableCommitFailedAcl, an unrelated test.
It now sits above the test it describes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(jfds): define ResetRefreshState in the header

Server.h calls JointFabricDatastore::OnFabricRemoved when
CHIP_DEVICE_CONFIG_ENABLE_JOINT_FABRIC is set, and OnFabricRemoved and
ClearAllRecords are defined in the header. Linux and Darwin test builds
set the define, but link JointFabricDatastore.cpp only when
chip_device_config_enable_joint_fabric is set. ClearAllRecords now calls
ResetRefreshState, which was defined in JointFabricDatastore.cpp, so
apps such as chip-shell failed to link. ResetRefreshState is now defined
in the header.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
…haracters (#74674)

* [AccountLogin] Return ConstraintError for a SetupPIN shorter than 8 characters

The Login command's SetupPIN field has a spec minimum length of 8
characters, but the server never checked it, so a short PIN reached the
delegate and the failure was reported as UnsupportedAccess. Check the
length before calling the delegate and return ConstraintError. The check
is on string length only, so values with leading zeros ("00001234") are
accepted. Fixes TC-IDM-9.1 (#74571).

Also zero-pad the passcode to 8 digits when ContentAppPlatform builds the
SetupPIN for its post-commissioning Login, so a passcode such as 00001234
is no longer sent as "1234".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
…tion and PlayPreset (#74671)

* [ContentLauncher] Spec-compliant delegate defaults for ContentReplication and PlayPreset

The default ContentReplicationRequest handler returned Success with no
ReplicationInfo, which the spec does not allow. It now returns
ReplicationNotSupported with a null ReplicationInfo. The default
PlayPreset handler returned Success for any PresetID even though the
default Presets list is empty; it now returns PresetNotFound.

Add unit tests for both defaults.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Fix TestContentLaunchServer on Tizen and clang-tidy

Initialize chip::Platform memory for the suite, since encoding responses
into MockCommandHandler allocates through it (the test aborted on
Tizen). Compare the whole ClusterStatusCode instead of calling .value()
on the optional cluster code, which clang-tidy flags as unchecked.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…bot) (#73536)

* Updated wifi scan type to extended

* Updated sl_wifi_set_scan_callback_v2 and added NetworkScanCallbackContext

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Minor fix

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Applied coderabbitai suggestions

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Addressed comments

* Dropped semaphore for advance and extended scans

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
… (#74700)

* [Chef] Add delegates for code-driven Thermostat cluster

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
@silabs-matter-ci-bot
silabs-matter-ci-bot Bot requested a review from a team as a code owner October 13, 2026 00:54
@silabs-matter-ci-bot silabs-matter-ci-bot Bot added changing-git-submodules-on-purpose sl-require-admin-action This TAG indicates that an admin must take action. labels Oct 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

The check for sl-require-admin-action label CI failure for this job is normal. An admin must do the merge.

@Sarthak-Shaha
sarthak shaha (Sarthak-Shaha) merged commit 6a40ccf into main Oct 13, 2026
115 of 118 checks passed
@Sarthak-Shaha
sarthak shaha (Sarthak-Shaha) deleted the automation/update_main branch October 13, 2026 14:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changing-git-submodules-on-purpose sl-require-admin-action This TAG indicates that an admin must take action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants