Skip to content

Latest commit

 

History

History
184 lines (152 loc) · 9.31 KB

File metadata and controls

184 lines (152 loc) · 9.31 KB

Agent Guidelines

Toolchain & Project Layout

Package Manager

Use pnpm (not npm or yarn). The lockfile is pnpm-lock.yaml. Install deps with pnpm install; run scripts with pnpm run <script> or pnpm <script>.

Build

The library is built with tsc (not vite build). vite.config.ts exists only to configure Vitest and to run vite dev as a server for Playwright. Running pnpm run build compiles src/ to dist/ via tsconfig.json.

Two tsconfigs

  • tsconfig.json — library build only; includes src/**/*
  • tsconfig.dev.json — extends the above with noEmit: true; adds test/**/*, vite.config.ts, and playwright.config.ts so ESLint's type-aware rules cover all files

Do not add test files to tsconfig.json — they would be emitted into dist/.

Tests

  • test/node/ — Vitest unit tests (pnpm run test:node); run in Node
  • test/browser/ — Playwright tests (pnpm run test:browser); run in real Chromium via a Vite dev server (pnpm run dev)

The dev script exists solely to give Playwright a server that can serve and transform TypeScript source files on the fly. There is no browser app.

ESM & import paths

The package is ESM-only ("type": "module"). Local imports must use the .js extension even though source files are .ts — e.g. import { Example } from '../../src/index.js'. TypeScript's moduleResolution: Bundler resolves these to the .ts source at compile time.

Architecture

The current shape of the library lives in ARCHITECTURE.md, rationale inline, updated in the same change set that alters the shape. It is load-bearing for the conventions below: the design gate scopes on the invariants it documents, touches: entries name it as a deliverable, and the breaking-release audit checks it against the code. The template copy is a skeleton (layer map, numbered invariants, ownership heuristics, glossary, current state labels); scaffolded repos fill it in and keep the sections.

Domain language

ARCHITECTURE.md's Glossary is the repo's vocabulary. Use its terms as written in code identifiers, test names, docs, commit messages, and conversation, and treat the Avoid: synonyms as banned.

Refine the glossary as you work, in the same change set that settles a term. When a term in the conversation conflicts with the glossary, say so before using it. When a term is vague or overloaded, propose one canonical term and record it. When a new module or concept needs a name the glossary lacks, add the entry. A new term that becomes a wire artifact (a field name, a log entry kind, an error name) is a wire-level convention and still needs core-contributor sign-off before it is coded; the glossary entry is written after that sign-off, not instead of it.

Skills and agent instructions written for other conventions refer to a CONTEXT.md or CONTEXT-MAP.md glossary and a docs/adr/ directory. In this ecosystem those map to ARCHITECTURE.md's Glossary section and the repo's decisions/ directory. Do not create CONTEXT.md, CONTEXT-MAP.md, or docs/adr/. The context map is the ecosystem itself: each repo's "What lives elsewhere" and "Ownership heuristics" sections state the relationships between repos.

Roadmap & Task Conventions

All roadmap tracking lives in ROADMAP.md: narrative context plus structured work items. Never create a parallel task list elsewhere (no TODO.md, no task lists in other docs).

Each work item follows this schema:

  • A heading ### ILT-N: Title, then a field block, then free prose context.
  • The prose opens with a Context: paragraph: a few plain-language sentences stating what is wrong today, how it came about, and why it matters, readable on its own without following any file pointer. The detailed mechanics (file:line cites, stage orders, edge cases) follow in ordinary prose after it. Acceptance boxes record exit criteria, not motivation, so the Context paragraph is where a returning reader or an agent picks up the problem; on a design-gated item it also seeds the design doc's Problem-and-scope section. Items predating the convention (added 2026-08-25) are backfilled when next touched, not in bulk.
  • Fields: status (todo / in-progress / draft / done), priority (high / medium / low), labels (comma-separated), optional blocked-by (other ILT-N ids), a touches: list where the rule below applies, design: + design-approved: where the design gate below applies, and an acceptance: checklist.
  • draft marks items with no actionable done-state yet (blocked externally or parking records); a draft states why instead of acceptance criteria and must gain acceptance criteria when promoted to todo.
  • touches: is required for any item that changes a spec, a wire contract, or a shared @interop/* API. It lists every affected repo AND that repo's ARCHITECTURE/AGENTS files -- the docs are entries in their own right, not an afterthought, since doc drift is what the field exists to prevent. Each entry starts unresolved and is resolved in place: marked shipped (naming what landed) or explicitly waived as unaffected: <repo> (<why>).

Rules:

  • Item ids are permanent and never reused. A new item takes the next unused number, regardless of which section it lands in.
  • Every non-draft item needs acceptance criteria before it may be moved to in-progress.
  • Statuses are edited in place (change the status: field); acceptance checkboxes are ticked as they are met.
  • An item carrying a touches: field may not flip to done while any entry in it is unresolved -- an unresolved entry is unfinished work of the item itself, not a follow-up.
  • Completed items move verbatim (number, title, field block, prose, with their done date) from ROADMAP.md to archived-roadmap.md once shipped, append-only -- this keeps ILT-N references resolvable. CHANGELOG.md remains the permanent record of what landed. Do not rewrite or summarize items on the way in, and do not fix old references.
  • Work discovered mid-implementation gets its own item immediately, noting discovered-from: ILT-N in its prose, plus a blocked-by link if it blocks anything.
  • The design gate: a cross-cutting item (one that changes persistence semantics, key custody, a ceremony's stage order, or any invariant the repo's ARCHITECTURE.md documents) carries design: (a doc per designs/TEMPLATE.md) and design-approved: (a date only core contributors set), and no implementation starts until the doc is approved. Approval extracts the design's durable decisions -- contract-binding ones, and do-not-reopen rejections of an approach -- into tracked decisions/ records. The full definition is canonical in this repo's designs/ directory.
  • Reference item ids in commit messages and PR descriptions where relevant.

Decision Records

Cross-repo decisions -- the ones whose driving roadmap item carries a touches: field -- get a durable record in the owning repo's decisions/ directory (decisions/NNNN-slug.md). The convention and template are canonical in this repo's decisions/ directory: required sections Context / Decision / Consequences / Revisit Criteria, Rejected Alternatives where applicable, records superseded in place rather than rewritten. A pre-implementation design review may additionally mint a record for a repo-internal do-not-reopen decision (an approach rejected with concrete revisit criteria); other repo-internal decisions stay in ARCHITECTURE.md prose and do not get a record. The full scope rule lives in the decisions/ README. Within either case, a record is written only when the decision passes the qualifying test in that README (hard to reverse, surprising without context, a real trade-off); a skill's offer to "write an ADR" is a proposal for such a record, pending that test and core-contributor approval, and uses decisions/TEMPLATE.md.

Releasing

The @interop/* publish convention (this section is its canonical home; downstream repos defer here):

  • The version published is the one the CHANGELOG's top entry names; its TBD date is replaced with the release date at publish time.
  • Breaking-release doc-vs-code audit. Before publishing a version whose CHANGELOG carries a breaking entry, audit the ARCHITECTURE/AGENTS files of the consumers named in the affected contract's "Parties to this contract" registry (the AGENTS.md tables in app-connect-spec, encrypted-collections-spec, and the WAS spec repo), and file roadmap items for what the audit finds. The cheap mechanism, as run 2026-08-11: parallel read-only agents, one per consumer repo, each checking that repo's ARCHITECTURE/AGENTS statements against its own code and the new contract -- a recipe, not an aspiration. A consumer with nothing affected is recorded as unaffected: <repo> (<why>) on the driving roadmap item.
  • A breaking profile change also bumps the profile's version handle where the contract states one (e.g. the App Connect context URL) and the CHANGELOG names the profile version the package now speaks.

Conventions

Code style, refactoring, JSDoc, comment, and error-handling conventions live in @CONTRIBUTING.md -- follow them. That file's marked conventions block is the canonical shared core copied across @interop/* repos; edit it there, not in downstream copies.