[
  {
    "type": "function",
    "function": {
      "name": "acceptance_criteria_validator",
      "description": "QA advisor: validate acceptance criteria quality. POST a list of AC (or a story) and get per-AC problems (vague/untestable, non-atomic, no observable outcome) + a missing-coverage flag if there is no failure-path AC, plus a 0-100 score and pass/needs_work verdict. Tells you exactly what to fix. Deterministic, no LLM. Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "properties": {
          "acceptance_criteria": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "story": {
            "type": "string"
          },
          "strictness": {
            "type": "string",
            "enum": [
              "normal",
              "strict"
            ]
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "alignment_gate",
      "description": "Run an AI system prompt (and optional agent config) through a 45-criterion alignment/safety rubric. Returns a letter grade (A-F), numeric score, per-flag remediation, and a pass/fail verdict. Costs 2 credits per call.",
      "parameters": {
        "type": "object",
        "required": [
          "system_prompt"
        ],
        "properties": {
          "system_prompt": {
            "type": "string",
            "description": "The system prompt text to evaluate."
          },
          "agent_config": {
            "type": "object",
            "description": "Optional agent config (tools, memory, temperature, etc.)."
          },
          "model_id": {
            "type": "string",
            "description": "Optional target model identifier."
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "blm_land_lookup",
      "description": "Look up Bureau of Land Management land status for a US coordinate: BLM ownership, jurisdiction, allowed activities (rockhounding, camping), permit requirements, and special designations (ACEC, Wilderness, WSA, NM/NCA). Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "required": [
          "lat",
          "lon"
        ],
        "properties": {
          "lat": {
            "type": "number",
            "description": "Latitude, -90 to 90."
          },
          "lon": {
            "type": "number",
            "description": "Longitude, -180 to 180."
          },
          "radius_km": {
            "type": "number",
            "description": "Optional buffer radius in km (0-50, default 1.0)."
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "coverage_check",
      "description": "Scope-completeness advisor. POST a brief (or requirements[]) + your stories[] and get a coverage score + the gaps (requirements no story covers), orphan stories (possible scope creep), and missing structural buckets (auth/CRUD/error-states/tests). Tells you what the scope is missing. Deterministic, no LLM. Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "required": [
          "stories"
        ],
        "properties": {
          "brief": {
            "type": "string"
          },
          "requirements": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "stories": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "defect_triage",
      "description": "Bug-triage advisor. POST one bug report (or a list) and get severity (critical/high/medium/low), category, whether it has repro steps, and what info is missing (no repro / no expected-vs-actual / no environment). For a list: priority ranking + likely-duplicate clusters. Deterministic, no LLM. Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "properties": {
          "report": {
            "type": "string"
          },
          "reports": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "dependency_check",
      "description": "Dependency-manifest hygiene check. POST package manifests (package.json, requirements.txt, pyproject.toml, go.mod, Gemfile, composer.json, pubspec.yaml, lockfiles) or an upload_id and get findings with severity + concrete fixes: wildcard/unbounded versions, missing lockfiles, unpinned installs, non-https indexes, install-script risks, dependency-confusion signals, and matches against a static snapshot of famously compromised packages. NOT a live CVE feed - pair with npm audit / pip-audit / osv-scanner for that. Deterministic, no network, no LLM. Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "properties": {
          "manifests": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "filename": {
                  "type": "string"
                },
                "content": {
                  "type": "string"
                }
              },
              "required": [
                "filename",
                "content"
              ]
            },
            "description": "Up to 20 manifest files inline."
          },
          "upload_id": {
            "type": "string",
            "description": "Alternative: a single manifest uploaded via the uploads tool."
          },
          "filename": {
            "type": "string",
            "description": "Required with upload_id so the manifest type can be detected."
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "diagram_contrast",
      "description": "Diagram quality QA. Catch and fix the things that ruin diagrams: (1) unreadable label contrast - POST a mermaid/SVG or HTML diagram, get every WCAG-AA failure (incl. mermaid <style>-block label colors, with unresolvable fills flagged honestly, not false-passed) + auto-corrected colors; (2) harden a mermaid SOURCE before it renders - rewrites every fill/label pair and remaps fills no label color can rescue, which scanning cannot do because a per-node style line overrides the theme block; (3) HTML-looks-fine-but-prints-broken - checks for the print-color-adjust/page-break gotchas and returns the fix CSS; (4) arrows crossing objects - returns the ELK-renderer config + layout rules that minimize crossings. Pure deterministic - no AI, no rate limit. Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "scan",
              "harden",
              "contrast",
              "readable",
              "palette",
              "print",
              "layout"
            ],
            "description": "Default \"scan\". scan=check rendered output; harden=fix a mermaid source before rendering; print=print-safety check; layout=arrow-crossing reduction."
          },
          "content": {
            "type": "string",
            "description": "scan/print: the SVG or HTML diagram/document source."
          },
          "source": {
            "type": "string",
            "description": "harden: the mermaid SOURCE text (not rendered SVG)."
          },
          "format": {
            "type": "string",
            "enum": [
              "svg",
              "html"
            ],
            "description": "scan: content format (default svg)."
          },
          "autofix": {
            "type": "boolean",
            "description": "scan: include suggested corrected colors."
          },
          "add_init": {
            "type": "boolean",
            "description": "harden: prepend the %%{init}%% theme block (default true)."
          },
          "fg": {
            "type": "string",
            "description": "contrast: foreground hex (#rrggbb)."
          },
          "bg": {
            "type": "string",
            "description": "contrast/readable: background/fill hex (#rrggbb)."
          },
          "large": {
            "type": "boolean",
            "description": "contrast/harden: use the 3:1 large-text threshold."
          },
          "brand": {
            "type": "string",
            "description": "brand palette to use (e.g. appstango). Default from config."
          },
          "renderer": {
            "type": "string",
            "description": "layout: mermaid renderer (default \"elk\")."
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "humanize",
      "description": "Rewrite text to remove AI-writing tells. POST prose and get it back with the mechanical tells fixed (AI vocabulary swapped for plain words, filler phrases stripped, em-dash overuse reduced, significance inflation deflated) plus a change log, before/after ai-ness scores, and a residual list of tells that need human judgment (not auto-rewritten). Code fences, inline code, URLs, and quotes are never touched. Deterministic, no LLM. Sister to humanizer_score (the detector). Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "required": [
          "text"
        ],
        "properties": {
          "text": {
            "type": "string",
            "description": "The prose to rewrite (up to 100k chars)."
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "humanizer_score",
      "description": "Detect AI-writing tells in text. POST prose and get a 0-1 ai_ness score + band (low/medium/high) + the EXACT patterns that fired (AI vocabulary, significance inflation, promotional language, filler phrases, negative parallelism, rule-of-three, em-dash overuse) with sample spans. Explainable, not an opaque classifier - every point is a named, located pattern. Deterministic, no LLM. The rewrite is a separate step. Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "required": [
          "text"
        ],
        "properties": {
          "text": {
            "type": "string",
            "description": "The prose to score (up to 100k chars)."
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "log_analyzer",
      "description": "Analyze a log file. POST raw log text (or an upload_id from the uploads tool, up to 5MB) and get: level breakdown + time range, error clusters (messages normalized so variable ids/numbers collapse into one signature, with counts + first/last seen + a sample), a timeline, detected anomalies (error spikes, retry storms, new error signatures, log gaps/outages, level-ratio shifts) with evidence, and templated recommendations. Handles JSON-lines and plain formats (ISO8601/syslog/CLF/epoch timestamps). Deterministic, single-pass, no LLM. Costs 2 credits per call.",
      "parameters": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "description": "Raw log content (up to 1M chars)."
          },
          "upload_id": {
            "type": "string",
            "description": "Alternative: a log file uploaded via the uploads tool."
          },
          "top_n": {
            "type": "number",
            "description": "Top clusters to return (1-50, default 10)."
          },
          "format": {
            "type": "string",
            "enum": [
              "auto",
              "json",
              "plain"
            ]
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "log_audit_creator",
      "description": "Generate a concrete audit-logging spec for an app. POST your feature list (and optional compliance targets: soc2/hipaa/gdpr/pci) and get a full audit-event catalog (namespaced event names, actor/target/required fields, PII flags, retention), a canonical event envelope schema, a storage plan (append-only, access control, alerting), and per-framework compliance notes. A dev team can implement it directly. Deterministic, no LLM. Retention/compliance figures are common-practice defaults to verify with counsel. Costs 2 credits per call.",
      "parameters": {
        "type": "object",
        "properties": {
          "features": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "App features, e.g. [\"user login\", \"payments\", \"file upload\"]."
          },
          "compliance": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "soc2",
                "hipaa",
                "gdpr",
                "pci"
              ]
            }
          },
          "description": {
            "type": "string",
            "description": "Optional free-text app description (scanned for features)."
          },
          "stack": {
            "type": "string"
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "model_advisor",
      "description": "LLM selection + cost advisor. POST a task description (+ optional volume/tokens/constraints like local-only or cheap) and get a recommended model + fallback chain + do-not-use (with reasons), the complexity tier, and per-run + monthly cost. A maintained model+price catalog. Deterministic, no LLM. Tells the AI/user which model to use and what it costs. Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "required": [
          "task"
        ],
        "properties": {
          "task": {
            "type": "string"
          },
          "volume_per_month": {
            "type": "number"
          },
          "tokens_in": {
            "type": "number"
          },
          "tokens_out": {
            "type": "number"
          },
          "constraints": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "saas_metrics",
      "description": "SaaS health advisor. POST your MRR/customers (+ optional churn/CAC/margin/growth) and get ARR/ARPA/LTV/CAC/payback/Rule-of-40/NRR/GRR computed, each with a health tag, plus an overall grade + a ranked \"what to fix first\" focus list. Deterministic math + advisory, no LLM. Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "required": [
          "mrr",
          "customers"
        ],
        "properties": {
          "mrr": {
            "type": "number"
          },
          "customers": {
            "type": "number"
          },
          "prior_mrr": {
            "type": "number"
          },
          "new_mrr": {
            "type": "number"
          },
          "churned_mrr": {
            "type": "number"
          },
          "expansion_mrr": {
            "type": "number"
          },
          "cac": {
            "type": "number"
          },
          "gross_margin_pct": {
            "type": "number"
          },
          "sales_marketing_spend": {
            "type": "number"
          },
          "new_customers": {
            "type": "number"
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "sprint_health",
      "description": "Sprint/delivery health advisor. POST 1-24 sprints (committed/completed points, optional per-ticket estimate-vs-actual data) and get computed metrics each with a good/warn/bad health tag: velocity avg + trend + stability, commitment reliability, spillover rate, mid-sprint scope change, estimate accuracy (median + chronic-overrun pct), and WIP concentration per assignee. Plus an overall grade and a ranked what-to-fix-first focus list. Pure math + advisory, no LLM. Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "required": [
          "sprints"
        ],
        "properties": {
          "sprints": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Oldest first: [{name, committed_points, completed_points, added_points?, spillover_points?, tickets?: [{key, estimate_hours, actual_hours, status, assignee}]}]."
          },
          "team_size": {
            "type": "number"
          },
          "sprint_length_days": {
            "type": "number",
            "description": "Default 10."
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "ticket_lint",
      "description": "Full Jira-ticket quality linter (whole ticket, not just AC - use acceptance_criteria_validator for the deep AC pass). POST one ticket or a batch (max 50) and get per-ticket findings with severity + concrete fixes: missing/weak summary or description, missing AC or estimate, bugs without repro/expected-vs-actual/environment, missing epic link, points-vs-hours mismatch, oversized estimates to split, urgent-but-thin tickets. Returns score, grade, and a ready/needs_work verdict per ticket plus batch summary. Type-aware rules (story/bug/task/epic/subtask), strict profile available. Deterministic, no LLM. Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "properties": {
          "ticket": {
            "type": "object",
            "description": "One ticket: {key, summary, description, acceptance_criteria, issue_type, estimate_hours|story_points, priority, labels, components, epic_link, ...}. Missing fields ARE findings."
          },
          "tickets": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Alternative: batch of up to 50 tickets."
          },
          "profile": {
            "type": "string",
            "enum": [
              "normal",
              "strict"
            ]
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "uploads",
      "description": "Get a presigned S3 PUT URL to upload a file (policy doc, config, log, up to 5MB) that a file-ingesting endpoint then reads by upload_id. Two-step: call this, PUT your file to the returned url, then pass upload_id to the consuming endpoint. Uploads auto-expire in 1 day and are readable only by your key. Auth required; not billed.",
      "parameters": {
        "type": "object",
        "properties": {
          "content_type": {
            "type": "string",
            "description": "MIME type of the file you will PUT (e.g. text/plain, application/json). Default application/octet-stream."
          }
        }
      }
    }
  },
  {
    "type": "function",
    "function": {
      "name": "worklog_guardrail",
      "description": "Worklog/timesheet policy checker - run a batch of worklog entries through configurable guardrails BEFORE posting them to a time-tracking system. Checks: rounding increment (default 0.25h, float-safe), per-entry min/max, per-author daily totals, duplicates, over-estimate alerts (never suggests inflating hours or estimates - flags to PM instead), future dates, weekends, immutable-author edit protection, missing description/ticket. Returns pass/warnings/blocked verdict + per-entry violations with fixes + hour totals by author and date. Caller supplies the reference date - fully deterministic, no LLM. Costs 1 credit per call.",
      "parameters": {
        "type": "object",
        "required": [
          "entries",
          "today"
        ],
        "properties": {
          "entries": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Up to 500: [{author, date \"YYYY-MM-DD\", hours, ticket?, description?, estimate_hours?, already_logged_hours?, id?, edit?, delete?, new?}]."
          },
          "today": {
            "type": "string",
            "description": "Reference date \"YYYY-MM-DD\" for future-date checks."
          },
          "policy": {
            "type": "object",
            "description": "Optional overrides: rounding_increment, max_hours_per_day, max_hours_per_entry, min_hours_per_entry, immutable_authors, require_description, require_ticket, over_estimate_policy (alert|block|ignore), future_dates (block|alert), weekend_policy (allow|alert)."
          }
        }
      }
    }
  }
]
