Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message
Agents
atoms/database-illuminate
claude-code
cursor
database
eloquent
atoms

Guidance for coding agents working in this repository. Thin by design: each subdirectory's own AGENTS.md is binding for work under it; this file holds only the map and what crosses the boundaries.

Install
php artisan boost:add-skill atoms/database-illuminate

Save this content to: AGENTS.md

# AGENTS.md

Guidance for coding agents working in this repository. Thin by design: each
subdirectory's own AGENTS.md is binding for work under it; this file holds
only the map and what crosses the boundaries.

## What this repo is

`atoms` is the **Atoms monorepo** — both halves of the product in one tree:
the PHP framework a customer installs into their existing app, and the
Cloudflare Worker runtime their Atoms actually execute inside.

An **Atom** is a persistent PHP object with its own SQLite database. The
framework packages let a Laravel or Symfony monolith call one like a local
object; the Worker hosts it as a PHP 8.3 interpreter compiled to WebAssembly,
parked inside a SQLite-backed Durable Object.

| Directory | What it is | Guidance |
|---|---|---|
| `packages/` | The eight MIT PHP packages: `atoms/{core,client,laravel,symfony,testing,phpstan-rules,cli,database-illuminate}` | `docs/conventions.md` (normative) |
| `cloudflare/` | The Worker runtime: `worker/` (host JS, `Atoms\Cf\` guest runtime, fixtures, conformance suite), `docs/` (runtime spec + PDO matrix), `corresponding-source/`, the licence files | `cloudflare/README.md`, `cloudflare/docs/runtime-spec.md` |
| `docs/` | Framework docs: `conventions.md`, `cloudflare-toolchain.md`, `two-worlds.md`, `errors.md` | — |
| `action/` | The deploy GitHub Action (composite) | `action/README.md` |
| `tests/` | Cross-package integration tests (`Atoms\Tests\Integration\`) | `docs/conventions.md` |
| `site/` | The public marketing site (Astro; content in `src/pages/index.astro`, tokens in `src/styles/global.css`) | `site/AGENTS.md` |
| `docs-site/` | The public documentation site at docs.atomsphp.dev (Astro Starlight; a static-asset Cloudflare Worker like `site/`) | `docs-site/README.md` |

Assembled 2026-08-08 from two predecessor repositories, under deliberately
different rules. The framework half was imported **with** its full history.
`cloudflare/` was imported **without** history, as files rather than commits:
the repository it came from has a GPL php-wasm binary reachable in its history,
and `git clone` delivers history rather than the tip, so inheriting it would
have republished the binary. **Never graft that history on**, however
convenient it looks.

## Read before non-trivial work

1. `docs/conventions.md` — cross-package contracts, the frozen `atoms/core`
   API, error-catalog rules, layering. **Normative.** If code and this file
   disagree, the code is wrong.
2. `docs/two-worlds.md` — the two-worlds model: which code ships to the
   runtime, which stays in the monolith, and how the file layout makes the
   difference unmistakable.
3. `cloudflare/docs/runtime-spec.md` — the binding spec for the Worker: PHP↔JS
   wire protocol, DO lifecycle, routes, envelopes, bundle format, and an
   appendix of **measured** platform deviations. Read the appendix before
   assuming anything about workerd.
4. `docs/cloudflare-toolchain.md` — **normative** for how the two halves meet:
   the runtime auth decision (`atoms/client` calls the Worker's prefixless,
   single-tenant `/invoke/...`), how a PHP CLI drives a pinned Wrangler, and
   the bundle bridge between `atoms build` and the Worker. Everything
   downstream inherits all three decisions, so read it before changing any
   of them.

## Hard rules — the PHP packages

- **`atoms/core` is the frozen runtime API.** Its public surface is wire-protocol
  grade: never change an existing signature, only add. It depends on nothing
  framework-ish (`psr/*` interfaces only). It must run on PHP 8.3.
  Pre-1.0, changing one is still on the table when a signature is genuinely
  unusable — see `docs/conventions.md` §The `atoms/core` API. It takes an
  explicit decision and a build error naming the new shape; it is never a
  judgement call to make mid-task.
- **Layering is the product.** core ← client ← {laravel, symfony};
  core ← {testing, phpstan-rules, cli}. The Symfony bundle must never need
  `atoms/laravel`; the CLI and testing packages must never need
  `atoms/client`. Nothing ships in `atoms/laravel` that could live in
  `atoms/client` or `atoms/core`.
- **The error catalog is the single source of truth.**
  `packages/core/resources/errors.json` — every user-facing failure in every
  package carries its `ATOMS-E###` code and catalog fix line. Append-only;
  never renumber or repoint an existing code; keep the `ErrorCode` enum in sync
  (a core test enforces it). Rewording an existing code's message/fix **is**
  allowed — see `docs/conventions.md` §Error catalog.
- **No native `serialize()`/`unserialize()`** anywhere in the codebase.
  Boundary data moves as JSON through `Atoms\Serialization\Serializer`.
- **Builds are pure functions of the repo.** `atoms build` must be
  deterministic (byte-identical bundles from identical trees) and must never
  execute customer code.
- **The CLI never fetches a toolchain, and never holds a credential.**
  `deploy`/`status`/`rollback`/`secrets` run a Wrangler that is already on the
  machine — never `npx`, which would defeat the pin in the Worker project's
  lockfile. Cloudflare credentials go into the Wrangler child process's
  environment and nowhere else: no file, no log, no echo. The single exception
  is `action/action.yml`'s `::add-mask::` step, which echoes the token to
  register it for redaction — GitHub has no non-echoing form of that command,
  and an action input is not masked automatically unless it came from
  `secrets.*`. Masking is what keeps the rest of the rule true in a log.
- Package versions and inter-package constraints are coordinated from
  `release/manifest.json` by the release tooling — don't hand-edit them. Root
  `composer.json` wires the packages via path repositories; one root
  `composer install`, one root `vendor/`.

## Hard rules — `cloudflare/`

- **The php-wasm runtime binary is never committed.** `npm ci` fetches it from
  `@php-wasm/web-8-3`, and `scripts/prepare-runtime.mjs` stages it into a
  gitignored `worker/.php-wasm/` after verifying the upstream size and SHA-256
  of both the wasm and the JS glue. It is a large generated upstream artifact,
  not repository source. Never soften or skip the hash check either — a
  mismatch is a real finding, not CI noise.
- **Licenses and provenance.** Atoms-authored source is MIT by grant file
  (`LICENSE`, `cloudflare/LICENSE-MIT`). Upstream component licenses and
  provenance are recorded in `THIRD_PARTY_NOTICES.md`.
- **No speculative per-file SPDX headers or `LICENSES/` directory.** The grant
  files cover Atoms-authored source; upstream packages carry their own
  metadata and notices.
- **`app()`, `dispatch()`, `broadcast()`, WebSockets and timers/alarms are
  implemented**, over a signed callback channel, the Hibernation API and
  a multiplexed Durable Object alarm respectively — see
  `cloudflare/docs/runtime-spec.md` §The callback channel, §The WebSocket seam and
  §Timers. `AtomsNotSupported` (`worker/php/runtime/`) now legitimately
  remains only on the permanently-unsupported corner of the PDO shim
  (`AtomsPDO.php`/`AtomsStatement.php` — see `worker/php/README.md`
  §Documented leaks and limits); that restriction is not a stub, and it is
  machine-verified rather than hand-audited: a reflection tripwire (conformance check 26) asserts every
  public member of the runtime's `\PDO`/`\PDOStatement` is genuinely declared,
  and a differential harness (checks 27-28) measures the remaining corner
  against a native in-guest `pdo_sqlite`, publishing the result as
  `cloudflare/docs/pdo-compatibility.md` (check 30). Adding to the runtime
  surface is a spec change first — do not "fix" a gap by inventing a
  half-implementation.
- **No capacity numbers in code.** Every TTL, cap, deadline, limit and poll
  interval comes from an environment variable with a default, resolved in
  `worker/src/config.js` and nowhere else.
- `worker/php/atoms-core/` is a **verbatim** copy of `packages/core/src`,
  hash-recorded in its `VENDORED-FROM.md`. Never edit it in place — fix
  `packages/core/` and re-vendor.
- **The committed bundle embeds its inputs.** Any change under
  `cloudflare/worker/php/` or `cloudflare/worker/fixtures/counter/` —
  comment-only edits and re-vendors included — requires regenerating and
  committing `src/bundle.generated.js` (`npm run bundle`). CI's staleness
  gate enforces it; `npm run check:fresh` runs the same check locally.

## Cross-cutting rules

- **PR descriptions are for reviewer context, not CI/CD output.** Do not add
  test commands, pass/fail counts, CI status, deployment or preview status,
  generated-artifact freshness, or contract/layering results that GitHub
  checks already surface. Mention validation only when it is not visible in
  checks and materially affects review, such as a manual or external
  measurement that informed the implementation.
- **One CI workflow tests everything, from one clone.** `.github/workflows/ci.yml`
  runs the PHP suites (`composer test` on 8.3–8.6), `composer stan`,
  manifest lint, *and* the Worker's conformance suite under a local
  `wrangler dev`, run for three auth postures: the full suite with
  `ATOMS_BEARER_AUTH=disabled`, the ticket/rotation/cross-language checks
  again with `ATOMS_BEARER_AUTH=required` and a per-run `ATOMS_SHARED_SECRET`,
  and a tiny run against a Worker with no secret configured, asserting
  `misconfigured`. Keep that true: a change to either half must leave the
  whole workflow green, and no job may need a Cloudflare account, an API
  token, or a cross-repo fetch of any kind.
- **The conformance suite is the acceptance gate for `cloudflare/`.** Its
  assertions are not edited to accommodate an implementation; the only legal
  edits are ADDITIVE ones that make a check assert more. Checks 12, 21, 24 and
  25 each wait out a real eviction, so the run takes minutes — shortening
  `ATOMS_EVICTION_WAIT_MS` does not make it faster, it makes it assert nothing.
  The one narrow exception: when the spec itself **removes** a surface (a
  route, a header, an env var), a check that exercised that surface is
  reworked in the same change, and every removed positive assertion is
  replaced by an explicit negative one — the surface must now be proven
  absent, not merely left unchecked. The rework is recorded in
  `cloudflare/worker/test/README.md` and in the spec's own conformance
  narrative. This is a carve-out for spec-driven removals, made in lockstep
  with the spec change that mandates them — it is not a general licence to
  weaken a check because an implementation fell short of it.
- **Tests never hit the network.** HTTP is tested against an in-memory PSR-18
  fake; SQLite tests use `:memory:` or a temp dir. The Worker suite talks only
  to a worker you started locally.
- Agent guidance lives in `AGENTS.md` files; every `CLAUDE.md` here is a
  symlink to its sibling `AGENTS.md`. Keep the convention when adding
  directories.

## Common commands

```sh
# PHP framework — from the repo root
composer install                     # one root install for all packages
composer test                        # all test suites
composer test -- --testsuite=core    # one package's suite
composer stan                        # phpstan across all packages/*/src
packages/cli/bin/atoms               # run the CLI from source
packages/cli/bin/atoms dev           # build + `wrangler dev`; no Cloudflare account needed

# Cloudflare Worker — from cloudflare/worker
npm ci                               # installs deps and stages .php-wasm/
npm run prepare-runtime              # stage the runtime unconditionally
npm run bundle                       # build src/bundle.generated.js from the conformance fixture
npm run bundle:cli -- B M src/bundle.generated.js   # ...or from an `atoms build` bundle + manifest
npx wrangler dev                     # serves on 127.0.0.1:8787 (wrangler.jsonc)
npm run dev:callback                 # same, plus a per-run ATOMS_SHARED_SECRET and
                                      # ATOMS_CALLBACK_URL wired in, for the callback checks
ATOMS_BASE_URL=http://127.0.0.1:8787 node test/conformance.mjs
```

The conformance runner reads `ATOMS_BASE_URL` (required) and one of
`ATOMS_SHARED_SECRET` (full capability: derives the bearer, forges test
tickets, verifies callbacks — the local/CI posture) or `ATOMS_BEARER_TOKEN`
(a pre-derived bearer for invoke-only checks against a deployed Worker, so
the root never has to travel to the runner). `ATOMS_BEARER_AUTH`
(`required` or `disabled`) names the posture the Worker under test is
running. `ATOMS_EVICTION_WAIT_MS` (default 12500), `ATOMS_SKIP`/`ATOMS_ONLY`
(comma-separated check numbers), and the callback-channel, rotation and
deny-list toggles are documented in `test/conformance.mjs`'s own header
comment. Debug endpoints, which some checks need, are gated on the worker's
own `ATOMS_DEBUG_ENDPOINTS` var, already set in `wrangler.jsonc`. No
Cloudflare account is needed for any of it.

AGENTS.md

Guidance for coding agents working in this repository. Thin by design: each subdirectory's own AGENTS.md is binding for work under it; this file holds only the map and what crosses the boundaries.

What this repo is

atoms is the Atoms monorepo — both halves of the product in one tree: the PHP framework a customer installs into their existing app, and the Cloudflare Worker runtime their Atoms actually execute inside.

An Atom is a persistent PHP object with its own SQLite database. The framework packages let a Laravel or Symfony monolith call one like a local object; the Worker hosts it as a PHP 8.3 interpreter compiled to WebAssembly, parked inside a SQLite-backed Durable Object.

Directory What it is Guidance
packages/ The eight MIT PHP packages: atoms/{core,client,laravel,symfony,testing,phpstan-rules,cli,database-illuminate} docs/conventions.md (normative)
cloudflare/ The Worker runtime: worker/ (host JS, Atoms\Cf\ guest runtime, fixtures, conformance suite), docs/ (runtime spec + PDO matrix), corresponding-source/, the licence files cloudflare/README.md, cloudflare/docs/runtime-spec.md
docs/ Framework docs: conventions.md, cloudflare-toolchain.md, two-worlds.md, errors.md —
action/ The deploy GitHub Action (composite) action/README.md
tests/ Cross-package integration tests (Atoms\Tests\Integration\) docs/conventions.md
site/ The public marketing site (Astro; content in src/pages/index.astro, tokens in src/styles/global.css) site/AGENTS.md
docs-site/ The public documentation site at docs.atomsphp.dev (Astro Starlight; a static-asset Cloudflare Worker like site/) docs-site/README.md

Assembled 2026-08-08 from two predecessor repositories, under deliberately different rules. The framework half was imported with its full history. cloudflare/ was imported without history, as files rather than commits: the repository it came from has a GPL php-wasm binary reachable in its history, and git clone delivers history rather than the tip, so inheriting it would have republished the binary. Never graft that history on, however convenient it looks.

Read before non-trivial work

  1. docs/conventions.md — cross-package contracts, the frozen atoms/core API, error-catalog rules, layering. Normative. If code and this file disagree, the code is wrong.
  2. docs/two-worlds.md — the two-worlds model: which code ships to the runtime, which stays in the monolith, and how the file layout makes the difference unmistakable.
  3. cloudflare/docs/runtime-spec.md — the binding spec for the Worker: PHP↔JS wire protocol, DO lifecycle, routes, envelopes, bundle format, and an appendix of measured platform deviations. Read the appendix before assuming anything about workerd.
  4. docs/cloudflare-toolchain.md — normative for how the two halves meet: the runtime auth decision (atoms/client calls the Worker's prefixless, single-tenant /invoke/...), how a PHP CLI drives a pinned Wrangler, and the bundle bridge between atoms build and the Worker. Everything downstream inherits all three decisions, so read it before changing any of them.

Hard rules — the PHP packages

  • atoms/core is the frozen runtime API. Its public surface is wire-protocol grade: never change an existing signature, only add. It depends on nothing framework-ish (psr/* interfaces only). It must run on PHP 8.3. Pre-1.0, changing one is still on the table when a signature is genuinely unusable — see docs/conventions.md §The atoms/core API. It takes an explicit decision and a build error naming the new shape; it is never a judgement call to make mid-task.
  • Layering is the product. core ← client ← {laravel, symfony}; core ← {testing, phpstan-rules, cli}. The Symfony bundle must never need atoms/laravel; the CLI and testing packages must never need atoms/client. Nothing ships in atoms/laravel that could live in atoms/client or atoms/core.
  • The error catalog is the single source of truth. packages/core/resources/errors.json — every user-facing failure in every package carries its ATOMS-E### code and catalog fix line. Append-only; never renumber or repoint an existing code; keep the ErrorCode enum in sync (a core test enforces it). Rewording an existing code's message/fix is allowed — see docs/conventions.md §Error catalog.
  • No native serialize()/unserialize() anywhere in the codebase. Boundary data moves as JSON through Atoms\Serialization\Serializer.
  • Builds are pure functions of the repo. atoms build must be deterministic (byte-identical bundles from identical trees) and must never execute customer code.
  • The CLI never fetches a toolchain, and never holds a credential. deploy/status/rollback/secrets run a Wrangler that is already on the machine — never npx, which would defeat the pin in the Worker project's lockfile. Cloudflare credentials go into the Wrangler child process's environment and nowhere else: no file, no log, no echo. The single exception is action/action.yml's ::add-mask:: step, which echoes the token to register it for redaction — GitHub has no non-echoing form of that command, and an action input is not masked automatically unless it came from secrets.*. Masking is what keeps the rest of the rule true in a log.
  • Package versions and inter-package constraints are coordinated from release/manifest.json by the release tooling — don't hand-edit them. Root composer.json wires the packages via path repositories; one root composer install, one root vendor/.

Hard rules — cloudflare/

  • The php-wasm runtime binary is never committed. npm ci fetches it from @php-wasm/web-8-3, and scripts/prepare-runtime.mjs stages it into a gitignored worker/.php-wasm/ after verifying the upstream size and SHA-256 of both the wasm and the JS glue. It is a large generated upstream artifact, not repository source. Never soften or skip the hash check either — a mismatch is a real finding, not CI noise.
  • Licenses and provenance. Atoms-authored source is MIT by grant file (LICENSE, cloudflare/LICENSE-MIT). Upstream component licenses and provenance are recorded in THIRD_PARTY_NOTICES.md.
  • No speculative per-file SPDX headers or LICENSES/ directory. The grant files cover Atoms-authored source; upstream packages carry their own metadata and notices.
  • app(), dispatch(), broadcast(), WebSockets and timers/alarms are implemented, over a signed callback channel, the Hibernation API and a multiplexed Durable Object alarm respectively — see cloudflare/docs/runtime-spec.md §The callback channel, §The WebSocket seam and §Timers. AtomsNotSupported (worker/php/runtime/) now legitimately remains only on the permanently-unsupported corner of the PDO shim (AtomsPDO.php/AtomsStatement.php — see worker/php/README.md §Documented leaks and limits); that restriction is not a stub, and it is machine-verified rather than hand-audited: a reflection tripwire (conformance check 26) asserts every public member of the runtime's \PDO/\PDOStatement is genuinely declared, and a differential harness (checks 27-28) measures the remaining corner against a native in-guest pdo_sqlite, publishing the result as cloudflare/docs/pdo-compatibility.md (check 30). Adding to the runtime surface is a spec change first — do not "fix" a gap by inventing a half-implementation.
  • No capacity numbers in code. Every TTL, cap, deadline, limit and poll interval comes from an environment variable with a default, resolved in worker/src/config.js and nowhere else.
  • worker/php/atoms-core/ is a verbatim copy of packages/core/src, hash-recorded in its VENDORED-FROM.md. Never edit it in place — fix packages/core/ and re-vendor.
  • The committed bundle embeds its inputs. Any change under cloudflare/worker/php/ or cloudflare/worker/fixtures/counter/ — comment-only edits and re-vendors included — requires regenerating and committing src/bundle.generated.js (npm run bundle). CI's staleness gate enforces it; npm run check:fresh runs the same check locally.

Cross-cutting rules

  • PR descriptions are for reviewer context, not CI/CD output. Do not add test commands, pass/fail counts, CI status, deployment or preview status, generated-artifact freshness, or contract/layering results that GitHub checks already surface. Mention validation only when it is not visible in checks and materially affects review, such as a manual or external measurement that informed the implementation.
  • One CI workflow tests everything, from one clone. .github/workflows/ci.yml runs the PHP suites (composer test on 8.3–8.6), composer stan, manifest lint, and the Worker's conformance suite under a local wrangler dev, run for three auth postures: the full suite with ATOMS_BEARER_AUTH=disabled, the ticket/rotation/cross-language checks again with ATOMS_BEARER_AUTH=required and a per-run ATOMS_SHARED_SECRET, and a tiny run against a Worker with no secret configured, asserting misconfigured. Keep that true: a change to either half must leave the whole workflow green, and no job may need a Cloudflare account, an API token, or a cross-repo fetch of any kind.
  • The conformance suite is the acceptance gate for cloudflare/. Its assertions are not edited to accommodate an implementation; the only legal edits are ADDITIVE ones that make a check assert more. Checks 12, 21, 24 and 25 each wait out a real eviction, so the run takes minutes — shortening ATOMS_EVICTION_WAIT_MS does not make it faster, it makes it assert nothing. The one narrow exception: when the spec itself removes a surface (a route, a header, an env var), a check that exercised that surface is reworked in the same change, and every removed positive assertion is replaced by an explicit negative one — the surface must now be proven absent, not merely left unchecked. The rework is recorded in cloudflare/worker/test/README.md and in the spec's own conformance narrative. This is a carve-out for spec-driven removals, made in lockstep with the spec change that mandates them — it is not a general licence to weaken a check because an implementation fell short of it.
  • Tests never hit the network. HTTP is tested against an in-memory PSR-18 fake; SQLite tests use :memory: or a temp dir. The Worker suite talks only to a worker you started locally.
  • Agent guidance lives in AGENTS.md files; every CLAUDE.md here is a symlink to its sibling AGENTS.md. Keep the convention when adding directories.

Common commands

# PHP framework — from the repo root
composer install                     # one root install for all packages
composer test                        # all test suites
composer test -- --testsuite=core    # one package's suite
composer stan                        # phpstan across all packages/*/src
packages/cli/bin/atoms               # run the CLI from source
packages/cli/bin/atoms dev           # build + `wrangler dev`; no Cloudflare account needed

# Cloudflare Worker — from cloudflare/worker
npm ci                               # installs deps and stages .php-wasm/
npm run prepare-runtime              # stage the runtime unconditionally
npm run bundle                       # build src/bundle.generated.js from the conformance fixture
npm run bundle:cli -- B M src/bundle.generated.js   # ...or from an `atoms build` bundle + manifest
npx wrangler dev                     # serves on 127.0.0.1:8787 (wrangler.jsonc)
npm run dev:callback                 # same, plus a per-run ATOMS_SHARED_SECRET and
                                      # ATOMS_CALLBACK_URL wired in, for the callback checks
ATOMS_BASE_URL=http://127.0.0.1:8787 node test/conformance.mjs

The conformance runner reads ATOMS_BASE_URL (required) and one of ATOMS_SHARED_SECRET (full capability: derives the bearer, forges test tickets, verifies callbacks — the local/CI posture) or ATOMS_BEARER_TOKEN (a pre-derived bearer for invoke-only checks against a deployed Worker, so the root never has to travel to the runner). ATOMS_BEARER_AUTH (required or disabled) names the posture the Worker under test is running. ATOMS_EVICTION_WAIT_MS (default 12500), ATOMS_SKIP/ATOMS_ONLY (comma-separated check numbers), and the callback-channel, rotation and deny-list toggles are documented in test/conformance.mjs's own header comment. Debug endpoints, which some checks need, are gated on the worker's own ATOMS_DEBUG_ENDPOINTS var, already set in wrangler.jsonc. No Cloudflare account is needed for any of it.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route