Skip to content

Latest commit

 

History

History
152 lines (135 loc) · 8.81 KB

AGENTS.md

File metadata and controls

152 lines (135 loc) · 8.81 KB

AGENTS.md

These are the rules for coding agents that work on laya-apple. This file is the single source of truth for agents; CLAUDE.md only imports it. Human contributors should read CONTRIBUTING.md, which has the full setup, the test tiers and the release policy. These rules summarise it and do not replace it.

Scope

laya-apple is one repository. It covers:

  • Fast Laya runtime (product direction): loading, the MLX GPU and Core ML / ANE backends, parity and provenance.
  • GPU + ANE serving (product direction): routing, heterogeneous serving and benchmarking.
    • This includes laya-apple serve: a local, loopback-only HTTP decision backend with a Jev-compatible API. Existing clients, such as Claude Code plugins, call it without code changes.
    • Serving answers the decisions a client sends. It does not decide what an agent offloads, so it does not resume the paused research below.
  • Agent offloading (research, paused): local Laya decisions inside coding agents (OpenClaw, Hermes Agent, Pi).
    • The EXP-001 and EXP-002 quick probes found no measurable upside, so no further experiments are added (research/agent-decision-offloading/).
    • Resume only if new evidence shows a workload with measurable offloading value, such as substantial redundant tool-output context or a meaningful fraction of fixed-action post-tool LLM turns.
    • Integrations, adapters, hooks, installers and CLI integration belong here when that work is promoted.

Rules:

  • Research vs production. Research lives in research/<track>/. The laya_apple package never imports it, and it never ships.
    • A result is promoted to production only after its experiment passes its recorded criteria.
    • The promoted code is rebuilt with tests in its own pull request, for example under integrations/<agent>/.
  • Agent integrations use the agent's official plugin, hook or extension API.
    • Never fork, vendor, patch or rewrite a third-party agent framework.
    • Record the upstream version you verified against.
  • Client compatibility (Jev-compatible clients and plugins) is verified against the client's released version, without modifying the client. Record the versions tested.

Git workflow

  • main is stable and always releasable. Never commit or push to it directly.
  • Check the branch before changing anything: git status --short --branch. If it shows main, create a branch first. Use one of these prefixes:
    • feat/, fix/, docs/;
    • bench/, research/, release/.
  • Every change goes through a pull request. Merge only after CI passes. Prefer squash merge.
  • Title pull requests as <type>(<scope>): <imperative summary>. The title becomes the squash commit subject on main.
    • Types: feat, fix, perf, docs, test, refactor, build, ci, chore, bench.
    • Scope: optional, short and lowercase, for example runtime, routing, scheduler, mlx, ane, parity, artifacts, benchmarks, hardware, community, readme, media, offloading or integrations.
    • Summary: concise and imperative, lowercase after the colon, no trailing period.
    • Examples:
      • feat(routing): add calibrated profile selection
      • fix(ane): reject artifacts that fail placement validation
      • perf(scheduler): reduce short-request queueing
      • docs(community): clarify hardware benchmark submissions
      • bench(hardware): add M3 Max benchmark result
    • One pull request is still one logical change. The convention applies from now on; merged pull requests are not renamed, and CI does not check titles.
  • Protect published history:
    • never force-push main;
    • never rewrite main's published history;
    • never move, delete or recreate a published tag.
  • Never commit generated or local-only files:
    • generated Core ML models (*.mlpackage, *.mlmodelc);
    • model weights;
    • credentials;
    • machine-specific absolute paths.
  • docs/private/ and docs/DEVELOPMENT_PLAN.md are gitignored private notes. Never link them from README.md or published docs/, or copy their contents there.

Validation

Run what the change needs. The table in CONTRIBUTING.md ("Which tests a PR needs") gives the exact commands.

Sync with uv sync --extra dev --extra serve, as CI does. The fast suite imports fastapi (tests/unit/test_serve.py), so --extra dev alone fails at collection, and uv sync removes every extra it is not given: add --extra ane or --extra convert alongside these, not instead of them.

Change Minimum validation
Any change What CI (.github/workflows/ci.yml) runs: uv run ruff check ., uv run ruff format --check laya_apple scripts tests, the fast suite HF_HUB_OFFLINE=1 uv run pytest -q -m "not integration and not parity and not ane and not stress", the data-drift checks (scripts/derive_routing.py, scripts/derive_placement.py, scripts/make_goldens.py, scripts/generate_readme_svgs.py, each with --check) and scripts/check_file_sizes.py
Docs only Fast suite and CI. For packaging or README changes, also run uv build and uvx twine check --strict dist/*
Runtime, routing, scheduler, backend, model or ANE code Also the relevant integration, parity and ane tests on Apple silicon (CI runs none of them)
Performance-sensitive change Re-run the affected benchmark and compare it with the recorded baseline in benchmarks/ (scripts/compare_bench.py). Report the comparison in the PR
  • Never loosen a gate to make CI or a benchmark pass. This covers:

    • the parity tolerances in laya_apple/parity/__init__.py;
    • routing thresholds;
    • release-gate criteria.

    A tolerance or threshold change needs its own PR with measurements behind it.

  • Never edit historical raw benchmark data (benchmarks/*/, research/*/) to change a result. A new measurement goes in a new file or directory, with its methodology.

  • Raw data over 1 MiB does not go in Git. scripts/check_file_sizes.py (a CI step) fails any tracked file over 1 MiB that is not on its grandfathered allowlist. Run it before committing new files under research/ or benchmarks/. Publish larger raw data as external evidence with an in-repo manifest (URL, SHA-256, size) (docs/evidence.md). Never add research or benchmark data to the allowlist. Any other addition needs explicit maintainer agreement in the pull request.

  • Every performance or correctness claim in README.md or docs/ must trace to recorded measurement data. Name the file it comes from.

  • Keep the Chinese READMEs in sync. A change to README.md updates README.zh-TW.md and README.zh-CN.md in the same pull request. English is authoritative.

Correctness and benchmark principles

  • Correctness comes before speed.
    • A faster path that changes decisions against upstream Laya is a regression.
    • The FP16 gate is: probability error ≤ 0.02, 0 hard mismatches, and near-tie flips listed, not hidden (docs/correctness.md).
  • Explicit ANE requests never fall back silently. device="ane" either runs a validated artifact on the Neural Engine or raises (docs/no-silent-fallback.md).
  • Unvalidated platforms and artifacts are handled conservatively. auto stays on MLX unless the artifact passed parity on the machine that uses it.
  • Benchmark methodology changes are recorded explicitly. This includes changes to workloads, windows, arrival patterns, warm-up and hardware state. Numbers measured under different methodologies are never compared without saying so.
  • Keep throughput, latency, correctness and isolation as separate results. Never merge them into one PASS/FAIL that hides a failing dimension.
  • Published limitations stay published. Do not remove or soften a limitation to make a release look better. Remove one only when new measurements show it no longer applies.

Releases

  • Not every PR needs a release. A release is its own PR, or a PR whose purpose is the version change.

  • Keep versions in sync. The version in pyproject.toml, laya_apple.__version__ and the CHANGELOG.md heading must agree.

  • Tag only after the release PR is merged and main is healthy (CI green). Tag the merge commit on main with vX.Y.Z.

  • Never move, delete or rewrite a published tag. A bad release is fixed by a new patch version.

  • Publish to PyPI only through .github/workflows/release.yml, which uses Trusted Publishing (GitHub OIDC). Never add a PyPI API token or password anywhere.

  • After publishing, verify a clean install:

    • pip install laya-apple==X.Y.Z in a fresh environment;
    • import it and check the version;
    • check that the GitHub release, the tag and the PyPI version agree.

    Details: docs/publishing.md.