Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: matter-js/matter.js
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main@{1day}
Choose a base ref
...
head repository: matter-js/matter.js
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
  • 7 commits
  • 36 files changed
  • 3 contributors

Commits on May 6, 2026

  1. Configuration menu
    Copy the full SHA
    808b70b View commit details
    Browse the repository at this point in the history
  2. feat(chip-testing): add AllDevicesTestApp mimic for spec-compliant pe…

    …r-device-type tests (#3687)
    
    * feat(chip-testing): add getParameters helper for repeatable CLI flags
    
    Adds getParameters(name): string[] alongside existing getParameter/hasParameter/getIntParameter
    in GenericTestApp.ts. Returns all values for repeated -name <v> / --name <v> occurrences in
    argv order. Required by the upcoming AllDevicesTestApp's repeatable --device flag.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add DeviceTypeRegistry contract for AllDevicesApp
    
    Introduces EndpointHandle / DeviceTypeEntry interfaces and a Map-based registry
    with register/get/list helpers. Forms the seam between AllDevicesTestInstance
    (orchestrator) and per-device-type endpoint modules (each self-registers via
    side-effect import).
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add RootEndpoint module with WiFi/Ethernet variants
    
    Lifts AllClustersTestInstance.setupServer()'s ServerNode.create body verbatim into
    buildRootNode(opts), exposing two seams:
      1. NetworkCommissioning variant + networkCommissioning.networks switch on opts.wifi
         (Ethernet -> WiFi stub with empty networks list).
      2. enableKeyHex sourced from opts instead of process.argv parse.
    
    All other root behaviors, basicInformation, productDescription, MDNS broadcast schedule,
    generalDiagnostics, localizationConfiguration, networkCommissioning details,
    operationalCredentials, timeFormatLocalization (incl. Buddhist calendar workaround),
    and userLabel are preserved exactly so AllDevicesTestApp inherits the same chip-test
    compatibility AllClustersTestApp has today.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add on-off-light device type for AllDevicesApp
    
    First per-device-type endpoint module. Self-registers in DeviceTypeRegistry
    under the chip-CLI-compatible name "on-off-light" and constructs a single
    OnOffLightDevice endpoint. No backchannel — the spec doesn't require any
    test-injected commands for plain on/off lights.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add dimmable-light device type for AllDevicesApp
    
    Same pattern as on-off-light: plain DimmableLightDevice on the requested endpoint,
    no backchannel. Spec compliance comes from the device-type definition itself.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add contact-sensor device type with setBooleanState backchannel
    
    Initial booleanState.stateValue = false. Backchannel handles the same
    setBooleanState command that AllClustersTestInstance.backchannel() processes today
    (field name command.newState matches AllClusters convention). Endpoint-id filter
    prevents accidental cross-talk when multiple boolean-state-style devices share an
    AllDevicesTestApp instance.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add water-leak-detector device type with setBooleanState backchannel
    
    Mirrors ContactSensorEndpoint shape but uses WaterLeakDetectorDevice so the device
    type identity matches the chip CLI string "water-leak-detector". Same setBooleanState
    backchannel — chip's harness sends the same command shape regardless of which boolean-
    state-style sensor is targeted; the endpoint-id filter routes correctly.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add occupancy-sensor device type for AllDevicesApp
    
    OccupancySensorDevice requires explicit OccupancySensingServer feature selection per
    Matter 1.5 cluster definition; we pick PassiveInfrared (matches AllClustersTestInstance
    EP1 wiring). Initial occupied=false to mirror chip's TogglingOccupancySensorDevice
    baseline. No backchannel — AllClusters has no precedent handler for occupancy.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add temperature-sensor device type for AllDevicesApp
    
    Initial measuredValue 2500 (25.00 degC, centi-degrees). No backchannel — the
    BackchannelCommand union does not currently include a setTemperature variant and
    AllClustersTestInstance has no precedent handler. A handler can be added later once
    the union is extended in @matter/testing.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add device-type registration barrel for AllDevicesApp
    
    Side-effect imports trigger each per-device module's top-level registerDeviceType
    call so the registry is populated by the time AllDevicesTestInstance.setupServer
    runs. Alphabetical order. Adding a future device type (chime, soil-sensor, speaker
    once Matter 1.5.1 lands) is a one-line edit here plus a new module file.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add AllDevicesTestInstance orchestrator
    
    Extends NodeTestInstance with:
      - parseDeviceArgs() — two-pass parser that respects CLI order while honoring
        explicit :N endpoint reservations. Spec example
        `--device contact-sensor --device on-off-light:5 --device occupancy-sensor`
        produces [contact-sensor:EP1, on-off-light:EP5, occupancy-sensor:EP2].
      - setupServer() — builds root via buildRootNode (with --wifi seam and
        --enable-key passthrough), then resolves each spec to a registered factory
        and adds the constructed endpoint. Throws ValidationError with sorted
        listDeviceTypes() in the message for missing/unknown --device flags.
      - backchannel() — targeted-then-broadcast dispatch. command.endpointId
        addresses one endpoint first; remaining endpoints get a broadcast pass;
        unhandled commands fall through to NodeTestInstance.backchannel.
    
    Identity "alldevices-6100" keeps KVS namespace separate from AllClusters'
    "binford-6100". Side-effect import of devices/all-devices.js triggers all
    registerDeviceType calls before setupServer runs.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add AllDevicesTestApp bin entrypoint
    
    Mirrors AllClustersTestApp.ts shape: imports @matter/nodejs platform, sets
    process.title for stress-test detection, logs pid/argv for CI parsing, then
    delegates to startDeviceTestApp(AllDevicesTestInstance, StorageBackendAsyncJsonFile).
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add AllDevicesTestApp.sh wrapper
    
    SIGTERM-handling wrapper sibling to AllClustersTestApp.sh. Tees stdout/stderr to
    test_alldevices.log, normalizes exit code 134 (abort) to 0 on SIGTERM, forwards
    all args to dist/esm/AllDevicesTestApp.js. Used by chip-tool-tests.yml jobs that
    expect a script entry rather than a node invocation.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add chime device type for AllDevicesApp (Matter 1.5.1)
    
    ChimeServer requires installedChimeSounds (non-empty), selectedChime matching
    one of them, and enabled. Defaults to a single "Default" sound (chimeId=0)
    with playback enabled — sufficient for chip's chime test surface; tests that
    exercise sound selection can write a different selectedChime.
    
    Closes follow-up filed during initial design (TODO under matter-1.5/all-devices-app-chime.md).
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add soil-sensor device type for AllDevicesApp (Matter 1.5.1)
    
    SoilMeasurement cluster requires both soilMoistureMeasurementLimits (a
    MeasurementAccuracy struct with at least one accuracyRange entry) and
    soilMoistureMeasuredValue. Defaults to a single 0-99% range with 5%
    percentMax accuracy, initial measuredValue 50% — chip's all-devices-app
    uses an IncreasingMoistureSoilSensorDevice that mutates this over time;
    our mimic provides a static baseline.
    
    Closes follow-up filed during initial design (TODO under matter-1.5/all-devices-app-soil-sensor.md).
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): add speaker device type for AllDevicesApp (Matter 1.5.1)
    
    SpeakerDevice composes OnOffServer (mute) and LevelControlServer (volume) per
    the Matter 1.5.1 spec. No initial state needed — cluster defaults are valid.
    No backchannel — chip's LoggingSpeakerDevice in all-devices-app just logs;
    test coverage exercises the cluster commands directly.
    
    Closes follow-up filed during initial design (TODO under matter-1.5/all-devices-app-speaker.md).
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): register chime/soil-sensor/speaker in AllDevicesApp barrel
    
    Adds the 3 newly implemented device types to the side-effect-import barrel so
    they self-register at AllDevicesTestInstance startup. Matches chip's all-devices-app
    supported set 1:1 (9 device types total).
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(chip-testing): satisfy WiFi NetworkCommissioning init constraints in AllDevices RootEndpoint
    
    The 1.5.1 NetworkCommissioning cluster requires non-empty supportedWiFiBands
    (min 1) plus scanMaxTimeSeconds and connectMaxTimeSeconds when WiFi feature is
    selected. Without these, the WiFi-variant root fails behavior validation at
    ServerNode.create with "Array length 0 is not within bounds" on supportedWiFiBands.
    Add minimal stub values (2.4GHz band, 1s timeouts) so --wifi smoke passes.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * ci(chip-testing): route all-devices target to new AllDevicesTestApp
    
    Switches all 10 --app-path all-devices: mappings in chip-tool-tests.yml from
    AllClustersTestApp.{js,sh} to AllDevicesTestApp.{js,sh}. The matter.js side
    of the all-devices test target now exercises the spec-compliant per-device-type
    mimic instead of the kitchen-sink AllClusters EP1 it shared with all-clusters.
    
    all-clusters: mappings are untouched. chip-matterjs-tests.yml:113 (chip-native
    bin/all-devices-app) is also untouched — that workflow tests matter.js controller
    against chip's own device binary.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(chip-testing): mirror AllClusters TCP fields in AllDevices RootEndpoint
    
    AllClustersTestInstance's network block sets `tcp: true` and a
    TEST_PREFER_TCP-driven `transportPreference`. Without these, the new
    AllDevicesTestApp silently runs UDP-only even when the matterjs-tests-core-tcp
    CI job exports TEST_PREFER_TCP=1 — that job's `--app-path all-devices:` now
    points at AllDevicesTestApp, so the bug would let TCP transport tests pass-by-skip
    rather than actually exercising TCP.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * ci(chip-testing): cat AllDevices log on TestSelfFabricRemoval failure
    
    The two TestSelfFabricRemoval invocations in chip-tool-tests.yml fall back to
    cat ./test_allclusters.log on failure. Now that AllDevicesTestApp.sh writes
    to ./test_alldevices.log and the all-devices test target maps to that script,
    also cat ./test_alldevices.log so a failure originating from AllDevices is
    debuggable in CI logs (otherwise we'd see the AllClusters log alone, likely
    unrelated to the actual failure).
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(chip-testing): throw on missing value in getParameters
    
    Per Copilot PR review: silently dropping a trailing -name/--name token (no
    value following) makes "--device required" errors confusing when the user
    actually typed --device. Now throws ValidationError with the parameter name,
    matching chip CLI parity expectations.
    
    Existing single-value getParameter retains its lenient behavior to avoid
    churn in callers that rely on it; the strict throw applies only to the new
    repeatable helper used by --device.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(chip-testing): enforce EndpointNumber upper bound in --device parser
    
    Per Copilot PR review: parseDeviceArgs validated ep >= 1 but not ep <= 0xFFFE,
    so --device foo:70000 would surface a generic out-of-bounds throw from the
    EndpointNumber() brand at later use rather than the token-specific
    "Invalid endpoint in --device" message. Add the upper-bound check next to
    the existing lower-bound check.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(chip-testing): correct exit code capture in AllDevicesTestApp.sh SIGTERM handler
    
    Per Copilot PR review: when SIGTERM arrives before CHILD_PID is assigned, the
    prior implementation captured \$? from the [ -n "\$CHILD_PID" ] test (status 1)
    rather than from a wait, so the wrapper would exit 1 even though no child
    failed. Initialize EXIT_CODE=0 up front and only overwrite from wait when a
    child was actually waited for.
    
    (The same bug exists in AllClustersTestApp.sh — left for a separate follow-up
    to keep this change scoped.)
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(chip-testing): correct exit code capture in AllClustersTestApp.sh SIGTERM handler
    
    Same bug we just fixed in AllDevicesTestApp.sh: when SIGTERM arrives before
    CHILD_PID is assigned, the prior code captured \$? from the [ -n "\$CHILD_PID" ]
    test rather than wait, so the wrapper exited 1 with no child failure.
    Initialize EXIT_CODE=0 up front and only overwrite from wait when a child was
    actually waited for.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(testing): extend Subject.Factory with optional appArgs
    
    Adds a second optional parameter Subject.Options to the Factory signature so
    per-run app-args (chip header `app-args:`) can flow into in-process subjects
    without going through process.argv. Existing factories that ignore the extra
    arg remain compatible.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(testing): add chip.subjectFor app-string→factory registry
    
    Introduces a Map<string, Subject.Factory> keyed by chip-test-header app names
    ("all-clusters", "all-devices", "bridge", "tv", "rvc", future). Setup-time
    registration via chip.subjectFor("name", factory). Duplicate registration
    throws. Task 3 will wire the registry into defineTest dispatch.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(testing): dispatch chip tests by descriptor.app and forward app-args
    
    Wires the runtime side of the chip-test app registry:
      - parseAppArgs() splits descriptor.config["app-args"] (string or array form).
      - defineTest's beforeOne resolves the factory by priority: explicit .subject()
        override on the builder, then State.subjectForApp(descriptor.app), then
        chip.defaultSubject. A descriptor that names an unregistered app fails loud
        with a message naming the missing app and pointing at chip.subjectFor.
      - activateSubject + loadSubject thread appArgs through. The subject cache key
        becomes (factory, kind, appArgs) so distinct per-run app-args produce
        distinct cached subjects (chip multi-run tests with different --device flags).
    
    Backward compatible: tests without descriptor.app keep using chip.defaultSubject.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): plumb appArgs through DeviceTestInstanceConfig
    
    Adds an optional appArgs?: string[] field to DeviceTestInstanceConfig so the
    support.ts factory can forward chip-framework Subject.Options.appArgs into the
    TestInstance constructor. Subjects that need runtime CLI-style configuration
    (AllDevicesTestApp's --device list) consume it via this.config.appArgs in
    setupServer(). Existing TestInstance classes (AllClusters/Bridge/Tv/Rvc) ignore
    the field — change is purely additive.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * refactor(chip-testing): AllDevicesTestInstance reads device list from config first
    
    Replaces parseDeviceArgs() (which read process.argv directly via getParameters/
    hasParameter/getParameter) with parseRuntimeArgs(args[]) — same logic but
    argv-source-independent. Constructor extracts config.appArgs into a private
    field; setupServer() uses this.#appArgs ?? process.argv.slice(2) as the source.
    
    Behavior unchanged for standalone CLI runs (chip-tool-tests CI binary, local
    smoke). Test framework now flows per-run --device/--wifi/--enable-key into the
    subject via Subject.Options.appArgs, unblocking chip multi-run python tests
    where each run targets a different device type.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(chip-testing): register all subjects via chip.subjectFor for descriptor-app dispatch
    
    Adds AllDevicesApp and registers all 5 subjects (all-clusters, all-devices,
    bridge, tv, rvc) under their normalized chip-header names. The App() helper
    now also threads Subject.Options.appArgs into the constructor so per-run
    chip-header app-args (e.g. "--device on-off-light:1") flow into the in-process
    subject. chip.defaultSubject stays at AllClustersApp for tests without
    descriptor.app.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(testing): scope app-args to descriptor-app dispatch only
    
    CI regression: forwarding parseAppArgs() output for every test (including
    tests that fall through to chip.defaultSubject) caused per-test cache key
    divergence — chip headers carry per-test --trace-to / --KVS values, so
    loadSubject() spawned a fresh subject for every test, thrashing MDNS and
    producing CASE timeouts on subsequent tests (TC_WHM_2_1, TC_DRLK_*, etc).
    
    Only set appArgs when descriptor.app is at top-level (= multi-run suite
    member explicitly dispatched via chip.subjectFor). Tests using
    chip.defaultSubject keep their pre-PR cache behavior (kind only).
    
    Also enhances print-report to surface descriptor.app per test in brackets,
    which made the bug easy to spot during inspect.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(chip-testing): pass full method name to get_test_desc in descriptor generator
    
    chip's MatterBaseTest.get_test_desc(test) does getattr(self, test) and requires the
    full method name (test_TC_FOO_2_3). The legacy short-form aliases ("FOO_2_3") that
    made our previous call signature work have been removed upstream — TC_CGEN_2_4 now
    raises AttributeError, which abort-aborts the descriptor build and leaves the chip
    docker image with a stale /lib/test-descriptor.json (no recent multi-run / new app
    references, no chime/soil/speaker, etc).
    
    Pass test_method_name instead of the stripped form. Wrap in try/except so a single
    bad test class can't break the whole image build going forward.
    
    [rebuild-chip]
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * feat(testing): skip multi-run tests targeting unregistered apps instead of erroring
    
    When a multi-run python test descriptor names an app we have no Subject.Factory
    for (e.g. \${LOCK_APP}, \${LIT_ICD_APP}, \${WATER_HEATER_APP}), skip just that run
    rather than throwing. Chip CI lists more apps than we mimic; whitelist semantics
    let the runs we DO support proceed without surfacing failures from runs we
    deliberately don't cover. Other runs of the same test continue normally.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(testing): drop appArgs from subject cache key to keep fabric stable
    
    Including appArgs in loadSubject's cache key spawned a fresh in-process subject
    for each multi-run member of a chip python test that shared a factory but
    differed in script-side flags (e.g. TC_SWTCH run1/run2/run3 all use
    ALL_CLUSTERS_APP but pass different --app-pipe paths). Each new subject was
    commissioned independently — chip controller storage held one fabric while the
    restored subject snapshot held another, producing the symptom
    
      CHIP: Compressed FabricId 0x6BB913D815052317
      matter.js: mdns:074A2057D2EE4E7C-...
    
    and CASE Avahi resolve timeouts.
    
    Cache by (factory, kind) only. appArgs are still forwarded on first construct
    (needed for AllDevicesTestApp's --device list); cache hits reuse the cached
    subject's commissioning state so all multi-run members of a single factory
    share fabric and chip controller storage stays consistent.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * chore(chip-testing): bump chip pin + show config.app in test output
    
    - support/chip/sha.txt: 6891456 (Apr 21) -> e8152e9 (today). The Apr 21 pin
      predated chip's TC_OO_2_7 multi-run addition (Apr 23) plus all the recent
      chime/soil/speaker/etc test additions, so our descriptor never picked them up.
    - print-report.ts: surface descriptor.config.app in the [...] tag when
      descriptor.app (top-level, set only for multi-run suite members) is absent.
      Single-run python tests now also display the app they target.
    
    [rebuild-chip]
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * chore(chip-testing): pin chip just before today's TC_LVL_9_1 step0c addition
    
    e8152e9 (today's master) added a step0c label to TC_LVL_9_1, which the matter.js
    LevelControl behavior doesn't yet satisfy and surfaced as the only test-app-slow
    failure on PR #3687. Roll the pin back one commit to ee82434 (also today, just
    the prior commit) — keeps the multi-run TC_OO_2_7 (added Apr 23) and chime/soil/
    speaker definitions, drops the new step0c assertion. TC_LVL_9_1 step0c is
    follow-up matter.js work.
    
    [rebuild-chip]
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * test(chip-testing): add diag job running TC_LVL_9_1 with --all-logs
    
    Adds a diagnostic-only test file (test/diag/LVL_9_1.test.ts), an
    npm test-diag script, and a continue-on-error CI job in build-test.chip.yml.
    The job runs only LVL/9.1 with --all-logs to capture the full chip subprocess
    output so we can see why TC_LVL_9_1 fails against newer chip pins (annotation-
    level CI logs swallow chip stderr/stdout).
    
    [rebuild-chip]
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * chore(chip-testing): bump chip pin to 501ae86 with TC_LVL_9_1 main entry fix
    
    Upstream chip landed the missing
    \`if __name__ == "__main__": default_matter_test_main()\`
    on TC_LVL_9_1.py, so the test now actually runs when invoked directly. Bump
    the pin and trigger an image rebuild to verify.
    
    [rebuild-chip]
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * test(chip-testing): drop diag scaffolding now that TC_LVL_9_1 runs
    
    Upstream chip added the missing default_matter_test_main() entry; the
    test-diag job confirmed TC_LVL_9_1 runs against the new chip pin. Remove the
    diagnostic test file, npm script, and CI job — served their purpose.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    Apollon77 and claude authored May 6, 2026
    Configuration menu
    Copy the full SHA
    eae343f View commit details
    Browse the repository at this point in the history
  3. chore(ci): bump actions/download-artifact v4 → v8 in load-chip (#3691)

    Custom composite actions under .github/actions/ are not covered by
    dependabot's default scan, so this dependency had drifted four major
    versions behind. v8 brings the action to Node 24, fails on artifact
    hash mismatch by default (was warning), and migrates to ESM. Pairs
    fine with the existing actions/upload-artifact@v7 (zip uploads still
    auto-decompressed via Content-Type detection).
    Apollon77 authored May 6, 2026
    Configuration menu
    Copy the full SHA
    98ffc5c View commit details
    Browse the repository at this point in the history
  4. fix(codegen): alias FieldSchema.id to "fieldid" for command param tab…

    …les (#3692)
    
    Matter 1.5.1 AudioOutput cluster spec uses "Field ID" column header in
    SelectOutput and RenameOutput parameter tables. Header normalizes to
    column key "fieldid", but FieldSchema.id was bare Integer with no alias,
    so the lookup failed and both commands generated with no parameters.
    
    Add "fieldid" alias so the parser recognizes that header. Regenerated
    intermediate spec and standard model — AudioOutput SelectOutput now has
    Index and RenameOutput has Index + Name as the spec defines.
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    Apollon77 and claude authored May 6, 2026
    Configuration menu
    Copy the full SHA
    43d0df6 View commit details
    Browse the repository at this point in the history
  5. fix(node): expose subscriptions on ClientNodeInteraction wrapper (#3694)

    CommissioningClient assigns `node.interaction as ClientInteraction` to
    `peer.interaction`, but `node.interaction` is a `ClientNodeInteraction`
    wrapper that did not expose `subscriptions`. PeerAddressMonitor's
    address-migration path then dereferenced `interaction.subscriptions`,
    crashing with "Cannot read properties of undefined (reading
    'closeForPeer')" whenever a session migrated to a discovered IP.
    
    Add a `subscriptions` getter on `ClientNodeInteraction` that resolves
    the singleton from the node environment, matching what the inner
    `ClientInteraction` returns. Tighten `ClientInteraction.environment`
    from `protected` to `#environment` since no subclass needs it.
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    Apollon77 and claude authored May 6, 2026
    Configuration menu
    Copy the full SHA
    ccd892f View commit details
    Browse the repository at this point in the history
  6. fix(protocol): re-solicit A/AAAA for stale cache entries on commissio…

    …nable discovery (#3695)
    
    * chore(chip-testing): add discovery diagnostic logs and run matterjs on PRs
    
    Intermittent CI failure on the matterjs controller variant of the CHIP
    Discovery test: step 7 returns 12 commissionables, step 8 (~3s later)
    returns empty. Insufficient instrumentation to determine whether the
    mDNS scanner cache was emptied between calls, addresses got pruned, or
    the Discovery callback chain dropped them.
    
    Add INFO logs at the relevant chokepoints:
    
    - CommissionableMdnsScanner: log cache size on entry, per-entry match
      decision (matched / rejected: no addresses / rejected: filter), waiter
      notifications for new arrivals, cache add and cache delete events,
      and final result size.
    - Discovery: log whether the scanner callback reused an existing
      ClientNode or created a new one (and whether find() hit an
      already-commissioned node).
    - LegacyControllerCommandHandler.handleDiscovery: log incoming findBy,
      raw result count, picked entry, and empty-return.
    
    Also temporarily extend the matterjs controller matrix gate in
    build-test.chip.yml to run on pull_request so this branch can capture
    fresh logs from CI.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(protocol): avoid BigInt-unsafe JSON.stringify in discovery diagnostic logs
    
    Previous logging commit serialized the CommissionableDeviceIdentifiers
    object via JSON.stringify, which throws "Do not know how to serialize
    a BigInt" when the identifier carries a BigInt-typed field, breaking
    every commissionable discovery on the matterjs CHIP test variant.
    
    Replace with the field-key list (sufficient to know what was queried)
    and replace the legacy handler's raw result dump with a slim
    {id, D, CM} projection so neither path can hit a BigInt at log time.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * fix(protocol): re-solicit A/AAAA for stale cache entries on discovery
    
    CHIP Discovery test on the matterjs controller reproducibly returned an
    empty result on the second discover-commissionables call within a step
    (step 8 "Check Hostname" failed with hostName: NoneType). Diagnostic
    logs added in the previous commit showed the scanner cache held all 13
    entries but every entry was rejected by the addresses-length filter on
    the second call:
    
      1st call: matched: 13, rejectedNoAddr: 0, resultSize: 13
      2nd call: matched:  0, rejectedNoAddr: 13, resultSize:  0
    
    Cache itself was intact (DnssdName.isDiscovered still true) but each
    entry's IpService.addresses had been pruned because the A/AAAA TTL on
    matter commissionable broadcasts is short (~4s) and elapses between
    unsolicited rebroadcasts. #cacheDevice solicited and armed an
    onAddresses observer when a device was first cached without addresses,
    but the observer deregistered itself after the first delivery, so a
    later expiry could not re-trigger it, and #startDiscovery solicits PTR
    records only.
    
    Extract the "solicit SRV-target A/AAAA + arm onAddresses observer"
    logic from #cacheDevice into a new idempotent helper
    #solicitAndArmAddresses, and call it from the cache iteration loop
    whenever a cached entry matches the identifier but has zero addresses.
    The current discovery's waiter is already registered, so when A/AAAA
    records resolve before the discovery timeout fires, #deliverDeviceIfResolved
    notifies the waiter and the device flows through the callback chain.
    
    Idempotent: skips re-arming if the onAddresses observer is already
    attached, so concurrent overlapping discoveries do not double-register.
    
    Diagnostic logs from the previous commit are kept so the next CI run
    verifies the fix.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * chore: remove diagnostic logs and PR-trigger gate after fix verified
    
    Two consecutive matterjs CHIP runs on this branch passed cleanly with
    the A/AAAA re-solicit fix in place.  Drop the diagnostic logs added
    across CommissionableMdnsScanner, Discovery, and LegacyControllerCommandHandler
    and revert the temporary pull_request gate in build-test.chip.yml so
    the branch contains only the surgical fix.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    * test(protocol): add regression for stale-cache A/AAAA re-solicit
    
    Cover the path fixed in the parent commit: a cached commissionable
    device whose A record TTL has elapsed while SRV/TXT remain valid is
    re-delivered on a subsequent findCommissionableDevicesContinuously
    call once the responder replies to the re-solicited hostname query.
    
    Verified: the test fails on the pre-fix code (expected 1 to equal 0
    after the second discovery returns no devices) and passes after the
    #solicitAndArmAddresses helper is reused from the cache iteration loop.
    
    Addresses copilot-pull-request-reviewer review comment on PR #3695.
    
    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    
    ---------
    
    Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    Apollon77 and claude authored May 6, 2026
    Configuration menu
    Copy the full SHA
    638f289 View commit details
    Browse the repository at this point in the history
  7. Configuration menu
    Copy the full SHA
    5eab618 View commit details
    Browse the repository at this point in the history
Loading