{
  "version": "2026-09-18",
  "product": "warestack",
  "docs_base": "https://documentation.warestack.com",
  "purpose": "Single catalog for docs crawlers, org Claude/Codex, and a future Warestack MCP. Propose a pack. Do not enable. Do not invent IDs.",
  "availability_statuses": {
    "available": "Shipped product surface or authorable template.",
    "available_when_installed": "Shipped capability that requires its workspace integration or agent installation.",
    "week_one": "Recommended for a bounded first enablement.",
    "later": "Shipped and available, but left off the recommended first enablement.",
    "candidate_only": "Name eligible people; the individual must enable it.",
    "not_generally_available": "Not a generally available self-serve control. Do not claim it is enabled.",
    "unknown": "Evidence or readiness cannot be established without guessing."
  },
  "honesty": [
    "A ticket key in a branch, title, body, or Refs: is not a Linear association in Warestack's store.",
    "A Linear parent does not cover child issues or sibling PRs. Associate each PR with the issue that describes its diff.",
    "Bot reviews and the pull-request author do not count toward human approvals.",
    "GitHub login is not a Slack handle. An owner for Review SLA is a person who can receive a Slack DM.",
    "Merge-blocking stays off until the team asks to require the Warestack Rules check in branch protection.",
    "Run now on a report rebuilds SQL. Slack announce is the scheduled_report chain calendar.",
    "Production changelog fires on GitHub deployment_succeeded in production or prod, not on merge or waiting.",
    "Personal digest is opt-in per person. An admin cannot enable it for someone else.",
    "Linear agent is mention-only and must not invent owner/repo#n when no PR is linked.",
    "The console calls the live queue Overview > Needs attention. Digest copy may say Today and opens Overview.",
    "Pull-request stacks stay inside one repository. Cross-repository guards are not generally available.",
    "A chain marked later can still be shipped and authorable. Later is rollout guidance, not product unavailability.",
    "Dedicated SOC 2 period export and a complete exception-register UI are maturity items, not shipped self-serve surfaces.",
    "Write unknown instead of guessing an owner, channel, ticket, or environment.",
    "Do not invent a seventh funnel, a new card shape, or a second scheduler."
  ],
  "week_one": {
    "do_not_number_as": "1-8",
    "id_warning": "Catalog rule 1 is concise PRs. Linear-in-store is custom.linear_issue_required.",
    "rules": [
      "custom.linear_issue_required",
      7,
      8,
      12,
      "custom.conventions",
      "custom.feature_test_evidence",
      13,
      "custom.evidence_in_approval_body"
    ],
    "chains": [
      "pull_request_slack_live_card",
      "pull_request_review_sla",
      "scheduled_report",
      "production_rollout_changelog"
    ],
    "personal_digest": "candidate_only",
    "merge_blocking": false,
    "scope": "prefer_1_or_2_production_repos"
  },
  "surfaces": [
    {
      "route": "/overview",
      "name": "Overview and Needs attention",
      "status": "available",
      "jobs": ["for_me_attention", "for_space_attention", "personal_digest_customize"]
    },
    {
      "route": "/events",
      "name": "Events and timelines",
      "status": "available",
      "jobs": ["activity_feed", "attention_filter", "event_detail", "timeline", "rule_findings"]
    },
    {
      "route": "/events/stacks",
      "name": "Pull-request stacks",
      "status": "available",
      "boundary": "same_repository_only",
      "identity_sources": ["github_native", "warestack_detected"]
    },
    {
      "route": "/rules",
      "name": "Rules",
      "status": "available"
    },
    {
      "route": "/chains",
      "name": "Chains",
      "status": "available",
      "jobs": ["author", "enable", "pause", "dry_run", "activity"]
    },
    {
      "route": "/slack",
      "name": "Slack",
      "status": "available",
      "jobs": ["live_card", "request_update", "review_sla", "commands", "digests", "changelog"]
    },
    {
      "route": "/linear",
      "name": "Linear association and workspace agent",
      "status": "available_when_installed",
      "default_agent_mode": "read_only_governance"
    },
    {
      "route": "/reports",
      "name": "Reports",
      "status": "available",
      "jobs": ["natural_language_to_reviewable_sql", "preview", "run_history", "csv"]
    },
    {
      "route": "/metrics",
      "name": "Metrics",
      "status": "available"
    },
    {
      "route": "/people",
      "name": "People",
      "status": "available",
      "jobs": ["members", "identities", "requests"]
    },
    {
      "route": "/repositories",
      "name": "Repositories",
      "status": "available",
      "jobs": ["monitoring_scope", "individual_owner", "branch_protection_visibility"]
    }
  ],
  "propose": {
    "inspect": [
      "Open and merged PRs in the last 14 days on production-path repos",
      "Linear attachments vs ticket-string-only vs none",
      "Who requested review, who approved, whether the body cites a named check/command/result",
      "CODEOWNERS and GitHub teams vs who actually reviewed",
      "Slack channels that already get deploy or review noise",
      "GitHub deployments: environment names, success vs failure, associated PRs",
      "Default-branch workflow failures and waiting deployment reviews",
      "Same-repository pull-request stacks and their blocked layers",
      "Repo pairs that moved together",
      "People with a plausible Slack identity for DMs or a digest"
    ],
    "output": [
      "status_per_proposal",
      "in_scope_repos_or_team",
      "individual_owner_per_repo",
      "reviewer_pool",
      "rules_on_with_pr_examples",
      "chains_on",
      "report_intents",
      "live_card_channel",
      "digest_and_changelog_channels",
      "personal_digest_candidates",
      "production_environment_name",
      "linear_active_states",
      "cross_repo_pairs",
      "open_questions"
    ],
    "status_values": [
      "week_one",
      "on",
      "off",
      "later",
      "candidate_only",
      "not_generally_available",
      "unknown"
    ],
    "needs_to_objects": [
      {
        "observe": "PRs with no Linear association, or only a key in the title/branch/Refs",
        "propose": ["custom.linear_issue_required", 7, 8, 12]
      },
      {
        "observe": "feat/ or refactor/ merged or open with fewer than two human APPROVEs",
        "propose": [13, "custom.evidence_in_approval_body"]
      },
      {
        "observe": "APPROVE bodies that are LGTM, looks good, or tested with no named result",
        "propose": ["custom.evidence_in_approval_body"]
      },
      {
        "observe": "feat/ source changes with no test file and no concrete Testing section",
        "propose": ["custom.feature_test_evidence"]
      },
      {
        "observe": "Requested reviews sitting in GitHub with no human review",
        "propose": ["pull_request_review_sla", "identities.individual_owner"]
      },
      {
        "observe": "Successful GitHub deployments in production or prod",
        "propose": ["production_rollout_changelog"]
      },
      {
        "observe": "Need a weekly sample for Vanta or engineering ops",
        "propose": ["scheduled_report", "report.merged_prs_open_findings"]
      },
      {
        "observe": "One GitHub team owns many production repos",
        "propose": ["scope.team_for_rules_and_live_card", "identities.individual_owner_still_required"]
      },
      {
        "observe": "Two repos must stay isolated (separate owners, channels, or blast radius)",
        "propose": ["scope.repository"]
      },
      {
        "observe": "API and frontend or schema and migrations moved in the same window",
        "propose": ["cross_repo.named_pair_draft"]
      },
      {
        "observe": "Reviewers or owners already live in Slack and miss GitHub noise",
        "propose": ["personal_digest.candidates_only"]
      },
      {
        "observe": "Large PRs without tests, stale PRs, failed main CI, bot-only approval",
        "propose": ["later_chain_kinds"]
      },
      {
        "observe": "Several dependent pull requests form one same-repository branch chain",
        "propose": ["/events/stacks"]
      },
      {
        "observe": "Operators need to prove whether a chain delivered, skipped, or failed",
        "propose": ["/chains/activity"]
      },
      {
        "observe": "A GitHub-writing chain needs evidence before enablement",
        "propose": ["/chains/dry-run"]
      }
    ]
  },
  "rules": {
    "catalog": [
      {
        "id": 1,
        "name": "Require concise pull requests",
        "propose_when": "PRs are routinely huge and reviews stall.",
        "do_not": "Treat lockfile-only diffs as the same size cap without excluding them."
      },
      {
        "id": 2,
        "name": "Require atomic commits",
        "propose_when": "Commits mix unrelated work and the audit trail is unreadable.",
        "typical_parameter": "lines_per_commit"
      },
      {
        "id": 3,
        "name": "Route review requests based on branch prefixes",
        "propose_when": "feat/ should always request a named reviewer pool."
      },
      {
        "id": 4,
        "name": "Route review requests based on file paths",
        "propose_when": "Path ownership exists (CODEOWNERS or a stable directory map)."
      },
      {
        "id": 5,
        "name": "Detect review fatigue",
        "propose_when": "A few people hold most open review requests."
      },
      {
        "id": 6,
        "name": "Require a linked ticket",
        "note": "Accepts Linear or GitHub issue in Warestack's store. The recommended Linear-first set uses custom.linear_issue_required instead."
      },
      {
        "id": 7,
        "name": "Require linked ticket to be assigned",
        "propose_when": "Tickets exist but nobody owns the work."
      },
      {
        "id": 8,
        "name": "Require active linked ticket",
        "propose_when": "PRs link Done/Backlog issues. Confirm which workflow states count as active."
      },
      {
        "id": 9,
        "name": "Require timely acknowledgment of review requests",
        "note": "This is a finding. Review SLA DMs are chain pull_request_review_sla."
      },
      {
        "id": 10,
        "name": "Require timely updates for draft pull requests",
        "propose_when": "Drafts sit idle for days."
      },
      {
        "id": 11,
        "name": "Require timely acknowledgment of high-priority linked tickets",
        "propose_when": "Urgent Linear or Critical GitHub issues are ignored."
      },
      {
        "id": 12,
        "name": "Detect pull request scope drift",
        "propose_when": "Diffs do not match the linked issue."
      },
      {
        "id": 13,
        "name": "Require approvals by branch prefix",
        "propose_when": "feat/ and refactor/ need two humans. Bots and author do not count.",
        "default_params": {
          "feat/": 2,
          "refactor/": 2,
          "fix/": 1,
          "test/": 1,
          "chore/": 1,
          "docs/": 1,
          "ci/": 1
        }
      }
    ],
    "custom": [
      {
        "id": "custom.linear_issue_required",
        "name": "Require a Linear issue in Warestack's store",
        "tightens": 6
      },
      {
        "id": "custom.conventions",
        "name": "Branch, PR, and commit conventions",
        "requires": [
          "<type>/<linear-issue>-<imperative-description>",
          "Conventional Commit title",
          "body summary and bullets",
          "Testing section",
          "Refs:",
          "matching commit trail"
        ]
      },
      {
        "id": "custom.feature_test_evidence",
        "name": "Feature test evidence",
        "requires": "Relevant tests, or a Testing section naming the behavior and a concrete reason.",
        "rejects": ["generic N/A", "not tested"],
        "does_not_claim": "coverage percentage"
      },
      {
        "id": "custom.evidence_in_approval_body",
        "name": "Evidence in the approval body"
      }
    ],
    "reeval": "Warestack Rules run on pull_request opened, synchronized, and edited. A GitHub review updates the live card immediately but does not by itself re-run the check."
  },
  "chain_kinds": [
    {
      "id": "pull_request_slack_live_card",
      "when": "subscribed_triggers on pull_request events",
      "then": "notify live_card on Slack; optional 12h no-review reminder",
      "availability": "available",
      "rollout": "week_one",
      "week_one": true,
      "docs": "/slack"
    },
    {
      "id": "pull_request_review_sla",
      "when": "review_requested",
      "then": "DM reviewer at 4h, then individual repository_owner at 24h by default",
      "availability": "available",
      "rollout": "week_one_if_ready",
      "week_one": true,
      "docs": "/slack/review-sla",
      "requires": "confirmed Slack identities"
    },
    {
      "id": "production_rollout_changelog",
      "when": "deployment_succeeded",
      "condition": "environment is production (matches GitHub prod)",
      "then": "wait pull_requests_associated <=300s, then Slack announce rollout_changelog with PRs or unassociated commit and monitoring link",
      "availability": "available",
      "rollout": "week_one",
      "week_one": true,
      "docs": "/slack/changelog",
      "scope": "deploy-producing repository"
    },
    {
      "id": "scheduled_report",
      "when": "schedule",
      "then": "run_report then Slack announce",
      "availability": "available",
      "rollout": "week_one",
      "week_one": true,
      "docs": "/slack/digests",
      "note": "Run now is not the announce step"
    },
    {
      "id": "personal_digest",
      "when": "schedule weekday local time",
      "then": "private Overview Needs attention For me snapshot",
      "availability": "candidate_only",
      "rollout": "candidate_only",
      "week_one": "candidate_only",
      "available_in_create": false,
      "docs": "/slack/digests",
      "owner_only": true,
      "history_limit_in_console": 7,
      "delivery_attempts_max": 2,
      "retry_minutes": 10,
      "empty_behavior": "skip without message"
    },
    {
      "id": "urgent_pr_needs_reviewer",
      "availability": "available",
      "rollout": "later",
      "week_one": false,
      "note": "Default template includes block_merge. Do not enable as a gate in the first enablement."
    },
    {
      "id": "reviewer_at_capacity",
      "availability": "available",
      "rollout": "later",
      "week_one": false
    },
    {
      "id": "breaking_schema_change",
      "availability": "available",
      "rollout": "later",
      "week_one": false,
      "note": "Default includes block_merge and evaluates one repository. Cross-repository counterpart enforcement is not_generally_available."
    },
    {
      "id": "cicd_change_without_owner_review",
      "availability": "available",
      "rollout": "later",
      "week_one": false,
      "note": "Default includes block_merge."
    },
    {
      "id": "from_scratch",
      "availability": "available",
      "rollout": "later",
      "week_one": false,
      "note": "Shown separately after the opinionated templates. Use only if no named kind fits; do not invent unsupported events or steps."
    },
    {
      "id": "rule_fired_act",
      "availability": "available",
      "rollout": "later",
      "week_one": false,
      "note": "Default includes fail_check."
    },
    {
      "id": "stale_pull_request",
      "availability": "available",
      "rollout": "later",
      "week_one": false,
      "note": "Waits in configured business hours, then nudges the author and team lead."
    },
    {
      "id": "deployment_review_waiting",
      "availability": "available",
      "rollout": "later",
      "week_one": false
    },
    {
      "id": "failed_workflow_default_branch",
      "availability": "available",
      "rollout": "later",
      "week_one": false,
      "note": "Can announce and optionally create a deduplicated Linear issue."
    },
    {
      "id": "large_pr_without_tests",
      "availability": "available",
      "rollout": "later",
      "week_one": false,
      "note": "Default comments and adds needs-tests."
    },
    {
      "id": "issue_live_card",
      "availability": "available",
      "rollout": "later",
      "week_one": false
    },
    {
      "id": "deployment_review_live_card",
      "availability": "available",
      "rollout": "later",
      "week_one": false
    },
    {
      "id": "review_feedback_follow_up",
      "availability": "available",
      "rollout": "later",
      "week_one": false
    },
    {
      "id": "bot_approval_needs_human",
      "availability": "available",
      "rollout": "later",
      "week_one": false
    },
    {
      "id": "repository_without_owner",
      "availability": "available",
      "rollout": "later",
      "week_one": false
    }
  ],
  "reports": {
    "object": "Saved SQL with run history. Delivery is always a scheduled_report chain.",
    "status": "available",
    "authoring": ["natural_language_ask", "review_sql", "preview_rows", "save", "run_history", "csv"],
    "honesty": "Optional AI analysis does not replace saved SQL, rows, timestamps, or delivery history.",
    "intents": [
      {
        "id": "report.failed_workflow_runs_7d",
        "title": "Failed workflow runs from the past 7 days"
      },
      {
        "id": "report.merged_prs_open_findings",
        "title": "Merged PRs still showing unresolved high findings"
      },
      {
        "id": "report.prs_missing_linear",
        "title": "Open or merged PRs missing a Linear association"
      },
      {
        "id": "report.reviews_waiting",
        "title": "Requested reviews with no human review"
      },
      {
        "id": "report.sla_breaches",
        "title": "Review SLA breaches in the window"
      },
      {
        "id": "report.repos_missing_owner",
        "title": "Governed repos missing an individual owner"
      },
      {
        "id": "report.failed_production_deploys",
        "title": "Failed production deployments"
      }
    ]
  },
  "dry_run": {
    "status": "available",
    "docs": "/chains/dry-run",
    "effect": "none",
    "supported_evidence": ["pull_request", "review", "rule_event"],
    "unsupported_triggers": [
      "deployment",
      "workflow",
      "issue",
      "repository_ownership",
      "schedule"
    ],
    "required_before_enable": "Current definition of a chain with a GitHub-writing step.",
    "enable_is_not_backfill": true
  },
  "automation_activity": {
    "status": "available",
    "docs": "/chains/activity",
    "person_delivery_statuses": ["delivered", "skipped", "failed"],
    "terminal_outcomes": [
      "completed",
      "reminded",
      "escalated",
      "condition_met",
      "skipped",
      "cancelled",
      "failed"
    ]
  },
  "events": {
    "status": "available",
    "docs": "/events",
    "jobs": ["activity_feed", "attention_filter", "event_detail", "timeline", "findings"],
    "pull_request_stacks": {
      "status": "available",
      "docs": "/events/stacks",
      "boundary": "same_repository_only",
      "identity_sources": ["github_native", "warestack_detected"],
      "cross_repository": false
    }
  },
  "metrics": {
    "status": "available",
    "docs": "/metrics",
    "analytics": [
      "deployment_frequency",
      "failed_deployments",
      "lead_time_for_changes",
      "review_turnaround_time",
      "stale_and_aging_prs",
      "prs_merged_without_proper_review"
    ],
    "overview": [
      "prs_merged",
      "prs_opened",
      "prs_shipped_rate",
      "deployments_total",
      "deployments_failed",
      "time_to_first_review_median",
      "review_comments_total",
      "review_comments_unresolved",
      "actionable_review_threads"
    ]
  },
  "scope": {
    "types": ["repository", "team", "path", "space"],
    "week_one": "repository unless one team clearly owns the in-scope repos",
    "owner": "individual person with GitHub plus Slack. A team cannot receive a Slack DM.",
    "path": "Changed-file boundary inside authorized repositories; only where the event/condition supports paths.",
    "cross_repo_guards": {
      "status": "not_generally_available",
      "self_serve": false,
      "contract": "Explicit repository IDs in one space, bounded counterpart evidence, unknown when unavailable.",
      "families": ["schema_contract", "database_migrations", "frontend_backend_compatibility"]
    }
  },
  "people_and_repositories": {
    "status": "available",
    "people_docs": "/people",
    "repository_docs": "/repositories",
    "people_jobs": ["members", "github_slack_identities", "access_requests", "team_invitations"],
    "repository_jobs": ["monitoring_scope", "individual_owner", "branch_protection_visibility"],
    "branch_protection_managed_in": "github"
  },
  "soc2": {
    "vanta_role": "GRC system of record",
    "warestack_role": "Operate and preserve engineering change-management evidence.",
    "available": ["saved_report_runs", "csv", "event_timelines", "production_changelog", "identity_and_owner_evidence"],
    "not_generally_available": [
      "dedicated_period_export",
      "complete_exception_register_ui",
      "self_serve_cross_repository_guards"
    ]
  },
  "mcp": {
    "status": "not_shipped",
    "shared_payload": "/catalog.json",
    "intended_tools": [
      {
        "name": "warestack.catalog",
        "returns": "this document"
      },
      {
        "name": "warestack.propose_pack",
        "input": "org signals from GitHub, Linear, Slack (last 14 days)",
        "returns": "recommended first-enablement pack using only IDs in this catalog",
        "side_effects": "none"
      },
      {
        "name": "warestack.explain_rule",
        "input": "rule id or custom id"
      },
      {
        "name": "warestack.explain_chain",
        "input": "chain kind id"
      }
    ]
  }
}
