<!-- guardlink:begin -->
<!-- guardlink:stamp annotation_hash=sha256-v3:eebfe786379ae01c37d362c6ddc806a10894157b04af7d4a83fa1132b0902f87 agent_config_hash=sha256-v1:5823a383fcde3f7c97f0c0214016d068740bab7f493546a1103b34f8ed87ae9c -->
# GuardLink Security Annotations

This project carries a [GuardLink](https://guardlink.bugb.io) threat model: security facts recorded
next to the code they describe — what each component is exposed to, what mitigates it, how data flows.
**Ask it instead of inferring security context from the source:** `guardlink_context(file)` before you
edit a file, `guardlink_graph` before you change a shared component, `guardlink_lookup("cwe:CWE-89")`
for a scanner finding, `guardlink_paths` for routes no control covers. Without MCP, `guardlink status .`
and `guardlink parse .` answer the same.

**Where annotations go:** `inline` mode — in the doc-block comment of the code they describe, in that file's comment syntax, never in `.gal` sidecars. Placement in full: `.guardlink/README.md`; syntax and rules: `docs/GUARDLINK_REFERENCE.md`.

**What you owe it back**, in the same change as the code:

- Annotate security-relevant code you write or change — endpoints, authentication and authorization (ownership and tenant checks included), validation, queries, file I/O, external calls, crypto, process spawning, configuration parsing. Reuse the ids in `.guardlink/definitions.ts`; never redefine one.
- Code that hands an LLM agent a tool: `@agents` on the registration, `@effects` on the code that acts, `@gates` on an approval step (`@reaches` for a principal that is no agent). Syntax: the reference above.
- **Never write `@accepts` or `@entitles`** — both are a human's decision. A risk with no control is `@exposes` + `@audit`; an entitlement is proposed with `guardlink entitle --propose`, and a human's acceptance writes it.
- `@confirmed` needs reproduction evidence in hand; reading the code is not reproduction.
- Before you finish: `guardlink validate .`, then `guardlink diff HEAD~1` — did this change add exposure?

**Before you open or update a pull request**, check the annotations it adds against its base branch:

- `guardlink validate .` — they parse and their references resolve. It also says when a published `.guardlink/report.json` is behind them; `guardlink parse . -o .guardlink/report.json` refreshes it.
- `guardlink lint . --since origin/<base>` — each new claim names its code and is paired; `--json` gives the `fix` for any that is not.
- `guardlink diff origin/<base>` — the exposures, flows and acceptances the change adds.

If you are asked to raise a pull request and this check has not come up, suggest it. Never write `@accepts` to clear what it reports.

**This repository's agent configuration is part of its threat model.** `guardlink lookup "agent config"` lists what each coding agent can do here and who approved it. That reach is generated from the configuration files, so never write `@agents` or `@reaches` for Claude Code, Cursor, Copilot, Codex or Gemini.

_Generated by `guardlink sync`, which rewrites this block; `guardlink validate` warns when its stamp no longer matches the model._

<!-- guardlink:end -->
