--- name: ax-annotation description: '@AX code annotation workflow skill for agent-driven tag application' compatibility: omp --- # @AX Annotation Skill The canonical @AX rule set is emitted into this skill by the harness generator, so the tag definitions, trigger conditions, lifecycle rules, and per-file limits below are authoritative for this installation. This skill provides actionable guidance for WHEN and HOW agents apply @AX tags. ## Activation @AX annotation is opt-in. It is not a pipeline phase and no workflow tags files on its own. Run it only when one of these is true: - the user asks for @AX tags, or names this skill; - the run passes the annotation opt-in, so `auto spec gates --annotation` evaluates the `annotation` gate and returns `required`. Without that opt-in the `annotation` gate is `not_applicable`, the pipeline records no annotation step, and completion evidence reads `@AX: not requested`. A repository that has never adopted @AX therefore stays untagged instead of accumulating machine-authored comments nobody asked for. When the gate is opted in but the reference source or the annotator surface is missing, report `blocked` with the fallback "record modified files, defer tagging" rather than looping. Nothing to annotate is `not_applicable`, not `blocked`. ## Canonical Source Do NOT redefine tag rules elsewhere. Treat the sections of this document as the single source and apply them as written. ## When to Apply @AX Tags ### NOTE Triggers Apply `@AX:NOTE` when you encounter: - A magic constant with no explanation - An exported function over 100 lines that has no godoc comment - A business rule that is not self-evident from the code ### WARN Triggers Apply `@AX:WARN` (with `@AX:REASON`) when you detect: - A goroutine or channel launched without a `context.Context` - Cyclomatic complexity >= 15 (check with `gocyclo` or manual count) - Mutation of a package-level or global variable - A function with 8 or more `if` branches ### ANCHOR Triggers Apply `@AX:ANCHOR` (with `@AX:REASON`) when: - A function has fan_in >= 3 callers (heuristic: `grep -r "FuncName(" . | wc -l`) - Removing or renaming the symbol would break multiple consumers ### TODO Triggers Apply `@AX:TODO` when: - A public function has no corresponding test file - A SPEC requirement is referenced but not yet implemented - An error is returned without handling (silent discard) ## Application Workflow Execute after the GREEN or REFACTOR phase of TDD, once the opt-in above is satisfied: 1. **Scan** — list all files modified in this task 2. **Detect triggers** — for each file, check NOTE / WARN / ANCHOR / TODO conditions above 3. **Draft tags** — prefix every agent-generated tag with `[AUTO]` 4. **Attach REASON** — add `@AX:REASON` immediately after every WARN and ANCHOR tag 5. **Count per-file** — verify ANCHOR <= 3 and WARN <= 5 per file 6. **Handle overflow** — apply overflow strategy (see below) 7. **Commit** — include tags in the same commit as the code change ## Per-File Limits and Overflow | Tag | Limit | Overflow Strategy | |-----|-------|-------------------| | ANCHOR | 3 per file | Downgrade the entry with the lowest fan_in count to NOTE | | WARN | 5 per file | Retain the 5 highest-priority (oldest / most severe); drop new candidates | When a downgrade occurs, add a comment: `// @AX:NOTE: [downgraded from ANCHOR — fan_in < threshold]` ## [AUTO] Prefix Rule Every tag inserted by an agent MUST begin with `[AUTO]`: ```go // @AX:NOTE [AUTO]: Magic constant — see payment SLA documentation const retryLimit = 3 ``` Human-authored tags omit `[AUTO]`. Never remove an existing `[AUTO]` prefix. ## @AX:CYCLE Tracking `@AX:TODO` tags that survive 3 or more TDD cycles without resolution must be escalated to `@AX:WARN`. Cycle count is tracked via a `sync` comment on the tag line: ```go // @AX:TODO [AUTO] @AX:CYCLE:2: Add input validation — SPEC-AUTH-001 ``` When CYCLE reaches 3, replace the TODO with a WARN and add `@AX:REASON`. ## Language-Specific Comment Syntax | Language | Prefix | |----------|--------| | Go, Java, TypeScript, Rust | `//` | | Python, Ruby | `#` | | Haskell | `--` |