{"_id":"@agentlane/agent-ready","_rev":"2-0a70288f4ff27e74664e5381510823b7","name":"@agentlane/agent-ready","dist-tags":{"latest":"0.2.0"},"versions":{"0.0.4":{"name":"@agentlane/agent-ready","version":"0.0.4","keywords":["ai","agents","sdlc","linter","definition-of-ready","jira","github-issues","copilot","claude-code","cursor"],"license":"MIT","_id":"@agentlane/agent-ready@0.0.4","maintainers":[{"name":"syedshoaib","email":"syedschoaib@icloud.com"}],"homepage":"https://github.com/agentlane/agent-ready#readme","bugs":{"url":"https://github.com/agentlane/agent-ready/issues"},"bin":{"story-lint":"dist/cli.js","agent-ready":"dist/cli.js"},"dist":{"shasum":"bf259d00e0a39f211a93b11c68d7faeef7a23c0d","tarball":"https://registry.npmjs.org/@agentlane/agent-ready/-/agent-ready-0.0.4.tgz","fileCount":22,"integrity":"sha512-Sxd+yfW+gycBHqqPTqzseksJ4+o/h7ZWGI5zdpQrEcnlVnMrqio7RCLQK7Aaxnww8ZFV+7rTSCWU1E4yncyefg==","signatures":[{"sig":"MEYCIQCXX3hgXFR/l1cSTWqCaytQQot8vnJg4CPPjnKMC+uiDAIhAPrGioXVYF9niAmf3xT2T77yR1UiWFYTUuUPAXrc/qMP","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":46119},"main":"dist/lint.js","type":"module","types":"dist/lint.d.ts","engines":{"node":">=20"},"scripts":{"test":"node --test test/*.test.js","build":"tsc","start":"node dist/cli.js","check:bad":"node dist/cli.js check examples/tickets/bad-ticket.json","check:good":"node dist/cli.js check examples/tickets/good-ticket.json"},"_npmUser":{"name":"syedshoaib","email":"syedschoaib@icloud.com"},"repository":{"url":"git+https://github.com/agentlane/agent-ready.git","type":"git"},"_npmVersion":"11.8.0","description":"Make every ticket ready for AI coding agents — a Definition-of-Ready linter.","directories":{},"_nodeVersion":"25.5.0","dependencies":{"yaml":"^2.6.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.6.0","@types/node":"^22.9.0"},"_npmOperationalInternal":{"tmp":"tmp/agent-ready_0.0.4_1779025146223_0.2798161084444426","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@agentlane/agent-ready","version":"0.2.0","description":"Make every ticket ready for AI coding agents — a Definition-of-Ready linter.","type":"module","bin":{"agent-ready":"dist/cli.js","agent-ready-mcp":"dist/mcp/server.js","story-lint":"dist/cli.js"},"main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./adapters":{"types":"./dist/adapters/index.d.ts","import":"./dist/adapters/index.js"},"./render":{"types":"./dist/render/index.d.ts","import":"./dist/render/index.js"},"./types":{"types":"./dist/types.d.ts","import":"./dist/types.js"},"./mcp":{"types":"./dist/mcp/server.d.ts","import":"./dist/mcp/server.js"}},"scripts":{"build":"tsc","start":"node dist/cli.js","check:bad":"node dist/cli.js check examples/tickets/bad-ticket.json","check:good":"node dist/cli.js check examples/tickets/good-ticket.json","test":"node --test test/*.test.js","example:sdk":"node examples/sdk/programmatic.mjs"},"engines":{"node":">=20"},"keywords":["ai","agents","sdlc","linter","definition-of-ready","jira","github-issues","copilot","claude-code","cursor"],"license":"MIT","dependencies":{"@modelcontextprotocol/sdk":"^1.29.0","yaml":"^2.6.0"},"devDependencies":{"@types/node":"^22.9.0","typescript":"^5.6.0"},"repository":{"type":"git","url":"git+https://github.com/agentlane/agent-ready.git"},"bugs":{"url":"https://github.com/agentlane/agent-ready/issues"},"homepage":"https://github.com/agentlane/agent-ready#readme","gitHead":"dbff89df3cd5c0896167a495010619ca675212fa","_id":"@agentlane/agent-ready@0.2.0","_nodeVersion":"22.22.2","_npmVersion":"11.14.1","dist":{"integrity":"sha512-S1xWTRxyYRGQjy3uiL/Wj5MWLwQjtckH036MNWJtsQ/Z64q4krM9SwSOXazmE1T2kUHI2gCPLBvpIn1mm7aaPw==","shasum":"0322aa21c6bb5325ecd845a4b9370a0bbda39d62","tarball":"https://registry.npmjs.org/@agentlane/agent-ready/-/agent-ready-0.2.0.tgz","fileCount":52,"unpackedSize":124614,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@agentlane%2fagent-ready@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDiMWJtUlulP/H44kEbcbASrh+p7uA/HguZRJjOA5ar5QIge8hbOTRFgzTogQg87Lyk4v6cIBI8h0+7Wl9bEJVUhqg="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:330f48f9-854d-441b-8f64-7b3af019f2dc"}},"directories":{},"maintainers":[{"name":"syedshoaib","email":"syedschoaib@icloud.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/agent-ready_0.2.0_1779196331056_0.5853039171651124"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-17T13:39:06.109Z","modified":"2026-05-19T13:12:11.526Z","0.0.4":"2026-05-17T13:39:06.395Z","0.2.0":"2026-05-19T13:12:11.204Z"},"bugs":{"url":"https://github.com/agentlane/agent-ready/issues"},"license":"MIT","homepage":"https://github.com/agentlane/agent-ready#readme","keywords":["ai","agents","sdlc","linter","definition-of-ready","jira","github-issues","copilot","claude-code","cursor"],"repository":{"type":"git","url":"git+https://github.com/agentlane/agent-ready.git"},"description":"Make every ticket ready for AI coding agents — a Definition-of-Ready linter.","maintainers":[{"name":"syedshoaib","email":"syedschoaib@icloud.com"}],"readme":"# agent-ready\n\n> The Definition-of-Ready gate for AI coding agents.\n\n[![CI](https://github.com/agentlane/agent-ready/actions/workflows/ci.yml/badge.svg)](https://github.com/agentlane/agent-ready/actions/workflows/ci.yml) [![npm](https://img.shields.io/npm/v/@agentlane/agent-ready)](https://www.npmjs.com/package/@agentlane/agent-ready) [![GitHub release](https://img.shields.io/github/v/release/agentlane/agent-ready)](https://github.com/agentlane/agent-ready/releases) [![License](https://img.shields.io/github/license/agentlane/agent-ready)](LICENSE)\n\nBefore Copilot, Cursor, Claude Code, Codex, or any custom agent picks up a ticket, `agent-ready` checks whether that ticket has enough context to produce a safe, correct PR.\n\n**Bad ticket in → exact gaps out — in 50 ms, before any tokens are spent.**\n\n![agent-ready demo](docs/demo.gif)\n\n```bash\n$ npx @agentlane/agent-ready check examples/tickets/bad-ticket.json\n\n✗ PROJ-1234  not ready  (4 blocker(s), 7 warning(s))\nSignals: path C | context T2 | risk medium\n\n  ✗ has-acceptance-criteria       No acceptance criteria found (need at least 1)\n  ⚠ has-definition-of-done        No Definition of Done found\n  ✗ has-repo-target               Ticket does not specify the target repo\n  ✗ has-risk-classification       No risk classification label\n  ⚠ has-test-expectations         No test expectations described\n  ⚠ no-ambiguous-verbs            Ambiguous verb(s): improve, make it better\n  ✗ body-min-length               Body too short: 91 chars (need >= 100)\n  ⚠ no-tribal-knowledge           Tribal-knowledge phrase(s): you know what i mean\n  ⚠ t-shirt-size-present          No t-shirt size estimate\n  ⚠ has-design-link               UI ticket has no design link\n  ⚠ restricted-paths-declared     Restricted-scope signals without risk:high: checkout\n```\n\n```bash\n$ npx @agentlane/agent-ready check examples/tickets/good-ticket.json\n\n✓ PROJ-2042  ready  (10 checks passed, 1 warning(s))\nSignals: path B | context T2 | risk low\n```\n\n## Try it in 30 seconds\n\n```bash\nnpx @agentlane/agent-ready check https://github.com/agentlane/agent-ready/issues/1 --adapter github\n```\n\nNo install needed. Uses `gh auth token` or `GITHUB_TOKEN` automatically.\n\n---\n\n## Why agent-ready exists\n\nEvery team adopting AI coding agents hits the same wall:\n\n> **Garbage tickets → garbage PRs.**\n\nAgents are confident and fast. Without a clear ticket, that's a liability — they invent context, miss the real requirement, and silently burn tokens chasing the wrong thing.\n\n`agent-ready` is the **front door** of the agentic SDLC: an automated readiness gate that runs in 50 ms, plugs into the workflows your team already uses, and produces machine-readable verdicts agents can act on.\n\n### Before vs. after\n\n| Without `agent-ready` | With `agent-ready` |\n|---|---|\n| Agent invents missing context | Ticket validated before agent picks it up |\n| Vague verbs slip through (\"improve\", \"clean up\") | Ambiguous verbs flagged at issue-open time |\n| No design link → agent guesses UI | UI tickets require a Figma/Miro link |\n| Agent burns tokens on a half-baked ticket | CI fails fast (50 ms) before any tokens are spent |\n| No repo target → wrong codebase modified | `repo:` field enforced as a blocker |\n| Subjective PR review (\"this doesn't match the ticket\") | Objective AC checklist baked into the ticket |\n| No data on what makes agents succeed | Feedback loop surfaces which rules predict success |\n\n### How it's different\n\n- **Pure linter, not another agent framework.** `agent-ready` doesn't try to write tickets, run agents, or review PRs. It does one thing: grade the readiness of a ticket. That's why it's 50 ms and 800 lines of TypeScript, not a platform.\n- **Pluggable into every surface.** CLI, GitHub Action, MCP tool, Node SDK, and observability sinks — the same lint engine, exposed five ways. Pick the surface that fits your stack.\n- **Deterministic signals.** Every check emits `path_recommendation` (A/B/C), `context_tier` (T1/T2/T3), and `risk_classification` (low/medium/high) — so downstream agents and policy engines route on objective fields, not free text.\n- **Policy-as-code via OPA.** Built-in rules cover the common cases; Rego policies handle your org-specific governance.\n- **Closes the loop.** Record agent outcomes against `run_id` and surface which rules actually predict success.\n\n---\n\n## Five ways to integrate\n\nThe same lint engine, exposed five ways. Pick the surface that fits your stack — they're not exclusive:\n\n| Surface | Best for | Latency | Setup |\n|---|---|---|---|\n| **CLI** | Local dev, CI scripts | ~50 ms | `npx @agentlane/agent-ready` |\n| **GitHub Action** | Auto-check on issue-open | ~3 s cold | Drop YAML in `.github/workflows` |\n| **MCP server** | Claude Desktop, Cursor, custom agents | ~50 ms in-process | Add to MCP config |\n| **Node SDK** | Custom orchestrators, embedded checks | direct call | `import { lintTicket }` |\n| **Telemetry sinks** | Dashboards, trend analysis (Grafana, Langfuse, OTel) | fire-and-forget | Add `output.sinks` to rule pack |\n\nAll five share one rule pack, one schema, and one verdict.\n\n---\n\n## Who is this for?\n\n- **Open-source maintainers** — gate AI-generated PRs before accepting them; require issues to meet your readiness bar first\n- **Platform / DevEx teams** — enforce a pre-flight check before any coding agent starts work, company-wide\n- **DevSecOps & governance teams** — auditable, automated evidence that restricted-scope tickets declared risk correctly; OPA policy bridge for policy-as-code\n- **Product owners** — force better specs before engineering starts; catch \"as discussed\" and missing AC early\n- **Teams using Copilot, Cursor, Claude Code, Codex, or any custom agent** — stop wasting tokens on half-baked tickets\n\n---\n\n## Install\n\n```bash\n# One-off use with a local ticket file\nnpx @agentlane/agent-ready check <path-to-ticket-json>\n\n# Or fetch a real GitHub Issue\nnpx @agentlane/agent-ready check owner/repo#123 --adapter github\n\n# Or install globally\nnpm i -g @agentlane/agent-ready\nagent-ready check ./ticket.json\n\n# Or install as a library for programmatic use\nnpm install @agentlane/agent-ready\n```\n\n> Supports local JSON tickets, GitHub Issues, Jira Cloud, and Linear out of the box.\n\n---\n\n## CLI\n\n```bash\n# Lint a ticket\nagent-ready check examples/tickets/bad-ticket.json\nagent-ready check agentlane/agent-ready#1 --adapter github\nagent-ready check PROJ-123 --adapter jira\nagent-ready check TEAM-123 --adapter linear\n\n# Use a custom rule pack\nagent-ready check ./ticket.json --rules ./my-rules.yaml\n\n# Output formats\nagent-ready check ./ticket.json --format text       # default (human)\nagent-ready check ./ticket.json --format markdown   # PR comment\nagent-ready check ./ticket.json --format json       # machine-readable\nagent-ready check ./ticket.json --format sarif      # GitHub code-scanning\n\n# Skip telemetry sinks for this run\nagent-ready check ./ticket.json --no-telemetry\n\n# Record agent outcomes for the feedback loop\nagent-ready feedback record --ticket-id PROJ-123 --outcome success --run-id <uuid> --duration-min 22\n\n# Report on recorded outcomes\nagent-ready feedback report --runs .agent-ready/runs.jsonl\n```\n\n**Exit codes:** `0` ready · `1` not ready · `2` usage error.\n\n### Auth\n\n| Adapter | Required env vars |\n|---|---|\n| **GitHub** | `GITHUB_TOKEN` / `GH_TOKEN` (or `gh auth token` automatically) |\n| **Jira Cloud** | `JIRA_BASE_URL`, `JIRA_EMAIL`, `JIRA_API_TOKEN` |\n| **Linear** | `LINEAR_API_KEY` |\n\n```bash\n# Jira\nexport JIRA_BASE_URL=https://acme.atlassian.net\nexport JIRA_EMAIL=you@example.com\nexport JIRA_API_TOKEN=...   # https://id.atlassian.com/manage-profile/security/api-tokens\nagent-ready check PROJ-123 --adapter jira\n\n# Linear\nexport LINEAR_API_KEY=lin_api_...   # https://linear.app/settings/api\nagent-ready check TEAM-123 --adapter linear\n```\n\n---\n\n## Node SDK\n\nCall `lintTicket` directly — no CLI shell-out:\n\n```ts\nimport { lintTicket, loadTicketFromFile, renderText } from \"@agentlane/agent-ready\";\nimport { readFile } from \"node:fs/promises\";\nimport { parse as parseYaml } from \"yaml\";\n\nconst pack = parseYaml(\n  await readFile(\"node_modules/@agentlane/agent-ready/rule-packs/default.yaml\", \"utf8\")\n);\n\nconst ticket = await loadTicketFromFile(\"./ticket.json\");\nconst result = await lintTicket(ticket, pack, { adapter: \"file\", rulePackName: \"default\" });\n\nconsole.log(result.ready);      // true | false\nconsole.log(result.signals);    // { path_recommendation, context_tier, risk_classification }\nconsole.log(result.run_id);     // UUIDv4 — join key for feedback events\nconsole.log(renderText(result));\n```\n\nSub-path imports: `@agentlane/agent-ready/adapters`, `@agentlane/agent-ready/render`, `@agentlane/agent-ready/types`.\n\nFull API reference: [docs/sdk.md](docs/sdk.md).\n\n---\n\n## MCP server\n\n`agent-ready` ships an MCP (Model Context Protocol) server. Wire it into Claude Desktop or Cursor once, then any agent can call the `agent_ready_check` tool inline as part of its reasoning loop.\n\n```json\n{\n  \"mcpServers\": {\n    \"agent-ready\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"--package=@agentlane/agent-ready\", \"agent-ready-mcp\"],\n      \"env\": { \"GITHUB_TOKEN\": \"ghp_...\" }\n    }\n  }\n}\n```\n\nThe tool accepts `target`, `adapter`, `rules`, and `format`, and returns the full `LintOutput` JSON. Agents can now reason about `ready`, `signals`, and per-rule `checks` without an external shell-out.\n\n> **Use case:** \"Claude, before you implement issue #42, check it with agent-ready.\" The agent calls the tool, reads the gaps, and asks you to add acceptance criteria before writing any code.\n\nFull setup (Claude Desktop, Cursor, custom Node clients): [docs/mcp.md](docs/mcp.md).\n\n---\n\n## GitHub Action\n\nAvailable on the [GitHub Marketplace](https://github.com/marketplace/actions/agent-ready-check). Drop into `.github/workflows/agent-ready.yml`:\n\n```yaml\nname: Agent-Ready Check\non:\n  issues:\n    types: [opened, edited, labeled]\n\njobs:\n  check:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: read\n      issues: write\n    steps:\n      - uses: actions/checkout@v4\n      - uses: agentlane/agent-ready@v0\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n          rules: .agent-ready/rules.yaml   # optional\n          comment-on-issue: true\n          fail-on-not-ready: true\n          set-label: true                  # adds/removes the `agent-ready` label\n```\n\nThe action fetches the triggering issue, lints it, posts a Markdown comment, and (when `set-label: true`) toggles the `agent-ready` label on each pass/fail. Step outputs: `ready`, `failed-count`, `warnings-count`.\n\n**Passing-issue comment:**\n\n![agent-ready Action comment](docs/comment-screenshot.png)\n\n### Trigger a coding agent only when ready\n\nBecause the action toggles a label, a second workflow can dispatch your agent **exactly once per passing issue** — not on every edit:\n\n```yaml\n# .github/workflows/start-agent.yml\non:\n  issues:\n    types: [labeled]\njobs:\n  dispatch:\n    if: github.event.label.name == 'agent-ready'\n    runs-on: ubuntu-latest\n    steps:\n      - run: echo \"Issue ${{ github.event.issue.number }} is ready — dispatch agent here\"\n        # Replace with: gh workflow run, invoke Copilot, call Claude Code CLI, etc.\n```\n\nFull walkthrough examples: [docs/use-cases.md](docs/use-cases.md).\n\n---\n\n## What it checks\n\n### 12 built-in rules\n\n| Rule | What it looks for |\n|---|---|\n| `has-acceptance-criteria` | At least N acceptance criteria (numbered list, checklist, or Given/When) |\n| `has-definition-of-done` | A DoD section in the body |\n| `has-repo-target` | `repo:` in the body or a `repo:<name>` label |\n| `has-risk-classification` | A `risk:low`/`risk:medium`/`risk:high` label |\n| `has-design-link` | Figma/Ardoq/Miro/Excalidraw link present when the ticket has a `ui`/`ux`/`frontend` label |\n| `has-test-expectations` | \"How to verify\" / test plan / Playwright / Jest / Pytest mentioned |\n| `no-ambiguous-verbs` | Flags vague verbs (`improve`, `optimize`, `clean up`, `refactor`, `enhance`, …) |\n| `body-min-length` | Body is at least 100 characters (configurable) |\n| `no-tribal-knowledge` | Flags phrases like \"as discussed\", \"you know what I mean\", \"the usual way\" |\n| `t-shirt-size-present` | `size:` in the body or a `size:S\\|M\\|L\\|XL` label |\n| `restricted-paths-declared` | Auth/payment/identity/IAM/infra signals without a `risk:high` label |\n| `llm-judge-ambiguity` | LLM clarity score with one-sentence explanation — **opt-in** (`enabled: false`) |\n| `links-resolve` | URLs in the body return HTTP 200 — **opt-in** (offline-CI-friendly default) |\n\n### Three rule extension points\n\n1. **Built-in overrides** — tune severity, thresholds, and keywords per rule\n2. **Custom regex rules** — `type: regex` for project-specific patterns (e.g. \"must link to an epic\")\n3. **OPA policies** — `type: opa` for full Rego policy-as-code, evaluated against ticket + signals\n\n### Why not just use issue templates?\n\nIssue templates **guide humans**. `agent-ready` **enforces readiness automatically**. Use both: templates for authoring, `agent-ready` for the gate.\n\n---\n\n## Rule pack format\n\nRule packs are plain YAML. One file can mix all three rule types and configure telemetry sinks:\n\n```yaml\n# .agent-ready/rules.yaml\nversion: 1\nextends: default\n\nrules:\n  # Built-in overrides\n  has-acceptance-criteria:\n    enabled: true\n    min_count: 2\n    severity: error\n\n  no-ambiguous-verbs:\n    severity: warn\n    extra_terms: [tidy, polish, modernize]\n\n  # Optional LLM judge\n  llm-judge-ambiguity:\n    enabled: true\n    provider: openai\n    model: gpt-4o-mini\n    threshold: 0.6\n    api_key_env: OPENAI_API_KEY\n\n  # Custom regex rule\n  must-link-epic:\n    type: regex\n    pattern: 'EPIC-\\d+'\n    field: body\n    severity: error\n    message: \"Ticket must link to a parent epic (EPIC-XXX)\"\n\n  # OPA policy rule\n  enforce-pii-risk:\n    type: opa\n    mode: remote\n    server: http://localhost:8181\n    query: data.pii.decision\n    severity: error\n\n# Deterministic routing thresholds\nsignals:\n  risk_classification:\n    default: medium\n    label_prefix: \"risk:\"\n  path_recommendation:\n    default: A\n    warning_threshold: 2\n    ui_value: B\n    warning_value: B\n    fail_value: C\n    high_risk_value: C\n  context_tier:\n    default: T1\n    body_length_t2: 800\n    body_length_t3: 2000\n\n# Optional: emit results to dashboards / OTel / a file\noutput:\n  sinks:\n    - type: webhook\n      url: https://collector.example.com/agent-ready\n      headers: { Authorization: \"Bearer ${WEBHOOK_TOKEN}\" }\n    - type: jsonl\n      path: .agent-ready/runs.jsonl\n    - type: otel\n      endpoint: http://localhost:4318/v1/traces\n```\n\nJSON Schemas live in [`schema/`](schema/) — rule pack ([`rule-pack.schema.json`](schema/rule-pack.schema.json)) and output ([`output.schema.json`](schema/output.schema.json)). The output schema is stable across versions; downstream tools can safely consume it.\n\n---\n\n## Signals: deterministic routing for downstream agents\n\nEvery lint produces three signals derived from the rule results and labels — designed to drive deterministic routing in agent orchestrators:\n\n| Signal | Values | Meaning |\n|---|---|---|\n| `path_recommendation` | `A` / `B` / `C` | A = autonomous, B = supervised, C = humans only |\n| `context_tier` | `T1` / `T2` / `T3` | How much context the agent needs (RAG depth, token budget) |\n| `risk_classification` | `low` / `medium` / `high` | Derived from `risk:*` label or default |\n\nA downstream agent runner reads `signals.path_recommendation` and dispatches to the appropriate model + policy. Thresholds are fully configurable per rule pack.\n\n---\n\n## Policy-as-code (OPA)\n\nDelegate decisions to [Open Policy Agent](https://www.openpolicyagent.org/) policies written in Rego. Two modes: REST server (`mode: remote`) or `opa eval` CLI (`mode: embedded`).\n\n```yaml\nrules:\n  enforce-pii-risk:\n    type: opa\n    mode: remote\n    server: http://localhost:8181\n    query: data.pii.decision\n    severity: error\n```\n\nOPA rules run **after** built-in rules and receive derived `signals` as input — so policies can enforce conditional risk routing based on the full lint context.\n\nThree ready-to-use example policies in [`examples/policies/`](examples/policies/):\n- `pii.rego` — restrict PII tickets to `risk:high`\n- `payment.rego` — require `risk:high` + `size:L|XL` for payment work\n- `infra.rego` — require `risk:high` and a rollback plan for infra changes\n\nFull reference: [docs/opa.md](docs/opa.md).\n\n---\n\n## Telemetry\n\nEmit each `LintOutput` to one or more observability sinks (webhook, JSONL, OTel) — for dashboards, trend analysis, and joining to downstream agent outcomes. All sinks are fail-soft.\n\n```yaml\noutput:\n  sinks:\n    - type: webhook\n      url: https://collector.example.com/agent-ready\n      headers: { Authorization: \"Bearer ${WEBHOOK_TOKEN}\" }\n    - type: jsonl\n      path: .agent-ready/runs.jsonl\n    - type: otel\n      endpoint: http://localhost:4318/v1/traces\n```\n\n- `webhook` — POST JSON with env-var interpolation, 5 s timeout, no retry\n- `jsonl` — append one line per run; parent dirs created automatically\n- `otel` — single OTLP/HTTP span with signals as attributes and `CheckResult`s as events\n\nPass `--no-telemetry` to skip sinks for a single run.\n\nFull reference: [docs/telemetry.md](docs/telemetry.md).\n\n---\n\n## Feedback loop\n\nEvery `LintOutput` carries a `run_id` (UUIDv4). Record agent outcomes against it, then surface which rules actually predict success:\n\n```bash\n# 1. Lint and capture the run_id\nRUN_ID=$(agent-ready check PROJ-123 --adapter github --format json | jq -r '.run_id')\n\n# 2. ... agent runs ...\n\n# 3. Record the outcome\nagent-ready feedback record \\\n  --ticket-id PROJ-123 \\\n  --run-id \"$RUN_ID\" \\\n  --outcome success \\\n  --duration-min 22\n\n# 4. Per-outcome counts + per-rule predictive value table\nagent-ready feedback report --runs .agent-ready/runs.jsonl\n```\n\n```\nTotal recorded runs: 42\n  ✓ success    28  (67%)\n  ~ partial     9  (21%)\n  ✗ failure     5  (12%)\n\nPer-rule predictive value:\n  Rule                        Pass→Success  Fail→Success  Signal\n  ───────────────────────────────────────────────────────────────\n  has-acceptance-criteria     91%           23%           strong ↑\n  has-test-expectations       88%           31%           strong ↑\n  body-min-length             79%           44%           moderate\n  t-shirt-size-present        62%           71%           inverse ↓\n```\n\nHigh-signal rules are reliable early-warnings — strong candidates for raising severity. Low-signal rules are candidates for tuning down. Full reference: [docs/feedback.md](docs/feedback.md).\n\n---\n\n## How it composes with the rest of your stack\n\n`agent-ready` is the **first** gate. It doesn't replace your existing tools — it makes them work better:\n\n| Tool | What it does | When it runs |\n|---|---|---|\n| **`agent-ready`** | Is this *ticket* ready for an agent? | Issue open → before agent picks up |\n| Spec Kit / Linear specs | Authoring help for the spec itself | While writing the ticket |\n| Your AI coding agent | Implements the change | After `agent-ready` passes |\n| Gatepack *(planned)* | Per-PR signed evidence bundle (includes `agent-ready` pre-flight) | After agent submits PR |\n| Evidence Gate Action | Traditional CI evidence (SBOM, SAST, tests) | During CI |\n| OPA / your policy engine | Decision enforcement | Throughout |\n\n### Gatepack pre-flight shape\n\nGatepack can store the JSON output under `pre_flight.agent_ready`. Fields intended for deterministic joining:\n\n```json\n{\n  \"pre_flight\": {\n    \"agent_ready\": {\n      \"schema_version\": \"1.2\",\n      \"run_id\": \"f47ac10b-58cc-4372-a567-0e02b2c3d479\",\n      \"ticket_id\": \"#123\",\n      \"source\": { \"adapter\": \"github\", \"url\": \"https://github.com/agentlane/agent-ready/issues/123\" },\n      \"rule_pack\": \"default\",\n      \"rule_pack_version\": \"1\",\n      \"rule_pack_hash\": \"sha256...\",\n      \"signals\": {\n        \"path_recommendation\": \"B\",\n        \"context_tier\": \"T2\",\n        \"risk_classification\": \"medium\"\n      },\n      \"ready\": true,\n      \"summary\": { \"passed\": 12, \"failed\": 0, \"warnings\": 1 }\n    }\n  }\n}\n```\n\n---\n\n## Status\n\n**Current development: 0.2.0** — pluggable Agentic SDLC component.\n\nShipped in 0.2.0:\n- **SDK surface** — barrel export and `exports` map (`@agentlane/agent-ready`, `/adapters`, `/render`, `/types`)\n- **MCP server** — `agent_ready_check` tool for Claude Desktop, Cursor, and custom agents\n- **Telemetry** — webhook, JSONL, and OTel sinks with env-var interpolation\n- **OPA bridge** — `type: opa` rules in remote or embedded mode, three example policies\n- **Feedback loop** — `run_id` on `LintOutput`, `feedback record/report` CLI, predictive value report\n- **Native Jira & Linear adapters** — full CLI parity with GitHub adapter\n\nCarried from 0.0.x: 12 built-in rules, regex custom rules, JSON/markdown/text/SARIF renderers, GitHub Action with label setter (Docker-based), CI on every PR. 204 passing tests, all verified end-to-end.\n\n### Pinning\n\nGitHub Action users should pin either:\n\n```yaml\n- uses: agentlane/agent-ready@v0.2.0  # exact release\n- uses: agentlane/agent-ready@v0      # floating major tag — always latest stable\n```\n\n### Roadmap\n\nTrack planned work in [GitHub Issues](https://github.com/agentlane/agent-ready/issues). Near-term highlights:\n\n- Expand Jira and Linear adapter coverage (ADF rendering, custom fields, sprints)\n- LLM judge for `no-ambiguous-verbs` — opt-in ([#17](https://github.com/agentlane/agent-ready/issues/17))\n- VS Code extension: lint as you type\n- Node plugin loader for custom rules (beyond regex)\n\n---\n\n## Contributing\n\nRules are the easiest contribution path — one rule = one entry in `src/rules/built-in.ts` + one fixture in `examples/tickets/`.\n\n**Good first contributions (no deep codebase knowledge needed):**\n- Add a new readiness rule\n- Add a bad/good ticket example pair\n- Write a use-case walkthrough in `docs/`\n- Improve Jira or Linear adapter coverage (e.g. ADF rendering, custom fields, sprints)\n- Add an enterprise rule-pack example\n- Author an OPA policy for `examples/policies/`\n\nBrowse [good first issues](https://github.com/agentlane/agent-ready/issues?q=is%3Aopen+label%3A%22good+first+issue%22) · [open an issue](https://github.com/agentlane/agent-ready/issues/new/choose) · PRs welcome.\n\n## License\n\nMIT.\n","readmeFilename":"README.md"}