Skip to content

Latest commit

 

History

History
233 lines (194 loc) · 11.8 KB

AGENTS.md

File metadata and controls

233 lines (194 loc) · 11.8 KB

AI Agent Guidelines for Matter SDK

This file provides guidelines and instructions for AI agents working on the Matter SDK codebase.

General Principles

  • When in Rome: Match the prevailing style of the code being modified. See docs/style/CODING_STYLE_GUIDE.md.
  • Atomicity: Make small, incremental changes. Do not mix refactoring with feature implementation.
  • No Filler Names: Avoid names like "support", "common", "helpers", "util", "core". Use concrete names.
  • Error Handling: Use CHIP_ERROR as the standard return type for fallible operations. Prefer VerifyOrReturnError and ReturnErrorOnFailure macros for concise error checking and propagation.
  • Ensure resources are cleaned up appropriately, especially on early returns. Generally prefer RAII patterns for cleanup.
  • Logging: Use the ChipLog* macros (e.g., ChipLogProgress, ChipLogError, ChipLogDetail) for logging. Ensure logs are appropriately categorized by module (e.g., AppServer, InteractionModel).

Ignored Directories

When searching for files or code patterns, ignore the following directories unless explicitly asked to look there:

  • third_party/ (contains external dependencies)
  • out/ (contains build artifacts)

Code Review Instructions

  • Do not comment on content for XML files or .matter content for clusters.
  • The SDK implements an in-progress Matter specification that may be in flux and may not be available to all contributors. Assume the Matter specification is unknown and out of scope unless you have explicit access to the latest version (e.g., via a specialized tool or skill).
  • Avoid "pat on the back" style comments that just restate what the code is doing. Focus on suggesting concrete code improvements.
  • Be concise. Do not over-explain code.
  • Look for common typos and suggest fixes.
  • Do not comment on whitespace or formatting (auto-formatters handle this).
  • Review changes for embedded development:
    • Minimize use of heap allocation.
    • Optimize for resource usage (RAM/Flash).
    • Be cautious with complex templates that could lead to code bloat.

API Stability

Public APIs often have consumers outside this tree, so source compatibility is something to think about when changing or extending them. Breaking compatibility is not strictly prohibited, but should only be done for good reasons. There is no hard line between public and internal APIs: how much compatibility matters in a given area depends on how likely it is to be used by external clients, and on whether the API itself is considered stable or belongs to a feature still in development.

Where compatibility shapes a decision, record it in a comment or the commit message; a deliberate break and a deliberate workaround both read as accidents otherwise.

API preferences

  • Prefer using chip::Span from src/lib/support/Span.h to pointer + size groups. Pass Span by value rather than const reference (treat it as a string_view)
  • Use "foo"_span (i.e. operator _span) for const char spans instead of fromCharString.
  • Prefer std::optional to chip::Optional
  • Prefer StringBuilder from src/lib/support/StringBuilder.h to using snprintf for string formatting.

Coding Style (Highlights)

Refer to docs/style/CODING_STYLE_GUIDE.md for full details.

  • C++: C++17 standard.
    • Use fixed-width integer types from <cstdint> for POD integer types
    • Avoid top-level using namespace in headers.
    • Use anonymous namespaces for file-internal classes/objects.
    • Avoid heap allocation and auto-resizing containers in core SDK.
  • Python: Python 3.11 standard.
    • Use type hints on public APIs.
    • Include docstrings for public APIs.
  • Always include {} bracketing for control flows, even if using one liners (e.g. for if, while, for and such)

Comments and Technical Writing

  • Explain "Why", Not "What":
    • In both code comments and PR descriptions, focus primarily on why a decision was made and the background context.
    • Do not restate the code. Readers can see the code and the diff.
    • In PR descriptions, state what changed only as needed to explain why it fixes the problem, rather than listing file-by-file or mechanical edits.
  • Code First, Comments Second:
    • Treat an inline implementation comment as an admission that the code is not clear on its own. Prefer writing obviously correct, self-explanatory code that needs no inline comments.
    • Most comments should be API doc comments on interfaces explaining how the API is used, its contract, lifetimes, locking, units, and why it exists.
    • Inline comments near implementation code are suspicious. The longer an inline comment gets, the stronger the code smell — simplify or restructure the code instead of growing the comment.
    • When an inline comment is necessary (e.g., for a non-obvious constraint or spec requirement), keep it to 1–3 lines. Use a table or compact ASCII diagram instead of paragraphs for state machines or event matrices.
  • Write for the Final Code, Not the Diff (Default to Deleting):
    • Keep a comment only if a future reader modifying the code would need it to avoid breaking a non-obvious invariant, contract, or spec constraint. When in doubt, delete the comment rather than shortening it.
    • Never narrate the diff or history in code comments (e.g., "moved X before Y so Z does not happen", "this used to do Y") and do not explain rejected alternatives that are not in the code. Put change history and alternatives in the commit/PR description, and state only the current invariant in the code.
    • Do not add comments that label obvious guards ("defensive check"), point out visible code structure ("using a map keyed by X"), or explain standard language/library mechanics.
  • Document API Contracts, Never Implementation Coupling:
    • It is fine for an inline comment to note a non-obvious API contract that the call site relies on, saving the reader from jumping to other headers or definitions.
    • Never justify local code by referencing the internal implementation details of another function or module (e.g., "this is safe because Foo() internally does X"). Implementation details are not a contract and may change over time; relying on them is a code smell. If a guarantee is required, make it part of the API contract or decouple the code.
  • Plain Technical Language (No Prose or Literature):
    • Code comments and technical docs are not literature. Use literal, plain words instead of figurative language, metaphors, idioms, or fancy synonyms.
    • Write "set the bool to true" (not "signal" or "latch" the bool), "start the timer" (not "arm" the timer), "clear the state" (not "burn" or "spend" the state), "use X" (not "leverage X" or "key off X"), and "what breaks / which case fails" (not "where it bites").
    • Avoid hype or self-praise ("robust", "seamless", "zero overhead"). State tradeoffs only when naming a concrete engineering cost (e.g., "chosen to reduce flash size at the cost of runtime").
    • Name the subject in every sentence (avoid vague "this" or "it") and keep sentences short.

Testing

  • Unit tests are required for all changes unless unit testing is impossible (e.g., platform-specific code).
  • Tests in src/python_testing and src/app/tests/suites which verify expected failures should clearly indicate why the failure is expected. Include a summary of the relevant specification requirements if possible.

Architectural Constraints

Code-Driven Clusters

Code-driven clusters are implementations in src/app/clusters that use DefaultServerCluster as a base class. When developing them:

  • ReadAttribute, WriteAttribute, and InvokeCommand are by API contract only called for existent paths. Do not add path validity checks — they increase code size and are redundant as long as Attributes or AcceptedCommands are correct.
  • Ember APIs and generated ZAP accessors must not be used outside the CodegenIntegration layer. CodegenIntegration.h/cpp is the documented bridge between generated configuration and code-driven cluster logic. Avoid types like EmberAfStatus or functions like emberAfContainsServer, emberAfReadAttribute, or emberAfWriteAttribute in core cluster code.
  • When adding files: codegen-specific files belong in app_config_dependent_sources.cmake/gni; all others belong in BUILD.gn. Ensure every file (especially headers) is listed in one of these — there should be no unreferenced files.

Example Applications (Documentation Discovery)

When operating on or analyzing reference applications (such as examples/all-devices-app or custom simulator tools), always inspect that application's dedicated docs/ folder or ARCHITECTURE.md file to understand its dynamic runtime Interaction Model, specific CLI parameters, and recommended product baseline patterns before modifying or generating code.

Common Commands

Most commands require an activated environment. The user may or may not have already done that before running an agent harness; if $PW_PROJECT_ROOT is set the environment is probably active.

Environment Activation

You can run commands within the environment using scripts/run_in_build_env.sh: scripts/run_in_build_env.sh "command"

Alternatively, you can activate the environment in your shell: source scripts/activate.sh

Build and Test

  • List available targets: scripts/run_in_build_env.sh "./scripts/build/build_examples.py targets"

  • Generate Ninja files: scripts/run_in_build_env.sh "./scripts/build/build_examples.py --target linux-x64-tests-clang --quiet gen"

  • Build and run all tests: scripts/run_in_build_env.sh "./scripts/build/build_examples.py --target linux-x64-tests-clang --quiet build"

  • Run a specific test: scripts/run_in_build_env.sh "ninja -C out/linux-x64-tests-clang --quiet path/to/test:test_name.run"

    • Explicit example: scripts/run_in_build_env.sh "ninja -C out/linux-x64-tests-clang src/app/clusters/occupancy-sensor-server/tests:TestOccupancySensingCluster.run"

    • Compile and run can be separated (e.g. if running under some memory debugger or needing to set other options):

      ```bash
      scripts/run_in_build_env.sh "ninja -C out/linux-x64-tests-clang src/app/clusters/occupancy-sensor-server/tests:TestOccupancySensingCluster"`
      ./out/linux-x64-tests-clang/tests/TestOccupancySensingCluster
      ```
      

Building Common Apps

  • chip-tool (Interactive commissioning tool): scripts/run_in_build_env.sh "./scripts/build/build_examples.py --target linux-x64-chip-tool-clang --quiet build"
  • all-clusters-app (Feature-rich device simulator): scripts/run_in_build_env.sh "./scripts/build/build_examples.py --target linux-x64-all-clusters-clang --quiet build"
  • all-devices-app (Alternative feature-rich simulator): scripts/run_in_build_env.sh "./scripts/build/build_examples.py --target linux-x64-all-devices-clang --quiet build"

Development Resources